support all colmap distortion models

This commit is contained in:
Harry Chen
2026-08-10 23:27:04 -04:00
parent c033971528
commit d126a7e875
435 changed files with 127983 additions and 24847 deletions
+4
View File
@@ -2,5 +2,9 @@
This project's instructions live in [AGENTS.md](AGENTS.md). Read that file.
If you are an agent writing code here, the one section you are most likely to
get wrong is **[Comments](AGENTS.md#comments--write-fewer-and-shorter)**. Read it before
you write your first comment, not after the review.
(A real file rather than a symlink, so Windows checkouts without
`core.symlinks` still get usable content.)
+8 -5
View File
@@ -51,9 +51,15 @@ list(REMOVE_DUPLICATES TORCH_CUDA_ARCH_LIST)
message(STATUS "CUDA architecture(s): ${TORCH_CUDA_ARCH_LIST}")
# "<arch>-real" emits cubin only; the bare form also emits PTX. See
# SS_CUDA_EMBED_PTX in SsOptions.cmake for why the default drops it.
set(CMAKE_CUDA_ARCHITECTURES "")
foreach(arch ${TORCH_CUDA_ARCH_LIST})
list(APPEND CMAKE_CUDA_ARCHITECTURES "${arch}")
if(SS_CUDA_EMBED_PTX)
list(APPEND CMAKE_CUDA_ARCHITECTURES "${arch}")
else()
list(APPEND CMAKE_CUDA_ARCHITECTURES "${arch}-real")
endif()
endforeach()
# ---------------------------------------------------------------------------
@@ -101,10 +107,7 @@ if(SS_DEBUG_SYMBOLS)
list(APPEND SPLAT_NVCC_FLAGS "-lineinfo" "--generate-line-info" "--source-in-ptx")
endif()
# Add gencode flags
foreach(arch ${TORCH_CUDA_ARCH_LIST})
list(APPEND SPLAT_NVCC_FLAGS "-gencode" "arch=compute_${arch},code=sm_${arch}")
endforeach()
# Host side optimizations
if(NOT WIN32)
+8
View File
@@ -91,6 +91,14 @@ option(SS_SEPARATE_TOOLS "Also build spirula-sfm / spirula-sam standalone" OFF)
# in the embedded SPIR-V). Turn on for profiling/debugging builds.
option(SS_DEBUG_SYMBOLS "Emit debug symbols / line info (host -g, CUDA cubin lineinfo, SPIR-V -g2)" OFF)
# Embed PTX alongside the cubin in the CUDA fatbin. PTX is only useful for
# JIT onto an architecture the binary was NOT built for, and the CUDA build
# detects the local GPU's compute capability from nvidia-smi, so a dev build
# carries it for nothing -- it is a third of every object file, and the
# per-(camera model, distortion tier) kernel instantiations make that a third
# of a large binary. Turn it on for a redistributable build.
option(SS_CUDA_EMBED_PTX "Embed PTX in the CUDA fatbin for forward-compatible JIT" OFF)
# ---------------------------------------------------------------------------
# Compute backend selection
#
+1
View File
@@ -69,6 +69,7 @@ without reconfiguring, e.g. `-B build_cuda` and `-B build`.
| `SS_SEPARATE_TOOLS` | `OFF` | *also* build `spirula-sfm` and `spirula-sam` standalone — same code, but neither links the engine (24 MB vs the combined 61 MB) |
| `SS_BUILD_BACKEND_TESTS` | `OFF` | build `backend/tests/*` (CUDA branch; Vulkan always builds them) |
| `SS_DEBUG_SYMBOLS` | `OFF` | host `-g`, CUDA cubin lineinfo, `slangc -g2`. Bloats binaries substantially — profiling/debugging only. |
| `SS_CUDA_EMBED_PTX` | `OFF` | embed PTX beside the cubin in the CUDA fatbin. Only buys JIT onto an architecture the binary was not built for, and costs about a third of every object; the build already detects the local GPU. Turn on for a redistributable binary. |
| `SS_SLANGC` | *(empty)* | path to a `slangc` to use; empty means find on PATH and fetch the pinned release on miss/mismatch |
| `SS_BUILD_SFM` | `ON` for `vulkan`, `OFF` for `cuda` | `ss_sfm` + `spirula sfm` + `sfm_*_test`. Vulkan-only; a CUDA build can opt in if the Vulkan SDK is present. |
| `SS_BUILD_SAM` | `ON` for `vulkan`, `OFF` for `cuda` | `ss_nn` + `ss_sam` + `spirula sam` + `nn_ops_test` / `sam_pipeline_test`, and the GUI's in-process masking. Same rule as SfM. |
+85 -6
View File
@@ -26,18 +26,97 @@ cameras), and equirectangular/spherical. See `src/core/CameraModel.h` — it is
plain C++17 with no CUDA dependency, which is why the WASM viewer can reuse
it.
COLMAP writes 18 camera models; `ColmapParser.cpp` knows every id (it has to,
to advance the `cameras.bin` read cursor) but maps only the ones the engine can
project. `EQUIRECTANGULAR` (id 17) is the spherical one: its params are `(w, h)`
COLMAP writes 18 camera models and `ColmapParser.cpp` accepts every one.
`EQUIRECTANGULAR` (id 17) is the spherical one: its params are `(w, h)`
rather than a calibration, because the image *is* the calibration. It reaches
the same `CameraModelType::EQUIRECTANGULAR` as a Metashape `spherical` sensor,
with the same convention — +Z forward at the image centre, azimuth wrapping at
the left/right edge — so the two formats describe an identical camera and
`bake_post_split` treats them identically. Note the engine's canonical panorama
intrinsics assume a 2:1 (360°×180°) image; the parser warns when one is not.
`RAD_TAN_THIN_PRISM_FISHEYE`, `SIMPLE_DIVISION`, `DIVISION`, `EUCM` and `FOV`
are recognised but rejected with a named error — there is no undistortion for
them on the engine side.
## Lens distortion tiers
Distortion is a separate axis from the camera model, and a COMPILE-TIME one:
a template argument in CUDA, a `kDistortion` specialization constant on Vulkan.
The four tiers, cheapest first, are `None`, `OpenCV` (`k1 k2 p1 p2`),
`ThinPrism` (`k1 k2 k3 k4 p1 p2 sx1 sy1`, COLMAP's `THIN_PRISM_FISHEYE`) and
`Rational` (`k1..k6 p1 p2`, COLMAP's `FULL_OPENCV`, where `k4..k6` divide).
A slot index does NOT mean the same thing across tiers. `core/CameraModel.h`
is the one definition; `shaders/projection_utils.slang` is the one
implementation, generic over an `ICameraDistortion`.
The parser picks the CHEAPEST tier that represents the source camera exactly,
so a PINHOLE dataset costs no distortion registers at all and a `FULL_OPENCV`
camera whose `k4..k6` are zero demotes to `ThinPrism`
(`camera_distortion_demote`). Only eleven (model, tier) pairs are compiled —
no COLMAP fisheye model is rational, and EQUIRECTANGULAR carries no distortion.
`camera_distortion_is_compiled()` is that list, and it must stay in step with
`kCameraVariants` in `tools/codegen/generate_kernel_instantiation.py` and the
export list in `shaders/primitive_3dgs.slang`.
A `transforms.json` is ambiguous about what `k4` means -- OpenCV's first
rational DENOMINATOR term, or Kannala-Brandt's / Metashape's fourth RADIAL one.
An explicit `camera_distortion` key settles it (`MetashapeParser` always writes
one); failing that, a fisheye camera is Kannala-Brandt, `k5`/`k6` mean rational
on their own, and the mere PRESENCE of `b1`/`b2`/`sx1`/`sy1` -- keys a rational
camera never carries -- makes `k4` radial. That last rule is what a
Metashape-converted `transforms.json` needs: reading its `k4` as a denominator
is a different lens, not a small error.
`FOV`, `SIMPLE_DIVISION`, `DIVISION`, `EUCM` and `RAD_TAN_THIN_PRISM_FISHEYE`
have no exact tier, and neither does a Metashape sensor skew (`b2`), which is
an off-diagonal pixel term where every tier's pixel map is diagonal. They are
fitted onto a (model, `ThinPrism`) pair by near-minimax regression
(`data/DistortionFit.h`).
`fit_camera_auto` chooses the camera model from the source's MEASURED field of
view, not from its name: a COLMAP `FOV` lens is perspective at omega 0.3 and a
180-degree fisheye at omega 0.87, and forcing the second onto a pinhole target
puts `tan(85 deg) = 11.4` into a degree-8 polynomial and fails. It then walks a
coefficient ladder (all eight, no thin prism, no `k3`/`k4`, ..., none) until the
fitted distortion is invertible everywhere sampled. **It never fails**: a
dataset that took hours to reconstruct must not refuse to load over a lens
model, so the worst case is a plain fisheye and a warning, not an exception.
A fit closer than `dsfit::kExactFitPx` (0.1 px) is left alone -- the fitted
camera already reproduces the source to better than bilinear resampling can
resolve, so re-distorting would only cost VRAM and blur. In practice that
covers `FOV`, both division models and `EUCM`; `RAD_TAN_THIN_PRISM_FISHEYE` and
a real `b2` do not reach it. When it is not reached, the source model goes into
`ParsedDataset::redistort`, which makes `bake_post_split` set `any_warp` even at
K = 1 so the images route through the warp path's staging and get resampled.
The resampling reads the TRUE source projection (`shaders/camera_source.slang`,
the one place those models live on device; `data/SourceCamera.h` is the host
mirror, and the two must agree exactly) rather than the fit -- going through the
fit would be a no-op. Source model ids 0..17 are COLMAP's own `CameraModelId`
values with COLMAP's parameter array verbatim; ours start at 1000 so COLMAP can
keep appending to its enum.
A source model is sampled only where its image still grows outward as the ray
tilts off axis. Past that it has folded -- at the lens border for a polynomial
fisheye, well inside the frame for the division and unified models -- and two
directions share a pixel, so a warped face would be ringed by a mirrored copy
of the image instead of ending at the lens. Those rays are dropped, and the
synthesized FOV mask drops them by the same test. The fit domain stops earlier
still, where the radial rate falls below a quarter of its on-axis value: at the
fold itself no fitted distortion is invertible, so the coefficient ladder would
degrade a camera the tier otherwise reproduces to a fraction of a pixel.
Two paths, both gathering per destination pixel:
- **K = 1** (`kernels/pixelwise/ImageRedistort.cu`): destination pixel ->
ray through the fitted camera -> source pixel. The fit leaves the pose alone,
so a destination pixel and its source pixel are the SAME ray: depth (linear or
ray) and camera-frame normals transfer unchanged and only the sampling
coordinate moves. None of GtDepthNormalWarp.cu's point-space handling applies.
- **K > 1** (warp_to_pinhole): the cubemap face ray projects STRAIGHT through
the source camera, so the fitted camera is never materialized and the two
passes cost one kernel and no intermediate image. `RayToPixel<D, kFromSource>`
is the seam; `kFromSource` is a template argument (a specialization constant
on Vulkan) so an ordinary dataset pays neither the branch nor the 16 registers
the source parameters occupy.
## Two-stage parse
+1 -1
View File
@@ -48,7 +48,7 @@ be re-derived or re-attempted: D25, D26, D27, D11, D16, D47, D50, D45, D46.
| D31 | Geometry core on unit bearings (D29 phase B) |
| D32 | Kannala-Brandt fisheye model (COLMAP OPENCV_FISHEYE); per-real atan by Newton |
| D33 | Wide-FOV cheirality + physical fisheye focal init (D29 phase D) |
| D34 | THIN_PRISM_FISHEYE + reduced FULL_OPENCV models |
| D34 | THIN_PRISM_FISHEYE + FULL_OPENCV models |
| D35 | GPU pair selection instead of exhaustive pairing (or a vocab tree) |
| D36 | Mapper robustness: refined+gated registration, iterated refinement with retriangulation, and undo |
| D37 | Mapper time: incremental next-image scoring + retuned BA cadence |
+1 -1
View File
@@ -450,7 +450,7 @@ setup carried in `matches.bin`; BA solver (dense Cholesky, implicit-Schur PCG,
`float`/`double`/`df`, Huber/Cauchy, dof-tiered Schur kernels).
**Camera models.** SIMPLE_PINHOLE, PINHOLE, SIMPLE_RADIAL, RADIAL, OPENCV,
FULL_OPENCV (reduced), OPENCV_FISHEYE (Kannala-Brandt, past 180°),
FULL_OPENCV, OPENCV_FISHEYE (Kannala-Brandt, past 180°),
THIN_PRISM_FISHEYE, EQUIRECTANGULAR — with the principal point held constant
by default and one principal-point-free global BA at the end for a single
camera group.
+4 -2
View File
@@ -693,7 +693,7 @@ void TrainerSession::setup_engine() {
dm.mask_boundary_offset = cfg.mask_boundary_offset;
dm.warp_to_pinhole = cfg.warp_to_pinhole;
engine_setup_data_manager(
dm, ds.camera_models,
dm, ds.camera_models, ds.camera_distortions,
ds.image_filenames, ds.mask_filenames,
has_depth ? ds.depth_filenames : std::vector<std::string>{},
has_normal ? ds.normal_filenames : std::vector<std::string>{},
@@ -702,6 +702,7 @@ void TrainerSession::setup_engine() {
post.any_warp ? post.post_offsets : std::vector<int32_t>{},
post.viewmats, post.intrins, post.dist_coeffs,
post.input_intrins, post.input_dist_coeffs,
post.redistort_models, post.redistort_params,
ds.train_indices, ds.val_indices);
// ---- Bilagrid / PPISP init -----------------------------------------
@@ -1039,13 +1040,14 @@ void TrainerSession::eval() {
{
std::lock_guard<std::mutex> lk(engine_mutex);
engine_setup_data_manager(
dm, eds.camera_models,
dm, eds.camera_models, eds.camera_distortions,
eds.image_filenames, eds.mask_filenames, {}, {},
eds.widths, eds.heights,
epost.any_warp ? epost.K_per_camera : std::vector<int32_t>{},
epost.any_warp ? epost.post_offsets : std::vector<int32_t>{},
epost.viewmats, epost.intrins, epost.dist_coeffs,
epost.input_intrins, epost.input_dist_coeffs,
epost.redistort_models, epost.redistort_params,
all_idx, {});
}
+48 -29
View File
@@ -277,39 +277,56 @@ constexpr double kPi = 3.14159265358979323846; // MSVC has no M_PI by default
struct P3 { float x, y, z; };
bool has_distortion(const float* d) {
for (int i = 0; i < 10; i++) if (d[i] != 0.0f) return true;
bool has_distortion(int tier, const float* d) {
if (tier == (int)CameraDistortionType::None) return false;
for (int i = 0; i < kCameraDistortionParams; i++) if (d[i] != 0.0f) return true;
return false;
}
// dist = [k1 k2 k3 k4 p1 p2 s1 s2 b1 b2] (projection_utils.cuh:1166)
void distort_pt(double u, double v, const float* d, double out[2]) {
// Host mirror of the tier structs in shaders/projection_utils.slang; the slot
// order differs per tier, which is why the tier travels with the coefficients.
void distort_pt(double u, double v, int tier, const float* d, double out[2]) {
double r2 = u*u + v*v;
if (tier == (int)CameraDistortionType::None) {
out[0] = u; out[1] = v;
return;
}
if (tier == (int)CameraDistortionType::OpenCV) {
double radial = 1 + r2*(d[0] + r2*d[1]);
out[0] = u*radial + 2*d[2]*u*v + d[3]*(r2 + 2*u*u);
out[1] = v*radial + 2*d[3]*u*v + d[2]*(r2 + 2*v*v);
return;
}
if (tier == (int)CameraDistortionType::Rational) {
double radial = (1 + r2*(d[0] + r2*(d[1] + r2*d[2])))
/ (1 + r2*(d[3] + r2*(d[4] + r2*d[5])));
out[0] = u*radial + 2*d[6]*u*v + d[7]*(r2 + 2*u*u);
out[1] = v*radial + 2*d[7]*u*v + d[6]*(r2 + 2*v*v);
return;
}
double radial = 1 + r2*(d[0] + r2*(d[1] + r2*(d[2] + r2*d[3])));
double xd = u*radial + 2*d[4]*u*v + d[5]*(r2 + 2*u*u) + d[6]*r2;
double yd = v*radial + 2*d[5]*u*v + d[4]*(r2 + 2*v*v) + d[7]*r2;
out[0] = xd + d[8]*xd + d[9]*yd; // b1/b2 mix into x
out[1] = yd;
out[0] = u*radial + 2*d[4]*u*v + d[5]*(r2 + 2*u*u) + d[6]*r2;
out[1] = v*radial + 2*d[5]*u*v + d[4]*(r2 + 2*v*v) + d[7]*r2;
}
void distort_jac(double qx, double qy, const float* d, double J[4]) {
void distort_jac(double qx, double qy, int tier, const float* d, double J[4]) {
const double e = 1e-5;
double f[2], fx[2], fy[2];
distort_pt(qx, qy, d, f);
distort_pt(qx + e, qy, d, fx);
distort_pt(qx, qy + e, d, fy);
distort_pt(qx, qy, tier, d, f);
distort_pt(qx + e, qy, tier, d, fx);
distort_pt(qx, qy + e, tier, d, fy);
J[0] = (fx[0]-f[0])/e; J[1] = (fx[1]-f[1])/e; // j00 j10
J[2] = (fy[0]-f[0])/e; J[3] = (fy[1]-f[1])/e; // j01 j11
}
// Newton solve distort(q) = (u,v), with undistort_point_0's failure
// conditions (well-posed forward Jacobian + re-distorts within 0.01).
bool undistort_pt(double u, double v, const float* d, double out[2]) {
bool undistort_pt(double u, double v, int tier, const float* d, double out[2]) {
double qx = u, qy = v;
for (int it = 0; it < 8; it++) {
double f[2], J[4];
distort_pt(qx, qy, d, f);
distort_jac(qx, qy, d, J);
distort_pt(qx, qy, tier, d, f);
distort_jac(qx, qy, tier, d, J);
double det = J[0]*J[3] - J[2]*J[1];
if (std::fabs(det) < 1e-12) break;
double rx = f[0] - u, ry = f[1] - v, inv = 1/det;
@@ -318,10 +335,10 @@ bool undistort_pt(double u, double v, const float* d, double out[2]) {
}
if (!std::isfinite(qx) || !std::isfinite(qy)) return false;
double J[4], f[2];
distort_jac(qx, qy, d, J);
distort_jac(qx, qy, tier, d, J);
double det = J[0]*J[3] - J[2]*J[1];
if (std::min(det, std::min(J[0], J[3])) <= 0) return false; // folded
distort_pt(qx, qy, d, f);
distort_pt(qx, qy, tier, d, f);
if (std::hypot(f[0]-u, f[1]-v) >= 0.01) return false;
out[0] = qx; out[1] = qy;
return true;
@@ -337,7 +354,7 @@ bool norm3(double x, double y, double z, double out[3]) {
// Unproject a normalized image point to a unit ray in CV camera space
// (+Z forward, +Y down); false when outside the valid domain. Mirrors
// generate_ray (projection_utils.cuh:1368).
bool generate_ray(double u, double v, int model, const float* d, double out[3]) {
bool generate_ray(double u, double v, int model, int tier, const float* d, double out[3]) {
if (model == M_EQUIRECT) {
if (std::fabs(u) > kPi || std::fabs(v) > kPi/2) return false;
double cl = std::cos(v);
@@ -345,9 +362,9 @@ bool generate_ray(double u, double v, int model, const float* d, double out[3])
return true;
}
double uu = u, vv = v;
if (has_distortion(d)) {
if (has_distortion(tier, d)) {
double q[2];
if (!undistort_pt(u, v, d, q)) return false;
if (!undistort_pt(u, v, tier, d, q)) return false;
uu = q[0]; vv = q[1];
}
double r = std::hypot(uu, vv);
@@ -372,7 +389,7 @@ struct FrustumTemplate { std::vector<FrustumLine> lines; std::vector<P3> anchors
// interior gridlines (wire dome); equirectangular gets a lat/long wire
// globe over the pixel grid. See viewer/js/dataset.js frustumTemplate for
// the full rationale.
FrustumTemplate frustum_template(int model, int w, int h, float fx, float fy,
FrustumTemplate frustum_template(int model, int tier, int w, int h, float fx, float fy,
float cx, float cy, const float* dist) {
FrustumTemplate out;
if (w < 1) w = std::max(1, (int)std::lround(2*cx));
@@ -392,12 +409,12 @@ FrustumTemplate frustum_template(int model, int w, int h, float fx, float fy,
// Unproject; outside the valid domain, shrink uv toward the principal
// point until it re-enters (Visualizer.cu:146-157).
auto ray = [&](double u, double v, double dir[3]) {
if (generate_ray(u, v, model, dist, dir)) return;
if (generate_ray(u, v, model, tier, dist, dir)) return;
double t0 = 0, t1 = 1, best[3] = {0, 0, 1};
bool have = false;
for (int k = 0; k < 12; k++) {
double s = 0.5*(t0+t1), rr[3];
if (generate_ray(u*s, v*s, model, dist, rr)) {
if (generate_ray(u*s, v*s, model, tier, dist, rr)) {
t0 = s; best[0]=rr[0]; best[1]=rr[1]; best[2]=rr[2]; have = true;
} else t1 = s;
}
@@ -862,22 +879,24 @@ bool PreviewRenderer::build(const ParsedDataset& ds, const PostSplitCameras& pos
map_dir(dx, X); map_dir(dy, Y); map_dir(dz, Z);
int model = ds.camera_models.empty() ? M_PINHOLE : (int)ds.camera_models[i];
int tier = ds.camera_distortions.empty()
? (int)CameraDistortionType::None : ds.camera_distortions[i];
float fx = ds.intrins[i*4 + 0], fy = ds.intrins[i*4 + 1];
float cx = ds.intrins[i*4 + 2], cy = ds.intrins[i*4 + 3];
static const float kZeroDist[10] = {};
static const float kZeroDist[kCameraDistortionParams] = {};
const float* dist = ds.dist_coeffs.empty() ? kZeroDist
: &ds.dist_coeffs[i*10];
: &ds.dist_coeffs[i*kCameraDistortionParams];
char key[256];
std::snprintf(key, sizeof key, "%d|%d|%d|%.3f|%.3f|%.3f|%.3f", model,
ds.widths[i], ds.heights[i], fx, fy, cx, cy);
std::snprintf(key, sizeof key, "%d|%d|%d|%d|%.3f|%.3f|%.3f|%.3f",
model, tier, ds.widths[i], ds.heights[i], fx, fy, cx, cy);
std::string k = key;
for (int j = 0; j < 10; j++) {
for (int j = 0; j < kCameraDistortionParams; j++) {
std::snprintf(key, sizeof key, "|%g", dist[j]);
k += key;
}
auto it = templates.find(k);
if (it == templates.end())
it = templates.emplace(k, frustum_template(model, ds.widths[i],
it = templates.emplace(k, frustum_template(model, tier, ds.widths[i],
ds.heights[i], fx, fy, cx, cy, dist)).first;
const FrustumTemplate& tmpl = it->second;
+2 -2
View File
@@ -357,7 +357,7 @@ void SplatViewer::run(std::string path) {
// control, because there are none to show. What the call is
// really for is the state the axes/grid overlay lives in.
std::vector<float> intrins{32, 32, 32, 32};
std::vector<float> dist((size_t)10, 0.0f);
std::vector<float> dist((size_t)kCameraDistortionParams, 0.0f);
std::vector<float> c2w{1, 0, 0, center[0],
0, 1, 0, center[1],
0, 0, 1, center[2]};
@@ -367,7 +367,7 @@ void SplatViewer::run(std::string path) {
(uint32_t)sizeof(int32_t), std::move(shape)};
};
engine_viewer_init(tvi(models_i, {1}), tv(intrins, {1, 4}),
tv(dist, {1, 10}), tv(c2w, {1, 3, 4}),
tv(dist, {1, kCameraDistortionParams}), tv(c2w, {1, 3, 4}),
tvi(w_i, {1}), tvi(h_i, {1}),
/*camera_size=*/radius * 1e-3f);
// A file has no grid extent of its own; the model's does, and it
+6 -6
View File
@@ -244,7 +244,7 @@ struct RenderWorker::Impl {
vm[15] = 1.f;
float intr[4] = {q.fx, q.fy, q.cx, q.cy};
float dist0[10] = {0};
float dist0[8] = {0};
// Distortion images are FULL render resolution (never-freed pool
// slots) -- emit them only when the user is actually LOOKING at a
// distortion buffer, and only offer those buffers when a distortion
@@ -272,10 +272,10 @@ struct RenderWorker::Impl {
// Trainer.render's "post-processor + D->H inside the lock".
std::lock_guard<std::mutex> lk(*hooks.engine_mutex);
set_camera_params(W, H, q.model,
set_camera_params(W, H, q.model, "NONE",
tvp(vm, 4, {1, 4, 4}),
tvp(intr, 4, {1, 4}),
tvp(dist0, 4, {1, 10}));
tvp(dist0, 4, {1, 8}));
forward_3dgs(primitive, sh_deg, cfg.packed,
want_median, want_dist ? 2 : 0);
engine_copy_render_to_host(
@@ -355,7 +355,7 @@ struct RenderWorker::Impl {
float* di = (float*)d_intr.upload(intr, sizeof intr);
float* dc = (float*)d_dist.upload(dist0, sizeof dist0);
depth_to_normal_forward_tv(
q.model, tvp(di, 4, {1, 4}), tvp(dc, 4, {1, 10}),
q.model, "NONE", tvp(di, 4, {1, 4}), tvp(dc, 4, {1, 8}),
/*is_ray_depth=*/true,
tvp(dd, 4, {1, H, W, 1}), tvp(dn, 4, {1, H, W, 3}));
std::vector<float> n_host(npx * 3);
@@ -447,7 +447,7 @@ struct RenderWorker::Impl {
tvp(db, 4, {H, W, C}),
tvp(dz, 4, {H, W, 1}),
tvp(da, 4, {H, W, 3}),
(int)camera_model_from_name(q.model),
(int)camera_model_from_name(q.model), "NONE",
tvp(di, 4, {1, 4}),
tvp(dv, 4, {4, 4}),
tvp(dc, 4, {1, 10}),
@@ -532,7 +532,7 @@ float viewer_upload_cameras(const PostSplitCameras& post) {
engine_viewer_init(
tvp(post.post_models.data(), 4, {post.n_post}),
tvp(post.intrins.data(), 4, {post.n_post, 4}),
tvp(post.dist_coeffs.data(), 4, {post.n_post, 10}),
tvp(post.dist_coeffs.data(), 4, {post.n_post, kCameraDistortionParams}),
tvp(post.c2w_flip.data(), 4, {post.n_post, 3, 4}),
tvp(post.post_widths.data(), 4, {post.n_post}),
tvp(post.post_heights.data(), 4, {post.n_post}),
+59
View File
@@ -0,0 +1,59 @@
#pragma once
// Camera-distortion inputs shared by the backend parity tools: the compiled
// (camera model, tier) set and one coefficient row per (tier, camera).
#include <core/Common.cuh>
#include <cstdint>
#include <vector>
namespace dist_fixture {
inline const char* const kTierNames[4] = {"NONE", "OPENCV", "THIN_PRISM",
"RATIONAL"};
// Tiers compiled for each camera model, in CameraModelType order; see
// camera_distortion_is_compiled in core/CameraModel.h. Rows are padded with
// tier 0 so a fixed-width table indexes cleanly -- read only kNumTiers[m].
inline constexpr int kNumTiers[4] = {4, 3, 3, 1};
inline constexpr int kTiers[4][4] = {
{0, 1, 2, 3}, // PINHOLE
{0, 1, 2, 0}, // FISHEYE
{0, 1, 2, 0}, // EQUISOLID
{0, 0, 0, 0}, // EQUIRECTANGULAR
};
// [tier][camera][kCameraDistortionParams], each row written in ITS OWN tier's
// coefficient order (core/CameraModel.h) -- a row is only meaningful under the
// tier it was built for. Every tier fills the terms the cheaper tiers cannot
// express (tangential p1/p2, thin-prism sx1/sy1, the rational denominator
// k4..k6), so sweeping the tiers sweeps the distortion math and not just the
// dispatch. Magnitudes stay mild: a strong lens flips borderline culls, which
// rewrite whole rows of the comparison.
inline std::vector<float> distortion_rows(int64_t C) {
static const float row[4][kCameraDistortionParams] = {
{},
{0.05f, -0.01f, 0.0012f, -0.0020f},
{0.05f, -0.01f, 0.0020f, -0.0005f,
0.0012f, -0.0020f, 0.0015f, -0.0008f},
{0.05f, -0.01f, 0.0020f, 0.0300f, -0.0040f, 0.0010f,
0.0012f, -0.0020f},
};
std::vector<float> out((size_t)4 * C * kCameraDistortionParams, 0.0f);
for (int t = 0; t < 4; t++)
for (int64_t c = 0; c < C; c++) {
const float s = 1.0f - 0.3f * (float)(c % 3);
for (int k = 0; k < kCameraDistortionParams; k++)
out[((size_t)t * C + c) * kCameraDistortionParams + k] =
s * row[t][k];
}
return out;
}
// Offset in floats of camera `c`'s row under `tier`, into distortion_rows(C).
inline int64_t row_offset(int tier, int64_t C, int64_t c = 0) {
return ((int64_t)tier * C + c) * kCameraDistortionParams;
}
} // namespace dist_fixture
@@ -12,6 +12,7 @@
// pixels). The blit's uint8 output allows |d| <= 2 per byte (fp rounding at
// the byte quantization boundary) with the same violation cap.
#include <backend/tests/DistortionFixture.h>
#include <engine/Engine.h>
#include <engine/EngineState.h>
#include <kernels/pixelwise/PixelWise.cuh>
@@ -89,13 +90,13 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0.2f, 0, 1, 0, -0.1f, -sy_, 0, cy_, 4.2f, 0, 0, 0, 1,
};
std::vector<float> intr = {180, 182, 120, 90, 175, 177, 118, 92};
std::vector<float> dist(C * 10, 0.f);
dist[0] = 0.04f; dist[1] = -0.008f; dist[10] = -0.02f; dist[11] = 0.003f;
std::vector<float> dist = dist_fixture::distortion_rows(C);
auto set_cams = [&](const char* model) {
set_camera_params(W, H, model, ttv(vm.data(), {C, 4, 4}),
ttv(intr.data(), {C, 4}),
ttv(dist.data(), {C, 10}));
auto set_cams = [&](const char* model, int tier) {
set_camera_params(W, H, model, dist_fixture::kTierNames[tier],
ttv(vm.data(), {C, 4, 4}), ttv(intr.data(), {C, 4}),
ttv(dist.data() + dist_fixture::row_offset(tier, C),
{C, kCameraDistortionParams}));
};
// --- background: SH skybox with deterministic coefficients ---
@@ -149,18 +150,22 @@ int main(int argc, char** argv) {
struct Cfg {
const char* prim;
const char* cam;
int tier; // distortion tier, index into dist_fixture::kTierNames
bool packed;
bool median;
int dist_type; // 0 None, 2 RGB_D
};
// Rows 1 and 2 differ only in the tier, so the NONE fast path is read
// against a distorted neighbour.
const Cfg cfgs[] = {
{"3dgs", "PINHOLE", false, true, 0},
{"mip", "FISHEYE", false, false, 2},
{"3dgut", "PINHOLE", false, false, 0},
{"3dgs", "EQUIRECTANGULAR", true, false, 0},
{"3dgs", "PINHOLE", 0, false, true, 0},
{"3dgs", "PINHOLE", 1, false, true, 0},
{"mip", "FISHEYE", 2, false, false, 2},
{"3dgut", "PINHOLE", 3, false, false, 0},
{"3dgs", "EQUIRECTANGULAR", 0, true, false, 0},
};
for (const Cfg& c : cfgs) {
set_cams(c.cam);
set_cams(c.cam, c.tier);
forward_3dgs(c.prim, 3, c.packed, c.median, c.dist_type);
backend::device_synchronize();
if (const char* err = backend::last_error()) {
@@ -173,7 +178,7 @@ int main(int argc, char** argv) {
// --- noise background mode ---
engine_init_background_noise(/*linear=*/false);
set_cams("PINHOLE");
set_cams("PINHOLE", 1);
forward_3dgs("3dgs", 3, false, false, 0);
backend::device_synchronize();
pull(0, 0);
@@ -184,9 +189,10 @@ int main(int argc, char** argv) {
float* d_normals =
(float*)backend::device_malloc((size_t)C * H * W * 3 * 4);
depth_to_normal_forward_tv(
"PINHOLE",
"PINHOLE", "OPENCV",
ttv(engine().camera.intrins.data_ptr(), {C, 4}),
ttv(engine().camera.dist_coeffs.data_ptr(), {C, 10}),
ttv(engine().camera.dist_coeffs.data_ptr(),
{C, kCameraDistortionParams}),
/*is_ray_depth=*/true,
ttv(depth_t.data_ptr(), {C, H, W, 1}),
ttv(d_normals, {C, H, W, 3}));
@@ -199,8 +205,8 @@ int main(int argc, char** argv) {
// --- viewer blit: synthetic 6-camera dataset + grid overlay ---
{
std::vector<float> v_intr(N_CAM * 4), v_dist(N_CAM * 10, 0.f),
v_c2w(N_CAM * 12);
std::vector<float> v_intr(N_CAM * 4),
v_dist(N_CAM * kCameraDistortionParams, 0.f), v_c2w(N_CAM * 12);
std::vector<int32_t> v_w(N_CAM, 320), v_h(N_CAM, 240),
v_model(N_CAM, 0);
for (int i = 0; i < N_CAM; i++) {
@@ -229,7 +235,7 @@ int main(int argc, char** argv) {
v_model[2] = 1; // one fisheye frustum
engine_viewer_init(ttv(v_model.data(), {N_CAM}),
ttv(v_intr.data(), {N_CAM, 4}),
ttv(v_dist.data(), {N_CAM, 10}),
ttv(v_dist.data(), {N_CAM, kCameraDistortionParams}),
ttv(v_c2w.data(), {N_CAM, 3, 4}),
ttv(v_w.data(), {N_CAM}),
ttv(v_h.data(), {N_CAM}), 0.25f);
@@ -238,7 +244,12 @@ int main(int argc, char** argv) {
// view camera = render camera 0 (device copies)
std::vector<float> view_vm(vm.begin(), vm.begin() + 16);
std::vector<float> view_intr(intr.begin(), intr.begin() + 4);
std::vector<float> view_dist(10, 0.f);
// Visualization camera: OpenCV, so the blit's own projection runs a
// distorted tier rather than only the fast path.
std::vector<float> view_dist(
dist.begin() + dist_fixture::row_offset(1, C),
dist.begin() + dist_fixture::row_offset(1, C) +
kCameraDistortionParams);
float* d_vm = upload(view_vm);
float* d_vi = upload(view_intr);
float* d_vd = upload(view_dist);
@@ -253,7 +264,8 @@ int main(int argc, char** argv) {
engine_blit_view(
"rgb", ttv(rgb_t.data_ptr(), {H, W, 3}),
ttv(depth_t.data_ptr(), {H, W, 1}), ttv(d_Ts, {H, W, 1}), 0,
ttv(d_vi, {1, 4}), ttv(d_vm, {4, 4}), ttv(d_vd, {1, 10}),
"OPENCV", ttv(d_vi, {1, 4}), ttv(d_vm, {4, 4}),
ttv(d_vd, {1, kCameraDistortionParams}),
/*show_training_cameras=*/cams, /*show_overlay=*/true,
/*grid_dist=*/3.0f, 0.2f, -0.1f, 0.0f,
ttv(d_out, {H, W, 3}));
@@ -20,6 +20,7 @@
// all optimizer steps (fed by atomically accumulated gradients).
// Densification is disabled so the splat count stays fixed.
#include <backend/tests/DistortionFixture.h>
#include <engine/Engine.h>
#include <engine/EngineState.h>
#include <kernels/pixelwise/PixelWise.cuh>
@@ -181,7 +182,7 @@ int main(int argc, char** argv) {
0, 0, 0, 1,
};
std::vector<float> intr = {70, 71, 48, 36, 69, 70, 47, 37};
std::vector<float> dist(C * 10, 0.f);
std::vector<float> dist = dist_fixture::distortion_rows(C);
auto gt_rgb = r.bytes((int64_t)C * H * W * 3);
auto gt_depth = r.words((int64_t)C * H * W, 12);
@@ -189,11 +190,15 @@ int main(int argc, char** argv) {
auto gt_alpha = r.bytes((int64_t)C * H * W);
for (auto& v : gt_alpha) v = v < 220 ? 1 : 0;
// One step per tier: PINHOLE compiles all four, and the tier is
// orthogonal to everything the step does with the GT.
for (int s = 0; s < 4; s++, step++) {
auto losses = engine_train_step(
step, max_steps, "3dgs", 3, /*packed=*/false, W, H,
"PINHOLE", ttv(vm.data(), 4, {C, 4, 4}),
ttv(intr.data(), 4, {C, 4}), ttv(dist.data(), 4, {C, 10}),
"PINHOLE", dist_fixture::kTierNames[s],
ttv(vm.data(), 4, {C, 4, 4}), ttv(intr.data(), 4, {C, 4}),
ttv(dist.data() + dist_fixture::row_offset(s, C), 4,
{C, kCameraDistortionParams}),
ttv(gt_rgb.data(), 1, {C, H, W, 3}),
ttv(gt_depth.data(), 2, {C, H, W, 1}),
ttv(gt_normal.data(), 1, {C, H, W, 3}),
@@ -222,21 +227,26 @@ int main(int argc, char** argv) {
post_intr.push_back(0.5f * out_W);
post_intr.push_back(0.5f * out_H);
}
std::vector<float> post_dist(B_post * 10, 0.f);
// engine_train_step_warped always sets the post-split table to
// PINHOLE / NONE.
std::vector<float> post_dist(B_post * kCameraDistortionParams, 0.f);
struct WarpCase {
const char* model;
int tier; // distortion tier, index into dist_fixture::kTierNames
int in_H, in_W;
float fx, fy;
};
const WarpCase wcases[2] = {
{"FISHEYE", 48, 64, 20.0f, 20.5f},
{"EQUIRECTANGULAR", 32, 64, 10.2f, 10.2f},
{"FISHEYE", 2, 48, 64, 20.0f, 20.5f},
{"EQUIRECTANGULAR", 0, 32, 64, 10.2f, 10.2f},
};
const std::vector<float> warp_dist = dist_fixture::distortion_rows(1);
for (const WarpCase& wc : wcases) {
std::vector<float> in_intr = {wc.fx, wc.fy, 0.5f * wc.in_W,
0.5f * wc.in_H};
std::vector<float> in_dist(10, 0.005f);
const float* in_dist =
warp_dist.data() + dist_fixture::row_offset(wc.tier, 1);
auto gt_rgb = r.bytes((int64_t)wc.in_H * wc.in_W * 3);
auto gt_alpha = r.bytes((int64_t)wc.in_H * wc.in_W);
@@ -249,10 +259,12 @@ int main(int argc, char** argv) {
step, max_steps, "3dgs", 3, /*packed=*/false, out_W, out_H,
ttv(post_vm.data(), 4, {B_post, 4, 4}),
ttv(post_intr.data(), 4, {B_post, 4}),
ttv(post_dist.data(), 4, {B_post, 10}), wc.model,
ttv(post_dist.data(), 4, {B_post, kCameraDistortionParams}),
wc.model, dist_fixture::kTierNames[wc.tier],
/*B_in=*/1, wc.in_H, wc.in_W, K,
ttv(in_intr.data(), 4, {1, 4}),
ttv(in_dist.data(), 4, {1, 10}),
ttv(in_dist, 4, {1, kCameraDistortionParams}),
ttv_null(), ttv_null(),
ttv(gt_rgb.data(), 1, {1, wc.in_H, wc.in_W, 3}),
ttv(gt_alpha.data(), 1, {1, wc.in_H, wc.in_W, 1}),
wc.in_H, wc.in_W,
+21 -11
View File
@@ -12,6 +12,7 @@
// N is a multiple of the 256-thread block (see projqgrad_parity note on the
// CUDA kernel's tail-thread reads).
#include <backend/tests/DistortionFixture.h>
#include <kernels/projection/ProjectionFwd.cuh>
#include <kernels/projection/ProjectionPackedFwd.cuh>
#include <kernels/optim/FusedProjectionBwdOptim.cuh>
@@ -125,9 +126,7 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0.3f, 0, 1, 0, -0.2f, -sy_, 0, cy_, 5.f, 0, 0, 0, 1,
};
std::vector<float> intr = {150, 152, 100, 75, 145, 146, 97, 78};
std::vector<float> dist(C * 10, 0.f);
dist[0] = 0.05f; dist[1] = -0.01f;
dist[10] = -0.03f;
std::vector<float> dist = dist_fixture::distortion_rows(C);
float* d_vm = upload(vm);
float* d_intr = upload(intr);
@@ -140,11 +139,16 @@ int main(int argc, char** argv) {
const char* cams[4] = {"PINHOLE", "FISHEYE", "EQUISOLID",
"EQUIRECTANGULAR"};
auto dist_tv = [&](int tier) {
return ttv(d_dist + dist_fixture::row_offset(tier, C),
{C, kCameraDistortionParams});
};
struct Cfg {
int prim; // 0 = 3dgs, 1 = mip, 2 = 3dgut
bool packed;
int cam;
int dist; // distortion tier, index into dist_fixture::kTierNames
int max_deg;
int level; // 0 fp32, 1 quantized SH
bool non_sh; // non-SH quant (level 1 only)
@@ -154,16 +158,19 @@ int main(int argc, char** argv) {
bool per_splat_steps;
bool densify;
};
// Rows 1 and 2 differ only in the tier, so the NONE fast path is read
// against a distorted neighbour.
const Cfg cfgs[] = {
{0, false, 0, 3, 0, false, false, false, 31, false, true},
{1, false, 1, 2, 0, false, true, false, 0, true, false},
{2, false, 0, 3, 0, false, false, true, 7, false, true},
{0, false, 0, 0, 3, 0, false, false, false, 31, false, true},
{0, false, 0, 1, 3, 0, false, false, false, 31, false, true},
{1, false, 1, 2, 2, 0, false, true, false, 0, true, false},
{2, false, 0, 3, 3, 0, false, false, true, 7, false, true},
// NOTE: scale-agnostic means x non-SH quant is excluded: the mixed
// g1/g2 units make u = g1/sqrt(g2) unbounded for edge splats
// (radii 0 with nonzero grad), so +-1 quantum decode differences
// amplify chaotically -- inherent to the lossy codec, on CUDA too.
{0, true, 2, 3, 1, true, false, false, 31, false, false},
{2, true, 3, 1, 1, false, false, true, 7, false, false},
{0, true, 2, 1, 3, 1, true, false, false, 31, false, false},
{2, true, 3, 0, 1, 1, false, false, true, 7, false, false},
};
for (const Cfg& cfg : cfgs) {
@@ -234,7 +241,8 @@ int main(int argc, char** argv) {
: projection_3dgut_packed_forward;
auto out = fn(N, cfg.max_deg, splats_fwd, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), radii, q_val_packed,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, q_val_packed,
q_val_bounds, (uint32_t)NUM_SH, level1 ? 16 : 32,
level1 ? 0 : 256);
cam_ids = std::get<0>(out);
@@ -247,7 +255,8 @@ int main(int argc, char** argv) {
: projection_3dgut_forward;
auto out = fn(N, cfg.max_deg, splats_fwd, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), radii, q_val_packed,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, q_val_packed,
q_val_bounds, (uint32_t)NUM_SH, level1 ? 16 : 32,
level1 ? 0 : 256);
aabb_nd = DeviceTensorFloatND(std::get<0>(out));
@@ -375,7 +384,8 @@ int main(int argc, char** argv) {
n_isect * 4, MemcpyKind::HostToDevice);
fn(N, cfg.max_deg, splats, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), cam_ids, gauss_ids, aabb_nd, v_world,
dist_fixture::kTierNames[cfg.dist], dist_tv(cfg.dist),
cam_ids, gauss_ids, aabb_nd, v_world,
v_screen, g1_world, g2_world, shq_tv, shq_b_tv, shv_tv,
shv_b_tv, non_sh, radii, densify_score,
/*lr_means=*/1.6e-4f, /*lr_quats=*/1e-3f, /*lr_scales=*/5e-3f,
+29 -15
View File
@@ -30,6 +30,7 @@
// visibility) compare as exact CODES, also with a cap: a last-ulp Morton
// difference reorders one leaf and rewrites a whole subtree's links.
#include <backend/tests/DistortionFixture.h>
#include <mesh/MeshingDevice.h>
#include <kernels/projection/ProjectionFwd.cuh>
@@ -398,7 +399,10 @@ int main(int argc, char** argv) {
}
// === 4. rasterize_moments_3dgut_fwd over a real projection ===
std::vector<float> vm(16 * NCAM), intr(4 * NCAM), dist(10 * NCAM, 0.0f);
std::vector<float> vm(16 * NCAM), intr(4 * NCAM);
// One coefficient row per (tier, camera): the samplers below give each
// camera a different tier; the projection and the cull pick one block.
std::vector<float> dist = dist_fixture::distortion_rows(NCAM);
for (int c = 0; c < NCAM; ++c) {
// identity rotation, camera pushed back along -z
float* m = &vm[16 * c];
@@ -411,7 +415,6 @@ int main(int argc, char** argv) {
in[1] = 120.0f;
in[2] = 0.5f * (float)W;
in[3] = 0.5f * (float)H;
dist[10 * c + 0] = 0.02f; // mild radial distortion
}
float* d_vm = upload(vm);
float* d_intr = upload(intr);
@@ -436,9 +439,10 @@ int main(int argc, char** argv) {
backend::memset_sync(d_radii, 0, N * sizeof(float));
auto [aabb_2d, depths_2d, splats_s] = projection_3dgut_forward(
(int64_t)N, 0, in_splats, ttv(d_vm + 16 * cam, {1, 4, 4}),
ttv(d_intr + 4 * cam, {1, 4}), W, H, "PINHOLE",
ttv(d_dist + 10 * cam, {1, 10}), radii, std::nullopt, std::nullopt,
0, 32, 0);
ttv(d_intr + 4 * cam, {1, 4}), W, H, "PINHOLE", "THIN_PRISM",
ttv(d_dist + dist_fixture::row_offset(2, NCAM, cam),
{1, kCameraDistortionParams}),
radii, std::nullopt, std::nullopt, 0, 32, 0);
DeviceTensorFloatND aabb_nd(aabb_2d), depths_nd(depths_2d);
DeviceTensorFloatND proj_conic = splats_s[0];
DeviceTensorFloatND proj_opac = splats_s[1];
@@ -452,8 +456,10 @@ int main(int argc, char** argv) {
rasterize_moments_3dgut_fwd(
(int64_t)N, in_splats, splats_s, DeviceVector<int32_t>(),
ttv(d_vm + 16 * cam, {1, 4, 4}), ttv(d_intr + 4 * cam, {1, 4}),
"PINHOLE", ttv(d_dist + 10 * cam, {1, 10}), aabb_2d, W, H,
tile_offsets, flatten_ids, d_moments, nullptr);
"PINHOLE", "THIN_PRISM",
ttv(d_dist + dist_fixture::row_offset(2, NCAM, cam),
{1, kCameraDistortionParams}),
aabb_2d, W, H, tile_offsets, flatten_ids, d_moments, nullptr);
backend::device_synchronize();
if (check_error()) return 1;
readback(lacc, (const float*)d_moments, (int64_t)npix * 3);
@@ -461,8 +467,10 @@ int main(int argc, char** argv) {
rasterize_moments_3dgut_fwd(
(int64_t)N, in_splats, splats_s, DeviceVector<int32_t>(),
ttv(d_vm + 16 * cam, {1, 4, 4}), ttv(d_intr + 4 * cam, {1, 4}),
"PINHOLE", ttv(d_dist + 10 * cam, {1, 10}), aabb_2d, W, H,
tile_offsets, flatten_ids, d_moments, d_rgbimg);
"PINHOLE", "THIN_PRISM",
ttv(d_dist + dist_fixture::row_offset(2, NCAM, cam),
{1, kCameraDistortionParams}),
aabb_2d, W, H, tile_offsets, flatten_ids, d_moments, d_rgbimg);
backend::device_synchronize();
if (check_error()) return 1;
readback(lacc, (const float*)d_rgbimg, (int64_t)npix * 3);
@@ -504,14 +512,18 @@ int main(int argc, char** argv) {
for (int c = 0; c < NCAM; ++c) {
const int cm = 0; // PINHOLE
// Thin prism is covered by the projection and the cull.
const int td = c == 0 ? 0 : c == 1 ? 1 : 3;
const float* d_dc =
d_dist + dist_fixture::row_offset(td, NCAM, c);
meshing::launch_sample_occ(d_q, NQ, d_vm + 16 * c, d_intr + 4 * c,
d_dist + 10 * c, cm, d_mom_s, W, H, k,
d_dc, cm, td, d_mom_s, W, H, k,
d_kmin, d_cnt);
meshing::launch_sample_color(d_q, NQ, d_vm + 16 * c,
d_intr + 4 * c, d_dist + 10 * c, cm,
d_intr + 4 * c, d_dc, cm, td,
d_mom_s, d_rgb_s, W, H, d_num, d_den);
meshing::launch_sample_view_density(
d_q, NQ, d_vm + 16 * c, d_intr + 4 * c, d_dist + 10 * c, cm,
d_q, NQ, d_vm + 16 * c, d_intr + 4 * c, d_dc, cm, td,
d_mom_s, W, H, d_dens);
}
meshing::launch_finalize_occ(NQ, d_kmin, d_cnt, k, d_occ_k);
@@ -606,9 +618,11 @@ int main(int argc, char** argv) {
int32_t* d_W = upload(ws);
int32_t* d_H = upload(hs);
uint32_t* d_vis = alloc<uint32_t>(NV);
meshing::launch_cull(d_verts, NV, d_faces, NF, d_vm, d_intr, d_dist,
d_W, d_H, /*camera_model=*/0, NCAM, t_leafMin,
t_leafMax, t_internal, t_nodeAABB, d_vis);
meshing::launch_cull(
d_verts, NV, d_faces, NF, d_vm, d_intr,
d_dist + dist_fixture::row_offset(2, NCAM),
d_W, d_H, /*camera_model=*/0, /*distortion=*/2, NCAM, t_leafMin,
t_leafMax, t_internal, t_nodeAABB, d_vis);
backend::device_synchronize();
if (check_error()) return 1;
readback_i32(codes, (const int32_t*)d_vis, NV);
+23 -13
View File
@@ -11,6 +11,7 @@
// whose order differs between backends, so the comparison is tolerance-based
// with a small violation-fraction cap.
#include <backend/tests/DistortionFixture.h>
#include <kernels/projection/ProjectionFwd.cuh>
#include <kernels/projection/ProjectionPackedFwd.cuh>
#include <kernels/projection/ProjectionBwd.cuh>
@@ -98,9 +99,7 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0.3f, 0, 1, 0, -0.2f, -sy_, 0, cy_, 5.f, 0, 0, 0, 1,
};
std::vector<float> intr = {150, 152, 100, 75, 145, 146, 97, 78};
std::vector<float> dist(C * 10, 0.f);
dist[0] = 0.05f; dist[1] = -0.01f;
dist[10] = -0.03f;
std::vector<float> dist = dist_fixture::distortion_rows(C);
float* d_means = upload(means);
float* d_quats = upload(quats);
@@ -152,24 +151,32 @@ int main(int argc, char** argv) {
const char* cams[4] = {"PINHOLE", "FISHEYE", "EQUISOLID",
"EQUIRECTANGULAR"};
auto dist_tv = [&](int tier) {
return ttv(d_dist + dist_fixture::row_offset(tier, C),
{C, kCameraDistortionParams});
};
struct Cfg {
int prim; // 0 = 3dgs, 1 = mip, 2 = 3dgut
bool packed;
int cam;
int dist; // distortion tier, index into dist_fixture::kTierNames
int max_deg; // max_sh_degree passed to fwd + bwd
int qbits; // 0 = fp32 SH, 8/16 = value-quant
bool q_fpbo; // bounds layout when qbits != 0
bool vmg; // viewmat grad
};
// Rows 1 and 2 are the same config on NONE and on OpenCV, so the tier's
// fast path is read against a distorted neighbour.
const Cfg cfgs[] = {
{0, false, 0, 3, 0, false, true},
{1, false, 1, 2, 0, false, false},
{0, true, 2, 3, 0, false, false},
{2, false, 0, 3, 0, false, true},
{2, true, 1, 1, 0, false, false},
{0, false, 0, 3, 8, false, false},
{2, false, 3, 3, 16, true, false},
{0, false, 0, 0, 3, 0, false, true},
{0, false, 0, 1, 3, 0, false, true},
{1, false, 1, 2, 2, 0, false, false},
{0, true, 2, 1, 3, 0, false, false},
{2, false, 0, 3, 3, 0, false, true},
{2, true, 1, 0, 1, 0, false, false},
{0, false, 0, 2, 3, 8, false, false},
{2, false, 3, 0, 3, 16, true, false},
};
for (const Cfg& cfg : cfgs) {
@@ -200,7 +207,8 @@ int main(int argc, char** argv) {
: projection_3dgut_packed_forward;
auto out = fn(N, cfg.max_deg, splats_in, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), radii, q_packed, q_bounds,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, q_packed, q_bounds,
(uint32_t)NUM_SH, quant ? cfg.qbits : 32, q_stride);
cam_ids = std::get<0>(out);
gauss_ids = std::get<1>(out);
@@ -213,7 +221,8 @@ int main(int argc, char** argv) {
: projection_3dgut_forward;
auto out = fn(N, cfg.max_deg, splats_in, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), radii, q_packed, q_bounds,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, q_packed, q_bounds,
(uint32_t)NUM_SH, quant ? cfg.qbits : 32, q_stride);
aabb_2d = std::get<0>(out);
}
@@ -269,7 +278,8 @@ int main(int argc, char** argv) {
: cfg.prim == 1 ? projection_mip_backward
: projection_3dgut_backward;
bwd(N, cfg.max_deg, splats_in, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam], ttv(d_dist, {C, 10}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
dist_fixture::kTierNames[cfg.dist], dist_tv(cfg.dist),
cam_ids, gauss_ids, aabb_2d, v_screen, v_world,
cfg.vmg ? &v_viewmats : nullptr, q_packed, q_bounds,
(uint32_t)NUM_SH, quant ? cfg.qbits : 32, q_stride);
+38 -16
View File
@@ -5,11 +5,13 @@
// CUDA build: ./projection_parity dump ref.bin
// Vulkan build: ./projection_parity compare ref.bin (per device)
//
// Deterministic inputs; 16 configs = {3DGS, MIP} x 4 camera models x
// SH degree {0, 3} (+ one no-distortion config). Comparison is tolerance-
// based (fast-math exp/sqrt chains differ across compilers) with a small
// allowance for borderline-cull flips, which change entire rows.
// Deterministic inputs; the configs are {3DGS, MIP, 3DGUT} x 4 camera models
// x SH degree {0, 3} x the distortion tiers compiled for that model.
// Comparison is tolerance-based (fast-math exp/sqrt chains differ across
// compilers) with a small allowance for borderline-cull flips, which change
// entire rows.
#include <backend/tests/DistortionFixture.h>
#include <kernels/projection/ProjectionFwd.cuh>
#include <kernels/projection/ProjectionPackedFwd.cuh>
@@ -83,9 +85,7 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0.3f, 0, 1, 0, -0.2f, -sy_, 0, cy_, 5.f, 0, 0, 0, 1,
};
std::vector<float> intr = {600, 610, 400, 300, 580, 585, 390, 310};
std::vector<float> dist(C * 10, 0.f);
dist[0] = 0.05f; dist[1] = -0.01f; dist[2] = 0.001f; dist[3] = -0.002f;
dist[10] = -0.03f; dist[11] = 0.004f;
std::vector<float> dist = dist_fixture::distortion_rows(C);
float* d_means = upload(means);
float* d_quats = upload(quats);
@@ -112,12 +112,21 @@ int main(int argc, char** argv) {
const char* cams[4] = {"PINHOLE", "FISHEYE", "EQUISOLID",
"EQUIRECTANGULAR"};
auto dist_tv = [&](int tier) {
return ttv(d_dist + dist_fixture::row_offset(tier, C),
{C, kCameraDistortionParams});
};
std::vector<float> acc;
for (int prim = 0; prim < 3; prim++)
for (int ci = 0; ci < 4; ci++)
for (int shd = 0; shd <= 3; shd += 3)
for (int use_dist = 0; use_dist < 2; use_dist++) {
if (use_dist == 0 && ci != 0) continue; // one nodist cfg
// The tier is orthogonal to SH degree: sweep the compiled
// tiers at degree 3 and keep degree 0 on the NONE fast path,
// which also runs with a null coefficient tensor.
for (int t = 0; t < (shd ? dist_fixture::kNumTiers[ci] : 1);
t++) {
const int tier = dist_fixture::kTiers[ci][t];
backend::memset_sync(d_radii, 0, N * sizeof(float));
auto fn = prim == 0 ? projection_3dgs_forward
: prim == 1 ? projection_mip_forward
@@ -125,8 +134,9 @@ int main(int argc, char** argv) {
auto out = fn(
N, shd, in_splats, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[ci],
use_dist ? ttv(d_dist, {C, 10})
: ttv(nullptr, {C, 10}),
dist_fixture::kTierNames[tier],
shd ? dist_tv(tier)
: ttv(nullptr, {C, kCameraDistortionParams}),
radii, std::nullopt, std::nullopt, 0, 32, 0);
backend::device_synchronize();
if (const char* err = backend::last_error()) {
@@ -186,9 +196,14 @@ int main(int argc, char** argv) {
return std::make_pair(packed_tv, bounds_tv);
};
int qcfg = 0;
for (int prim = 0; prim < 3; prim++)
for (int bits = 8; bits <= 16; bits += 8)
for (int fpbo = 0; fpbo < 2; fpbo++) {
for (int fpbo = 0; fpbo < 2; fpbo++, qcfg++) {
// Value-quant and distortion are independent axes, so rotate
// the tier through the codec configs instead of crossing them.
const int tier = dist_fixture::kTiers[prim]
[qcfg % dist_fixture::kNumTiers[prim]];
backend::memset_sync(d_radii, 0, N * sizeof(float));
auto fn = prim == 0 ? projection_3dgs_forward
: prim == 1 ? projection_mip_forward
@@ -197,7 +212,8 @@ int main(int argc, char** argv) {
auto out = fn(
N, 3, in_splats_q, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[prim],
ttv(d_dist, {C, 10}), radii, packed_tv, bounds_tv,
dist_fixture::kTierNames[tier], dist_tv(tier), radii,
packed_tv, bounds_tv,
(uint32_t)NUM_SH, bits, fpbo ? 0 : 256);
backend::device_synchronize();
if (const char* err = backend::last_error()) {
@@ -220,14 +236,17 @@ int main(int argc, char** argv) {
// --- packed projection: nnz-compacted outputs (ids exact via float) ---
for (int prim = 0; prim < 3; prim++)
for (int ci = 0; ci < 4; ci += 3) { // PINHOLE + EQUIRECTANGULAR
// PINHOLE walks the three distorted tiers across the primitives;
// EQUIRECTANGULAR has no lens distortion.
const int tier = ci == 0 ? 1 + prim : 0;
backend::memset_sync(d_radii, 0, N * sizeof(float));
auto fn = prim == 0 ? projection_3dgs_packed_forward
: prim == 1 ? projection_mip_packed_forward
: projection_3dgut_packed_forward;
auto out = fn(N, 3, in_splats, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[ci],
ttv(d_dist, {C, 10}), radii, std::nullopt,
std::nullopt, 0, 32, 0);
dist_fixture::kTierNames[tier], dist_tv(tier),
radii, std::nullopt, std::nullopt, 0, 32, 0);
backend::device_synchronize();
if (const char* err = backend::last_error()) {
std::fprintf(stderr, "backend error: %s\n", err);
@@ -261,13 +280,16 @@ int main(int argc, char** argv) {
const int prim = k == 0 ? 0 : 2;
const int bits = k == 0 ? 8 : 16;
const int fpbo = k;
// PINHOLE rational, then FISHEYE thin-prism.
const int tier = k == 0 ? 3 : 2;
backend::memset_sync(d_radii, 0, N * sizeof(float));
auto fn = prim == 0 ? projection_3dgs_packed_forward
: projection_3dgut_packed_forward;
auto [packed_tv, bounds_tv] = quant_args(bits, fpbo);
auto out = fn(N, 3, in_splats_q, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[k],
ttv(d_dist, {C, 10}), radii, packed_tv, bounds_tv,
dist_fixture::kTierNames[tier], dist_tv(tier), radii,
packed_tv, bounds_tv,
(uint32_t)NUM_SH, bits, fpbo ? 0 : 256);
backend::device_synchronize();
if (const char* err = backend::last_error()) {
+18 -11
View File
@@ -13,6 +13,7 @@
// The register camera-loop accumulation is deterministic; codes compare with
// a +-1 quantum tolerance (codec rounding + last-ulp bound differences).
#include <backend/tests/DistortionFixture.h>
#include <kernels/projection/ProjectionFwd.cuh>
#include <kernels/projection/ProjectionPackedFwd.cuh>
#include <kernels/projection/ProjectionBwdQuantGrad.cuh>
@@ -120,9 +121,7 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0.3f, 0, 1, 0, -0.2f, -sy_, 0, cy_, 5.f, 0, 0, 0, 1,
};
std::vector<float> intr = {150, 152, 100, 75, 145, 146, 97, 78};
std::vector<float> dist(C * 10, 0.f);
dist[0] = 0.05f; dist[1] = -0.01f;
dist[10] = -0.03f;
std::vector<float> dist = dist_fixture::distortion_rows(C);
float* d_means = upload(means);
float* d_quats = upload(quats);
@@ -164,21 +163,26 @@ int main(int argc, char** argv) {
const char* cams[4] = {"PINHOLE", "FISHEYE", "EQUISOLID",
"EQUIRECTANGULAR"};
auto dist_tv = [&](int tier) {
return ttv(d_dist + dist_fixture::row_offset(tier, C),
{C, kCameraDistortionParams});
};
struct Cfg {
int prim; // 0 = 3dgs, 1 = mip, 2 = 3dgut
bool packed;
int cam;
int dist; // distortion tier, index into dist_fixture::kTierNames
int max_deg;
bool geom_quant; // quantize means/quats/scales (off for 3dgut)
bool qsrc; // q8 SH value source
};
const Cfg cfgs[] = {
{0, false, 0, 3, true, false},
{2, false, 1, 3, false, false},
{0, true, 2, 2, true, false},
{2, true, 0, 1, false, true},
{1, false, 0, 3, true, false},
{0, false, 0, 1, 3, true, false},
{2, false, 1, 2, 3, false, false},
{0, true, 2, 1, 2, true, false},
{2, true, 0, 3, 1, false, true},
{1, false, 0, 0, 3, true, false},
};
for (const Cfg& cfg : cfgs) {
@@ -203,7 +207,8 @@ int main(int argc, char** argv) {
: projection_3dgut_packed_forward;
auto out = fn(N, cfg.max_deg, splats_in, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), radii, q_packed, q_bounds,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, q_packed, q_bounds,
(uint32_t)NUM_SH, quant_src ? 8 : 32, 256);
cam_ids = std::get<0>(out);
gauss_ids = std::get<1>(out);
@@ -216,7 +221,8 @@ int main(int argc, char** argv) {
: projection_3dgut_forward;
auto out = fn(N, cfg.max_deg, splats_in, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), radii, q_packed, q_bounds,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, q_packed, q_bounds,
(uint32_t)NUM_SH, quant_src ? 8 : 32, 256);
aabb_2d = std::get<0>(out);
}
@@ -332,7 +338,8 @@ int main(int argc, char** argv) {
n_isect * 4, MemcpyKind::HostToDevice);
bwd(N, cfg.max_deg, splats_in, ttv(d_vm, {C, 16}),
ttv(d_intr, {C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {C, 10}), cam_ids, gauss_ids, aabb_2d, v_screen,
dist_fixture::kTierNames[cfg.dist], dist_tv(cfg.dist),
cam_ids, gauss_ids, aabb_2d, v_screen,
v_world, gq, q_packed, q_bounds, (uint32_t)NUM_SH,
quant_src ? 8 : 32, 256);
backend::device_synchronize();
+32 -23
View File
@@ -11,6 +11,7 @@
// contributions in a different order than CUDA's block-atomic scheme, so
// comparison uses the usual tolerance + small violation-fraction cap.
#include <backend/tests/DistortionFixture.h>
#include <kernels/pixelwise/PixelWise.cuh>
#include <kernels/background/BackgroundSphericalHarmonics.cuh>
#include <engine/EngineInternal.h>
@@ -136,35 +137,40 @@ int main(int argc, char** argv) {
// ---- cameras for depth kernels ----
std::vector<float> intrins = {50.f, 50.f, 32.f, 24.f,
55.f, 52.f, 30.f, 25.f}; // [B,4]
std::vector<float> dist(B * 10, 0.f);
dist[0] = 0.05f; // mild k1 on batch 0
dist[10 + 0] = -0.03f;
std::vector<float> dist = dist_fixture::distortion_rows(B);
float* d_intr = upload(intrins);
float* d_dist = upload(dist);
auto dist_tv = [&](int tier) {
return ttv(d_dist + dist_fixture::row_offset(tier, B),
{B, kCameraDistortionParams});
};
std::vector<float> depths(PIX);
fill(depths, 0.5f, 6.f);
float* d_depths = upload(depths);
// ---- depth_to_normal_backward (pinhole w/ dist; ray + linear depth) ----
for (int rd = 0; rd < 2; rd++) {
std::vector<float> vn(PIX * 3);
fill(vn, -1.f, 1.f);
float* d_vn = upload(vn);
float* d_vd = fresh1();
depth_to_normal_backward("PINHOLE", ttv(d_intr, {B, 4}),
ttv(d_dist, {B, 10}), rd != 0, t1(d_depths),
t3(d_vn), t1(d_vd));
backend::device_synchronize();
readback_f(acc, d_vd, PIX);
}
// ---- depth_to_normal_backward (pinhole; every tier x ray/linear) ----
for (int tier = 0; tier < 4; tier++)
for (int rd = 0; rd < 2; rd++) {
std::vector<float> vn(PIX * 3);
fill(vn, -1.f, 1.f);
float* d_vn = upload(vn);
float* d_vd = fresh1();
depth_to_normal_backward("PINHOLE",
dist_fixture::kTierNames[tier],
ttv(d_intr, {B, 4}), dist_tv(tier),
rd != 0, t1(d_depths), t3(d_vn),
t1(d_vd));
backend::device_synchronize();
readback_f(acc, d_vd, PIX);
}
// ---- linear_depth_to_ray_depth_inplace (fisheye, no dist view) ----
// ---- linear_depth_to_ray_depth_inplace (fisheye, thin prism) ----
{
std::vector<float> dcopy = depths;
float* d_d = upload(dcopy);
linear_depth_to_ray_depth_inplace("FISHEYE", ttv(d_intr, {B, 4}),
ttv(d_dist, {B, 10}), (int)W * 2,
(int)H * 2, t1(d_d));
linear_depth_to_ray_depth_inplace("FISHEYE", "THIN_PRISM",
ttv(d_intr, {B, 4}), dist_tv(2),
(int)W * 2, (int)H * 2, t1(d_d));
backend::device_synchronize();
readback_f(acc, d_d, PIX);
}
@@ -198,6 +204,7 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0, 0, 1, 0, 0, -sy_, 0, cy_, 1.f, 0, 0, 0, 1};
float* d_vm = upload(vm);
for (int deg : {1, 3}) {
const int tier = deg == 1 ? 1 : 2; // OpenCV, then thin prism
const int K = (deg + 1) * (deg + 1);
std::vector<float> sh(K * 3);
fill(sh, -0.4f, 0.4f);
@@ -205,16 +212,18 @@ int main(int argc, char** argv) {
float* d_sh = upload(sh);
float* d_out = fresh3();
render_background_sh_forward(
(int)W, (int)H, "PINHOLE", deg, ttv(d_vm, {B, 4, 4}),
ttv(d_intr, {B, 4}), ttv(d_dist, {B, 10}),
(int)W, (int)H, "PINHOLE", dist_fixture::kTierNames[tier],
deg, ttv(d_vm, {B, 4, 4}),
ttv(d_intr, {B, 4}), dist_tv(tier),
ttv(d_sh, {K, 3}), ttv(d_out, {B, H, W, 3}));
std::vector<float> vout2(PIX * 3);
fill(vout2, -1.f, 1.f);
float* d_vout2 = upload(vout2);
float* d_vsh = upload(std::vector<float>(K * 3, 0.f));
render_background_sh_backward(
(int)W, (int)H, "PINHOLE", deg, ttv(d_vm, {B, 4, 4}),
ttv(d_intr, {B, 4}), ttv(d_dist, {B, 10}),
(int)W, (int)H, "PINHOLE", dist_fixture::kTierNames[tier],
deg, ttv(d_vm, {B, 4, 4}),
ttv(d_intr, {B, 4}), dist_tv(tier),
ttv(d_sh, {K, 3}), ttv(d_out, {B, H, W, 3}),
ttv(d_vout2, {B, H, W, 3}), ttv(d_vsh, {K, 3}));
backend::device_synchronize();
+24 -12
View File
@@ -11,6 +11,7 @@
// whose order differs between backends (and between runs on CUDA), so the
// comparison is tolerance-based with a small violation-fraction cap.
#include <backend/tests/DistortionFixture.h>
#include <kernels/tile/IntersectTile.cuh>
#include <kernels/projection/ProjectionFwd.cuh>
#include <kernels/projection/ProjectionPackedFwd.cuh>
@@ -102,9 +103,7 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0.3f, 0, 1, 0, -0.2f, -sy_, 0, cy_, 5.f, 0, 0, 0, 1,
};
std::vector<float> intr = {150, 152, 100, 75, 145, 146, 97, 78};
std::vector<float> dist(C * 10, 0.f);
dist[0] = 0.05f; dist[1] = -0.01f;
dist[10] = -0.03f;
std::vector<float> dist = dist_fixture::distortion_rows(C);
float* d_means = upload(means);
float* d_quats = upload(quats);
@@ -163,20 +162,29 @@ int main(int argc, char** argv) {
int prim; // 0 = 3dgs, 2 = 3dgut
bool packed;
int cam;
int dist; // distortion tier, index into dist_fixture::kTierNames
DistortionType dt;
bool median;
bool aw;
bool vmg; // 3dgut viewmat grad
};
// The 3dgs backward never sees the camera, so the tier sweep lives on the
// 3dgut rows; the 3dgs rows carry it through the projection only.
const Cfg cfgs[] = {
{0, false, 0, DistortionType::None, false, false, false},
{0, false, 0, DistortionType::RGB_D, true, true, false},
{0, true, 1, DistortionType::D, false, false, false},
{2, false, 0, DistortionType::None, false, false, true},
{2, false, 1, DistortionType::D, true, true, false},
{0, false, 0, 0, DistortionType::None, false, false, false},
{0, false, 0, 1, DistortionType::RGB_D, true, true, false},
{0, true, 1, 2, DistortionType::D, false, false, false},
{2, false, 0, 0, DistortionType::None, false, false, true},
{2, false, 1, 2, DistortionType::D, true, true, false},
{2, false, 0, 1, DistortionType::RGB_D, false, false, false},
{2, true, 0, 3, DistortionType::D, false, false, false},
};
const char* cams[4] = {"PINHOLE", "FISHEYE", "EQUISOLID",
"EQUIRECTANGULAR"};
auto dist_tv = [&](int tier) {
return ttv(d_dist + dist_fixture::row_offset(tier, C),
{(int64_t)C, kCameraDistortionParams});
};
for (const Cfg& cfg : cfgs) {
backend::memset_sync(d_radii, 0, N * sizeof(float));
@@ -192,7 +200,8 @@ int main(int argc, char** argv) {
: projection_3dgut_packed_forward;
auto out = fn(N, 3, in_splats, ttv(d_vm, {(int64_t)C, 16}),
ttv(d_intr, {(int64_t)C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {(int64_t)C, 10}), radii, std::nullopt,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, std::nullopt,
std::nullopt, 0, 32, 0);
cam_ids = std::get<0>(out);
gauss_ids = std::get<1>(out);
@@ -207,7 +216,8 @@ int main(int argc, char** argv) {
: projection_3dgut_forward;
auto out = fn(N, 3, in_splats, ttv(d_vm, {(int64_t)C, 16}),
ttv(d_intr, {(int64_t)C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {(int64_t)C, 10}), radii, std::nullopt,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, std::nullopt,
std::nullopt, 0, 32, 0);
aabb_2d = std::get<0>(out);
auto depths_2d = std::get<1>(out);
@@ -248,7 +258,8 @@ int main(int argc, char** argv) {
rout = rasterize_to_pixels_3dgut_fwd(
N, in_splats, splats_s, gauss_ids,
ttv(d_vm, {(int64_t)C, 16}), ttv(d_intr, {(int64_t)C, 4}),
cams[cfg.cam], ttv(d_dist, {(int64_t)C, 10}), aabb_2d, W, H,
cams[cfg.cam], dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), aabb_2d, W, H,
tile_offsets, flatten_ids, cfg.dt, cfg.median);
} else {
rout = rasterize_to_pixels_3dgs_fwd(N, in_splats, splats_s,
@@ -281,7 +292,8 @@ int main(int argc, char** argv) {
N, in_splats, splats_s, gauss_ids,
ttv(d_vm, {(int64_t)C, 16}),
ttv(d_intr, {(int64_t)C, 4}), cams[cfg.cam],
ttv(d_dist, {(int64_t)C, 10}), aabb_2d, W, H,
dist_fixture::kTierNames[cfg.dist], dist_tv(cfg.dist),
aabb_2d, W, H,
tile_offsets, flatten_ids, render_Ts, last_ids, renders,
dist_fwd_opt, cfg.dt, DeviceTensor3D<float>{}, awmap_t,
v_renders, t3f1(d_v_T), v_med_t, v_dist_opt,
+37 -20
View File
@@ -6,13 +6,14 @@
// Vulkan build: ./render_parity compare ref.bin (per device)
//
// Sections:
// 1. Background SH forward: SH degree x camera model image parity.
// 1. Background SH forward: SH degree x (camera model, distortion tier).
// 2. Full pipeline (projection -> intersect -> rasterize), fused + packed,
// per primitive, with distortion / median variants. Rendered images,
// per primitive, with dist-loss / median variants. Rendered images,
// transmittances, and tile offsets are compared with tolerance; near-tie
// depth keys may sort differently across backends (last-ulp projection
// divergence), so a small violation fraction is allowed.
#include <backend/tests/DistortionFixture.h>
#include <kernels/background/BackgroundSphericalHarmonics.cuh>
#include <kernels/tile/IntersectTile.cuh>
#include <kernels/projection/ProjectionFwd.cuh>
@@ -115,9 +116,7 @@ int main(int argc, char** argv) {
cy_, 0, sy_, 0.3f, 0, 1, 0, -0.2f, -sy_, 0, cy_, 5.f, 0, 0, 0, 1,
};
std::vector<float> intr = {150, 152, 100, 75, 145, 146, 97, 78};
std::vector<float> dist(C * 10, 0.f);
dist[0] = 0.05f; dist[1] = -0.01f; dist[2] = 0.001f; dist[3] = -0.002f;
dist[10] = -0.03f; dist[11] = 0.004f;
std::vector<float> dist = dist_fixture::distortion_rows(C);
float* d_means = upload(means);
float* d_quats = upload(quats);
@@ -142,6 +141,10 @@ int main(int argc, char** argv) {
const char* cams[4] = {"PINHOLE", "FISHEYE", "EQUISOLID",
"EQUIRECTANGULAR"};
auto dist_tv = [&](int tier) {
return ttv(d_dist + dist_fixture::row_offset(tier, C),
{(int64_t)C, kCameraDistortionParams});
};
std::vector<float> acc;
@@ -152,12 +155,19 @@ int main(int argc, char** argv) {
float* d_bg_sh = upload(bg_sh);
float* d_bg_out =
(float*)backend::device_malloc((size_t)C * H * W * 3 * 4);
for (int shd = 0; shd <= 4; shd += 2) // degrees 0, 2, 4
for (int si = 0; si < 3; si++) // degrees 0, 2, 4
for (int ci = 0; ci < 4; ci++) {
const int shd = 2 * si;
// PINHOLE has four compiled tiers and only three slots here,
// so start it at OpenCV; the NONE path is covered by the
// other models.
const int tier =
dist_fixture::kTiers[ci][(ci == 0 ? si + 1 : si) %
dist_fixture::kNumTiers[ci]];
render_background_sh_forward(
W, H, cams[ci], shd, ttv(d_vm, {(int64_t)C, 16}),
ttv(d_intr, {(int64_t)C, 4}),
ttv(d_dist, {(int64_t)C, 10}),
W, H, cams[ci], dist_fixture::kTierNames[tier], shd,
ttv(d_vm, {(int64_t)C, 16}),
ttv(d_intr, {(int64_t)C, 4}), dist_tv(tier),
ttv(d_bg_sh, {(shd + 1) * (shd + 1), 3}),
ttv(d_bg_out, {(int64_t)C, H, W, 3}));
backend::device_synchronize();
@@ -173,18 +183,22 @@ int main(int argc, char** argv) {
int prim; // 0 = 3dgs, 1 = mip, 2 = 3dgut
bool packed;
int cam;
int dist; // distortion tier, index into dist_fixture::kTierNames
DistortionType dt;
bool median;
};
// Only the 3dgut rasterizer reads the camera, so its rows carry the tier
// sweep; for 3dgs/mip the tier reaches the projection alone.
const Cfg cfgs[] = {
{0, false, 0, DistortionType::RGB_D, true},
{1, false, 0, DistortionType::RGB_D, true},
{2, false, 0, DistortionType::RGB_D, true},
{0, false, 1, DistortionType::D, false},
{2, false, 3, DistortionType::None, true},
{0, true, 3, DistortionType::None, false},
{1, true, 0, DistortionType::D, false},
{2, true, 0, DistortionType::None, false},
{0, false, 0, 1, DistortionType::RGB_D, true},
{1, false, 0, 0, DistortionType::RGB_D, true},
{2, false, 0, 1, DistortionType::RGB_D, true},
{2, false, 0, 2, DistortionType::D, false},
{0, false, 1, 2, DistortionType::D, false},
{2, false, 3, 0, DistortionType::None, true},
{0, true, 3, 0, DistortionType::None, false},
{1, true, 0, 3, DistortionType::D, false},
{2, true, 0, 3, DistortionType::None, false},
};
for (const Cfg& cfg : cfgs) {
@@ -203,7 +217,8 @@ int main(int argc, char** argv) {
: projection_3dgut_packed_forward;
auto out = fn(N, 3, in_splats, ttv(d_vm, {(int64_t)C, 16}),
ttv(d_intr, {(int64_t)C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {(int64_t)C, 10}), radii, std::nullopt,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, std::nullopt,
std::nullopt, 0, 32, 0);
cam_ids = std::get<0>(out);
gauss_ids = std::get<1>(out);
@@ -220,7 +235,8 @@ int main(int argc, char** argv) {
: projection_3dgut_forward;
auto out = fn(N, 3, in_splats, ttv(d_vm, {(int64_t)C, 16}),
ttv(d_intr, {(int64_t)C, 4}), W, H, cams[cfg.cam],
ttv(d_dist, {(int64_t)C, 10}), radii, std::nullopt,
dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), radii, std::nullopt,
std::nullopt, 0, 32, 0);
aabb_2d = std::get<0>(out);
auto depths_2d = std::get<1>(out);
@@ -266,7 +282,8 @@ int main(int argc, char** argv) {
rout = rasterize_to_pixels_3dgut_fwd(
N, in_splats, splats_s, gauss_ids,
ttv(d_vm, {(int64_t)C, 16}), ttv(d_intr, {(int64_t)C, 4}),
cams[cfg.cam], ttv(d_dist, {(int64_t)C, 10}), aabb_2d, W, H,
cams[cfg.cam], dist_fixture::kTierNames[cfg.dist],
dist_tv(cfg.dist), aabb_2d, W, H,
tile_offsets, flatten_ids, cfg.dt, cfg.median);
} else {
auto fn = cfg.prim == 0 ? rasterize_to_pixels_3dgs_fwd
+177 -23
View File
@@ -17,13 +17,17 @@
// through the same channel; a flipped boundary texel counts as one
// violation.
//
// Coverage: all three wide camera models (PINHOLE with null dist_coeffs ->
// zeros-fallback path), u8/u16 image, u8 mask, u16-ray + f32-linear depth
// Coverage: all three wide camera models across the distortion tiers
// (the NONE row also passes null dist_coeffs, the zeros-fallback path),
// u8/u16 image, u8 mask, u16-ray + f32-linear depth
// (GT at a different resolution than the intrinsics reference, exercising
// the sx/sy rescale), u8/f32 normal (with all-zero "no data" sentinel
// pixels), the equirectangular variants (x-wrap sampling), and the four
// pixels), the equirectangular variants (x-wrap sampling), the re-distort
// family at two modality resolutions, both branches of the skewed source
// model and its fold rejection (shaders/camera_source.slang), and the four
// raw byte->float converters with odd element counts (word-tail handling).
#include <backend/tests/DistortionFixture.h>
#include <kernels/pixelwise/PixelWise.cuh>
#include <engine/EngineInternal.h>
#include <core/Tensor.h>
@@ -167,13 +171,22 @@ int main(int argc, char** argv) {
struct Cam {
const char* model;
float fx, fy;
bool null_dist;
int dist; // tier; NONE also drives the null dist_coeffs path
int source; // COLMAP model id for the fused re-distort, 0 = none
};
const Cam cams[3] = {
{"FISHEYE", 20.0f, 20.5f, false},
{"EQUISOLID", 24.0f, 24.0f, false},
{"PINHOLE", 30.0f, 31.0f, true},
const Cam cams[6] = {
{"FISHEYE", 20.0f, 20.5f, 2, 0},
{"EQUISOLID", 24.0f, 24.0f, 1, 0},
{"PINHOLE", 30.0f, 31.0f, 0, 0},
{"PINHOLE", 30.0f, 31.0f, 3, 0},
// EUCM source: the warp projects through it instead of the fitted
// camera, which is the fused re-distort + warp-to-pinhole path.
{"FISHEYE", 20.0f, 20.5f, 2, 16},
// The skewed source, its other branch (Metashape b2).
{"FISHEYE", 20.0f, 20.5f, 2, 1000},
};
std::vector<float> dist_rows = dist_fixture::distortion_rows(B);
const float* d_dist_all = upload(dist_rows);
for (const Cam& cam : cams) {
std::vector<float> intr;
for (int b = 0; b < B; b++) {
@@ -183,10 +196,40 @@ int main(int argc, char** argv) {
intr.push_back(0.5f * Hin - 0.2f * b);
}
float* d_intr = upload(intr);
float* d_dist = nullptr;
if (!cam.null_dist) {
std::vector<float> dist = r.vec(B * 10, -0.02f, 0.02f);
d_dist = upload(dist);
const float* d_dist =
cam.dist ? d_dist_all + dist_fixture::row_offset(cam.dist, B)
: nullptr;
const char* d_tier = dist_fixture::kTierNames[cam.dist];
const int* d_src_models = nullptr;
const float* d_src_params = nullptr;
std::vector<int32_t> src_models;
std::vector<float> src_params;
if (cam.source) {
src_models.assign(B, cam.source);
src_params.assign((size_t)B * 16, 0.0f);
for (int b = 0; b < B; b++) {
float* p = &src_params[(size_t)b * 16];
p[0] = intr[b*4 + 0]; p[1] = intr[b*4 + 1];
p[2] = intr[b*4 + 2]; p[3] = intr[b*4 + 3];
if (cam.source == 1000) {
p[4] = 0.35f; // skew, pixels
p[5] = 0.02f; p[6] = -0.003f; // k1 k2
// k4 folds this lens at 110 deg, inside the 135 deg
// the widest face ray reaches, so source_unfolded runs
// both ways here.
p[7] = 0.001f; p[8] = -8e-4f; // k3 k4
p[9] = 7e-4f; p[10] = -4e-4f; // p1 p2
p[11] = 3e-4f; p[12] = -2e-4f; // sx1 sy1
p[13] = 1.0f; // equidistant fisheye base
p[14] = 0.0f; // polynomial radial
} else {
p[4] = 0.6f; // EUCM alpha
p[5] = 1.1f; // EUCM beta
}
}
d_src_models = (const int*)upload(src_models);
d_src_params = upload(src_params);
}
const int64_t n_out = (int64_t)B * K * Hout * Wout;
@@ -195,16 +238,16 @@ int main(int argc, char** argv) {
auto img = r.bytes((int64_t)B * Hin * Win * 3);
float* out = alloc_out<float>(n_out * 3);
launch_warp_byte_to_float_wide(
cam.model, d_intr, d_dist, upload(img), false, B, Hin,
Win, 3, out, K, Hout, Wout, d_axes);
cam.model, d_tier, d_intr, d_dist, d_src_models, d_src_params, upload(img), false,
B, Hin, Win, 3, out, K, Hout, Wout, d_axes);
readback_f(out, n_out * 3);
}
if (cam.model[0] == 'F') {
auto img = r.words((int64_t)B * Hin * Win * 3, 65535);
float* out = alloc_out<float>(n_out * 3);
launch_warp_byte_to_float_wide(
cam.model, d_intr, d_dist, upload(img), true, B, Hin,
Win, 3, out, K, Hout, Wout, d_axes);
cam.model, d_tier, d_intr, d_dist, d_src_models, d_src_params, upload(img), true,
B, Hin, Win, 3, out, K, Hout, Wout, d_axes);
readback_f(out, n_out * 3);
}
@@ -213,9 +256,9 @@ int main(int argc, char** argv) {
auto m = r.bytes((int64_t)B * Hin * Win);
for (auto& v : m) v = v < 200 ? 1 : 0;
uint8_t* out = alloc_out<uint8_t>(n_out);
launch_warp_mask_wide(cam.model, d_intr, d_dist, upload(m),
B, Hin, Win, out, K, Hout, Wout,
d_axes);
launch_warp_mask_wide(cam.model, d_tier, d_intr, d_dist, d_src_models, d_src_params,
upload(m), B, Hin, Win, out, K, Hout,
Wout, d_axes);
readback_b(out, n_out);
}
@@ -224,7 +267,7 @@ int main(int argc, char** argv) {
auto dep = r.words((int64_t)B * Hd * Wd, 5000);
for (size_t i = 0; i < dep.size(); i += 53) dep[i] = 0;
float* out = alloc_out<float>(n_out);
launch_warp_depth_wide(cam.model, d_intr, d_dist,
launch_warp_depth_wide(cam.model, d_tier, d_intr, d_dist, d_src_models, d_src_params,
upload(dep), 2, B, Hd, Wd, Hin, Win,
out, K, Hout, Wout, d_axes, true);
readback_f(out, n_out);
@@ -233,7 +276,7 @@ int main(int argc, char** argv) {
auto dep = r.vec((int64_t)B * Hd * Wd, 0.5f, 8.0f);
for (size_t i = 0; i < dep.size(); i += 41) dep[i] = -0.5f;
float* out = alloc_out<float>(n_out);
launch_warp_depth_wide(cam.model, d_intr, d_dist,
launch_warp_depth_wide(cam.model, d_tier, d_intr, d_dist, d_src_models, d_src_params,
upload(dep), 4, B, Hd, Wd, Hin, Win,
out, K, Hout, Wout, d_axes, false);
readback_f(out, n_out);
@@ -246,7 +289,7 @@ int main(int argc, char** argv) {
for (size_t i = 0; i + 2 < nrm.size(); i += 87)
nrm[i] = nrm[i + 1] = nrm[i + 2] = 0;
float* out = alloc_out<float>(n_out * 3);
launch_warp_normal_wide(cam.model, d_intr, d_dist,
launch_warp_normal_wide(cam.model, d_tier, d_intr, d_dist, d_src_models, d_src_params,
upload(nrm), 1, B, Hd, Wd, Hin, Win,
out, K, Hout, Wout, d_axes);
readback_f(out, n_out * 3);
@@ -254,7 +297,7 @@ int main(int argc, char** argv) {
if (cam.model[0] == 'F') {
auto nrm = r.vec((int64_t)B * Hd * Wd * 3, -1.0f, 1.0f);
float* out = alloc_out<float>(n_out * 3);
launch_warp_normal_wide(cam.model, d_intr, d_dist,
launch_warp_normal_wide(cam.model, d_tier, d_intr, d_dist, d_src_models, d_src_params,
upload(nrm), 4, B, Hd, Wd, Hin, Win,
out, K, Hout, Wout, d_axes);
readback_f(out, n_out * 3);
@@ -262,6 +305,117 @@ int main(int argc, char** argv) {
}
}
// ---- re-distort (K == 1): a camera whose lens model no tier represents,
// resampled from the true source projection onto the fitted tier. The
// modality grids deliberately DIFFER from the intrinsics reference: an
// equal-resolution case cannot tell scale_in from scale_out, so it would
// pass with the source scale applied to the destination step.
{
const int B = 2, refW = 42, refH = 58;
struct Grid { int in_w, in_h, out_w, out_h; };
const Grid grids[2] = {
{refW, refH, refW, refH}, // same resolution
{21, 29, 31, 43}, // half-res source, odd-size destination
};
std::vector<float> intr;
for (int b = 0; b < B; b++) {
intr.push_back(30.0f + 0.5f * b);
intr.push_back(31.0f + 0.3f * b);
intr.push_back(0.5f * refW + 0.4f * b);
intr.push_back(0.5f * refH - 0.2f * b);
}
float* d_intr = upload(intr);
std::vector<float> dist_rows = dist_fixture::distortion_rows(B);
const float* d_dist =
upload(dist_rows) + dist_fixture::row_offset(2, B); // ThinPrism
// EUCM (COLMAP model 16), the wide-angle case the fitter targets.
std::vector<int32_t> src_models(B, 16);
std::vector<float> src_params((size_t)B * 16, 0.0f);
for (int b = 0; b < B; b++) {
float* p = &src_params[(size_t)b * 16];
p[0] = intr[b*4 + 0]; p[1] = intr[b*4 + 1];
p[2] = intr[b*4 + 2]; p[3] = intr[b*4 + 3];
p[4] = 0.6f; p[5] = 1.1f;
}
const int* d_src_m = (const int*)upload(src_models);
const float* d_src_p = upload(src_params);
for (const Grid& g : grids) {
const int64_t n_in = (int64_t)B * g.in_h * g.in_w;
const int64_t n_out = (int64_t)B * g.out_h * g.out_w;
auto img = r.bytes(n_in * 3);
float* o_img = alloc_out<float>(n_out * 3);
launch_redistort_byte_to_float(
"FISHEYE", "THIN_PRISM", d_intr, d_dist, d_src_m, d_src_p,
upload(img), false, B, g.in_h, g.in_w, 3,
o_img, g.out_h, g.out_w, refH, refW, 0.5f);
readback_f(o_img, n_out * 3);
auto msk = r.bytes(n_in);
for (size_t i = 0; i < msk.size(); i++) msk[i] = (msk[i] > 40) ? 1 : 0;
uint8_t* o_msk = alloc_out<uint8_t>(n_out);
launch_redistort_mask(
"FISHEYE", "THIN_PRISM", d_intr, d_dist, d_src_m, d_src_p,
upload(msk), B, g.in_h, g.in_w,
o_msk, g.out_h, g.out_w, refH, refW);
readback_b(o_msk, n_out);
// A smooth ramp, not noise: neighbouring taps thousands of counts
// apart amplify a last-ULP difference in uv_src into a visible
// depth error that is data range, not geometry.
std::vector<uint16_t> dep((size_t)n_in);
for (int64_t i = 0; i < n_in; i++)
dep[i] = (uint16_t)(1000 + (i % 997));
float* o_dep = alloc_out<float>(n_out);
launch_redistort_depth(
"FISHEYE", "THIN_PRISM", d_intr, d_dist, d_src_m, d_src_p,
upload(dep), 2, B, g.in_h, g.in_w, 1,
o_dep, g.out_h, g.out_w, refH, refW, 0.0f);
readback_f(o_dep, n_out);
auto nrm = r.bytes(n_in * 3);
for (size_t i = 0; i + 2 < nrm.size(); i += 87)
nrm[i] = nrm[i + 1] = nrm[i + 2] = 0; // "no data" sentinel
float* o_nrm = alloc_out<float>(n_out * 3);
launch_redistort_normal(
"FISHEYE", "THIN_PRISM", d_intr, d_dist, d_src_m, d_src_p,
upload(nrm), false, B, g.in_h, g.in_w,
o_nrm, g.out_h, g.out_w, refH, refW);
readback_f(o_nrm, n_out * 3);
}
// The skewed source's rational branch on a perspective base -- the one
// combination the wide config above does not reach.
{
std::vector<int32_t> sm(B, 1000);
std::vector<float> sp((size_t)B * 16, 0.0f);
for (int b = 0; b < B; b++) {
float* p = &sp[(size_t)b * 16];
p[0] = intr[b*4 + 0]; p[1] = intr[b*4 + 1];
p[2] = intr[b*4 + 2]; p[3] = intr[b*4 + 3];
p[4] = 0.35f; // skew
p[5] = -0.28f; p[6] = 0.11f; p[7] = -0.02f; // k1 k2 k3
p[8] = 0.9f; p[9] = 0.05f; p[10] = -0.004f; // k4 k5 k6
p[11] = 7e-4f; p[12] = -4e-4f; // p1 p2
p[13] = 0.0f; // perspective base
p[14] = 1.0f; // rational radial
}
const int64_t n_in = (int64_t)B * refH * refW;
const int64_t n_out = n_in;
auto img = r.bytes(n_in * 3);
float* out = alloc_out<float>(n_out * 3);
launch_redistort_byte_to_float(
"PINHOLE", "RATIONAL", d_intr,
upload(dist_rows) + dist_fixture::row_offset(3, B),
(const int*)upload(sm), upload(sp),
upload(img), false, B, refH, refW, 3,
out, refH, refW, refH, refW, 0.5f);
readback_f(out, n_out * 3);
}
}
// ---- equirectangular warps -------------------------------------------
{
const int B = 1, Hin = 32, Win = 64, K = 4, Hout = 16, Wout = 16;
+47 -9
View File
@@ -155,10 +155,37 @@ Variant axes follow the CUDA instantiation structure
- **Primitive** (Vanilla3DGS / MipSplatting / Vanilla3DGUT) is a type
parameter → separate entry point (buffer layouts differ).
- **Camera model, SH degree, DistortionType, output_median, VALUE_BITS**
are value parameters → specialization constants on ONE SPIR-V module,
folded at pipeline creation. Pipelines are created lazily and cached by
(entry point, spec-constant tuple, device capability set).
- **Camera model, lens-distortion tier, SH degree, DistortionType,
output_median, VALUE_BITS** are value parameters → specialization
constants on ONE SPIR-V module, folded at pipeline creation. Pipelines are
created lazily and cached by (entry point, spec-constant tuple, device
capability set).
### The lens-distortion tier (`kDistortion`)
`CameraDistortionType` (0 None / 1 OpenCV / 2 ThinPrism / 3 Rational, see
`core/CameraModel.h`) is a Slang generic `D : ICameraDistortion` in
`shaders/projection_utils.slang`. `backend/vulkan/shaders/dist_spec.slang`
carries the glue: `load_dist_coeffs<D>` (a camera's prefix of the 8-float
storage row), `pixel_ray<D>`, and the `SS_DISPATCH_DIST` /
`SS_DISPATCH_CAM_DIST` macros that fold the constant — the latter covering
only the eleven compiled (model, tier) pairs, with the rest falling through
to the nearest compiled tier. Launchers reject an uncompiled pair up front
(`vkk::cam_dist_spec`), so the fallthrough is never reached.
**`kDistortion` is declared LAST in every module, and its value appended last
in every `SpecList`.** Spec-constant IDs are assigned by declaration order
within a module and the host passes `SpecList` by index, so a constant
inserted mid-module silently renumbers every axis after it (the class of bug
the densify copy kernel hit — see "Spec IDs follow declaration order" below).
The resulting IDs: warp 0; background_sh / pixel_wise_{render,train} /
meshing_raster / visualizer 1; rasterize_moments 3; projection_fwd /
rasterize_fwd 4; projection_bwd / rasterize_bwd 6; projection_qgrad 8;
fpbo 11 (12 axes, still under `SpecList::kMax` = 16).
The one axis declared after `kDistortion` is warp's `kFromSource` (ID 1),
which selects the source-camera projection in the wide warps: it trails so the
launches that never re-distort keep passing their one-element `SpecList`.
## Shaders: build and shipping
@@ -378,7 +405,9 @@ the engine level.
field a shader may load through is NEVER null — launchers substitute
`vkk::or_fallback()` (a 4 KB zeroed allocation in KernelCommon.h);
"null means zeros" inputs (dist_coeffs and friends) just read the
fallback; "null selects a mode" moved to specialization constants
fallback (the identity distortion tier reads nothing at all: a large
camera index would run past the 4 KB fallback);
"null selects a mode" moved to specialization constants
(intersect_tile kEllipse/kHasXy/kPacked, rasterize_fwd kRasterPacked —
spec-folding removes the dead load entirely) or explicit flag fields
(blit has_lss/has_tri, thumbnails has_alpha, optimizer has_steps/
@@ -671,11 +700,12 @@ the engine level.
under bilinear-resampled GT, and the Pearson-depth chain fed by
atomic-order-dependent sums); validation clean.
- **Dataset warp/conversion + end-to-end training (phase 5, eighth and
final slice)**: `kernels/Warp.cpp` implements the 12 remaining launch
final slice)**: `kernels/Warp.cpp` implements the 16 remaining launch
APIs — the fused byte->float GT warps of GtDepthNormalWarp.cu
(`launch_warp_{byte_to_float,mask,depth,normal}_{wide,equi}`) plus the
raw converters (`uint8/16_{image,depth,normal}_to_float_raw` and the
DeviceTensor3D wrappers). Device work in `warp.slang`:
(`launch_warp_{byte_to_float,mask,depth,normal}_{wide,equi}`), the
ImageRedistort.cu family (`launch_redistort_*`) and the raw converters
(`uint8/16_{image,depth,normal}_to_float_raw` and the DeviceTensor3D
wrappers). Device work in `warp.slang`:
- The wide warps project each pinhole-face ray through the CANONICAL
`projection_utils.slang` `*_proj_nav` exports (same functions the
CUDA kernels call), with the camera model as a runtime params field
@@ -694,6 +724,14 @@ the engine level.
by accident of the `valid` guard.
- One `bytes_to_float` entry (elem_kind + scale + offset) covers all
four raw converters.
- **Re-distort** (`launch_redistort_{byte_to_float,float,mask,normal}`,
mirroring ImageRedistort.cu): a COLMAP camera with no exact distortion
tier is fitted onto one, and the GT is resampled from the TRUE source
projection (`shaders/camera_source.slang`, shared with CUDA) instead of
from the fit. `redistort_{img,mask,normal}` cover the four launchers —
byte->float and float->float differ only in `elem_kind`. The fused
fisheye case never materializes the fitted camera: the wide warps take
the source projection directly under the `kFromSource` axis.
- Parity: `warp_parity` (170K floats, one tight channel — everything
here is deterministic per-pixel math; <= 0.0012% violations, isolated
proj_nav valid-flip / nearest-rounding boundary pixels) and
+9 -17
View File
@@ -44,14 +44,6 @@ int64_t _batch_count(const TorchTensorView& t, int64_t per_item) {
return n / per_item;
}
int _camera_model_int(const std::string& camera_model) {
auto cm = cmt(camera_model);
if (cm == (CameraModelType)-1)
throw std::runtime_error("Camera model " + camera_model +
" is not supported for skybox");
return (int)cm;
}
} // namespace
/* API definitions matching kernels/background/BackgroundSphericalHarmonics.cuh */
@@ -60,6 +52,7 @@ void render_background_sh_forward(
int w,
int h,
std::string camera_model,
std::string distortion,
int sh_degree,
TorchTensorView viewmats,
TorchTensorView intrins,
@@ -71,10 +64,7 @@ void render_background_sh_forward(
throw std::runtime_error(
"render_background_sh_forward: sh_degree must be in [0, 4]");
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Camera model " + camera_model +
" is not supported for skybox");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
int64_t b = _batch_count(out_color, (int64_t)h * w * 3);
if (b * h * w == 0) return;
@@ -91,9 +81,9 @@ void render_background_sh_forward(
p.width = (uint32_t)w;
p.height = (uint32_t)h;
p.B = (uint32_t)b;
p.camera_model = (int32_t)cam;
p.camera_model = (int32_t)cd.cam;
backend::vk::SpecList spec{(uint32_t)sh_degree};
backend::vk::SpecList spec{(uint32_t)sh_degree, cd.dist};
vkk::dispatch("background_sh.background_sh_fwd", spec,
(uint32_t)((w + 127) / 128), (uint32_t)h, (uint32_t)b, &p,
sizeof(p));
@@ -106,6 +96,7 @@ void render_background_sh_backward(
int w,
int h,
std::string camera_model,
std::string distortion,
int sh_degree,
TorchTensorView viewmats,
TorchTensorView intrins,
@@ -118,6 +109,7 @@ void render_background_sh_backward(
if (sh_degree < 0 || sh_degree > 4)
throw std::runtime_error(
"render_background_sh_backward: sh_degree must be in [0, 4]");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
int64_t b = _batch_count(out_color, (int64_t)h * w * 3);
if (b * h * w == 0) return;
if (_batch_count(viewmats, 16) != b || _batch_count(intrins, 4) != b)
@@ -143,10 +135,10 @@ void render_background_sh_backward(
p.width = (uint32_t)w;
p.height = (uint32_t)h;
p.B = (uint32_t)b;
p.camera_model = _camera_model_int(camera_model);
p.camera_model = (int32_t)cd.cam;
vkk::dispatch("background_sh.background_sh_bwd",
backend::vk::SpecList{(uint32_t)sh_degree}, kBgBwdWgs, 1, 1,
&p, sizeof(p));
backend::vk::SpecList{(uint32_t)sh_degree, cd.dist},
kBgBwdWgs, 1, 1, &p, sizeof(p));
BackgroundShBwdReduceParams r{};
r.scratch = (uint64_t)scratch;
@@ -53,7 +53,8 @@ void launch_fpbo_vk(
std::vector<DeviceTensorFloatND>& splats_world,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string& camera_model, const TorchTensorView& dist_coeffs,
const std::string& camera_model, const std::string& distortion,
const TorchTensorView& dist_coeffs,
const DeviceVector<int32_t>& camera_ids,
const DeviceVector<int32_t>& gaussian_ids,
DeviceTensorFloatND& aabb,
@@ -84,9 +85,7 @@ void launch_fpbo_vk(
"fused_projection_bwd_optimizer: quantization_level must be "
"0 or 1; got " + std::to_string(quantization_level));
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
Vanilla3DGS<0>::WorldBuffer wb(splats_world);
Vanilla3DGS<0>::WorldBuffer vwb(
@@ -234,7 +233,7 @@ void launch_fpbo_vk(
vkk::Fold f = vkk::fold_1d(N, 256);
p.wgs_per_row = f.per_row;
backend::vk::SpecList spec{
(uint32_t)cam,
cd.cam,
(uint32_t)sh_degree,
antialiased ? 1u : 0u,
level1 ? 16u : 0u, // kShValueBits: level 1 reads SH via the codec
@@ -244,7 +243,8 @@ void launch_fpbo_vk(
color_trust_linear ? 1u : 0u,
level1 ? 1u : 0u,
(level1 && non_sh.enabled) ? 1u : 0u,
vw_mask};
vw_mask,
cd.dist};
vkk::dispatch_ring("fpbo.fpbo", spec, f.per_row, f.rows, 1, &p,
sizeof(p));
}
@@ -255,7 +255,8 @@ void launch_fpbo_vk(
#define _FPBO_ARGS \
num_splats, max_sh_degree, splats_world, viewmats, intrins, \
image_width, image_height, camera_model, dist_coeffs, camera_ids, \
image_width, image_height, camera_model, distortion, dist_coeffs, \
camera_ids, \
gaussian_ids, aabb, v_splats_world, v_splats_screen, \
g1_splats_world, g2_splats_world, sh_packed, sh_quant_bounds, \
sh_value_packed, sh_value_bounds, non_sh, radii, densify_score, \
@@ -271,7 +272,8 @@ void launch_fpbo_vk(
std::vector<DeviceTensorFloatND> splats_world, \
TorchTensorView viewmats, TorchTensorView intrins, \
const uint32_t image_width, const uint32_t image_height, \
const std::string camera_model, const TorchTensorView dist_coeffs, \
const std::string camera_model, const std::string distortion, \
const TorchTensorView dist_coeffs, \
const DeviceVector<int32_t> camera_ids, \
const DeviceVector<int32_t> gaussian_ids, DeviceTensorFloatND aabb, \
const std::vector<DeviceTensorFloatND> v_splats_world, \
@@ -298,7 +300,8 @@ void launch_fpbo_vk(
static void _fpbo_call(bool eval3d, bool antialiased, _FPBO_PARAMS) {
launch_fpbo_vk(eval3d, antialiased, num_splats, max_sh_degree,
splats_world, viewmats, intrins, image_width, image_height,
camera_model, dist_coeffs, camera_ids, gaussian_ids, aabb,
camera_model, distortion, dist_coeffs, camera_ids,
gaussian_ids, aabb,
v_splats_world, v_splats_screen, g1_splats_world,
g2_splats_world, sh_packed, sh_quant_bounds,
sh_value_packed, sh_value_bounds, non_sh, radii,
+37
View File
@@ -11,6 +11,7 @@
#include "backend/vulkan/VulkanPipelines.h"
#include "backend/common/SortScan.h"
#include <core/Common.cuh>
#include <core/Tensor.h>
#include <algorithm>
@@ -130,6 +131,42 @@ inline uint64_t or_fallback(const void* p) {
return or_fallback((uint64_t)p);
}
// The kCameraModel / kDistortion specialization values for a launch. Pairs
// outside the compiled set (camera_distortion_is_compiled in
// core/CameraModel.h) are rejected here rather than dispatched: the shaders'
// SS_DISPATCH_CAM_DIST folds them onto a neighbouring tier instead of carrying
// a dead arm, so an unchecked pair would silently project with the wrong
// distortion.
struct CamDistSpec {
uint32_t cam, dist;
};
inline CamDistSpec cam_dist_spec(const std::string& camera_model,
const std::string& distortion) {
const CameraModelType m = cmt(camera_model);
const CameraDistortionType d = cdt(distortion);
bool ok = (int)m >= 0 && (int)m <= 3 && (int)d >= 0 && (int)d <= 3;
if (ok) {
if (m == CameraModelType::FISHEYE || m == CameraModelType::EQUISOLID)
ok = d != CameraDistortionType::Rational;
else if (m == CameraModelType::EQUIRECTANGULAR)
ok = d == CameraDistortionType::None;
}
if (!ok)
throw std::runtime_error("Unsupported camera model / distortion tier");
return {(uint32_t)m, (uint32_t)d};
}
// kDistortion alone, for launches whose camera model stays a runtime value and
// may differ from the one the coefficients were written for (the visualizer
// blits the dataset cameras through a free-navigation view camera).
inline uint32_t distortion_spec(const std::string& distortion) {
const CameraDistortionType d = cdt(distortion);
if ((int)d < 0 || (int)d > 3)
throw std::runtime_error("Unsupported camera distortion tier");
return (uint32_t)d;
}
// Validation + resolution of the SH value-quant launch args shared by the
// projection launchers (fwd, packed fwd; bwd reuses it in the training
// phase). Returns the kShValueBits spec value (0 = fp32). Mirrors the CUDA
+28 -21
View File
@@ -194,11 +194,13 @@ void fill_scene(P& p, const meshing::GpuScene& s) {
p.sc_iso = s.iso;
}
// Spec IDs for meshing_raster.slang: 0 = camera model.
backend::vk::SpecList camera_spec(int camera_model) {
if (camera_model < 0 || camera_model > 3)
throw std::runtime_error("meshing: unsupported camera model");
return backend::vk::SpecList{(uint32_t)camera_model};
// Spec IDs for meshing_raster.slang: 0 = camera model, 1 = distortion tier.
backend::vk::SpecList camera_spec(int camera_model, int distortion) {
if (camera_model < 0 || camera_model > 3 || distortion < 0 ||
distortion > 3)
throw std::runtime_error(
"meshing: unsupported camera model / distortion tier");
return backend::vk::SpecList{(uint32_t)camera_model, (uint32_t)distortion};
}
// Ring dispatch of a flat 1D range (the params structs above the push floor).
@@ -434,7 +436,8 @@ void launch_occ_combine(int n, float* occ, const float* occ_static) {
void launch_sample_occ(
const float* xyz, int n,
const float* viewmat, const float* intrin, const float* dist,
int camera_model, const float3* moments, int W, int H, int k,
int camera_model, int distortion,
const float3* moments, int W, int H, int k,
float* occ_kmin, int* cnt
) {
if (n <= 0) return;
@@ -451,8 +454,8 @@ void launch_sample_occ(
p.H = (uint32_t)H;
p.k = (uint32_t)k;
vkk::dispatch_flat("meshing_raster.mesh_sample_occ",
camera_spec(camera_model), n, 256, &p, sizeof(p),
&p.wgs_per_row);
camera_spec(camera_model, distortion), n, 256, &p,
sizeof(p), &p.wgs_per_row);
}
void launch_finalize_occ(int n, const float* occ_kmin, const int* cnt, int k,
@@ -464,14 +467,15 @@ void launch_finalize_occ(int n, const float* occ_kmin, const int* cnt, int k,
p.occ = (uint64_t)occ;
p.n = (uint32_t)n;
p.k = (uint32_t)k;
vkk::dispatch_flat("meshing_raster.mesh_finalize_occ", camera_spec(0), n,
vkk::dispatch_flat("meshing_raster.mesh_finalize_occ", camera_spec(0, 0), n,
256, &p, sizeof(p), &p.wgs_per_row);
}
void launch_sample_color(
const float* xyz, int n,
const float* viewmat, const float* intrin, const float* dist,
int camera_model, const float3* moments, const float3* rgb_img,
int camera_model, int distortion,
const float3* moments, const float3* rgb_img,
int W, int H, float3* num, float* den
) {
if (n <= 0) return;
@@ -488,8 +492,8 @@ void launch_sample_color(
p.W = (uint32_t)W;
p.H = (uint32_t)H;
vkk::dispatch_flat("meshing_raster.mesh_sample_color",
camera_spec(camera_model), n, 256, &p, sizeof(p),
&p.wgs_per_row);
camera_spec(camera_model, distortion), n, 256, &p,
sizeof(p), &p.wgs_per_row);
}
void launch_finalize_color(int n, const float3* num, const float* den,
@@ -500,14 +504,16 @@ void launch_finalize_color(int n, const float3* num, const float* den,
p.den = (uint64_t)den;
p.rgb = (uint64_t)rgb;
p.n = (uint32_t)n;
vkk::dispatch_flat("meshing_raster.mesh_finalize_color", camera_spec(0), n,
256, &p, sizeof(p), &p.wgs_per_row);
vkk::dispatch_flat("meshing_raster.mesh_finalize_color",
camera_spec(0, 0), n, 256, &p, sizeof(p),
&p.wgs_per_row);
}
void launch_sample_view_density(
const float* xyz, int n,
const float* viewmat, const float* intrin, const float* dist,
int camera_model, const float3* moments, int W, int H, float* dens
int camera_model, int distortion,
const float3* moments, int W, int H, float* dens
) {
if (n <= 0) return;
MeshViewDensityParams p{};
@@ -521,8 +527,8 @@ void launch_sample_view_density(
p.W = (uint32_t)W;
p.H = (uint32_t)H;
vkk::dispatch_flat("meshing_raster.mesh_sample_view_density",
camera_spec(camera_model), n, 256, &p, sizeof(p),
&p.wgs_per_row);
camera_spec(camera_model, distortion), n, 256, &p,
sizeof(p), &p.wgs_per_row);
}
void launch_tri_prep(
@@ -545,14 +551,14 @@ void launch_tri_prep(
p.ext_y = inv_ext.y;
p.ext_z = inv_ext.z;
p.nf = (uint32_t)nf;
vkk::dispatch_flat("meshing_raster.mesh_tri_prep", camera_spec(0), nf, 256,
&p, sizeof(p), &p.wgs_per_row);
vkk::dispatch_flat("meshing_raster.mesh_tri_prep", camera_spec(0, 0), nf,
256, &p, sizeof(p), &p.wgs_per_row);
}
void launch_cull(
const float* verts, int nv, const int* faces, int nf,
const float* viewmats, const float* intrins, const float* dist,
const int* Ws, const int* Hs, int camera_model, int C,
const int* Ws, const int* Hs, int camera_model, int distortion, int C,
const float3* leafMin, const float3* leafMax,
const int2* internal, const float3* nodeAABB,
uint32_t* visible
@@ -576,7 +582,8 @@ void launch_cull(
p.nv = (uint32_t)nv;
p.nf = (uint32_t)nf;
p.C = (uint32_t)C;
dispatch_flat_ring("meshing_raster.mesh_cull", camera_spec(camera_model),
dispatch_flat_ring("meshing_raster.mesh_cull",
camera_spec(camera_model, distortion),
nv, 256, &p, sizeof(p), &p.wgs_per_row);
}
@@ -107,6 +107,7 @@ void rgb_to_srgb_forward(
void depth_to_normal_forward(
std::string camera_model,
std::string distortion,
TorchTensorView intrins,
TorchTensorView dist_coeffs,
bool is_ray_depth,
@@ -126,21 +127,24 @@ void depth_to_normal_forward(
p.H = H;
p.B = B;
p.is_ray_depth = is_ray_depth ? 1u : 0u;
p.camera_model = (int32_t)cmt(camera_model);
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
p.camera_model = (int32_t)cd.cam;
vkk::dispatch("pixel_wise_render.depth_to_normal_fwd",
backend::vk::SpecList{}, (W + 15) / 16, (H + 15) / 16, B,
&p, sizeof(p));
backend::vk::SpecList{0u, cd.dist}, (W + 15) / 16,
(H + 15) / 16, B, &p, sizeof(p));
}
void depth_to_normal_forward_tv(
std::string camera_model,
std::string distortion,
TorchTensorView intrins,
TorchTensorView dist_coeffs,
bool is_ray_depth,
TorchTensorView depths,
TorchTensorView normals
) {
depth_to_normal_forward(camera_model, intrins, dist_coeffs, is_ray_depth,
depth_to_normal_forward(camera_model, distortion, intrins, dist_coeffs,
is_ray_depth,
DeviceTensor3D<float>(depths),
DeviceTensor3D<float3>(normals));
}
+14 -6
View File
@@ -175,6 +175,7 @@ void overexposure_grad_add(
void depth_to_normal_backward(
std::string camera_model,
std::string distortion,
TorchTensorView intrins,
TorchTensorView dist_coeffs,
bool is_ray_depth,
@@ -196,13 +197,16 @@ void depth_to_normal_backward(
p.H = H;
p.B = B;
p.is_ray_depth = is_ray_depth ? 1u : 0u;
p.camera_model = (int32_t)cmt(camera_model);
vkk::dispatch("pixel_wise_train.d2n_bwd", backend::vk::SpecList{},
(W + 15) / 16, (H + 15) / 16, B, &p, sizeof(p));
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
p.camera_model = (int32_t)cd.cam;
vkk::dispatch("pixel_wise_train.d2n_bwd",
backend::vk::SpecList{0u, cd.dist}, (W + 15) / 16,
(H + 15) / 16, B, &p, sizeof(p));
}
void depth_to_normal_backward_tv(
std::string camera_model,
std::string distortion,
TorchTensorView intrins,
TorchTensorView dist_coeffs,
bool is_ray_depth,
@@ -210,7 +214,8 @@ void depth_to_normal_backward_tv(
TorchTensorView v_normals,
TorchTensorView v_depths
) {
depth_to_normal_backward(camera_model, intrins, dist_coeffs, is_ray_depth,
depth_to_normal_backward(camera_model, distortion, intrins, dist_coeffs,
is_ray_depth,
DeviceTensor3D<float>(depths),
DeviceTensor3D<float3>(v_normals),
DeviceTensor3D<float>(v_depths));
@@ -218,6 +223,7 @@ void depth_to_normal_backward_tv(
void linear_depth_to_ray_depth_inplace(
std::string camera_model,
std::string distortion,
TorchTensorView intrins,
TorchTensorView dist_coeffs,
int image_width, int image_height,
@@ -234,8 +240,10 @@ void linear_depth_to_ray_depth_inplace(
p.W = (uint32_t)w;
p.H = (uint32_t)h;
p.B = (uint32_t)b;
p.camera_model = (int32_t)cmt(camera_model);
vkk::dispatch("pixel_wise_train.lin_to_ray_depth", backend::vk::SpecList{},
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
p.camera_model = (int32_t)cd.cam;
vkk::dispatch("pixel_wise_train.lin_to_ray_depth",
backend::vk::SpecList{0u, cd.dist},
(uint32_t)((w + 127) / 128), (uint32_t)h, (uint32_t)b, &p,
sizeof(p));
}
+12 -9
View File
@@ -64,7 +64,8 @@ void launch_projection_bwd_vk(
const int max_sh_degree,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string& camera_model, const TorchTensorView& dist_coeffs,
const std::string& camera_model, const std::string& distortion,
const TorchTensorView& dist_coeffs,
const DeviceVector<int32_t>& camera_ids,
const DeviceVector<int32_t>& gaussian_ids,
const DeviceTensor2D<float4>& aabb,
@@ -83,9 +84,7 @@ void launch_projection_bwd_vk(
sh_value_bits, sh_bounds_stride, &q_packed,
&q_bounds, &q_stride);
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
// WorldBuffer layout is identical for 3DGS/Mip/3DGUT (TensorArray<6>).
Vanilla3DGS<0>::WorldBuffer wb(
@@ -113,9 +112,10 @@ void launch_projection_bwd_vk(
const uint64_t total = (uint64_t)C * (uint64_t)N;
vkk::Fold f = vkk::fold_1d(total, 128);
backend::vk::SpecList spec{(uint32_t)cam, (uint32_t)sh_degree,
backend::vk::SpecList spec{cd.cam, (uint32_t)sh_degree,
antialiased ? 1u : 0u, spec_bits,
packed ? 1u : 0u, viewmat_grad ? 1u : 0u};
packed ? 1u : 0u, viewmat_grad ? 1u : 0u,
cd.dist};
if (!eval3d) {
Vanilla3DGS<0>::ScreenBuffer vsb(
@@ -215,6 +215,7 @@ void projection_3dgs_backward(
const uint32_t image_width,
const uint32_t image_height,
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
const DeviceVector<int32_t> camera_ids,
const DeviceVector<int32_t> gaussian_ids,
@@ -231,7 +232,7 @@ void projection_3dgs_backward(
launch_projection_bwd_vk(
/*eval3d=*/false, /*antialiased=*/false, num_splats, splats_world,
max_sh_degree, viewmats, intrins, image_width, image_height,
camera_model, dist_coeffs, camera_ids, gaussian_ids, aabb,
camera_model, distortion, dist_coeffs, camera_ids, gaussian_ids, aabb,
v_splats_screen, v_splats_world, v_viewmats, sh_value_packed,
sh_value_bounds, num_sh_buffer, sh_value_bits, sh_bounds_stride);
}
@@ -245,6 +246,7 @@ void projection_mip_backward(
const uint32_t image_width,
const uint32_t image_height,
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
const DeviceVector<int32_t> camera_ids,
const DeviceVector<int32_t> gaussian_ids,
@@ -261,7 +263,7 @@ void projection_mip_backward(
launch_projection_bwd_vk(
/*eval3d=*/false, /*antialiased=*/true, num_splats, splats_world,
max_sh_degree, viewmats, intrins, image_width, image_height,
camera_model, dist_coeffs, camera_ids, gaussian_ids, aabb,
camera_model, distortion, dist_coeffs, camera_ids, gaussian_ids, aabb,
v_splats_screen, v_splats_world, v_viewmats, sh_value_packed,
sh_value_bounds, num_sh_buffer, sh_value_bits, sh_bounds_stride);
}
@@ -275,6 +277,7 @@ void projection_3dgut_backward(
const uint32_t image_width,
const uint32_t image_height,
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
const DeviceVector<int32_t> camera_ids,
const DeviceVector<int32_t> gaussian_ids,
@@ -291,7 +294,7 @@ void projection_3dgut_backward(
launch_projection_bwd_vk(
/*eval3d=*/true, /*antialiased=*/false, num_splats, splats_world,
max_sh_degree, viewmats, intrins, image_width, image_height,
camera_model, dist_coeffs, camera_ids, gaussian_ids, aabb,
camera_model, distortion, dist_coeffs, camera_ids, gaussian_ids, aabb,
v_splats_screen, v_splats_world, v_viewmats, sh_value_packed,
sh_value_bounds, num_sh_buffer, sh_value_bits, sh_bounds_stride);
}
@@ -52,7 +52,8 @@ void launch_projection_qgrad_vk(
const std::vector<DeviceTensorFloatND>& splats_world,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string& camera_model, const TorchTensorView& dist_coeffs,
const std::string& camera_model, const std::string& distortion,
const TorchTensorView& dist_coeffs,
const DeviceVector<int32_t>& camera_ids,
const DeviceVector<int32_t>& gaussian_ids,
const DeviceTensor2D<float4>& aabb,
@@ -71,9 +72,7 @@ void launch_projection_qgrad_vk(
sh_value_bits, sh_value_bounds_stride, &q_packed,
&q_bounds, &q_stride);
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
Vanilla3DGS<0>::WorldBuffer wb(
const_cast<std::vector<DeviceTensorFloatND>&>(splats_world));
@@ -168,10 +167,11 @@ void launch_projection_qgrad_vk(
vkk::Fold f = vkk::fold_1d(N, 256);
p.wgs_per_row = f.per_row;
backend::vk::SpecList spec{(uint32_t)cam, (uint32_t)sh_degree,
backend::vk::SpecList spec{cd.cam, (uint32_t)sh_degree,
antialiased ? 1u : 0u, spec_bits,
packed ? 1u : 0u, eval3d ? 1u : 0u,
gq_mask, world_grad_add ? 1u : 0u};
gq_mask, world_grad_add ? 1u : 0u,
cd.dist};
vkk::dispatch_ring("projection_qgrad.projection_qgrad", spec, f.per_row,
f.rows, 1, &p, sizeof(p));
}
@@ -189,6 +189,7 @@ void projection_3dgs_backward_quantgrad(
const uint32_t image_width,
const uint32_t image_height,
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
const DeviceVector<int32_t> camera_ids,
const DeviceVector<int32_t> gaussian_ids,
@@ -205,7 +206,7 @@ void projection_3dgs_backward_quantgrad(
launch_projection_qgrad_vk(
/*eval3d=*/false, /*antialiased=*/false, num_splats, max_sh_degree,
splats_world, viewmats, intrins, image_width, image_height,
camera_model, dist_coeffs, camera_ids, gaussian_ids, aabb,
camera_model, distortion, dist_coeffs, camera_ids, gaussian_ids, aabb,
v_splats_screen, v_splats_world, gq, sh_value_packed,
sh_value_bounds, num_sh_buffer, sh_value_bits,
sh_value_bounds_stride);
@@ -220,6 +221,7 @@ void projection_mip_backward_quantgrad(
const uint32_t image_width,
const uint32_t image_height,
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
const DeviceVector<int32_t> camera_ids,
const DeviceVector<int32_t> gaussian_ids,
@@ -236,7 +238,7 @@ void projection_mip_backward_quantgrad(
launch_projection_qgrad_vk(
/*eval3d=*/false, /*antialiased=*/true, num_splats, max_sh_degree,
splats_world, viewmats, intrins, image_width, image_height,
camera_model, dist_coeffs, camera_ids, gaussian_ids, aabb,
camera_model, distortion, dist_coeffs, camera_ids, gaussian_ids, aabb,
v_splats_screen, v_splats_world, gq, sh_value_packed,
sh_value_bounds, num_sh_buffer, sh_value_bits,
sh_value_bounds_stride);
@@ -251,6 +253,7 @@ void projection_3dgut_backward_quantgrad(
const uint32_t image_width,
const uint32_t image_height,
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
const DeviceVector<int32_t> camera_ids,
const DeviceVector<int32_t> gaussian_ids,
@@ -267,7 +270,7 @@ void projection_3dgut_backward_quantgrad(
launch_projection_qgrad_vk(
/*eval3d=*/true, /*antialiased=*/false, num_splats, max_sh_degree,
splats_world, viewmats, intrins, image_width, image_height,
camera_model, dist_coeffs, camera_ids, gaussian_ids, aabb,
camera_model, distortion, dist_coeffs, camera_ids, gaussian_ids, aabb,
v_splats_screen, v_splats_world, gq, sh_value_packed,
sh_value_bounds, num_sh_buffer, sh_value_bits,
sh_value_bounds_stride);
+17 -17
View File
@@ -1,7 +1,7 @@
// Vulkan implementation of the projection-forward launch API
// (kernels/projection/ProjectionFwd.cuh). Mirrors ProjectionFwd.cu's launcher logic; the
// device work runs shaders/projection_fwd.slang with camera model /
// SH degree / antialiased as specialization constants.
// distortion tier / SH degree / antialiased as specialization constants.
#include <kernels/projection/ProjectionFwd.cuh>
@@ -56,7 +56,8 @@ launch_projection_fwd_vk(
const int max_sh_degree,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string& camera_model, const TorchTensorView& dist_coeffs,
const std::string& camera_model, const std::string& distortion,
const TorchTensorView& dist_coeffs,
DeviceVector<float>& radii,
const std::optional<TorchTensorView>& sh_value_packed,
const std::optional<TorchTensorView>& sh_value_bounds,
@@ -70,9 +71,7 @@ launch_projection_fwd_vk(
sh_value_bits, sh_bounds_stride, &q_packed,
&q_bounds, &q_stride);
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
Vanilla3DGS<0>::WorldBuffer wb(in_splats);
int sh_degree = wb.sh_degree();
@@ -123,8 +122,8 @@ launch_projection_fwd_vk(
p.height = image_height;
p.wgs_per_row = per_row;
backend::vk::SpecList spec{(uint32_t)cam, (uint32_t)sh_degree,
antialiased ? 1u : 0u, spec_bits};
backend::vk::SpecList spec{cd.cam, (uint32_t)sh_degree,
antialiased ? 1u : 0u, spec_bits, 0u, cd.dist};
vkk::dispatch_ring("projection_fwd.projection_fwd_3dgs", spec, per_row,
rows, 1, &p, sizeof(p));
@@ -142,7 +141,8 @@ std::tuple<
const std::vector<DeviceTensorFloatND> &in_splats,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string camera_model, const TorchTensorView dist_coeffs,
const std::string camera_model, const std::string distortion,
const TorchTensorView dist_coeffs,
DeviceVector<float> radii,
const std::optional<TorchTensorView> sh_value_packed,
const std::optional<TorchTensorView> sh_value_bounds,
@@ -153,7 +153,7 @@ std::tuple<
return launch_projection_fwd_vk(
/*antialiased=*/false, num_splats, in_splats, max_sh_degree,
viewmats, intrins, image_width, image_height, camera_model,
dist_coeffs, radii, sh_value_packed, sh_value_bounds,
distortion, dist_coeffs, radii, sh_value_packed, sh_value_bounds,
num_sh_buffer, sh_value_bits, sh_bounds_stride);
}
@@ -164,7 +164,8 @@ std::tuple<
const std::vector<DeviceTensorFloatND> &in_splats,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string camera_model, const TorchTensorView dist_coeffs,
const std::string camera_model, const std::string distortion,
const TorchTensorView dist_coeffs,
DeviceVector<float> radii,
const std::optional<TorchTensorView> sh_value_packed,
const std::optional<TorchTensorView> sh_value_bounds,
@@ -175,7 +176,7 @@ std::tuple<
return launch_projection_fwd_vk(
/*antialiased=*/true, num_splats, in_splats, max_sh_degree,
viewmats, intrins, image_width, image_height, camera_model,
dist_coeffs, radii, sh_value_packed, sh_value_bounds,
distortion, dist_coeffs, radii, sh_value_packed, sh_value_bounds,
num_sh_buffer, sh_value_bits, sh_bounds_stride);
}
@@ -186,7 +187,8 @@ std::tuple<
const std::vector<DeviceTensorFloatND> &in_splats,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string camera_model, const TorchTensorView dist_coeffs,
const std::string camera_model, const std::string distortion,
const TorchTensorView dist_coeffs,
DeviceVector<float> radii,
const std::optional<TorchTensorView> sh_value_packed,
const std::optional<TorchTensorView> sh_value_bounds,
@@ -201,9 +203,7 @@ std::tuple<
sh_value_bits, sh_bounds_stride, &q_packed,
&q_bounds, &q_stride);
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
const int64_t N = num_splats;
Vanilla3DGUT<0>::WorldBuffer wb(in_splats);
@@ -253,8 +253,8 @@ std::tuple<
p.height = image_height;
p.wgs_per_row = per_row;
backend::vk::SpecList spec{(uint32_t)cam, (uint32_t)sh_degree, 0u,
spec_bits};
backend::vk::SpecList spec{cd.cam, (uint32_t)sh_degree, 0u, spec_bits, 0u,
cd.dist};
vkk::dispatch_ring("projection_fwd.projection_fwd_3dgut", spec, per_row,
rows, 1, &p, sizeof(p));
@@ -51,7 +51,8 @@ launch_projection_packed_vk(
const int max_sh_degree,
TorchTensorView viewmats, TorchTensorView intrins,
const uint32_t image_width, const uint32_t image_height,
const std::string& camera_model, const TorchTensorView& dist_coeffs,
const std::string& camera_model, const std::string& distortion,
const TorchTensorView& dist_coeffs,
DeviceVector<float>& radii,
const std::optional<TorchTensorView>& sh_value_packed,
const std::optional<TorchTensorView>& sh_value_bounds,
@@ -65,9 +66,7 @@ launch_projection_packed_vk(
sh_value_bits, sh_bounds_stride, &q_packed,
&q_bounds, &q_stride);
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
Vanilla3DGS<0>::WorldBuffer wb(in_splats);
int sh_degree = wb.sh_degree();
@@ -101,10 +100,11 @@ launch_projection_packed_vk(
mp.wgs_per_row = per_row;
// Spec IDs: 0 = camera model, 1 = SH degree (unused by the mask),
// 2 = antialiased, 3 = SH value bits (unused by the mask), 4 = eval3d.
backend::vk::SpecList spec{(uint32_t)cam, (uint32_t)sh_degree,
// 2 = antialiased, 3 = SH value bits (unused by the mask), 4 = eval3d,
// 5 = distortion tier.
backend::vk::SpecList spec{cd.cam, (uint32_t)sh_degree,
antialiased ? 1u : 0u, spec_bits,
eval3d ? 1u : 0u};
eval3d ? 1u : 0u, cd.dist};
vkk::dispatch("projection_fwd.projection_packed_mask", spec, per_row,
rows, 1, &mp, sizeof(mp));
@@ -197,6 +197,7 @@ std::tuple< \
const uint32_t image_width, \
const uint32_t image_height, \
const std::string camera_model, \
const std::string distortion, \
const TorchTensorView dist_coeffs, \
DeviceVector<float> radii, \
const std::optional<TorchTensorView> sh_value_packed, \
@@ -208,7 +209,7 @@ std::tuple< \
return launch_projection_packed_vk( \
eval3d, antialiased, num_splats, in_splats, max_sh_degree, \
viewmats, intrins, image_width, image_height, camera_model, \
dist_coeffs, radii, sh_value_packed, sh_value_bounds, \
distortion, dist_coeffs, radii, sh_value_packed, sh_value_bounds, \
num_sh_buffer, sh_value_bits, sh_bounds_stride); \
}
+6 -6
View File
@@ -190,6 +190,7 @@ std::tuple<
TorchTensorView viewmats,
TorchTensorView intrins,
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
DeviceTensor2D<float4> aabb,
const uint32_t image_width,
@@ -212,9 +213,7 @@ std::tuple<
bool need_viewmat_grad
) {
(void)loss_map; // declared but unused by the CUDA kernel as well
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
const uint32_t spec_dist = dist_spec_bwd(dist_type);
const bool aw = accum_weight_map.data_ptr() != nullptr;
const bool md = v_median.data_ptr() != nullptr;
@@ -308,11 +307,12 @@ std::tuple<
p.tile_height = tile_height;
// Spec IDs: cam(0), dist(1), median(2), accum(3), viewmat(4),
// packed(5).
// packed(5), distortion tier(6).
backend::vk::SpecList spec{
(uint32_t)cam, spec_dist,
cd.cam, spec_dist,
md ? 1u : 0u, aw ? 1u : 0u,
need_viewmat_grad ? 1u : 0u, packed ? 1u : 0u};
need_viewmat_grad ? 1u : 0u, packed ? 1u : 0u,
cd.dist};
vkk::dispatch_ring("rasterize_bwd.rasterize_bwd_3dgut", spec, I,
tile_height * 2, tile_width * 2, &p, sizeof(p));
}
+5 -6
View File
@@ -206,6 +206,7 @@ std::tuple<
TorchTensorView viewmats, // [..., C, 4, 4]
TorchTensorView intrins, // [..., C, 4], fx, fy, cx, cy
const std::string camera_model,
const std::string distortion,
const TorchTensorView dist_coeffs,
DeviceTensor2D<float4> aabb, // [..., N] projected 2D AABB
const uint32_t image_width,
@@ -215,9 +216,7 @@ std::tuple<
DistortionType dist_type,
bool output_median
) {
CameraModelType cam = cmt(camera_model);
if ((int)cam < 0 || (int)cam > 3)
throw std::runtime_error("Unsupported camera model");
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
const int64_t batch = tile_offsets.size<0>();
const uint32_t tile_height = (uint32_t)tile_offsets.size<1>();
@@ -261,10 +260,10 @@ std::tuple<
p.tile_height = tile_height;
// Spec IDs: 0 = camera model, 1 = dist type, 2 = median,
// 3 = kRasterPacked (gaussian_ids present).
backend::vk::SpecList spec{(uint32_t)cam, dist_spec(dist_type),
// 3 = kRasterPacked (gaussian_ids present), 4 = distortion tier.
backend::vk::SpecList spec{cd.cam, dist_spec(dist_type),
output_median ? 1u : 0u,
gaussian_ids.data_ptr() ? 1u : 0u};
gaussian_ids.data_ptr() ? 1u : 0u, cd.dist};
dispatch_raster("rasterize_fwd.rasterize_fwd_3dgut", spec,
(uint32_t)batch, tile_width, tile_height, &p, sizeof(p));
@@ -38,6 +38,7 @@ void rasterize_moments_3dgut_fwd(
TorchTensorView viewmats,
TorchTensorView intrins,
const std::string& camera_model,
const std::string& distortion,
TorchTensorView dist_coeffs,
DeviceTensor2D<float4> aabb,
uint32_t image_width,
@@ -47,9 +48,8 @@ void rasterize_moments_3dgut_fwd(
float3* render_moments,
float3* render_rgb
) {
CameraModelType cam = cmt(camera_model);
if (cam != CameraModelType::PINHOLE && cam != CameraModelType::FISHEYE &&
cam != CameraModelType::EQUISOLID)
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
if (cd.cam == (uint32_t)CameraModelType::EQUIRECTANGULAR)
throw std::runtime_error(
"rasterize_moments_3dgut_fwd: unsupported camera model");
@@ -86,10 +86,11 @@ void rasterize_moments_3dgut_fwd(
p.tile_width = tile_width;
p.tile_height = tile_height;
// Spec IDs: 0 = camera model, 1 = kRasterPacked, 2 = kOutputRgb.
backend::vk::SpecList spec{(uint32_t)cam,
// Spec IDs: 0 = camera model, 1 = kRasterPacked, 2 = kOutputRgb,
// 3 = distortion tier.
backend::vk::SpecList spec{cd.cam,
gaussian_ids.data_ptr() ? 1u : 0u,
render_rgb ? 1u : 0u};
render_rgb ? 1u : 0u, cd.dist};
vkk::dispatch_ring("rasterize_moments.rasterize_moments_3dgut", spec, I,
tile_height * MACRO_TILE_SIZE_Y,
tile_width * MACRO_TILE_SIZE_X, &p, sizeof(p));
+23 -15
View File
@@ -283,8 +283,9 @@ RootBox compute_root_box(const void* root_aabb_dev) {
void fill_frustums(int64_t n, const void* intrins, const void* widths,
const void* heights, const void* camera_models,
const void* dist_coeffs, const void* c2w, float size,
void* lss_buffer, void* tri_buffer) {
const void* dist_coeffs, uint32_t dist_spec,
const void* c2w, float size, void* lss_buffer,
void* tri_buffer) {
VisFrustumParams p{};
p.intrins = (uint64_t)intrins;
p.widths = (uint64_t)widths;
@@ -296,8 +297,9 @@ void fill_frustums(int64_t n, const void* intrins, const void* widths,
p.tri_buffer = (uint64_t)tri_buffer;
p.size = size;
p.N = (uint32_t)n;
vkk::dispatch("visualizer.vis_fill_frustum", backend::vk::SpecList{},
(uint32_t)n, 1, 1, &p, sizeof(p));
vkk::dispatch("visualizer.vis_fill_frustum",
backend::vk::SpecList{0u, dist_spec}, (uint32_t)n, 1, 1, &p,
sizeof(p));
}
// root_aabb: u32[6] mapped; min words init 0xffffffff, max words 0.
@@ -347,7 +349,7 @@ struct BlitGeom {
void run_blit(const TorchTensorView& render_rgbs,
const TorchTensorView& render_depths,
const TorchTensorView& render_alphas, int view_camera_model,
const TorchTensorView& view_intrins,
uint32_t dist_spec, const TorchTensorView& view_intrins,
const TorchTensorView& view_viewmat,
const TorchTensorView& view_dist_coeffs, const BlitGeom& geom,
const void* thumbnails, int thumb_w, int thumb_h,
@@ -396,7 +398,7 @@ void run_blit(const TorchTensorView& render_rgbs,
if (!backend::vk::params_alloc(sizeof(p), &params_addr, &params_mapped))
throw std::runtime_error("Vulkan backend: params ring failed");
std::memcpy(params_mapped, &p, sizeof(p));
vkk::dispatch("visualizer.vis_blit", backend::vk::SpecList{},
vkk::dispatch("visualizer.vis_blit", backend::vk::SpecList{0u, dist_spec},
(uint32_t)((w + 7) / 8), (uint32_t)((h + 3) / 4), 1,
&params_addr, sizeof(params_addr));
@@ -411,7 +413,7 @@ void run_blit(const TorchTensorView& render_rgbs,
/* ---- engine-cached BVH build (mirrors _viewer_build_bvh) ---- */
void _viewer_build_bvh() {
void _viewer_build_bvh(uint32_t dist_spec) {
auto& v = engine().viewer;
int64_t n = v.N_post;
@@ -426,8 +428,9 @@ void _viewer_build_bvh() {
fill_frustums(n, v.d_intrins.data_ptr(), v.d_widths.data_ptr(),
v.d_heights.data_ptr(), v.d_camera_models.data_ptr(),
v.d_dist_coeffs.data_ptr(), v.d_camera_to_worlds.data_ptr(),
v.camera_size, lss_buffer, tri_buffer);
v.d_dist_coeffs.data_ptr(), dist_spec,
v.d_camera_to_worlds.data_ptr(), v.camera_size, lss_buffer,
tri_buffer);
if (v.num_overlay > 0)
backend::memcpy_sync(lss_buffer + (size_t)num_cam_lss * 2,
@@ -557,7 +560,8 @@ void engine_viewer_init(
_hv_to_dv<int32_t>(PoolSlot::ViewerCmodels, camera_models);
v.d_dist_coeffs = _hv_to_dv<float>(
PoolSlot::ViewerDist,
TorchTensorView(std::get<0>(dist_coeffs), 4, {N * 10LL}));
TorchTensorView(std::get<0>(dist_coeffs), 4,
{N * (int64_t)kCameraDistortionParams}));
v.d_camera_to_worlds = _hv_to_dv<float>(
PoolSlot::ViewerC2w,
TorchTensorView(std::get<0>(camera_to_worlds), 4, {N * 12LL}));
@@ -677,6 +681,7 @@ void engine_blit_view(
TorchTensorView render_depth,
TorchTensorView render_alpha,
int view_camera_model,
std::string distortion,
TorchTensorView view_intrins,
TorchTensorView view_viewmat,
TorchTensorView view_dist_coeffs,
@@ -688,6 +693,7 @@ void engine_blit_view(
float grid_target_z,
TorchTensorView out_rgb)
{
const uint32_t dist_spec = vkk::distortion_spec(distortion);
std::lock_guard<std::mutex> _vlock(viewer_mutex());
auto& v = engine().viewer;
if (!v.initialized) {
@@ -715,7 +721,7 @@ void engine_blit_view(
BlitGeom geom;
if (show_training_cameras || show_overlay) {
if (!v.bvh_built || v.bvh_camera_size != v.camera_size)
_viewer_build_bvh();
_viewer_build_bvh(dist_spec);
geom.lss_buffer = DevicePool::global().acquire<float4>(
PoolSlot::ViewerLss, (size_t)v.bvh_num_lss * 2);
geom.lss_nodes = v.bvh_lss_nodes_ptr;
@@ -733,7 +739,7 @@ void engine_blit_view(
}
run_blit(render_buffer, render_depth, render_alpha, view_camera_model,
view_intrins, view_viewmat, view_dist_coeffs, geom,
dist_spec, view_intrins, view_viewmat, view_dist_coeffs, geom,
v.thumbnails.data_ptr(), VIEWER_THUMBNAIL_SIZE,
VIEWER_THUMBNAIL_SIZE, min_max, out_rgb);
}
@@ -744,6 +750,7 @@ void blit_train_cameras_tensor(
TorchTensorView render_depths,
TorchTensorView render_alphas,
const int view_camera_model,
std::string distortion,
TorchTensorView view_intrins,
TorchTensorView view_viewmat,
TorchTensorView view_dist_coeffs,
@@ -758,6 +765,7 @@ void blit_train_cameras_tensor(
bool show_training_cameras,
TorchTensorView out_rgb
) {
const uint32_t dist_spec = vkk::distortion_spec(distortion);
auto& rgb_shape = std::get<2>(render_rgbs);
int64_t h = rgb_shape[0], w = rgb_shape[1], c = rgb_shape[2];
int64_t n = std::get<2>(intrins)[0];
@@ -773,7 +781,7 @@ void blit_train_cameras_tensor(
if (!show_training_cameras) {
BlitGeom geom; // no frusta, no overlay
run_blit(render_rgbs, render_depths, render_alphas,
view_camera_model, view_intrins, view_viewmat,
view_camera_model, dist_spec, view_intrins, view_viewmat,
view_dist_coeffs, geom, (void*)std::get<0>(thumbnails),
thumb_w, thumb_h, min_max, out_rgb);
return;
@@ -789,7 +797,7 @@ void blit_train_cameras_tensor(
(const void*)std::get<0>(widths),
(const void*)std::get<0>(heights),
(const void*)std::get<0>(camera_models),
(const void*)std::get<0>(dist_coeffs),
(const void*)std::get<0>(dist_coeffs), dist_spec,
(const void*)std::get<0>(camera_to_worlds), camera_size,
lss_buffer, tri_buffer);
@@ -815,7 +823,7 @@ void blit_train_cameras_tensor(
geom.show_cams = true;
geom.show_overlay = false;
run_blit(render_rgbs, render_depths, render_alphas, view_camera_model,
view_intrins, view_viewmat, view_dist_coeffs, geom,
dist_spec, view_intrins, view_viewmat, view_dist_coeffs, geom,
(void*)std::get<0>(thumbnails), thumb_w, thumb_h, min_max,
out_rgb);
}
+215 -34
View File
@@ -1,7 +1,8 @@
// Vulkan implementation of the dataset GT warp + byte->float conversion
// launch APIs (the launch_warp_* section of kernels/pixelwise/PixelWise.cuh and the
// uint8/16_*_to_float_raw converters of EngineInternal.h). Mirrors the
// CUDA launchers in kernels/pixelwise/ImageWarp.cu; the device work runs
// Vulkan implementation of the dataset GT warp / re-distort + byte->float
// conversion launch APIs (the launch_warp_* and launch_redistort_* sections of
// kernels/pixelwise/PixelWise.cuh and the uint8/16_*_to_float_raw converters of
// EngineInternal.h). Mirrors the CUDA launchers in
// kernels/pixelwise/ImageWarp.cu + ImageRedistort.cu; the device work runs
// shaders/warp.slang.
//
// All launchers take raw device pointers (the engine's DataManager path
@@ -24,26 +25,30 @@ constexpr int kElemF32 = 2;
// Mirrors WarpParams in shaders/warp.slang.
struct WarpParams {
uint64_t intrins, dist_coeffs, src, dst, axes;
uint64_t intrins, dist_coeffs, source_models, source_params;
uint64_t src, dst, axes;
int32_t B, Hin, Win, C;
int32_t K, Hout, Wout;
int32_t elem_kind, camera_model;
int32_t in_H, in_W;
int32_t ref_H, ref_W;
int32_t ray_depth;
float norm_inv, decode_off;
float norm_inv, decode_off, invalid;
int32_t _pad0;
};
static_assert(sizeof(WarpParams) == 5 * 8 + 14 * 4,
static_assert(sizeof(WarpParams) == 7 * 8 + 16 * 4,
"params layout must match the slang struct");
// Mirrors WarpMaskParams in shaders/warp.slang.
struct WarpMaskParams {
uint64_t intrins, dist_coeffs, src, dst, axes;
uint64_t intrins, dist_coeffs, source_models, source_params;
uint64_t src, dst, axes;
int32_t B, Hin, Win;
int32_t K, Hout, Wout;
int32_t camera_model;
int32_t ref_H, ref_W;
uint32_t wgs_per_row;
};
static_assert(sizeof(WarpMaskParams) == 5 * 8 + 8 * 4,
static_assert(sizeof(WarpMaskParams) == 7 * 8 + 10 * 4,
"params layout must match the slang struct");
// Mirrors BytesToFloatParams in shaders/warp.slang.
@@ -58,17 +63,25 @@ struct BytesToFloatParams {
static_assert(sizeof(BytesToFloatParams) == 2 * 8 + 6 * 4,
"params layout must match the slang struct");
// Source pointers, which the ordinary (non-re-distorting) path leaves null.
struct SourceCam {
const int* models = nullptr;
const float* params = nullptr;
};
// Common WarpParams assembly for the image / depth / normal warps.
WarpParams make_warp_params(const float* d_intrins, const float* d_dist,
const void* d_src, float* d_dst,
SourceCam src_cam, const void* d_src, float* d_dst,
const float* d_axes, int B, int Hin, int Win,
int C, int K, int Hout, int Wout, int elem_kind,
CameraModelType cm, int in_H, int in_W,
CameraModelType cm, int ref_H, int ref_W,
bool ray_depth, float norm_inv,
float decode_off) {
WarpParams p{};
p.intrins = vkk::or_fallback(d_intrins);
p.dist_coeffs = vkk::or_fallback(d_dist);
p.source_models = vkk::or_fallback(src_cam.models);
p.source_params = vkk::or_fallback(src_cam.params);
p.src = vkk::or_fallback(d_src);
p.dst = (uint64_t)d_dst;
p.axes = vkk::or_fallback(d_axes);
@@ -76,7 +89,7 @@ WarpParams make_warp_params(const float* d_intrins, const float* d_dist,
p.K = K; p.Hout = Hout; p.Wout = Wout;
p.elem_kind = elem_kind;
p.camera_model = (int)cm;
p.in_H = in_H; p.in_W = in_W;
p.ref_H = ref_H; p.ref_W = ref_W;
p.ray_depth = ray_depth ? 1 : 0;
p.norm_inv = norm_inv;
p.decode_off = decode_off;
@@ -85,15 +98,33 @@ WarpParams make_warp_params(const float* d_intrins, const float* d_dist,
// (ceil(Wout/16), ceil(Hout/16), B) grid of flat-256 workgroups (16x16
// logical tiles), mirroring the CUDA _LAUNCH_ARGS_3D(Wout, Hout, B, 16, 16, 1).
void dispatch_warp(const char* entry, const WarpParams& p) {
void dispatch_warp(const char* entry, const WarpParams& p,
const backend::vk::SpecList& spec) {
if ((int64_t)p.B * p.K * p.Hout * p.Wout <= 0) return;
if (p.B > 65535)
throw std::runtime_error("warp: batch exceeds grid limit");
vkk::dispatch(entry, {}, (uint32_t)((p.Wout + 15) / 16),
vkk::dispatch(entry, spec, (uint32_t)((p.Wout + 15) / 16),
(uint32_t)((p.Hout + 15) / 16), (uint32_t)p.B, &p,
sizeof(p));
}
// Re-distort of one modality, whose input and output grids are independent of
// each other and of the (ref_H, ref_W) intrinsics reference.
WarpParams make_redistort_params(const float* d_intrins, const float* d_dist,
SourceCam src_cam, const void* d_src,
float* d_dst, int B, int in_H, int in_W,
int C, int out_H, int out_W, int elem_kind,
CameraModelType cm, int ref_H, int ref_W,
float norm_inv, float decode_off,
float invalid) {
WarpParams p = make_warp_params(d_intrins, d_dist, src_cam, d_src, d_dst,
nullptr, B, in_H, in_W, C, 1, out_H, out_W,
elem_kind, cm, ref_H, ref_W, false,
norm_inv, decode_off);
p.invalid = invalid;
return p;
}
void run_bytes_to_float(const void* d_in, float* d_out, int64_t total,
int elem_kind, float scale, float offset) {
BytesToFloatParams p{};
@@ -107,6 +138,11 @@ void run_bytes_to_float(const void* d_in, float* d_out, int64_t total,
&p.wgs_per_row);
}
// kFromSource: the CUDA _SS_DISPATCH_SOURCE predicate.
uint32_t from_source_spec(const int* d_source_models) {
return d_source_models != nullptr ? 1u : 0u;
}
int resolve_depth_kind(uint32_t elem_size, const char* who) {
if (elem_size == 2) return kElemU16;
if (elem_size == 4) return kElemF32;
@@ -162,20 +198,27 @@ void uint16_image_to_float_tensor(DeviceTensor3D<uint16_t> img_in,
void launch_warp_byte_to_float_wide(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const void* d_byte, bool input_is_u16,
int B, int Hin, int Win, int C,
float* d_float_out, int K, int Hout, int Wout,
const float* d_axes)
{
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
dispatch_warp("warp.warp_img_wide",
make_warp_params(
d_intrins, d_dist_coeffs, d_byte, d_float_out, d_axes,
d_intrins, d_dist_coeffs,
{d_source_models, d_source_params},
d_byte, d_float_out, d_axes,
B, Hin, Win, C, K, Hout, Wout,
input_is_u16 ? kElemU16 : kElemU8, cmt(camera_model),
Hin, Win, false,
input_is_u16 ? 1.0f / 65535.0f : 1.0f / 255.0f, 0.0f));
input_is_u16 ? kElemU16 : kElemU8,
(CameraModelType)cd.cam, Hin, Win, false,
input_is_u16 ? 1.0f / 65535.0f : 1.0f / 255.0f, 0.0f),
{cd.dist, from_source_spec(d_source_models)});
}
void launch_warp_byte_to_float_equi(
@@ -186,17 +229,21 @@ void launch_warp_byte_to_float_equi(
{
dispatch_warp("warp.warp_img_equi",
make_warp_params(
nullptr, nullptr, d_byte, d_float_out, d_axes,
nullptr, nullptr, {}, d_byte, d_float_out, d_axes,
B, Hin, Win, C, K, Hout, Wout,
input_is_u16 ? kElemU16 : kElemU8,
CameraModelType::EQUIRECTANGULAR, Hin, Win, false,
input_is_u16 ? 1.0f / 65535.0f : 1.0f / 255.0f, 0.0f));
input_is_u16 ? 1.0f / 65535.0f : 1.0f / 255.0f, 0.0f),
{});
}
void launch_warp_mask_wide(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const uint8_t* d_byte_mask,
int B, int Hin, int Win,
uint8_t* d_byte_out, int K, int Hout, int Wout,
@@ -205,15 +252,19 @@ void launch_warp_mask_wide(
WarpMaskParams p{};
p.intrins = vkk::or_fallback(d_intrins);
p.dist_coeffs = vkk::or_fallback(d_dist_coeffs);
p.source_models = vkk::or_fallback(d_source_models);
p.source_params = vkk::or_fallback(d_source_params);
p.src = vkk::or_fallback(d_byte_mask);
p.dst = (uint64_t)d_byte_out;
p.axes = vkk::or_fallback(d_axes);
p.B = B; p.Hin = Hin; p.Win = Win;
p.K = K; p.Hout = Hout; p.Wout = Wout;
p.camera_model = (int)cmt(camera_model);
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
p.camera_model = (int)cd.cam;
int64_t words = ((int64_t)B * K * Hout * Wout + 3) / 4;
vkk::dispatch_flat("warp.warp_mask_wide", {}, words, 256, &p, sizeof(p),
&p.wgs_per_row);
vkk::dispatch_flat("warp.warp_mask_wide",
{cd.dist, from_source_spec(d_source_models)}, words,
256, &p, sizeof(p), &p.wgs_per_row);
}
void launch_warp_mask_equi(
@@ -225,6 +276,8 @@ void launch_warp_mask_equi(
WarpMaskParams p{};
p.intrins = vkk::or_fallback(nullptr);
p.dist_coeffs = vkk::or_fallback(nullptr);
p.source_models = vkk::or_fallback(nullptr);
p.source_params = vkk::or_fallback(nullptr);
p.src = vkk::or_fallback(d_byte_mask);
p.dst = (uint64_t)d_byte_out;
p.axes = vkk::or_fallback(d_axes);
@@ -238,21 +291,28 @@ void launch_warp_mask_equi(
void launch_warp_depth_wide(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const void* d_depth, uint32_t elem_size,
int B, int Hin, int Win,
int in_H, int in_W,
float* d_float_out, int K, int Hout, int Wout,
const float* d_axes, bool input_is_ray_depth)
{
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
dispatch_warp("warp.warp_depth_wide",
make_warp_params(
d_intrins, d_dist_coeffs, d_depth, d_float_out, d_axes,
d_intrins, d_dist_coeffs,
{d_source_models, d_source_params},
d_depth, d_float_out, d_axes,
B, Hin, Win, 1, K, Hout, Wout,
resolve_depth_kind(elem_size, "launch_warp_depth_wide"),
cmt(camera_model), in_H, in_W, input_is_ray_depth,
1.0f, 0.0f));
(CameraModelType)cd.cam, in_H, in_W, input_is_ray_depth,
1.0f, 0.0f),
{cd.dist, from_source_spec(d_source_models)});
}
void launch_warp_depth_equi(
@@ -263,17 +323,21 @@ void launch_warp_depth_equi(
{
dispatch_warp("warp.warp_depth_equi",
make_warp_params(
nullptr, nullptr, d_depth, d_float_out, d_axes,
nullptr, nullptr, {}, d_depth, d_float_out, d_axes,
B, Hin, Win, 1, K, Hout, Wout,
resolve_depth_kind(elem_size, "launch_warp_depth_equi"),
CameraModelType::EQUIRECTANGULAR, Hin, Win,
input_is_ray_depth, 1.0f, 0.0f));
input_is_ray_depth, 1.0f, 0.0f),
{});
}
void launch_warp_normal_wide(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const void* d_normal, uint32_t elem_size,
int B, int Hin, int Win,
int in_H, int in_W,
@@ -284,12 +348,17 @@ void launch_warp_normal_wide(
throw std::runtime_error(
"launch_warp_normal_wide: normal must be uint8 or float32");
bool u8 = elem_size == 1;
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
dispatch_warp("warp.warp_normal_wide",
make_warp_params(
d_intrins, d_dist_coeffs, d_normal, d_float_out, d_axes,
d_intrins, d_dist_coeffs,
{d_source_models, d_source_params},
d_normal, d_float_out, d_axes,
B, Hin, Win, 3, K, Hout, Wout,
u8 ? kElemU8 : kElemF32, cmt(camera_model), in_H, in_W,
false, u8 ? 1.0f / 127.5f : 1.0f, u8 ? -1.0f : 0.0f));
u8 ? kElemU8 : kElemF32, (CameraModelType)cd.cam, in_H,
in_W, false, u8 ? 1.0f / 127.5f : 1.0f,
u8 ? -1.0f : 0.0f),
{cd.dist, from_source_spec(d_source_models)});
}
void launch_warp_normal_equi(
@@ -304,9 +373,121 @@ void launch_warp_normal_equi(
bool u8 = elem_size == 1;
dispatch_warp("warp.warp_normal_equi",
make_warp_params(
nullptr, nullptr, d_normal, d_float_out, d_axes,
nullptr, nullptr, {}, d_normal, d_float_out, d_axes,
B, Hin, Win, 3, K, Hout, Wout,
u8 ? kElemU8 : kElemF32,
CameraModelType::EQUIRECTANGULAR, Hin, Win, false,
u8 ? 1.0f / 127.5f : 1.0f, u8 ? -1.0f : 0.0f));
u8 ? 1.0f / 127.5f : 1.0f, u8 ? -1.0f : 0.0f),
{});
}
// ---- Re-distort onto the fitted tier (PixelWise.cuh) ------------------------
void launch_redistort_byte_to_float(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const void* d_byte, bool input_is_u16,
int B, int in_H, int in_W, int C,
float* d_float_out, int out_H, int out_W,
int ref_H, int ref_W,
float invalid)
{
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
dispatch_warp("warp.redistort_img",
make_redistort_params(
d_intrins, d_dist_coeffs,
{d_source_models, d_source_params},
d_byte, d_float_out, B, in_H, in_W, C, out_H, out_W,
input_is_u16 ? kElemU16 : kElemU8,
(CameraModelType)cd.cam, ref_H, ref_W,
input_is_u16 ? 1.0f / 65535.0f : 1.0f / 255.0f, 0.0f,
invalid),
{cd.dist});
}
// Depth is raw counts either way, so norm_inv stays 1 -- same convention as
// the wide warp.
void launch_redistort_depth(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const void* d_in, uint32_t elem_size,
int B, int in_H, int in_W, int C,
float* d_float_out, int out_H, int out_W,
int ref_H, int ref_W,
float invalid)
{
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
dispatch_warp("warp.redistort_img",
make_redistort_params(
d_intrins, d_dist_coeffs,
{d_source_models, d_source_params},
d_in, d_float_out, B, in_H, in_W, C, out_H, out_W,
elem_size == 2 ? kElemU16 : kElemF32,
(CameraModelType)cd.cam, ref_H, ref_W, 1.0f, 0.0f,
invalid),
{cd.dist});
}
void launch_redistort_mask(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const uint8_t* d_byte_mask,
int B, int in_H, int in_W,
uint8_t* d_byte_out, int out_H, int out_W,
int ref_H, int ref_W)
{
WarpMaskParams p{};
p.intrins = vkk::or_fallback(d_intrins);
p.dist_coeffs = vkk::or_fallback(d_dist_coeffs);
p.source_models = vkk::or_fallback(d_source_models);
p.source_params = vkk::or_fallback(d_source_params);
p.src = vkk::or_fallback(d_byte_mask);
p.dst = (uint64_t)d_byte_out;
p.axes = vkk::or_fallback(nullptr);
p.B = B; p.Hin = in_H; p.Win = in_W;
p.K = 1; p.Hout = out_H; p.Wout = out_W;
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
p.camera_model = (int)cd.cam;
p.ref_H = ref_H; p.ref_W = ref_W;
int64_t words = ((int64_t)B * out_H * out_W + 3) / 4;
vkk::dispatch_flat("warp.redistort_mask", {cd.dist}, words, 256, &p,
sizeof(p), &p.wgs_per_row);
}
void launch_redistort_normal(
std::string camera_model,
std::string distortion,
const float* d_intrins,
const float* d_dist_coeffs,
const int* d_source_models,
const float* d_source_params,
const void* d_in, bool input_is_float,
int B, int in_H, int in_W,
float* d_float_out, int out_H, int out_W,
int ref_H, int ref_W)
{
const vkk::CamDistSpec cd = vkk::cam_dist_spec(camera_model, distortion);
dispatch_warp("warp.redistort_normal",
make_redistort_params(
d_intrins, d_dist_coeffs,
{d_source_models, d_source_params},
d_in, d_float_out, B, in_H, in_W, 3, out_H, out_W,
input_is_float ? kElemF32 : kElemU8,
(CameraModelType)cd.cam, ref_H, ref_W,
input_is_float ? 1.0f : 1.0f / 127.5f,
input_is_float ? 0.0f : -1.0f, 0.0f),
{cd.dist});
}
+23 -19
View File
@@ -4,9 +4,9 @@
// the camera-to-world rotation use the same projection_utils.slang exports
// the CUDA kernel wraps (generate_ray + transform_ray_d).
//
// kShDegree is a specialization constant (the CUDA kernel's template
// parameter); the camera model is a plain runtime value, exactly like the
// CUDA kernel's `int camera_model` argument.
// kShDegree and kDistortion (declared last) are specialization constants (the
// CUDA kernel's template parameters); the camera model is a plain runtime
// value, exactly like the CUDA kernel's `int camera_model` argument.
//
// Backward: CUDA's 512-thread block-atomic SH reduction
// (sh_block_atomic_add_f3_512) hardcodes warp==32 and needs float atomics,
@@ -20,6 +20,7 @@
#include "shaders/projection_utils.slang"
#include "shaders/harmonics.slang"
#undef CudaDeviceExport
#include "dist_spec.slang"
[SpecializationConstant]
const int kShDegree = 0;
@@ -27,7 +28,7 @@ const int kShDegree = 0;
struct BackgroundShFwdParams { // 56 bytes: pushed directly
float* viewmats; // [B,16] row-major world->camera
float4* intrins; // [B] fx, fy, cx, cy
float* dist_coeffs; // [B,10] or null
float* dist_coeffs; // [B,8] or null
float* sh_coeffs; // [(kShDegree+1)^2, 3]
float* out_img; // [B,H,W,3]
uint32_t width;
@@ -39,6 +40,9 @@ struct BackgroundShFwdParams { // 56 bytes: pushed directly
// Workgroups are a flat 128x1 pixel-row segment (not the CUDA kernel's
// 16x16): REQUIRE_FULL_SUBGROUPS demands the X dimension be a multiple of
// the pinned subgroup size (README subgroup rules). Grid (ceil(W/128), H, B).
#define _bg_ray(D) \
ray_ok = pixel_ray<D>(p.dist_coeffs, bi, p.camera_model, uv, raydir)
[shader("compute")]
[numthreads(128, 1, 1)]
void background_sh_fwd(uint3 gtid: SV_DispatchThreadID,
@@ -55,18 +59,15 @@ void background_sh_fwd(uint3 gtid: SV_DispatchThreadID,
for (int r = 0; r < 3; r++)
R[r] = float3(vm[4 * r + 0], vm[4 * r + 1], vm[4 * r + 2]);
float4 intrin = p.intrins[bi];
float dist[10];
[ForceUnroll]
for (int i = 0; i < 10; i++)
dist[i] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * bi + i];
float2 uv = float2((float(px) + 0.5f - intrin.z) / intrin.x,
(float(py) + 0.5f - intrin.w) / intrin.y);
float3 color = float3(0.0f);
float3 raydir;
if (generate_ray(uv, p.camera_model, dist, raydir)) {
float3 raydir = float3(0.0f);
bool ray_ok = false;
SS_DISPATCH_DIST(_bg_ray)
if (ray_ok) {
float3 dir = transform_ray_d(R, raydir);
float3 dc = float3(p.sh_coeffs[0], p.sh_coeffs[1], p.sh_coeffs[2]);
float3* coeffs_l1 = (float3*)p.sh_coeffs + 1;
@@ -94,7 +95,7 @@ static const uint kBgBwdSlices = kBgBwdWgs * 256;
struct BackgroundShBwdParams { // 80 bytes: pushed directly
float* viewmats; // [B,16]
float4* intrins; // [B]
float* dist_coeffs; // [B,10] (fallback-backed)
float* dist_coeffs; // [B,8] (fallback-backed)
float* sh_coeffs; // [K,3], K = (kShDegree+1)^2
float* out_color; // [B,H,W,3] forward output (clamp mask)
float* v_out_color; // [B,H,W,3]
@@ -146,15 +147,12 @@ void background_sh_bwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
for (int r = 0; r < 3; r++)
R[r] = float3(vm[4 * r + 0], vm[4 * r + 1], vm[4 * r + 2]);
float4 intrin = p.intrins[bi];
float dist[10];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * bi + k];
float2 uv = float2((float(px) + 0.5f - intrin.z) / intrin.x,
(float(py) + 0.5f - intrin.w) / intrin.y);
float3 raydir;
if (!generate_ray(uv, p.camera_model, dist, raydir)) continue;
float3 raydir = float3(0.0f);
bool ray_ok = false;
SS_DISPATCH_DIST(_bg_ray)
if (!ray_ok) continue;
float3 dir = transform_ray_d(R, raydir);
// v_dir is discarded (engine holds cameras fixed, as in CUDA).
@@ -211,3 +209,9 @@ void background_sh_bwd_reduce(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
}
if (tid == 0) p.v_sh_coeffs[col] += _bgsh_red[0];
}
#undef _bg_ray
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
@@ -0,0 +1,86 @@
#pragma once
// Distortion tier as a specialization constant: the coefficient loader and the
// dispatch macros that fold `kDistortion` (and, where the camera model is also
// a spec constant, the pair) into the Slang generics of
// shaders/projection_utils.slang.
//
// `kDistortion` itself is NOT declared here. Specialization-constant IDs are
// assigned by declaration order within a module and the host passes SpecList by
// index, so a constant declared mid-module renumbers everything after it: every
// module declares `kDistortion` LAST and appends its value last in SpecList.
//
// Include after shaders/projection_utils.slang (directly or transitively) and
// after int64_compat.slang.
// Storage width of one camera's coefficient row; must match
// kCameraDistortionParams in core/CameraModel.h. Each tier reads a prefix.
static const int kDistCoeffRow = 8;
// The identity tier reads nothing: its one slot is unused (Slang has no
// zero-length array), and an undistorted launch passes the 4 KB zeroed
// fallback, which a large `cid` would index past.
[ForceInline]
void load_dist_coeffs<D : ICameraDistortion>(
float* dist_coeffs, uint cid, out float dist[D.kNumParams]
) {
[ForceUnroll]
for (int i = 0; i < D.kNumParams; i++)
dist[i] = (D.kIsIdentity || is_null(dist_coeffs))
? 0.0f
: dist_coeffs[kDistCoeffRow * cid + i];
}
// Ray through a pixel for the kernels that take the camera model as a runtime
// value (rasterization, background, pixel-wise): loads the tier's row and calls
// generate_ray, so callers dispatch on kDistortion alone.
[ForceInline]
bool pixel_ray<D : ICameraDistortion>(float* dist_coeffs, uint cid,
int camera_model, float2 uv,
out float3 raydir) {
float dist[D.kNumParams];
load_dist_coeffs<D>(dist_coeffs, cid, dist);
return generate_ray<D>(uv, camera_model, dist, raydir);
}
// CALL(D) once per tier, folded on kDistortion.
#define SS_DISPATCH_DIST(CALL) \
switch (kDistortion) { \
case 0: CALL(DistNone); break; \
case 1: CALL(DistOpenCV); break; \
case 2: CALL(DistThinPrism); break; \
default: CALL(DistRational); break; \
}
// CALL(camera model, D) over the ELEVEN compiled (model, tier) combos
// (camera_distortion_is_compiled in core/CameraModel.h). Combos outside that
// set fall through to the nearest compiled tier rather than duplicating an
// arm -- no launcher dispatches them.
#define SS_DISPATCH_CAM_DIST(CALL) \
switch (kCameraModel) { \
case 1: \
switch (kDistortion) { \
case 0: CALL(CameraModelType::FISHEYE, DistNone); break; \
case 1: CALL(CameraModelType::FISHEYE, DistOpenCV); break; \
default: CALL(CameraModelType::FISHEYE, DistThinPrism); break; \
} \
break; \
case 2: \
switch (kDistortion) { \
case 0: CALL(CameraModelType::EQUISOLID, DistNone); break; \
case 1: CALL(CameraModelType::EQUISOLID, DistOpenCV); break; \
default: CALL(CameraModelType::EQUISOLID, DistThinPrism); break;\
} \
break; \
case 3: \
CALL(CameraModelType::EQUIRECTANGULAR, DistNone); \
break; \
default: \
switch (kDistortion) { \
case 0: CALL(CameraModelType::PINHOLE, DistNone); break; \
case 1: CALL(CameraModelType::PINHOLE, DistOpenCV); break; \
case 2: CALL(CameraModelType::PINHOLE, DistThinPrism); break; \
default: CALL(CameraModelType::PINHOLE, DistRational); break; \
} \
break; \
}
+53 -34
View File
@@ -18,6 +18,7 @@
// attributes); only ever set with kLevel == 1
// kVwMask = which v_splats_world tensors exist (1 means, 2 quats,
// 4 scales, 8 opac, 16 dc) -- folded loads
// kDistortion = CameraDistortionType (0..3), declared last
//
// Barriers only exist in the kLevel/kNonShQuant reduces and the staged SH
// writeback, which every thread reaches (`inside` masks work, never control
@@ -158,6 +159,51 @@ float _fp_sigmoid(float x) { return 1.0f / (1.0f + exp(-x)); }
// optim_quant.slang (oq_state_read / oq_accum_us / oq_state_encode /
// oq_sqrt3 / oq_sqrt4), shared with optim_geometry.slang.
// The per-splat camera loop, generic over the two projection spec axes so the
// entry point folds them once (its block reduces stay outside).
[ForceInline]
void _fpbo_camera_loop<let cam : CameraModelType, D : ICameraDistortion>(
FpboParams p, PbSplat s, uint gid, int cid_0, int cid_1, gindex_t qbase,
gindex_t vstride, inout PbGrads g) {
for (int cid_t = cid_0; cid_t < cid_1; ++cid_t) {
int idx = (kPacked != 0) ? p.perm[cid_t]
: cid_t * int(p.N) + int(gid);
int cid = (kPacked != 0) ? p.camera_ids[idx] : cid_t;
float4 bb = p.aabb[idx];
if (bb.z <= bb.x || bb.w <= bb.y)
continue;
PbCamera<D> c = pb_load_camera<D>(p.viewmats, p.intrins,
p.dist_coeffs, uint(cid));
if (kEval3d != 0) {
float3 v_ss = float3(p.vs0[3 * idx], p.vs0[3 * idx + 1],
p.vs0[3 * idx + 2]);
float v_so = p.vs1[idx];
float3 v_rgb = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
pb_vjp_3dgut<cam, D>(s, c, p.width, p.height, v_ss, v_so, g);
pb_sh_vjp<D>(s, c, p.features_sh + gid * 3 * p.num_sh_buffer,
p.sh_value_packed, p.sh_value_bounds, qbase,
vstride, v_rgb, g);
} else {
float2 v_xy = float2(p.vs0[2 * idx], p.vs0[2 * idx + 1]);
float v_depth = p.vs1[idx];
float3 v_conic = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
float v_opac = p.vs3[idx];
float3 v_rgb = float3(p.vs4[3 * idx], p.vs4[3 * idx + 1],
p.vs4[3 * idx + 2]);
pb_vjp_2d<cam, D>(s, c, p.width, p.height, v_xy, v_depth, v_conic,
v_opac, g);
pb_sh_vjp<D>(s, c, p.features_sh + gid * 3 * p.num_sh_buffer,
p.sh_value_packed, p.sh_value_bounds, qbase,
vstride, v_rgb, g);
}
}
}
#define _fpbo_call(M, D) \
_fpbo_camera_loop<M, D>(p, s, gid, cid_0, cid_1, qbase, vstride, g)
[shader("compute")]
[numthreads(256, 1, 1)]
void fpbo(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -209,40 +255,7 @@ void fpbo(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
// all 3*K cells; the host passes kShValueBits = 16 and the FPBO
// stride below).
gindex_t vstride = (gindex_t)256 * 3 * (gindex_t)p.num_sh_buffer;
for (int cid_t = cid_0; cid_t < cid_1; ++cid_t) {
int idx = (kPacked != 0) ? p.perm[cid_t]
: cid_t * int(p.N) + int(gid);
int cid = (kPacked != 0) ? p.camera_ids[idx] : cid_t;
float4 bb = p.aabb[idx];
if (bb.z <= bb.x || bb.w <= bb.y)
continue;
PbCamera cam = pb_load_camera(p.viewmats, p.intrins,
p.dist_coeffs, uint(cid));
if (kEval3d != 0) {
float3 v_ss = float3(p.vs0[3 * idx], p.vs0[3 * idx + 1],
p.vs0[3 * idx + 2]);
float v_so = p.vs1[idx];
float3 v_rgb = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
pb_vjp_3dgut(s, cam, p.width, p.height, v_ss, v_so, g);
pb_sh_vjp(s, cam, p.features_sh + gid * 3 * p.num_sh_buffer,
p.sh_value_packed, p.sh_value_bounds, qbase,
vstride, v_rgb, g);
} else {
float2 v_xy = float2(p.vs0[2 * idx], p.vs0[2 * idx + 1]);
float v_depth = p.vs1[idx];
float3 v_conic = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
float v_opac = p.vs3[idx];
float3 v_rgb = float3(p.vs4[3 * idx], p.vs4[3 * idx + 1],
p.vs4[3 * idx + 2]);
pb_vjp_2d(s, cam, p.width, p.height, v_xy, v_depth, v_conic,
v_opac, g);
pb_sh_vjp(s, cam, p.features_sh + gid * 3 * p.num_sh_buffer,
p.sh_value_packed, p.sh_value_bounds, qbase,
vstride, v_rgb, g);
}
}
SS_DISPATCH_CAM_DIST(_fpbo_call)
// per-splat regularizers -> gradient
float v_losses[5] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
@@ -744,3 +757,9 @@ void fpbo(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
}
}
}
#undef _fpbo_call
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
+83 -47
View File
@@ -15,9 +15,11 @@
#include "int64_compat.slang"
#include "shaders/projection_utils.slang"
#undef CudaDeviceExport
#include "dist_spec.slang"
// Camera model of the images being sampled. Value parameter on the CUDA side;
// a specialization constant here, like every other camera-model axis.
// a specialization constant here, like every other camera-model axis
// (kDistortion follows at the end of the file).
[SpecializationConstant]
const int kCameraModel = 0;
@@ -58,8 +60,9 @@ float3 bilinear3(float* img, int W, int H, float u, float v) {
// Project p (world) into the camera. Returns false if behind the camera or out
// of frame; else fills pixel (u,v) and the along-ray depth z = |p_cam|.
[ForceInline]
bool project_point(float* viewmat, float* intrin, float* dist, int W, int H,
float3 pw, out float u, out float v, out float z) {
bool project_point<D : ICameraDistortion>(
float* viewmat, float* intrin, float* dist, int W, int H, float3 pw,
out float u, out float v, out float z) {
u = 0.0f; v = 0.0f; z = 0.0f;
float3 p_cam;
[ForceUnroll]
@@ -68,17 +71,18 @@ bool project_point(float* viewmat, float* intrin, float* dist, int W, int H,
viewmat[4 * r + 2] * pw.z + viewmat[4 * r + 3];
float4 intr = float4(intrin[0], intrin[1], intrin[2], intrin[3]);
float dc[10];
float dc[D.kNumParams];
[ForceUnroll]
for (int t = 0; t < 10; ++t) dc[t] = dist[t];
for (int t = 0; t < D.kNumParams; ++t) dc[t] = dist[t];
// proj_nav handles the behind-camera / invalid-distortion cases and returns
// pixel-space uv (already scaled by fx,fy and offset by cx,cy).
// The projections handle the behind-camera / invalid-distortion cases and
// return pixel-space uv (already scaled by fx,fy and offset by cx,cy).
float2 uv;
bool valid =
(kCameraModel == 1) ? fisheye_proj_nav(p_cam, intr, dc, uv) :
(kCameraModel == 2) ? equisolid_proj_nav(p_cam, intr, dc, uv) :
persp_proj_nav(p_cam, intr, dc, uv);
(kCameraModel == 1) ? fisheye_proj<D, false>(p_cam, intr, dc, uv) :
(kCameraModel == 2) ? equisolid_proj<D, false>(p_cam, intr, dc, uv) :
(kCameraModel == 3) ? equirect_proj<false>(p_cam, intr, uv) :
persp_proj<D, false>(p_cam, intr, dc, uv);
if (!valid) return false;
u = uv.x; v = uv.y;
if (u < 0.0f || u >= float(W) || v < 0.0f || v >= float(H)) return false;
@@ -148,16 +152,11 @@ struct MeshSampleOccParams { // 56 bytes: pushed directly
uint32_t _pad0;
};
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_sample_occ(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshSampleOccParams p) {
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.n) return;
int i = int(gid);
[ForceInline]
void _ms_occ<D : ICameraDistortion>(MeshSampleOccParams p, int i) {
float u, v, z;
if (!project_point(p.viewmat, p.intrin, p.dist, int(p.W), int(p.H),
ld3(p.xyz, i), u, v, z))
if (!project_point<D>(p.viewmat, p.intrin, p.dist, int(p.W), int(p.H),
ld3(p.xyz, i), u, v, z))
return;
float occ;
if (!occ_bilinear(p.moments, int(p.W), int(p.H), u, v, z, occ))
@@ -173,6 +172,18 @@ void mesh_sample_occ(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
p.cnt[i] += 1;
}
#define _ms_occ_call(D) _ms_occ<D>(p, int(gid))
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_sample_occ(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshSampleOccParams p) {
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.n) return;
SS_DISPATCH_DIST(_ms_occ_call)
}
#undef _ms_occ_call
struct MeshFinalizeOccParams { // 32 bytes: pushed directly
float* occ_kmin;
int* cnt;
@@ -215,16 +226,11 @@ struct MeshSampleColorParams { // 72 bytes: pushed directly
uint32_t wgs_per_row;
};
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_sample_color(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshSampleColorParams p) {
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.n) return;
int i = int(gid);
[ForceInline]
void _ms_color<D : ICameraDistortion>(MeshSampleColorParams p, int i) {
float u, v, z;
if (!project_point(p.viewmat, p.intrin, p.dist, int(p.W), int(p.H),
ld3(p.xyz, i), u, v, z))
if (!project_point<D>(p.viewmat, p.intrin, p.dist, int(p.W), int(p.H),
ld3(p.xyz, i), u, v, z))
return;
float occ;
// Sample the occlusion slightly IN FRONT of the point (2% of depth):
@@ -246,6 +252,18 @@ void mesh_sample_color(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
p.den[i] += w4;
}
#define _ms_color_call(D) _ms_color<D>(p, int(gid))
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_sample_color(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshSampleColorParams p) {
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.n) return;
SS_DISPATCH_DIST(_ms_color_call)
}
#undef _ms_color_call
struct MeshFinalizeColorParams { // 32 bytes: pushed directly
float* num;
float* den;
@@ -286,16 +304,11 @@ struct MeshViewDensityParams { // 56 bytes: pushed directly
uint32_t wgs_per_row;
};
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_sample_view_density(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshViewDensityParams p) {
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.n) return;
int i = int(gid);
[ForceInline]
void _ms_density<D : ICameraDistortion>(MeshViewDensityParams p, int i) {
float u, v, z;
if (!project_point(p.viewmat, p.intrin, p.dist, int(p.W), int(p.H),
ld3(p.xyz, i), u, v, z))
if (!project_point<D>(p.viewmat, p.intrin, p.dist, int(p.W), int(p.H),
ld3(p.xyz, i), u, v, z))
return;
float occ;
// same front-shifted sample as the color path: tolerate surface fuzz
@@ -307,6 +320,18 @@ void mesh_sample_view_density(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
if (nu > p.dens[i]) p.dens[i] = nu;
}
#define _ms_density_call(D) _ms_density<D>(p, int(gid))
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_sample_view_density(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshViewDensityParams p) {
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.n) return;
SS_DISPATCH_DIST(_ms_density_call)
}
#undef _ms_density_call
// ===========================================================================
// Visibility cull
// ===========================================================================
@@ -487,20 +512,14 @@ struct MeshCullParams {
uint32_t wgs_per_row;
};
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_cull(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshCullParams* pp) {
MeshCullParams p = *pp;
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.nv) return;
int i = int(gid);
[ForceInline]
void _ms_cull<D : ICameraDistortion>(MeshCullParams p, int i) {
float3 pt = ld3(p.verts, i);
for (uint c = 0; c < p.C; ++c) {
float* vm = p.viewmats + c * 16;
float u, v, z;
if (!project_point(vm, p.intrins + c * 4, p.dist + c * 10,
p.Ws[c], p.Hs[c], pt, u, v, z))
if (!project_point<D>(vm, p.intrins + c * 4, p.dist + c * kDistCoeffRow,
p.Ws[c], p.Hs[c], pt, u, v, z))
continue; // out of frame / behind camera
// camera center in world: C = -R^T t (viewmat row-major world->cam)
float3 cam = float3(
@@ -515,3 +534,20 @@ void mesh_cull(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
}
p.visible[i] = 0u; // seen by no camera
}
#define _ms_cull_call(D) _ms_cull<D>(p, int(gid))
[shader("compute")]
[numthreads(256, 1, 1)]
void mesh_cull(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uniform MeshCullParams* pp) {
MeshCullParams p = *pp;
uint gid = (wg.y * p.wgs_per_row + wg.x) * 256 + tid;
if (gid >= p.nv) return;
SS_DISPATCH_DIST(_ms_cull_call)
}
#undef _ms_cull_call
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
@@ -14,6 +14,7 @@
#include "int64_compat.slang"
#include "shaders/pixel_wise.slang"
#undef CudaDeviceExport
#include "dist_spec.slang"
// Single boolean variant flag shared by the entries that need one
// (noise blend: is_linear; srgb: is_input_linear).
@@ -158,7 +159,7 @@ static const int D2N_TILE = 16;
struct DepthToNormalParams { // 52 bytes: pushed directly
float4* intrins; // [B]
float* dist_coeffs; // [B,10] or null
float* dist_coeffs; // [B,8] or null
float* depths; // [B,H,W,1]
float* normals; // [B,H,W,3]
uint32_t W;
@@ -170,6 +171,33 @@ struct DepthToNormalParams { // 52 bytes: pushed directly
groupshared float3 _d2n_points[(D2N_TILE + 2) * (D2N_TILE + 2)];
// Apron fill, generic over the tier so the entry folds kDistortion once
// instead of switching inside the loop.
[ForceInline]
void _d2n_fill_apron<D : ICameraDistortion>(DepthToNormalParams p, uint bid,
uint2 tile0, uint tid,
float4 intrin) {
float dist[D.kNumParams];
load_dist_coeffs<D>(p.dist_coeffs, bid, dist);
for (uint k = tid; k < uint((D2N_TILE + 2) * (D2N_TILE + 2)); k += 256) {
int it = int(k % (D2N_TILE + 2)), jt = int(k / (D2N_TILE + 2));
int ig = int(tile0.x) + it - 1;
int jg = int(tile0.y) + jt - 1;
float depth =
(ig >= 0 && ig < int(p.W) && jg >= 0 && jg < int(p.H))
? p.depths[(bid * p.H + uint(jg)) * p.W + uint(ig)]
: 0.0f;
float3 ray = generate_ray_d2n<D>(
float2(float(ig) + 0.5f, float(jg) + 0.5f), intrin, dist,
p.camera_model, p.is_ray_depth != 0);
_d2n_points[k] = ray * depth;
}
}
#define _d2n_call(D) \
_d2n_fill_apron<D>(p, bid, uint2(wg.x * D2N_TILE, wg.y * D2N_TILE), tid, \
intrin)
[shader("compute")]
[numthreads(256, 1, 1)]
void depth_to_normal_fwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -189,27 +217,10 @@ void depth_to_normal_fwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
}
float4 intrin = p.intrins[bid];
float dist[10];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * bid + k];
// Shared apron of unprojected points (ray * depth), same layout as the
// CUDA kernel's shared_points[TILE+2][TILE+2].
for (uint k = tid; k < uint((D2N_TILE + 2) * (D2N_TILE + 2)); k += 256) {
int it = int(k % (D2N_TILE + 2)), jt = int(k / (D2N_TILE + 2));
int ig = int(wg.x * D2N_TILE) + it - 1;
int jg = int(wg.y * D2N_TILE) + jt - 1;
float depth =
(ig >= 0 && ig < int(p.W) && jg >= 0 && jg < int(p.H))
? p.depths[(bid * p.H + uint(jg)) * p.W + uint(ig)]
: 0.0f;
float3 ray = generate_ray_d2n(
float2(float(ig) + 0.5f, float(jg) + 0.5f), intrin, dist,
p.camera_model, p.is_ray_depth != 0);
_d2n_points[k] = ray * depth;
}
SS_DISPATCH_DIST(_d2n_call)
GroupMemoryBarrierWithGroupSync();
if (!inside) return;
@@ -226,3 +237,9 @@ void depth_to_normal_fwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
p.normals[3 * o + 1] = normal.y;
p.normals[3 * o + 2] = normal.z;
}
#undef _d2n_call
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
@@ -13,6 +13,7 @@
#undef CudaDeviceExport
#include "atomic_float.slang"
#include "dist_spec.slang"
// Shared boolean variant flag (noise blend: is_linear; srgb:
// is_input_linear), same convention as pixel_wise_render.slang.
@@ -208,7 +209,7 @@ static const int D2NB_TILE = 16;
struct DepthToNormalBwdParams { // 60 bytes: pushed directly
float4* intrins; // [B]
float* dist_coeffs; // [B,10] (fallback-backed)
float* dist_coeffs; // [B,8] (fallback-backed)
float* depths; // [B,H,W,1]
float* v_normals; // [B,H,W,3]
float* v_depths; // [B,H,W,1] accumulated in place
@@ -221,6 +222,33 @@ struct DepthToNormalBwdParams { // 60 bytes: pushed directly
groupshared float4 _d2nb_points[(D2NB_TILE + 2) * (D2NB_TILE + 2)];
// Apron fill, generic over the tier so the entry folds kDistortion once
// instead of switching inside the loop.
[ForceInline]
void _d2nb_fill_apron<D : ICameraDistortion>(DepthToNormalBwdParams p,
uint bid, uint2 tile0, uint tid,
float4 intrin) {
float dist[D.kNumParams];
load_dist_coeffs<D>(p.dist_coeffs, bid, dist);
for (uint k = tid; k < uint((D2NB_TILE + 2) * (D2NB_TILE + 2)); k += 256) {
int it = int(k % (D2NB_TILE + 2)), jt = int(k / (D2NB_TILE + 2));
int ig = int(tile0.x) + it - 1;
int jg = int(tile0.y) + jt - 1;
float depth =
(ig >= 0 && ig < int(p.W) && jg >= 0 && jg < int(p.H))
? p.depths[(bid * p.H + uint(jg)) * p.W + uint(ig)]
: 0.0f;
float3 ray = generate_ray_d2n<D>(
float2(float(ig) + 0.5f, float(jg) + 0.5f), intrin, dist,
p.camera_model, p.is_ray_depth != 0);
_d2nb_points[k] = float4(ray, depth);
}
}
#define _d2nb_call(D) \
_d2nb_fill_apron<D>(p, bid, uint2(wg.x * D2NB_TILE, wg.y * D2NB_TILE), \
tid, intrin)
[shader("compute")]
[numthreads(256, 1, 1)]
void d2n_bwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -234,25 +262,8 @@ void d2n_bwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
if (i == 0 || i == p.W - 1 || j == 0 || j == p.H - 1) inside = false;
float4 intrin = p.intrins[bid];
float dist[10];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * bid + k];
for (uint k = tid; k < uint((D2NB_TILE + 2) * (D2NB_TILE + 2)); k += 256) {
int it = int(k % (D2NB_TILE + 2)), jt = int(k / (D2NB_TILE + 2));
int ig = int(wg.x * D2NB_TILE) + it - 1;
int jg = int(wg.y * D2NB_TILE) + jt - 1;
float depth =
(ig >= 0 && ig < int(p.W) && jg >= 0 && jg < int(p.H))
? p.depths[(bid * p.H + uint(jg)) * p.W + uint(ig)]
: 0.0f;
float3 ray = generate_ray_d2n(
float2(float(ig) + 0.5f, float(jg) + 0.5f), intrin, dist,
p.camera_model, p.is_ray_depth != 0);
_d2nb_points[k] = float4(ray, depth);
}
SS_DISPATCH_DIST(_d2nb_call)
GroupMemoryBarrierWithGroupSync();
if (!inside) return;
@@ -289,7 +300,7 @@ void d2n_bwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
struct LinToRayDepthParams { // 48 bytes: pushed directly
float4* intrins; // [B] at IMAGE resolution
float* dist_coeffs; // [B,10] (fallback-backed)
float* dist_coeffs; // [B,8] (fallback-backed)
float* depths; // [B,Hd,Wd,1] in/out
float sx, sy; // depth_res / image_res
uint32_t W, H, B;
@@ -297,6 +308,19 @@ struct LinToRayDepthParams { // 48 bytes: pushed directly
uint32_t _pad0;
};
[ForceInline]
float _l2r_factor<D : ICameraDistortion>(LinToRayDepthParams p, uint bid,
float4 scaled, float2 pix) {
float dist[D.kNumParams];
load_dist_coeffs<D>(p.dist_coeffs, bid, dist);
return ray_depth_to_linear_depth_factor<D>(pix, scaled, dist,
p.camera_model);
}
#define _l2r_call(D) \
factor = _l2r_factor<D>(p, bid, scaled, \
float2(float(i) + 0.5f, float(j) + 0.5f))
[shader("compute")]
[numthreads(128, 1, 1)]
void lin_to_ray_depth(uint3 gtid: SV_DispatchThreadID,
@@ -307,17 +331,11 @@ void lin_to_ray_depth(uint3 gtid: SV_DispatchThreadID,
float4 intrin = p.intrins[bid];
float4 scaled = float4(intrin.x * p.sx, intrin.y * p.sy, intrin.z * p.sx,
intrin.w * p.sy);
float dist[10];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * bid + k];
uint o = (bid * p.H + j) * p.W + i;
float in_depth = p.depths[o];
float factor = ray_depth_to_linear_depth_factor(
float2(float(i) + 0.5f, float(j) + 0.5f), scaled, dist,
p.camera_model);
float factor = 0.0f;
SS_DISPATCH_DIST(_l2r_call)
p.depths[o] = (factor > 0.0f) ? (in_depth / factor) : 0.0f;
}
@@ -391,3 +409,10 @@ void color_shift_update(uint tid: SV_GroupThreadID,
p.batch_sum[tid] = 0.0f;
}
}
#undef _d2nb_call
#undef _l2r_call
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
@@ -7,12 +7,14 @@
// Declares the spec constants shared by every kernel in the family --
// includers must list their extra spec constants AFTER this include so the
// auto-assigned constant IDs stay 0..4 here and 5.. in the includer,
// matching the host-side SpecList order.
// matching the host-side SpecList order. kDistortion is the one exception:
// every includer declares it LAST, after its own constants.
//
// Include AFTER primitive_3dgs.slang / harmonics.slang / sh_quant.slang /
// sh_vjp.slang / atomic_float.slang.
#include "int64_compat.slang"
#include "dist_spec.slang"
[SpecializationConstant]
const int kCameraModel = 0;
@@ -48,17 +50,17 @@ PbSplat pb_load_splat(float* means, float* quats, float* scales,
return s;
}
struct PbCamera {
struct PbCamera<D : ICameraDistortion> {
float3x3 R;
float3 t;
float4 intrin;
float dist[10];
float dist[D.kNumParams];
};
[ForceInline]
PbCamera pb_load_camera(float* viewmats, float4* intrins, float* dist_coeffs,
uint cid) {
PbCamera c;
PbCamera<D> pb_load_camera<D : ICameraDistortion>(
float* viewmats, float4* intrins, float* dist_coeffs, uint cid) {
PbCamera<D> c;
float* vm = viewmats + cid * 16;
[ForceUnroll]
for (int r = 0; r < 3; r++) {
@@ -66,9 +68,7 @@ PbCamera pb_load_camera(float* viewmats, float4* intrins, float* dist_coeffs,
c.t[r] = vm[4 * r + 3];
}
c.intrin = intrins[cid];
[ForceUnroll]
for (int i = 0; i < 10; i++)
c.dist[i] = is_null(dist_coeffs) ? 0.0f : dist_coeffs[10 * cid + i];
load_dist_coeffs<D>(dist_coeffs, cid, c.dist);
return c;
}
@@ -99,101 +99,55 @@ PbGrads pb_grads_zero() {
return g;
}
// primitive_3dgs.slang exports one VJP per (camera model, tier); this generic
// conformance is the same body, reached with both axes still symbolic so the
// callers can stay generic and fold once at the entry point.
struct PbProj<let cam : CameraModelType, D : ICameraDistortion,
let eval3d : bool> : _DiffProjection3DGS<D.kNumParams> {
[ForceInline]
[Differentiable]
static void projection(_projection_3dgs_ARGS(D.kNumParams)) {
return projection_3dgs<cam, D, true, eval3d>(
antialiased, mean, quat, scale, in_opacity, R, t,
fx, fy, cx, cy, dist_coeffs, image_width, image_height,
aabb_xyxy, sorting_depth, radius, mean2d, depth, conic, opacity);
}
};
// One intersection's projection VJP, 2D (3DGS / Mip) screen layout
// {xy, depth, conic, opac}. kAntialiased selects Mip.
[ForceInline]
void pb_vjp_2d(PbSplat s, PbCamera c, uint width, uint height, float2 v_xy,
float v_depth, float3 v_conic, float v_opac,
inout PbGrads g) {
const bool aa = kAntialiased != 0;
switch (kCameraModel) {
case 0:
projection_3dgs_persp_vjp(aa, s.mean, s.quat, s.scale, s.in_opacity,
c.R, c.t, c.intrin.x, c.intrin.y,
c.intrin.z, c.intrin.w, c.dist, width,
height, v_xy, v_depth, v_conic, v_opac,
g.v_mean, g.v_quat, g.v_scale, g.v_opacity,
g.v_R, g.v_t);
break;
case 1:
projection_3dgs_fisheye_vjp(aa, s.mean, s.quat, s.scale,
s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w,
c.dist, width, height, v_xy, v_depth,
v_conic, v_opac, g.v_mean, g.v_quat,
g.v_scale, g.v_opacity, g.v_R, g.v_t);
break;
case 2:
projection_3dgs_equisolid_vjp(aa, s.mean, s.quat, s.scale,
s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w,
c.dist, width, height, v_xy, v_depth,
v_conic, v_opac, g.v_mean, g.v_quat,
g.v_scale, g.v_opacity, g.v_R, g.v_t);
break;
default:
projection_3dgs_equirect_vjp(aa, s.mean, s.quat, s.scale,
s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w,
c.dist, width, height, v_xy, v_depth,
v_conic, v_opac, g.v_mean, g.v_quat,
g.v_scale, g.v_opacity, g.v_R, g.v_t);
break;
}
void pb_vjp_2d<let cam : CameraModelType, D : ICameraDistortion>(
PbSplat s, PbCamera<D> c, uint width, uint height, float2 v_xy,
float v_depth, float3 v_conic, float v_opac, inout PbGrads g) {
_projection_3dgs_vjp<D.kNumParams, PbProj<cam, D, false> >(
kAntialiased != 0, s.mean, s.quat, s.scale, s.in_opacity, c.R, c.t,
c.intrin.x, c.intrin.y, c.intrin.z, c.intrin.w, c.dist, width, height,
v_xy, v_depth, v_conic, v_opac, g.v_mean, g.v_quat, g.v_scale,
g.v_opacity, g.v_R, g.v_t);
}
// One intersection's projection VJP, 3DGUT screen layout {scale, opac}: the
// screen-scale grad feeds the conic slot with v_mean2d = 0, v_depth = 0
// (mirrors Primitive3DGUT::project_vjp), antialiased always false.
[ForceInline]
void pb_vjp_3dgut(PbSplat s, PbCamera c, uint width, uint height,
float3 v_sscale, float v_sopac, inout PbGrads g) {
switch (kCameraModel) {
case 0:
projection_3dgut_persp_vjp(false, s.mean, s.quat, s.scale,
s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w,
c.dist, width, height, float2(0.0f), 0.0f,
v_sscale, v_sopac, g.v_mean, g.v_quat,
g.v_scale, g.v_opacity, g.v_R, g.v_t);
break;
case 1:
projection_3dgut_fisheye_vjp(false, s.mean, s.quat, s.scale,
s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w,
c.dist, width, height, float2(0.0f),
0.0f, v_sscale, v_sopac, g.v_mean,
g.v_quat, g.v_scale, g.v_opacity, g.v_R,
g.v_t);
break;
case 2:
projection_3dgut_equisolid_vjp(false, s.mean, s.quat, s.scale,
s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w,
c.dist, width, height, float2(0.0f),
0.0f, v_sscale, v_sopac, g.v_mean,
g.v_quat, g.v_scale, g.v_opacity,
g.v_R, g.v_t);
break;
default:
projection_3dgut_equirect_vjp(false, s.mean, s.quat, s.scale,
s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w,
c.dist, width, height, float2(0.0f),
0.0f, v_sscale, v_sopac, g.v_mean,
g.v_quat, g.v_scale, g.v_opacity,
g.v_R, g.v_t);
break;
}
void pb_vjp_3dgut<let cam : CameraModelType, D : ICameraDistortion>(
PbSplat s, PbCamera<D> c, uint width, uint height, float3 v_sscale,
float v_sopac, inout PbGrads g) {
_projection_3dgs_vjp<D.kNumParams, PbProj<cam, D, true> >(
false, s.mean, s.quat, s.scale, s.in_opacity, c.R, c.t, c.intrin.x,
c.intrin.y, c.intrin.z, c.intrin.w, c.dist, width, height,
float2(0.0f), 0.0f, v_sscale, v_sopac, g.v_mean, g.v_quat, g.v_scale,
g.v_opacity, g.v_R, g.v_t);
}
// SH color VJP with the value-quant bit depth folded from kShValueBits
// (generic args must be parse-time constants; the branch folds away).
// `coeffs` is the splat's fp32 SH pointer (unused when kShValueBits != 0).
[ForceInline]
void pb_sh_vjp(PbSplat s, PbCamera c, float* coeffs, uint* qpacked,
float2* qbounds, gindex_t qbase, gindex_t qstride, float3 v_rgb,
inout PbGrads g) {
void pb_sh_vjp<D : ICameraDistortion>(
PbSplat s, PbCamera<D> c, float* coeffs, uint* qpacked, float2* qbounds,
gindex_t qbase, gindex_t qstride, float3 v_rgb, inout PbGrads g) {
if (kShValueBits == 8)
sh_color_vjp<8>(kShDegree, s.mean, c.R, c.t, s.dc, coeffs, qpacked,
qbounds, qbase, qstride, v_rgb, g.v_dc, g.v_sh,
+29 -13
View File
@@ -14,6 +14,7 @@
// kViewmatGrad = 1: accumulate v_R / v_t into v_viewmats (per-thread CAS
// adds -- CUDA's labeled-partition warp reduce is a perf
// shortcut with identical, order-nondeterministic sums)
// kDistortion = CameraDistortionType (0..3), declared last
#define CudaDeviceExport ForceInline
#include "int64_compat.slang"
@@ -43,7 +44,7 @@ struct ProjectionBwd3dgsParams {
// cameras
float* viewmats; // [C,16] row-major
float4* intrins; // [C]
float* dist_coeffs; // [C,10] or fallback zeros
float* dist_coeffs; // [C,8] or fallback zeros
// packed intersection ids (kPacked; fallback otherwise)
int* camera_ids; // [nnz]
int* gaussian_ids; // [nnz]
@@ -76,7 +77,8 @@ struct ProjectionBwd3dgsParams {
uint32_t num_sh_buffer;
};
void _pb_run_3dgs(ProjectionBwd3dgsParams p, uint idx) {
void _pb_run_3dgs<let cam : CameraModelType, D : ICameraDistortion>(
ProjectionBwd3dgsParams p, uint idx) {
uint cid, gid;
if (kPacked != 0) {
cid = uint(p.camera_ids[idx]);
@@ -89,7 +91,8 @@ void _pb_run_3dgs(ProjectionBwd3dgsParams p, uint idx) {
gid = idx % p.N;
}
PbCamera cam = pb_load_camera(p.viewmats, p.intrins, p.dist_coeffs, cid);
PbCamera<D> c = pb_load_camera<D>(p.viewmats, p.intrins, p.dist_coeffs,
cid);
PbSplat s = pb_load_splat(p.means, p.quats, p.scales, p.opacities,
p.features_dc, gid);
@@ -102,10 +105,11 @@ void _pb_run_3dgs(ProjectionBwd3dgsParams p, uint idx) {
p.vs_rgb[3 * idx + 2]);
PbGrads g = pb_grads_zero();
pb_vjp_2d(s, cam, p.width, p.height, v_xy, v_depth, v_conic, v_opac, g);
pb_vjp_2d<cam, D>(s, c, p.width, p.height, v_xy, v_depth, v_conic, v_opac,
g);
gindex_t qbase = (gindex_t)3 * (gindex_t)p.num_sh_buffer * (gindex_t)gid;
pb_sh_vjp(s, cam, p.features_sh + gid * p.sh_stride_src, p.sh_packed,
p.sh_bounds, qbase, i64mem_get(p.sh_bounds_stride), v_rgb, g);
pb_sh_vjp<D>(s, c, p.features_sh + gid * p.sh_stride_src, p.sh_packed,
p.sh_bounds, qbase, i64mem_get(p.sh_bounds_stride), v_rgb, g);
pb_add3(p.vw_means + 3 * gid, g.v_mean);
pb_add4(p.vw_quats + 4 * gid, g.v_quat);
@@ -118,6 +122,8 @@ void _pb_run_3dgs(ProjectionBwd3dgsParams p, uint idx) {
pb_scatter_viewmat(p.v_viewmats, cid, g.v_R, g.v_t);
}
#define _pb_call_2d(M, D) _pb_run_3dgs<M, D>(p, idx)
[shader("compute")]
[numthreads(128, 1, 1)]
void projection_bwd_3dgs(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -126,8 +132,9 @@ void projection_bwd_3dgs(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uint idx = (wg.y * p.wgs_per_row + wg.x) * 128 + tid;
uint total = (kPacked != 0) ? p.N : p.C * p.N;
if (idx >= total) return;
_pb_run_3dgs(p, idx);
SS_DISPATCH_CAM_DIST(_pb_call_2d)
}
#undef _pb_call_2d
// ---------------------------------------------------------------------------
// 3DGUT: ScreenBuffer grads {scale, opacity, rgb}.
@@ -171,7 +178,8 @@ struct ProjectionBwd3dgutParams {
uint32_t num_sh_buffer;
};
void _pb_run_3dgut(ProjectionBwd3dgutParams p, uint idx) {
void _pb_run_3dgut<let cam : CameraModelType, D : ICameraDistortion>(
ProjectionBwd3dgutParams p, uint idx) {
uint cid, gid;
if (kPacked != 0) {
cid = uint(p.camera_ids[idx]);
@@ -184,7 +192,8 @@ void _pb_run_3dgut(ProjectionBwd3dgutParams p, uint idx) {
gid = idx % p.N;
}
PbCamera cam = pb_load_camera(p.viewmats, p.intrins, p.dist_coeffs, cid);
PbCamera<D> c = pb_load_camera<D>(p.viewmats, p.intrins, p.dist_coeffs,
cid);
PbSplat s = pb_load_splat(p.means, p.quats, p.scales, p.opacities,
p.features_dc, gid);
@@ -195,10 +204,10 @@ void _pb_run_3dgut(ProjectionBwd3dgutParams p, uint idx) {
p.vs_rgb[3 * idx + 2]);
PbGrads g = pb_grads_zero();
pb_vjp_3dgut(s, cam, p.width, p.height, v_sscale, v_sopac, g);
pb_vjp_3dgut<cam, D>(s, c, p.width, p.height, v_sscale, v_sopac, g);
gindex_t qbase = (gindex_t)3 * (gindex_t)p.num_sh_buffer * (gindex_t)gid;
pb_sh_vjp(s, cam, p.features_sh + gid * p.sh_stride_src, p.sh_packed,
p.sh_bounds, qbase, i64mem_get(p.sh_bounds_stride), v_rgb, g);
pb_sh_vjp<D>(s, c, p.features_sh + gid * p.sh_stride_src, p.sh_packed,
p.sh_bounds, qbase, i64mem_get(p.sh_bounds_stride), v_rgb, g);
pb_add3(p.vw_means + 3 * gid, g.v_mean);
pb_add4(p.vw_quats + 4 * gid, g.v_quat);
@@ -211,6 +220,8 @@ void _pb_run_3dgut(ProjectionBwd3dgutParams p, uint idx) {
pb_scatter_viewmat(p.v_viewmats, cid, g.v_R, g.v_t);
}
#define _pb_call_3d(M, D) _pb_run_3dgut<M, D>(p, idx)
[shader("compute")]
[numthreads(128, 1, 1)]
void projection_bwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -219,5 +230,10 @@ void projection_bwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uint idx = (wg.y * p.wgs_per_row + wg.x) * 128 + tid;
uint total = (kPacked != 0) ? p.N : p.C * p.N;
if (idx >= total) return;
_pb_run_3dgut(p, idx);
SS_DISPATCH_CAM_DIST(_pb_call_3d)
}
#undef _pb_call_3d
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
+50 -71
View File
@@ -8,6 +8,7 @@
// kAntialiased = 0 (Vanilla3DGS) | 1 (MipSplatting)
// kShValueBits = 0 (fp32) | 8 | 16 (the CUDA VALUE_BITS template axis;
// decode via sh_quant.slang's word-based q8/q16 loads)
// kDistortion = CameraDistortionType (0..3), declared last (dist_spec.slang)
//
// Params exceed the 128-byte push floor -> delivered via the params ring
// (push constant = one device address).
@@ -18,6 +19,7 @@
#include "shaders/harmonics.slang"
#undef CudaDeviceExport
#include "sh_quant.slang"
#include "dist_spec.slang"
[SpecializationConstant]
const int kCameraModel = 0;
@@ -68,7 +70,7 @@ struct ProjectionFwdParams {
// cameras
float* viewmats; // [C,16] row-major
float4* intrins; // [C]
float* dist_coeffs; // [C,10] or null
float* dist_coeffs; // [C,8] or null
// outputs
float4* out_aabb; // [C,N]
float* out_depths; // [C,N]
@@ -93,8 +95,8 @@ struct ProjectionFwdParams {
uint32_t _pad0;
};
void run_projection<let cam: CameraModelType>(ProjectionFwdParams p,
uint idx) {
void run_projection<let cam: CameraModelType, D : ICameraDistortion>(
ProjectionFwdParams p, uint idx) {
uint cid = (idx / p.N) % p.C;
uint gid = idx % p.N;
@@ -108,11 +110,8 @@ void run_projection<let cam: CameraModelType>(ProjectionFwdParams p,
t[r] = vm[4 * r + 3];
}
float4 intrin = p.intrins[cid];
float dist[10];
[ForceUnroll]
for (int i = 0; i < 10; i++)
dist[i] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * cid + i];
float dist[D.kNumParams];
load_dist_coeffs<D>(p.dist_coeffs, cid, dist);
// splat
float3 mean = float3(p.means[3 * gid], p.means[3 * gid + 1],
@@ -131,7 +130,7 @@ void run_projection<let cam: CameraModelType>(ProjectionFwdParams p,
float s_depth;
float3 s_conic;
float s_opac;
projection_3dgs<cam, false, false>(
projection_3dgs<cam, D, false, false>(
kAntialiased != 0,
mean, quat, scale, in_opacity, R, t,
intrin.x, intrin.y, intrin.z, intrin.w, dist,
@@ -177,6 +176,8 @@ void run_projection<let cam: CameraModelType>(ProjectionFwdParams p,
}
}
#define _pf_call(M, D) run_projection<M, D>(p, idx)
[shader("compute")]
[numthreads(128, 1, 1)]
void projection_fwd_3dgs(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -184,16 +185,12 @@ void projection_fwd_3dgs(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
ProjectionFwdParams p = *pp;
uint idx = (wg.y * p.wgs_per_row + wg.x) * 128 + tid;
if (idx >= p.C * p.N) return;
switch (kCameraModel) {
case 0: run_projection<CameraModelType::PINHOLE>(p, idx); break;
case 1: run_projection<CameraModelType::FISHEYE>(p, idx); break;
case 2: run_projection<CameraModelType::EQUISOLID>(p, idx); break;
case 3: run_projection<CameraModelType::EQUIRECTANGULAR>(p, idx); break;
}
SS_DISPATCH_CAM_DIST(_pf_call)
}
#undef _pf_call
// ---------------------------------------------------------------------------
// 3DGUT (eval3d): projection_3dgs<cam, false, true>, antialiased always
// 3DGUT (eval3d): projection_3dgs<cam, D, false, true>, antialiased always
// false; the ScreenBuffer is TensorArray<3> {scale, opacity, rgb} where the
// "conic" output lands in the scale slot (the eval3d rasterizer culls with
// the projected 2D conic). Mirrors Primitive3DGUT.cuh project().
@@ -228,8 +225,8 @@ struct Projection3dgutParams {
uint32_t _pad0;
};
void run_projection_3dgut<let cam: CameraModelType>(Projection3dgutParams p,
uint idx) {
void run_projection_3dgut<let cam: CameraModelType, D : ICameraDistortion>(
Projection3dgutParams p, uint idx) {
uint cid = (idx / p.N) % p.C;
uint gid = idx % p.N;
@@ -242,11 +239,8 @@ void run_projection_3dgut<let cam: CameraModelType>(Projection3dgutParams p,
t[r] = vm[4 * r + 3];
}
float4 intrin = p.intrins[cid];
float dist[10];
[ForceUnroll]
for (int i = 0; i < 10; i++)
dist[i] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * cid + i];
float dist[D.kNumParams];
load_dist_coeffs<D>(p.dist_coeffs, cid, dist);
float3 mean = float3(p.means[3 * gid], p.means[3 * gid + 1],
p.means[3 * gid + 2]);
@@ -264,7 +258,7 @@ void run_projection_3dgut<let cam: CameraModelType>(Projection3dgutParams p,
float depth;
float3 s_scale;
float s_opac;
projection_3dgs<cam, false, true>(
projection_3dgs<cam, D, false, true>(
false, // antialiased: always false for 3DGUT
mean, quat, scale, in_opacity, R, t,
intrin.x, intrin.y, intrin.z, intrin.w, dist,
@@ -302,6 +296,8 @@ void run_projection_3dgut<let cam: CameraModelType>(Projection3dgutParams p,
}
}
#define _pg_call(M, D) run_projection_3dgut<M, D>(p, idx)
[shader("compute")]
[numthreads(128, 1, 1)]
void projection_fwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -309,14 +305,9 @@ void projection_fwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
Projection3dgutParams p = *pp;
uint idx = (wg.y * p.wgs_per_row + wg.x) * 128 + tid;
if (idx >= p.C * p.N) return;
switch (kCameraModel) {
case 0: run_projection_3dgut<CameraModelType::PINHOLE>(p, idx); break;
case 1: run_projection_3dgut<CameraModelType::FISHEYE>(p, idx); break;
case 2: run_projection_3dgut<CameraModelType::EQUISOLID>(p, idx); break;
case 3: run_projection_3dgut<CameraModelType::EQUIRECTANGULAR>(p, idx);
break;
}
SS_DISPATCH_CAM_DIST(_pg_call)
}
#undef _pg_call
// ---------------------------------------------------------------------------
// Packed projection (two-pass compaction, ProjectionPackedFwd_kernel.cuh).
@@ -345,8 +336,8 @@ struct PackedMaskParams { // fits in the 128-byte push floor: pushed direct
uint32_t wgs_per_row;
};
void run_packed_mask<let cam: CameraModelType, let eval3d: bool>(
PackedMaskParams p, uint idx) {
void run_packed_mask<let cam: CameraModelType, D : ICameraDistortion,
let eval3d: bool>(PackedMaskParams p, uint idx) {
uint cid = (idx / p.N) % p.C;
uint gid = idx % p.N;
@@ -359,11 +350,8 @@ void run_packed_mask<let cam: CameraModelType, let eval3d: bool>(
t[r] = vm[4 * r + 3];
}
float4 intrin = p.intrins[cid];
float dist[10];
[ForceUnroll]
for (int i = 0; i < 10; i++)
dist[i] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * cid + i];
float dist[D.kNumParams];
load_dist_coeffs<D>(p.dist_coeffs, cid, dist);
float3 mean = float3(p.means[3 * gid], p.means[3 * gid + 1],
p.means[3 * gid + 2]);
@@ -381,7 +369,7 @@ void run_packed_mask<let cam: CameraModelType, let eval3d: bool>(
float opac;
// The mask only consumes the AABB; SH evaluation is skipped (the CUDA
// mask kernel computes and discards it).
projection_3dgs<cam, false, eval3d>(
projection_3dgs<cam, D, false, eval3d>(
!eval3d && kAntialiased != 0,
mean, quat, scale, in_opacity, R, t,
intrin.x, intrin.y, intrin.z, intrin.w, dist,
@@ -396,6 +384,9 @@ void run_packed_mask<let cam: CameraModelType, let eval3d: bool>(
(aabb.z - aabb.x > 1e-3f && aabb.w - aabb.y > 1e-3f) ? 1 : 0;
}
#define _pm_call_3d(M, D) run_packed_mask<M, D, true>(p, idx)
#define _pm_call_2d(M, D) run_packed_mask<M, D, false>(p, idx)
[shader("compute")]
[numthreads(128, 1, 1)]
void projection_packed_mask(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -403,21 +394,13 @@ void projection_packed_mask(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uint idx = (wg.y * p.wgs_per_row + wg.x) * 128 + tid;
if (idx >= p.C * p.N) return;
if (kEval3d != 0) {
switch (kCameraModel) {
case 0: run_packed_mask<CameraModelType::PINHOLE, true>(p, idx); break;
case 1: run_packed_mask<CameraModelType::FISHEYE, true>(p, idx); break;
case 2: run_packed_mask<CameraModelType::EQUISOLID, true>(p, idx); break;
case 3: run_packed_mask<CameraModelType::EQUIRECTANGULAR, true>(p, idx); break;
}
SS_DISPATCH_CAM_DIST(_pm_call_3d)
} else {
switch (kCameraModel) {
case 0: run_packed_mask<CameraModelType::PINHOLE, false>(p, idx); break;
case 1: run_packed_mask<CameraModelType::FISHEYE, false>(p, idx); break;
case 2: run_packed_mask<CameraModelType::EQUISOLID, false>(p, idx); break;
case 3: run_packed_mask<CameraModelType::EQUIRECTANGULAR, false>(p, idx); break;
}
SS_DISPATCH_CAM_DIST(_pm_call_2d)
}
}
#undef _pm_call_3d
#undef _pm_call_2d
struct PackedFwdParams {
float* means;
@@ -453,8 +436,8 @@ struct PackedFwdParams {
uint32_t _pad0;
};
void run_packed_fwd<let cam: CameraModelType, let eval3d: bool>(
PackedFwdParams p, uint idx) {
void run_packed_fwd<let cam: CameraModelType, D : ICameraDistortion,
let eval3d: bool>(PackedFwdParams p, uint idx) {
int out_idx = idx == 0 ? 0 : p.mask_scan[idx - 1];
if (p.mask_scan[idx] == out_idx) return;
@@ -470,11 +453,8 @@ void run_packed_fwd<let cam: CameraModelType, let eval3d: bool>(
t[r] = vm[4 * r + 3];
}
float4 intrin = p.intrins[cid];
float dist[10];
[ForceUnroll]
for (int i = 0; i < 10; i++)
dist[i] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * cid + i];
float dist[D.kNumParams];
load_dist_coeffs<D>(p.dist_coeffs, cid, dist);
float3 mean = float3(p.means[3 * gid], p.means[3 * gid + 1],
p.means[3 * gid + 2]);
@@ -492,7 +472,7 @@ void run_packed_fwd<let cam: CameraModelType, let eval3d: bool>(
float depth;
float3 conic; // eval3d: carries the culling scale (see 3DGUT notes)
float opac;
projection_3dgs<cam, false, eval3d>(
projection_3dgs<cam, D, false, eval3d>(
!eval3d && kAntialiased != 0,
mean, quat, scale, in_opacity, R, t,
intrin.x, intrin.y, intrin.z, intrin.w, dist,
@@ -546,6 +526,9 @@ void run_packed_fwd<let cam: CameraModelType, let eval3d: bool>(
InterlockedMax(p.out_radii[gid], asuint(radius));
}
#define _pk_call_3d(M, D) run_packed_fwd<M, D, true>(p, idx)
#define _pk_call_2d(M, D) run_packed_fwd<M, D, false>(p, idx)
[shader("compute")]
[numthreads(128, 1, 1)]
void projection_packed_fwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -554,18 +537,14 @@ void projection_packed_fwd(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
uint idx = (wg.y * p.wgs_per_row + wg.x) * 128 + tid;
if (idx >= p.C * p.N) return;
if (kEval3d != 0) {
switch (kCameraModel) {
case 0: run_packed_fwd<CameraModelType::PINHOLE, true>(p, idx); break;
case 1: run_packed_fwd<CameraModelType::FISHEYE, true>(p, idx); break;
case 2: run_packed_fwd<CameraModelType::EQUISOLID, true>(p, idx); break;
case 3: run_packed_fwd<CameraModelType::EQUIRECTANGULAR, true>(p, idx); break;
}
SS_DISPATCH_CAM_DIST(_pk_call_3d)
} else {
switch (kCameraModel) {
case 0: run_packed_fwd<CameraModelType::PINHOLE, false>(p, idx); break;
case 1: run_packed_fwd<CameraModelType::FISHEYE, false>(p, idx); break;
case 2: run_packed_fwd<CameraModelType::EQUISOLID, false>(p, idx); break;
case 3: run_packed_fwd<CameraModelType::EQUIRECTANGULAR, false>(p, idx); break;
}
SS_DISPATCH_CAM_DIST(_pk_call_2d)
}
}
#undef _pk_call_3d
#undef _pk_call_2d
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
@@ -13,6 +13,7 @@
// loads never exist (llvmpipe speculated-load rule)
// kWorldGradAdd = 1: add mean/quat/scale register grads onto the fp32
// world-grad buffer (3DGUT; one owner thread -> plain add)
// kDistortion = CameraDistortionType (0..3), declared last
//
// One thread per splat also for !inside tail threads: the camera loop is
// fully skipped for them (CUDA reads out-of-bounds aabb entries harmlessly
@@ -133,6 +134,55 @@ void _qg_nonsh<let PRIMS : int>(bool active, uint* packed, float2* bounds,
}
}
// The per-splat camera loop, generic over the two projection spec axes so the
// entry point folds them once (its block reduces stay outside).
[ForceInline]
void _qg_camera_loop<let cam : CameraModelType, D : ICameraDistortion>(
ProjectionQgradParams p, uint gid, bool inside, int cid_0, int cid_1,
inout PbGrads g) {
if (!inside)
return;
PbSplat s = pb_load_splat(p.means, p.quats, p.scales, p.opacities,
p.features_dc, gid);
gindex_t qbase = (gindex_t)3 * (gindex_t)p.num_sh_buffer * (gindex_t)gid;
for (int cid_t = cid_0; cid_t < cid_1; ++cid_t) {
int idx = (kPacked != 0) ? p.perm[cid_t]
: cid_t * int(p.N) + int(gid);
int cid = (kPacked != 0) ? p.camera_ids[idx] : cid_t;
float4 bb = p.aabb[idx];
if (bb.z <= bb.x || bb.w <= bb.y)
continue;
PbCamera<D> c = pb_load_camera<D>(p.viewmats, p.intrins,
p.dist_coeffs, uint(cid));
if (kEval3d != 0) {
float3 v_ss = float3(p.vs0[3 * idx], p.vs0[3 * idx + 1],
p.vs0[3 * idx + 2]);
float v_so = p.vs1[idx];
float3 v_rgb = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
pb_vjp_3dgut<cam, D>(s, c, p.width, p.height, v_ss, v_so, g);
pb_sh_vjp<D>(s, c, p.features_sh + gid * p.sh_stride_src,
p.sh_value_packed, p.sh_value_bounds, qbase,
i64mem_get(p.sh_value_bounds_stride), v_rgb, g);
} else {
float2 v_xy = float2(p.vs0[2 * idx], p.vs0[2 * idx + 1]);
float v_depth = p.vs1[idx];
float3 v_conic = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
float v_opac = p.vs3[idx];
float3 v_rgb = float3(p.vs4[3 * idx], p.vs4[3 * idx + 1],
p.vs4[3 * idx + 2]);
pb_vjp_2d<cam, D>(s, c, p.width, p.height, v_xy, v_depth, v_conic,
v_opac, g);
pb_sh_vjp<D>(s, c, p.features_sh + gid * p.sh_stride_src,
p.sh_value_packed, p.sh_value_bounds, qbase,
i64mem_get(p.sh_value_bounds_stride), v_rgb, g);
}
}
}
#define _qg_call(M, D) _qg_camera_loop<M, D>(p, gid, inside, cid_0, cid_1, g)
[shader("compute")]
[numthreads(256, 1, 1)]
void projection_qgrad(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -152,46 +202,7 @@ void projection_qgrad(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
}
PbGrads g = pb_grads_zero();
if (inside) {
PbSplat s = pb_load_splat(p.means, p.quats, p.scales, p.opacities,
p.features_dc, gid);
gindex_t qbase =
(gindex_t)3 * (gindex_t)p.num_sh_buffer * (gindex_t)gid;
for (int cid_t = cid_0; cid_t < cid_1; ++cid_t) {
int idx = (kPacked != 0) ? p.perm[cid_t]
: cid_t * int(p.N) + int(gid);
int cid = (kPacked != 0) ? p.camera_ids[idx] : cid_t;
float4 bb = p.aabb[idx];
if (bb.z <= bb.x || bb.w <= bb.y)
continue;
PbCamera cam = pb_load_camera(p.viewmats, p.intrins,
p.dist_coeffs, uint(cid));
if (kEval3d != 0) {
float3 v_ss = float3(p.vs0[3 * idx], p.vs0[3 * idx + 1],
p.vs0[3 * idx + 2]);
float v_so = p.vs1[idx];
float3 v_rgb = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
pb_vjp_3dgut(s, cam, p.width, p.height, v_ss, v_so, g);
pb_sh_vjp(s, cam, p.features_sh + gid * p.sh_stride_src,
p.sh_value_packed, p.sh_value_bounds, qbase,
i64mem_get(p.sh_value_bounds_stride), v_rgb, g);
} else {
float2 v_xy = float2(p.vs0[2 * idx], p.vs0[2 * idx + 1]);
float v_depth = p.vs1[idx];
float3 v_conic = float3(p.vs2[3 * idx], p.vs2[3 * idx + 1],
p.vs2[3 * idx + 2]);
float v_opac = p.vs3[idx];
float3 v_rgb = float3(p.vs4[3 * idx], p.vs4[3 * idx + 1],
p.vs4[3 * idx + 2]);
pb_vjp_2d(s, cam, p.width, p.height, v_xy, v_depth, v_conic,
v_opac, g);
pb_sh_vjp(s, cam, p.features_sh + gid * p.sh_stride_src,
p.sh_value_packed, p.sh_value_bounds, qbase,
i64mem_get(p.sh_value_bounds_stride), v_rgb, g);
}
}
}
SS_DISPATCH_CAM_DIST(_qg_call)
// fp32 geometry writeback (3DGUT: add proj contribution onto the
// raster-bwd world grads; one owner thread per gid -> race-free adds).
@@ -265,6 +276,8 @@ void projection_qgrad(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
}
}
#undef _qg_call
// ---------------------------------------------------------------------------
// Packed-mode preprocessing helpers (mirror the FPBO/qgrad iota +
// camera_id_bounds kernels; the sort itself runs via backend::sort_pairs).
@@ -306,3 +319,7 @@ void qgrad_camera_id_bounds(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
for (int k = lo; k <= hi; ++k)
p.camera_id_bounds[k] = int(i);
}
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
+17 -10
View File
@@ -31,6 +31,7 @@
// kAccumWeight = 0 | 1 (o_accum_weight + accum_weight_map wired)
// kViewmatGrad = 0 | 1 (3dgut entry only)
// kPacked = 0 | 1 (gaussian_ids present)
// kDistortion = CameraDistortionType 0..3 (3dgut entry only), last
#define CudaDeviceExport ForceInline
#include "int64_compat.slang"
@@ -39,6 +40,7 @@
#include "raster_common.slang"
#include "atomic_float.slang"
#include "dist_spec.slang"
[SpecializationConstant]
const int kCameraModel = 0;
@@ -491,7 +493,7 @@ struct Raster3dgutBwdParams { // via params ring
int* gaussian_ids;
float* viewmats; // [I,16]
float4* intrins; // [I]
float* dist_coeffs; // [I,10] (fallback-backed)
float* dist_coeffs; // [I,8] (fallback-backed)
float4* aabb;
int* tile_offsets;
int* flatten_ids;
@@ -610,6 +612,11 @@ void _rb3_reduce_add(float* dst, float val, uint tid) {
}
}
#define _rb_ray(D) \
ray_ok = pixel_ray<D>(p.dist_coeffs, image_id, kCameraModel, \
float2((px - intrin.z) / intrin.x, \
(py - intrin.w) / intrin.y), raydir)
[shader("compute")]
[numthreads(32, 1, 1)]
void rasterize_bwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -629,11 +636,6 @@ void rasterize_bwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
R[r] = float3(vm[4 * r + 0], vm[4 * r + 1], vm[4 * r + 2]);
float3 tvec = float3(vm[3], vm[7], vm[11]);
float4 intrin = p.intrins[image_id];
float dist[10];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * image_id + k];
float3 ray_o = transform_ray_o(R, tvec);
float3 total_v_ray_o = float3(0.0f);
@@ -647,10 +649,9 @@ void rasterize_bwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
int bin_final = inside ? p.last_ids[img_off + gpix] : -1;
float px = float(gx) + 0.5f;
float py = float(gy) + 0.5f;
float3 raydir;
bool ray_ok = generate_ray(
float2((px - intrin.z) / intrin.x, (py - intrin.w) / intrin.y),
kCameraModel, dist, raydir);
float3 raydir = float3(0.0f);
bool ray_ok = false;
SS_DISPATCH_DIST(_rb_ray)
inside = inside && ray_ok;
float3 ray_d = transform_ray_d(R, raydir);
_rb_raybin[pix] = float4(ray_d, asfloat(bin_final));
@@ -826,3 +827,9 @@ void rasterize_bwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
_rb3_reduce_add(v_viewmat + 11, v_t.z, tid);
}
}
#undef _rb_ray
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
+18 -11
View File
@@ -10,6 +10,7 @@
// kCameraModel = CameraModelType 0..3 (eval3d entry only)
// kDistType = 0 None | 1 D | 2 RGB_D (the instantiated subset)
// kOutputMedian = 0 | 1
// kDistortion = CameraDistortionType 0..3 (eval3d entry only), last
// The primitive pixel type is RGB_D for all current primitives, so the
// render output channels are hard-wired to rgb + depth.
//
@@ -27,6 +28,7 @@
#undef CudaDeviceExport
#include "raster_common.slang"
#include "dist_spec.slang"
[SpecializationConstant]
const int kCameraModel = 0;
@@ -306,7 +308,7 @@ struct RasterFwd3dgutParams {
// cameras
float* viewmats; // [I, 16] row-major
float4* intrins; // [I]
float* dist_coeffs; // [I, 10] or null
float* dist_coeffs; // [I, 8] or null
float4* aabb; // [..] projected 2D AABB (xmin,ymin,xmax,ymax)
int* tile_offsets; // [I, tile_height, tile_width]
int* flatten_ids; // [n_isects]
@@ -327,6 +329,11 @@ struct RasterFwd3dgutParams {
uint32_t tile_height;
};
#define _rf_ray(D) \
ray_ok = pixel_ray<D>(p.dist_coeffs, image_id, kCameraModel, \
float2((px - intrin.z) / intrin.x, \
(py - intrin.w) / intrin.y), raydir)
[shader("compute")]
[numthreads(64, 1, 1)]
void rasterize_fwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -351,11 +358,6 @@ void rasterize_fwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
ct[r] = vm[4 * r + 3];
}
float4 intrin = p.intrins[image_id];
float dist[10];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * image_id + k];
float3 ray_o = transform_ray_o(R, ct);
@@ -366,11 +368,10 @@ void rasterize_fwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
bool inside = (i < p.height && j < p.width);
float3 raydir;
inside = inside &&
generate_ray(float2((px - intrin.z) / intrin.x,
(py - intrin.w) / intrin.y),
kCameraModel, dist, raydir);
float3 raydir = float3(0.0f);
bool ray_ok = false;
SS_DISPATCH_DIST(_rf_ray)
inside = inside && ray_ok;
float3 ray_d = transform_ray_d(R, raydir);
bool done = !inside;
@@ -538,3 +539,9 @@ void rasterize_fwd_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
p.out_last_ids[pix_id_global] = int(cur_idx);
}
}
#undef _rf_ray
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
@@ -7,7 +7,8 @@
// occ_from_moment) -- plus the optional full-ray DC color image.
//
// Only 3DGUT with the three supported camera models is instantiated, matching
// the CUDA side; the camera model is a specialization constant.
// the CUDA side; the camera model and distortion tier are specialization
// constants (kDistortion declared last -- see dist_spec.slang).
#define CudaDeviceExport ForceInline
#include "int64_compat.slang"
@@ -15,6 +16,7 @@
#undef CudaDeviceExport
#include "raster_common.slang"
#include "dist_spec.slang"
[SpecializationConstant]
const int kCameraModel = 0;
@@ -51,7 +53,7 @@ struct RasterMomentsParams {
// cameras
float* viewmats; // [I, 16] row-major
float4* intrins; // [I]
float* dist_coeffs; // [I, 10] (never null: zeroed fallback)
float* dist_coeffs; // [I, 8] (never null: zeroed fallback)
float4* aabb; // [..] projected 2D AABB (xmin,ymin,xmax,ymax)
int* tile_offsets; // [I, tile_height, tile_width]
int* flatten_ids; // [n_isects]
@@ -68,6 +70,11 @@ struct RasterMomentsParams {
uint32_t _pad0;
};
#define _rm_ray(D) \
ray_ok = pixel_ray<D>(p.dist_coeffs, image_id, kCameraModel, \
float2((px - intrin.z) / intrin.x, \
(py - intrin.w) / intrin.y), raydir)
[shader("compute")]
[numthreads(64, 1, 1)]
void rasterize_moments_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
@@ -92,10 +99,6 @@ void rasterize_moments_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
ct[r] = vm[4 * r + 3];
}
float4 intrin = p.intrins[image_id];
float dist[10];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = p.dist_coeffs[10 * image_id + k];
float3 ray_o = transform_ray_o(R, ct);
@@ -106,11 +109,10 @@ void rasterize_moments_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
bool inside = (i < p.height && j < p.width);
float3 raydir;
inside = inside &&
generate_ray(float2((px - intrin.z) / intrin.x,
(py - intrin.w) / intrin.y),
kCameraModel, dist, raydir);
float3 raydir = float3(0.0f);
bool ray_ok = false;
SS_DISPATCH_DIST(_rm_ray)
inside = inside && ray_ok;
float3 ray_d = transform_ray_d(R, raydir);
bool done = !inside;
@@ -243,3 +245,9 @@ void rasterize_moments_3dgut(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
}
}
}
#undef _rm_ray
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
+42 -13
View File
@@ -28,6 +28,31 @@
#include "int64_compat.slang"
#include "int8_compat.slang"
#include "dist_spec.slang"
// generate_ray with the tier folded from kDistortion, taking the full 8-float
// storage row: the callers keep their groupshared barriers at top level.
[ForceInline]
bool _vis_ray<D : ICameraDistortion>(float2 uv, int camera_model,
float row[kDistCoeffRow],
out float3 raydir) {
float dc[D.kNumParams];
[ForceUnroll]
for (int k = 0; k < D.kNumParams; k++) dc[k] = row[k];
return generate_ray<D>(uv, camera_model, dc, raydir);
}
#define _vis_ray_call(D) ok = _vis_ray<D>(uv, camera_model, row, raydir)
[ForceInline]
bool vis_ray(float2 uv, int camera_model, float row[kDistCoeffRow],
out float3 raydir) {
bool ok = false;
raydir = float3(0.0f);
SS_DISPATCH_DIST(_vis_ray_call)
return ok;
}
#undef _vis_ray_call
static const int kNumFrustumSegments = 16;
static const int kNumFrustumFaces = 8;
@@ -64,7 +89,7 @@ struct VisFrustumParams { // 76 -> 80 bytes: pushed directly
int* widths; // [N]
int* heights; // [N]
int* camera_models; // [N]
float* dist_coeffs; // [N,10] or null
float* dist_coeffs; // [N,8] or null
float* camera_to_worlds; // [N,3,4]
float4* lss_buffer; // [N, 8*kNumFrustumSegments, 2]
float4* tri_buffer; // [N, 4*kNumFrustumFaces^2, 4]
@@ -76,15 +101,15 @@ struct VisFrustumParams { // 76 -> 80 bytes: pushed directly
groupshared float3 _vis_polylines[4 * kNumFrustumSegments];
[ForceInline]
float3 frustum_ray(float2 uv, int camera_model, float dist[10]) {
float3 frustum_ray(float2 uv, int camera_model, float dist[kDistCoeffRow]) {
float3 raydir = float3(asfloat(0x7fc00000u)); // NaN
if (!generate_ray(uv, camera_model, dist, raydir)) {
if (!vis_ray(uv, camera_model, dist, raydir)) {
// binary search for the last valid uv toward the center
float t0 = 0.0f, t1 = 1.0f;
for (int iter = 0; iter < 12; ++iter) {
float t = 0.5f * (t0 + t1);
float3 temp;
if (generate_ray(uv * t, camera_model, dist, temp)) {
if (vis_ray(uv * t, camera_model, dist, temp)) {
t0 = t;
raydir = temp;
} else {
@@ -107,11 +132,12 @@ void vis_fill_frustum(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
float width = float(p.widths[bid]);
float height = float(p.heights[bid]);
int camera_model = p.camera_models[bid];
float dist[10];
float dist[kDistCoeffRow];
[ForceUnroll]
for (int k = 0; k < 10; k++)
dist[k] = is_null(p.dist_coeffs) ? 0.0f
: p.dist_coeffs[10 * bid + k];
for (int k = 0; k < kDistCoeffRow; k++)
dist[k] = is_null(p.dist_coeffs)
? 0.0f
: p.dist_coeffs[kDistCoeffRow * bid + k];
float2 corners[4] = {
float2(-cx / fx, -cy / fy),
float2((width - cx) / fx, -cy / fy),
@@ -812,7 +838,7 @@ struct VisBlitParams { // 16 ptrs + 11 scalars: via params ring
float* render_alphas; // [H,W,1]
float4* view_intrins; // [4] (one camera)
float* view_viewmat; // [4,4]
float* view_dist; // [10] or null
float* view_dist; // [8] or null
float4* lss_buffer; // or null
int2* lss_nodes;
float3* lss_aabb;
@@ -922,9 +948,9 @@ void vis_blit(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
p.view_viewmat[4 * r + 2]);
float3 t = float3(p.view_viewmat[3], p.view_viewmat[7],
p.view_viewmat[11]);
float dist[10];
float dist[kDistCoeffRow];
[ForceUnroll]
for (int k = 0; k < 10; k++)
for (int k = 0; k < kDistCoeffRow; k++)
dist[k] = is_null(p.view_dist) ? 0.0f : p.view_dist[k];
float alpha_final = 0.0f;
@@ -938,8 +964,7 @@ void vis_blit(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
float3 ray_o = transform_ray_o(R, t);
float3 ray_d;
float2 uv = float2((px - cx) / fx, (py - cy) / fy);
bool inside =
generate_ray(uv, p.view_camera_model, dist, ray_d);
bool inside = vis_ray(uv, p.view_camera_model, dist, ray_d);
if (p.view_camera_model == 1 /*FISHEYE*/)
inside = inside && length(uv) < 3.14159265358979323846f;
if (p.view_camera_model == 2 /*EQUISOLID*/)
@@ -1197,3 +1222,7 @@ void vis_update_thumbnails(uint3 wg: SV_GroupID, uint tid: SV_GroupThreadID,
if (tid == 0)
u8_store(p.done_mask, post_idx, 0xffu);
}
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
[SpecializationConstant]
const int kDistortion = 0;
+295 -68
View File
@@ -1,6 +1,7 @@
// Dataset GT warp + byte->float conversion kernels (Vulkan backend),
// mirroring kernels/pixelwise/ImageWarp.cu + GtDepthNormalWarp.cu (launch_warp_*) and
// the raw converters (uint8/16_*_to_float_raw). The wide warps project each
// Dataset GT warp + re-distort + byte->float conversion kernels (Vulkan
// backend), mirroring kernels/pixelwise/ImageWarp.cu + GtDepthNormalWarp.cu
// (launch_warp_*) + ImageRedistort.cu (launch_redistort_*) and the raw
// converters (uint8/16_*_to_float_raw). The wide warps project each
// pinhole-face ray through the same canonical projection_utils.slang
// *_proj_nav exports the CUDA kernels call, so per-pixel outputs differ only
// by fast-math rounding (plus isolated valid-flip / nearest-rounding pixels
@@ -21,7 +22,9 @@
#include "int64_compat.slang"
#include "int8_compat.slang"
#include "shaders/projection_utils.slang"
#include "shaders/camera_source.slang"
#undef CudaDeviceExport
#include "dist_spec.slang"
// Input element kinds (the CUDA T_in template axis / elem_size dispatch).
static const int kElemU8 = 0;
@@ -92,14 +95,6 @@ float4 _wp_intrin(float* intrins, int bid) {
intrins[bid * 4 + 2], intrins[bid * 4 + 3]);
}
[ForceInline]
float[10] _wp_dist(float* dist_coeffs, int bid) {
float[10] dc;
[ForceUnroll]
for (int k = 0; k < 10; k++) dc[k] = dist_coeffs[bid * 10 + k];
return dc;
}
[ForceInline]
void _wp_axes(float* axes, int ki, out float3 ax, out float3 ay,
out float3 az) {
@@ -109,15 +104,44 @@ void _wp_axes(float* axes, int ki, out float3 ax, out float3 ay,
az = float3(axes[b + 6], axes[b + 7], axes[b + 8]);
}
// Camera-model dispatch matching the CUDA kernels' ternary chain.
// Camera-model dispatch matching the CUDA kernels' ternary chain; the
// distortion tier comes from kDistortion.
[ForceInline]
bool _wp_proj(int camera_model, float3 raydir, float4 intrin,
float[10] dist_coeffs, out float2 uv) {
bool _wp_proj<D : ICameraDistortion>(int camera_model, float3 raydir,
float4 intrin, float* dist_coeffs,
int bid, out float2 uv) {
float dc[D.kNumParams];
load_dist_coeffs<D>(dist_coeffs, uint(bid), dc);
if (camera_model == int(CameraModelType::FISHEYE))
return fisheye_proj_nav(raydir, intrin, dist_coeffs, uv);
return fisheye_proj<D, false>(raydir, intrin, dc, uv);
if (camera_model == int(CameraModelType::EQUISOLID))
return equisolid_proj_nav(raydir, intrin, dist_coeffs, uv);
return persp_proj_nav(raydir, intrin, dist_coeffs, uv);
return equisolid_proj<D, false>(raydir, intrin, dc, uv);
return persp_proj<D, false>(raydir, intrin, dc, uv);
}
// Ray -> pixel of image `bid` through its TRUE COLMAP lens model, for cameras
// the parser could only fit onto a tier (see shaders/camera_source.slang).
[ForceInline]
bool _wp_source_proj(int* source_models, float* source_params, int bid,
float3 raydir, out float2 uv) {
float sp[kSourceMaxParams];
[ForceUnroll]
for (int k = 0; k < kSourceMaxParams; k++)
sp[k] = source_params[kSourceMaxParams * bid + k];
return source_project(source_models[bid], sp, raydir, uv);
}
// RayToPixel mirror: kFromSource resamples from the source projection instead
// of the fitted one.
[ForceInline]
bool _wp_to_pixel<D : ICameraDistortion>(int camera_model, float3 raydir,
float4 intrin, float* dist_coeffs,
int* source_models,
float* source_params, int bid,
out float2 uv) {
if (kFromSource != 0)
return _wp_source_proj(source_models, source_params, bid, raydir, uv);
return _wp_proj<D>(camera_model, raydir, intrin, dist_coeffs, bid, uv);
}
// Equirectangular sample position for a face ray (see ImageWarp.cu; f is
@@ -164,15 +188,17 @@ float3 _wp_one_normal(uint* src, int kind, gindex_t plane, int H, int W,
return r / rl;
}
// Shared params for the image / depth / normal warp entries. 96 bytes:
// pushed directly (by value). Pointer fields are never null (zeros
// Shared params for the image / depth / normal warp and re-distort entries.
// 120 bytes: pushed directly (by value). Pointer fields are never null (zeros
// fallback); the *_equi entries statically ignore intrins / dist_coeffs.
struct WarpParams {
float* intrins; // [B, 4]
float* dist_coeffs; // [B, 10]
uint* src; // [B, Hin, Win, C] u8 / u16 / f32 elements
float* dst; // [B, K, Hout, Wout, C] float
float* axes; // [K, 3, 3] face axes
float* intrins; // [B, 4]
float* dist_coeffs; // [B, 8]
int* source_models; // [B] COLMAP model id (kFromSource / redistort)
float* source_params; // [B, 16] that model's parameters
uint* src; // [B, Hin, Win, C] u8 / u16 / f32 elements
float* dst; // [B, K, Hout, Wout, C] float
float* axes; // [K, 3, 3] face axes
int B;
int Hin;
int Win;
@@ -182,11 +208,13 @@ struct WarpParams {
int Wout;
int elem_kind; // kElemU8 / kElemU16 / kElemF32
int camera_model; // CameraModelType (wide entries)
int in_H; // intrinsics reference resolution (the projected uv is
int in_W; // in this pixel space; depth/normal rescale to Hin/Win)
int ref_H; // intrinsics reference resolution (the projected uv is
int ref_W; // in this pixel space; every grid rescales from it)
int ray_depth; // depth entries: input already stores ray depth
float norm_inv;
float decode_off; // normal entries: post-normalization offset
float invalid; // redistort entries: out-of-frame fill
int _pad0;
};
// 16x16 logical tile decode: flat 256-wide workgroups (the pinned 32-wide
@@ -202,22 +230,19 @@ bool _wp_tile(WarpParams p, uint3 wg, uint tid, out int i, out int j,
return i < p.Wout && j < p.Hout;
}
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_img_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
[ForceInline]
void _wp_img_wide<D : ICameraDistortion>(WarpParams p, int i, int j, int bid,
float tx, float ty) {
float4 intrin = _wp_intrin(p.intrins, bid);
float[10] dc = _wp_dist(p.dist_coeffs, bid);
gindex_t plane = gindex_t(bid) * p.Hin * p.Win;
for (int ki = 0; ki < p.K; ki++) {
float3 ax, ay, az;
_wp_axes(p.axes, ki, ax, ay, az);
float3 raydir = az + tx * ax + ty * ay;
float2 uv;
bool valid = _wp_proj(p.camera_model, raydir, intrin, dc, uv);
bool valid = _wp_to_pixel<D>(p.camera_model, raydir, intrin,
p.dist_coeffs, p.source_models,
p.source_params, bid, uv);
gindex_t base = (((gindex_t(bid) * p.K + ki) * p.Hout + j) * p.Wout + i) * p.C;
for (int c = 0; c < p.C; c++) {
float v = 0.5f;
@@ -229,6 +254,19 @@ void warp_img_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
}
}
#define _wp_img_call(D) _wp_img_wide<D>(p, i, j, bid, tx, ty)
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_img_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
SS_DISPATCH_DIST(_wp_img_call)
}
#undef _wp_img_call
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_img_equi(uniform WarpParams p, uint3 wg: SV_GroupID,
@@ -250,25 +288,22 @@ void warp_img_equi(uniform WarpParams p, uint3 wg: SV_GroupID,
}
}
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_depth_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
[ForceInline]
void _wp_depth_wide<D : ICameraDistortion>(WarpParams p, int i, int j,
int bid, float tx, float ty) {
float4 intrin = _wp_intrin(p.intrins, bid);
float[10] dc = _wp_dist(p.dist_coeffs, bid);
gindex_t plane = gindex_t(bid) * p.Hin * p.Win;
// Projected uv is in intrinsics-reference (RGB input) pixel space;
// rescale to the GT depth map's own resolution.
float sx = float(p.Win) / float(p.in_W), sy = float(p.Hin) / float(p.in_H);
float sx = float(p.Win) / float(p.ref_W), sy = float(p.Hin) / float(p.ref_H);
for (int ki = 0; ki < p.K; ki++) {
float3 ax, ay, az;
_wp_axes(p.axes, ki, ax, ay, az);
float3 raydir = az + tx * ax + ty * ay;
float2 uv;
bool valid = _wp_proj(p.camera_model, raydir, intrin, dc, uv);
bool valid = _wp_to_pixel<D>(p.camera_model, raydir, intrin,
p.dist_coeffs, p.source_models,
p.source_params, bid, uv);
float outv = 0.0f;
if (valid) {
float d = _wp_bilinear(p.src, p.elem_kind, plane, p.Hin, p.Win, 1,
@@ -280,6 +315,19 @@ void warp_depth_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
}
}
#define _wp_depth_call(D) _wp_depth_wide<D>(p, i, j, bid, tx, ty)
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_depth_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
SS_DISPATCH_DIST(_wp_depth_call)
}
#undef _wp_depth_call
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_depth_equi(uniform WarpParams p, uint3 wg: SV_GroupID,
@@ -300,23 +348,20 @@ void warp_depth_equi(uniform WarpParams p, uint3 wg: SV_GroupID,
}
}
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_normal_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
[ForceInline]
void _wp_normal_wide<D : ICameraDistortion>(WarpParams p, int i, int j,
int bid, float tx, float ty) {
float4 intrin = _wp_intrin(p.intrins, bid);
float[10] dc = _wp_dist(p.dist_coeffs, bid);
gindex_t plane = gindex_t(bid) * p.Hin * p.Win;
float sx = float(p.Win) / float(p.in_W), sy = float(p.Hin) / float(p.in_H);
float sx = float(p.Win) / float(p.ref_W), sy = float(p.Hin) / float(p.ref_H);
for (int ki = 0; ki < p.K; ki++) {
float3 ax, ay, az;
_wp_axes(p.axes, ki, ax, ay, az);
float3 raydir = az + tx * ax + ty * ay;
float2 uv;
bool valid = _wp_proj(p.camera_model, raydir, intrin, dc, uv);
bool valid = _wp_to_pixel<D>(p.camera_model, raydir, intrin,
p.dist_coeffs, p.source_models,
p.source_params, bid, uv);
float3 nf = float3(-1.0f);
if (valid)
nf = _wp_one_normal(p.src, p.elem_kind, plane, p.Hin, p.Win,
@@ -329,6 +374,19 @@ void warp_normal_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
}
}
#define _wp_normal_call(D) _wp_normal_wide<D>(p, i, j, bid, tx, ty)
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_normal_wide(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
SS_DISPATCH_DIST(_wp_normal_call)
}
#undef _wp_normal_call
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_normal_equi(uniform WarpParams p, uint3 wg: SV_GroupID,
@@ -356,12 +414,14 @@ void warp_normal_equi(uniform WarpParams p, uint3 wg: SV_GroupID,
// map to whole u32 OUTPUT words in the flat [B, K, Hout, Wout] byte space:
// each thread decodes its 4 byte positions independently and stores one
// word, so there is exactly one writer per word and no atomics.
struct WarpMaskParams { // 72 bytes: pushed directly
float* intrins; // [B, 4]
float* dist_coeffs; // [B, 10]
uint* src; // [B, Hin, Win] uint8
uint* dst; // [B, K, Hout, Wout] uint8 (word writes)
float* axes; // [K, 3, 3]
struct WarpMaskParams { // 96 bytes: pushed directly
float* intrins; // [B, 4]
float* dist_coeffs; // [B, 8]
int* source_models; // [B]
float* source_params; // [B, 16]
uint* src; // [B, Hin, Win] uint8
uint* dst; // [B, K, Hout, Wout] uint8 (word writes)
float* axes; // [K, 3, 3]
int B;
int Hin;
int Win;
@@ -369,11 +429,14 @@ struct WarpMaskParams { // 72 bytes: pushed directly
int Hout;
int Wout;
int camera_model;
int ref_H; // intrinsics reference resolution (redistort entry)
int ref_W;
uint wgs_per_row;
};
[ForceInline]
uint _wp_mask_byte(WarpMaskParams p, uint n, bool equi) {
uint _wp_mask_byte<D : ICameraDistortion>(WarpMaskParams p, uint n,
bool equi) {
uint i = n % uint(p.Wout);
uint t = n / uint(p.Wout);
uint j = t % uint(p.Hout);
@@ -395,9 +458,10 @@ uint _wp_mask_byte(WarpMaskParams p, uint n, bool equi) {
ys = clamp(ys, 0, p.Hin - 1);
} else {
float4 intrin = _wp_intrin(p.intrins, int(bid));
float[10] dc = _wp_dist(p.dist_coeffs, int(bid));
float2 uv;
if (!_wp_proj(p.camera_model, raydir, intrin, dc, uv)) return 0u;
if (!_wp_to_pixel<D>(p.camera_model, raydir, intrin, p.dist_coeffs,
p.source_models, p.source_params, int(bid), uv))
return 0u;
xs = int(floor(clamp(uv.x + 0.5f, -8.0f, float(p.Win) + 8.0f)));
ys = int(floor(clamp(uv.y + 0.5f, -8.0f, float(p.Hin) + 8.0f)));
if (xs < 0 || xs >= p.Win || ys < 0 || ys >= p.Hin) return 0u;
@@ -407,7 +471,8 @@ uint _wp_mask_byte(WarpMaskParams p, uint n, bool equi) {
}
[ForceInline]
void _wp_mask_main(WarpMaskParams p, uint3 wg, uint tid, bool equi) {
void _wp_mask_main<D : ICameraDistortion>(WarpMaskParams p, uint3 wg,
uint tid, bool equi) {
uint word = (wg.y * p.wgs_per_row + wg.x) * 256u + tid;
uint total = uint(p.B * p.K) * uint(p.Hout) * uint(p.Wout);
if (word >= (total + 3u) / 4u) return;
@@ -415,25 +480,179 @@ void _wp_mask_main(WarpMaskParams p, uint3 wg, uint tid, bool equi) {
for (uint b = 0; b < 4u; b++) {
uint n = word * 4u + b;
if (n < total)
outw |= _wp_mask_byte(p, n, equi) << (b * 8u);
outw |= _wp_mask_byte<D>(p, n, equi) << (b * 8u);
}
p.dst[word] = outw;
}
#define _wp_mask_call(D) _wp_mask_main<D>(p, wg, tid, false)
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_mask_wide(uniform WarpMaskParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
_wp_mask_main(p, wg, tid, false);
SS_DISPATCH_DIST(_wp_mask_call)
}
#undef _wp_mask_call
[shader("compute")]
[numthreads(256, 1, 1)]
void warp_mask_equi(uniform WarpMaskParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
_wp_mask_main(p, wg, tid, true);
_wp_mask_main<DistNone>(p, wg, tid, true);
}
// Re-distort: resample a GT image from a camera whose lens model no distortion
// tier represents onto the tier the parser fitted for it (mirrors
// kernels/pixelwise/ImageRedistort.cu). The fit keeps the pose, so a
// destination pixel and its source pixel are the same ray. Both grids are
// expressed relative to the intrinsics reference (ref_H/ref_W, the RGB
// resolution) and need not match: a depth or normal map carries its own size,
// so scale_out (destination step) and scale_in (source lookup) differ.
[ForceInline]
bool _rd_lookup<D : ICameraDistortion>(float* intrins, float* dist_coeffs,
int* source_models,
float* source_params, int camera_model,
int bid, int i, int j, float2 scale_out,
float2 scale_in, out float2 uv_src) {
uv_src = float2(0.0f);
float4 intrin = _wp_intrin(intrins, bid);
float2 uv = float2(((float(i) + 0.5f) / scale_out.x - intrin.z) / intrin.x,
((float(j) + 0.5f) / scale_out.y - intrin.w) / intrin.y);
float dc[D.kNumParams];
load_dist_coeffs<D>(dist_coeffs, uint(bid), dc);
float3 raydir;
if (!unproject_point<D>(uv, camera_model, dc, raydir))
return false;
if (!_wp_source_proj(source_models, source_params, bid, raydir, uv_src))
return false;
uv_src *= scale_in;
return true;
}
[ForceInline]
float2 _rd_scale(int W, int H, int ref_W, int ref_H) {
return float2(float(W) / float(ref_W), float(H) / float(ref_H));
}
[ForceInline]
void _rd_img<D : ICameraDistortion>(WarpParams p, int i, int j, int bid) {
float2 uv_src;
bool valid = _rd_lookup<D>(p.intrins, p.dist_coeffs, p.source_models,
p.source_params, p.camera_model, bid, i, j,
_rd_scale(p.Wout, p.Hout, p.ref_W, p.ref_H),
_rd_scale(p.Win, p.Hin, p.ref_W, p.ref_H),
uv_src);
gindex_t plane = gindex_t(bid) * p.Hin * p.Win;
gindex_t base = ((gindex_t(bid) * p.Hout + j) * p.Wout + i) * p.C;
for (int c = 0; c < p.C; c++) {
float v = p.invalid;
if (valid)
v = _wp_bilinear(p.src, p.elem_kind, plane, p.Hin, p.Win, p.C, c,
uv_src.x, uv_src.y, p.norm_inv, p.invalid, false);
p.dst[base + c] = v;
}
}
#define _rd_img_call(D) _rd_img<D>(p, i, j, bid)
[shader("compute")]
[numthreads(256, 1, 1)]
void redistort_img(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
SS_DISPATCH_DIST(_rd_img_call)
}
#undef _rd_img_call
[ForceInline]
void _rd_normal<D : ICameraDistortion>(WarpParams p, int i, int j, int bid) {
float2 uv_src;
float3 n = float3(-1.0f);
if (_rd_lookup<D>(p.intrins, p.dist_coeffs, p.source_models,
p.source_params, p.camera_model, bid, i, j,
_rd_scale(p.Wout, p.Hout, p.ref_W, p.ref_H),
_rd_scale(p.Win, p.Hin, p.ref_W, p.ref_H), uv_src)) {
gindex_t plane = gindex_t(bid) * p.Hin * p.Win;
float3 s;
s.x = _wp_bilinear(p.src, p.elem_kind, plane, p.Hin, p.Win, 3, 0,
uv_src.x, uv_src.y, p.norm_inv, 0.0f, false) + p.decode_off;
s.y = _wp_bilinear(p.src, p.elem_kind, plane, p.Hin, p.Win, 3, 1,
uv_src.x, uv_src.y, p.norm_inv, 0.0f, false) + p.decode_off;
s.z = _wp_bilinear(p.src, p.elem_kind, plane, p.Hin, p.Win, 3, 2,
uv_src.x, uv_src.y, p.norm_inv, 0.0f, false) + p.decode_off;
float sl = length(s);
// The pose is unchanged, so a camera-frame normal needs no rotation.
if (s.x + s.y + s.z > -2.366f && sl > 1e-8f)
n = s / sl;
}
gindex_t base = ((gindex_t(bid) * p.Hout + j) * p.Wout + i) * 3;
p.dst[base + 0] = n.x;
p.dst[base + 1] = n.y;
p.dst[base + 2] = n.z;
}
#define _rd_normal_call(D) _rd_normal<D>(p, i, j, bid)
[shader("compute")]
[numthreads(256, 1, 1)]
void redistort_normal(uniform WarpParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
int i, j, bid;
float tx, ty;
if (!_wp_tile(p, wg, tid, i, j, bid, tx, ty)) return;
SS_DISPATCH_DIST(_rd_normal_call)
}
#undef _rd_normal_call
// Out-of-frame is masked OUT rather than padded: the fitted camera can see a
// little past the source image. Word-per-thread output, as warp_mask_wide.
[ForceInline]
uint _rd_mask_byte<D : ICameraDistortion>(WarpMaskParams p, uint n) {
uint i = n % uint(p.Wout);
uint t = n / uint(p.Wout);
uint j = t % uint(p.Hout);
uint bid = t / uint(p.Hout);
float2 uv;
if (!_rd_lookup<D>(p.intrins, p.dist_coeffs, p.source_models,
p.source_params, p.camera_model, int(bid), int(i),
int(j), _rd_scale(p.Wout, p.Hout, p.ref_W, p.ref_H),
_rd_scale(p.Win, p.Hin, p.ref_W, p.ref_H), uv))
return 0u;
int xs = int(floor(clamp(uv.x + 0.5f, -8.0f, float(p.Win) + 8.0f)));
int ys = int(floor(clamp(uv.y + 0.5f, -8.0f, float(p.Hin) + 8.0f)));
if (xs < 0 || xs >= p.Win || ys < 0 || ys >= p.Hin) return 0u;
gindex_t idx = gindex_t(bid) * p.Hin * p.Win + gindex_t(ys) * p.Win + xs;
return _wp_load(p.src, idx, kElemU8) != 0.0f ? 1u : 0u;
}
[ForceInline]
void _rd_mask_main<D : ICameraDistortion>(WarpMaskParams p, uint3 wg,
uint tid) {
uint word = (wg.y * p.wgs_per_row + wg.x) * 256u + tid;
uint total = uint(p.B) * uint(p.Hout) * uint(p.Wout);
if (word >= (total + 3u) / 4u) return;
uint outw = 0u;
for (uint b = 0; b < 4u; b++) {
uint n = word * 4u + b;
if (n < total)
outw |= _rd_mask_byte<D>(p, n) << (b * 8u);
}
p.dst[word] = outw;
}
#define _rd_mask_call(D) _rd_mask_main<D>(p, wg, tid)
[shader("compute")]
[numthreads(256, 1, 1)]
void redistort_mask(uniform WarpMaskParams p, uint3 wg: SV_GroupID,
uint tid: SV_GroupIndex) {
SS_DISPATCH_DIST(_rd_mask_call)
}
#undef _rd_mask_call
// Flat byte/u16 -> float conversion: out[i] = elem(i) * scale + offset.
// Covers uint8/16_image_to_float (1/255, 1/65535), uint8_normal_to_float
// (1/127.5, -1) and uint16_depth_to_float (1, 0).
@@ -456,3 +675,11 @@ void bytes_to_float(uniform BytesToFloatParams p, uint3 wg: SV_GroupID,
if (idx >= p.total) return;
p.dst[idx] = _wp_load(p.src, gindex_t(idx), p.elem_kind) * p.scale + p.offset;
}
// Declared last: spec IDs follow declaration order (see dist_spec.slang).
// kFromSource trails kDistortion so the launches that never re-distort keep
// passing a one-element SpecList.
[SpecializationConstant]
const int kDistortion = 0;
[SpecializationConstant]
const int kFromSource = 0;
+28 -24
View File
@@ -8,9 +8,9 @@
//
// Two constraints are not visible from the declarations:
//
// - The model is ONE enum for the whole batch, not per camera, because that
// is how the projection / rasterization kernels dispatch. Mixed models in
// one batch have to be split into separate tables.
// - The model AND the distortion tier are ONE enum each for the whole batch,
// not per camera, because that is how the projection / rasterization
// kernels dispatch. Mixed cameras have to be split into separate tables.
//
// - Width / height live host-side. Only host code reads them (launch
// dimensions, image-size bookkeeping), so keeping them off device avoids
@@ -26,17 +26,6 @@
#include <vector>
// Distortion parameter layout per camera. MUST match the projection/raster
// kernels.
//
// index 0..3 : k1, k2, p1, p2 (radial + tangential)
// index 4..7 : k3, k4, k5, k6 (extended radial — OpenCV fisheye etc.)
// index 8..9 : sx1, sy1 (thin-prism)
//
// Cameras with fewer parameters pad the tail with zero.
inline constexpr int kCameraDistortionParams = 10;
// COLMAP / NerfStudio camera-model string -> CameraModelType.
// Returns CameraModelType(-1) for unknown / unsupported models; callers
// validate and raise.
@@ -57,6 +46,16 @@ inline CameraModelType camera_model_from_name(const std::string& name) {
return (CameraModelType)-1;
}
inline const char* camera_distortion_to_string(CameraDistortionType d) {
switch (d) {
case CameraDistortionType::None: return "NONE";
case CameraDistortionType::OpenCV: return "OPENCV";
case CameraDistortionType::ThinPrism: return "THIN_PRISM";
case CameraDistortionType::Rational: return "RATIONAL";
default: return "UNKNOWN";
}
}
inline const char* camera_model_to_string(CameraModelType m) {
switch (m) {
case CameraModelType::PINHOLE: return "PINHOLE";
@@ -82,10 +81,11 @@ public:
int32_t width,
int32_t height,
CameraModelType model,
CameraDistortionType distortion,
const TorchTensorView& viewmats, // host or device, [N, 4, 4]
const TorchTensorView& intrins, // host or device, [N, 4]
const TorchTensorView& dist_coeffs) // host or device, [N, 10]
: _num(num), _model(model)
const TorchTensorView& dist_coeffs) // host or device, [N, 8]
: _num(num), _model(model), _distortion(distortion)
{
_validate_shape("viewmats", viewmats, {num, 4, 4});
_validate_shape("intrins", intrins, {num, 4});
@@ -104,12 +104,13 @@ public:
Cameras(const std::string& key_prefix,
int64_t num,
CameraModelType model,
CameraDistortionType distortion,
const TorchTensorView& viewmats,
const TorchTensorView& intrins,
const TorchTensorView& dist_coeffs,
std::vector<int32_t> widths,
std::vector<int32_t> heights)
: _num(num), _model(model),
: _num(num), _model(model), _distortion(distortion),
_widths(std::move(widths)), _heights(std::move(heights))
{
_validate_shape("viewmats", viewmats, {num, 4, 4});
@@ -130,12 +131,13 @@ public:
// is the caller's responsibility.
Cameras(int64_t num,
CameraModelType model,
CameraDistortionType distortion,
DeviceTensor2D<float4> viewmats,
DeviceVector<float4> intrins,
DeviceTensor2D<float> dist_coeffs,
std::vector<int32_t> widths,
std::vector<int32_t> heights)
: _num(num), _model(model),
: _num(num), _model(model), _distortion(distortion),
_viewmats(viewmats), _intrins(intrins), _dist_coeffs(dist_coeffs),
_widths(std::move(widths)), _heights(std::move(heights))
{
@@ -153,9 +155,10 @@ public:
// ---- Read-only accessors ----------------------------------------------
int64_t num() const { return _num; }
CameraModelType model() const { return _model; }
bool empty() const { return _num == 0; }
int64_t num() const { return _num; }
CameraModelType model() const { return _model; }
CameraDistortionType distortion() const { return _distortion; }
bool empty() const { return _num == 0; }
const DeviceTensor2D<float4>& viewmats() const { return _viewmats; }
const DeviceVector<float4>& intrins() const { return _intrins; }
@@ -174,12 +177,13 @@ public:
private:
int64_t _num = 0;
CameraModelType _model = (CameraModelType)-1;
int64_t _num = 0;
CameraModelType _model = (CameraModelType)-1;
CameraDistortionType _distortion = CameraDistortionType::None;
DeviceTensor2D<float4> _viewmats; // [N, 4] -- each row is a float4
DeviceVector<float4> _intrins; // [N] -- (fx, fy, cx, cy)
DeviceTensor2D<float> _dist_coeffs; // [N, 10]
DeviceTensor2D<float> _dist_coeffs; // [N, 8]
std::vector<int32_t> _widths; // size N, host-side
std::vector<int32_t> _heights; // size N, host-side
+87
View File
@@ -0,0 +1,87 @@
#pragma once
// Compile-time selection of the per-tier Slang exports.
//
// slangc cannot export a generic, so shaders/projection_utils.slang emits one
// entry per distortion tier (`_none` / `_opencv` / `_prism` / `_rational`) and
// these traits pick one from a `CameraDistortionType` template argument.
//
// INCLUDE ORDER: this header names SlangProjectionUtils::* but does not open
// that namespace, because generated/projection_utils.cuh is `#pragma once` and
// would land in whichever namespace included it first. Include it after the
// TU's own `namespace SlangProjectionUtils { ... }` block.
#include "core/Common.cuh"
#ifdef __CUDACC__
template<CameraDistortionType D>
struct SlangDistortion;
#define _SS_DEF_SLANG_DISTORTION(TIER, SUFFIX) \
template<> \
struct SlangDistortion<CameraDistortionType::TIER> { \
using Coeffs = CameraDistortionCoeffsT<CameraDistortionType::TIER>; \
\
static __device__ __forceinline__ \
bool is_valid_distortion(float2 uv, const Coeffs& c) { \
return SlangProjectionUtils::is_valid_distortion##SUFFIX(uv, c.v); \
} \
static __device__ __forceinline__ \
bool persp_proj_nav(float3 p_view, float4 intrins, const Coeffs& c, float2* uv) { \
return SlangProjectionUtils::persp_proj_nav##SUFFIX(p_view, intrins, c.v, uv); \
} \
static __device__ __forceinline__ \
bool fisheye_proj_nav(float3 p_view, float4 intrins, const Coeffs& c, float2* uv) { \
return SlangProjectionUtils::fisheye_proj_nav##SUFFIX(p_view, intrins, c.v, uv); \
} \
static __device__ __forceinline__ \
bool equisolid_proj_nav(float3 p_view, float4 intrins, const Coeffs& c, float2* uv) { \
return SlangProjectionUtils::equisolid_proj_nav##SUFFIX(p_view, intrins, c.v, uv); \
} \
static __device__ __forceinline__ \
float2 distort_point(float2 uv, int camera_model, const Coeffs& c) { \
return SlangProjectionUtils::distort_point##SUFFIX(uv, camera_model, c.v); \
} \
static __device__ __forceinline__ \
bool undistort_point(float2 uv, int camera_model, const Coeffs& c, float2* out) { \
return SlangProjectionUtils::undistort_point##SUFFIX(uv, camera_model, c.v, out); \
} \
static __device__ __forceinline__ \
bool unproject_point(float2 uv, int camera_model, const Coeffs& c, float3* rd) { \
return SlangProjectionUtils::unproject_point##SUFFIX(uv, camera_model, c.v, rd); \
} \
static __device__ __forceinline__ \
bool generate_ray(float2 uv, int camera_model, const Coeffs& c, float3* rd) { \
return SlangProjectionUtils::generate_ray##SUFFIX(uv, camera_model, c.v, rd); \
} \
};
_SS_DEF_SLANG_DISTORTION(None, _none)
_SS_DEF_SLANG_DISTORTION(OpenCV, _opencv)
_SS_DEF_SLANG_DISTORTION(ThinPrism, _prism)
_SS_DEF_SLANG_DISTORTION(Rational, _rational)
#undef _SS_DEF_SLANG_DISTORTION
// Camera-model-aware `*_proj_nav`, for the kernels that take the model at run
// time (image warps, meshing raster). EQUIRECTANGULAR ignores the coefficients.
template<CameraDistortionType D>
__device__ __forceinline__ bool camera_proj_nav(
CameraModelType model, float3 p_view, float4 intrins,
const typename SlangDistortion<D>::Coeffs& c, float2* uv
) {
switch (model) {
case CameraModelType::FISHEYE:
return SlangDistortion<D>::fisheye_proj_nav(p_view, intrins, c, uv);
case CameraModelType::EQUISOLID:
return SlangDistortion<D>::equisolid_proj_nav(p_view, intrins, c, uv);
case CameraModelType::EQUIRECTANGULAR:
return SlangProjectionUtils::equirect_proj_nav(p_view, intrins, uv);
default:
return SlangDistortion<D>::persp_proj_nav(p_view, intrins, c, uv);
}
}
#endif // __CUDACC__
+136
View File
@@ -25,6 +25,142 @@ enum class CameraModelType {
EQUIRECTANGULAR = 3,
};
// Lens distortion, orthogonal to CameraModelType and chosen per camera group at
// load time: the parsers pick the cheapest tier that represents the source
// camera exactly, and fit + re-distort when none does. Values must match
// CameraDistortionType in shaders/projection_utils.slang and Common.cuh.
//
// Coefficient order is each tier's own -- a slot index does NOT mean the same
// thing across tiers:
// OpenCV k1 k2 p1 p2 (COLMAP OPENCV)
// ThinPrism k1 k2 k3 k4 p1 p2 sx1 sy1 (COLMAP THIN_PRISM_FISHEYE)
// Rational k1 k2 k3 k4 k5 k6 p1 p2 (COLMAP FULL_OPENCV; k4..k6 divide)
enum class CameraDistortionType {
None = 0,
OpenCV = 1,
ThinPrism = 2,
Rational = 3,
};
// Storage width of the per-camera coefficient row. Every tier reads a prefix of
// it; the tail is zero. MUST match kCameraDistortionParams in Common.cuh.
inline constexpr int kCameraDistortionParams = 8;
inline constexpr int camera_distortion_num_params(CameraDistortionType d) {
return d == CameraDistortionType::None ? 0 :
d == CameraDistortionType::OpenCV ? 4 : 8;
}
inline const char* camera_distortion_to_string(CameraDistortionType d) {
switch (d) {
case CameraDistortionType::None: return "NONE";
case CameraDistortionType::OpenCV: return "OPENCV";
case CameraDistortionType::ThinPrism: return "THIN_PRISM";
case CameraDistortionType::Rational: return "RATIONAL";
default: return "UNKNOWN";
}
}
inline CameraDistortionType camera_distortion_from_name(const std::string& name) {
if (name == "NONE") return CameraDistortionType::None;
if (name == "OPENCV") return CameraDistortionType::OpenCV;
if (name == "THIN_PRISM") return CameraDistortionType::ThinPrism;
if (name == "RATIONAL") return CameraDistortionType::Rational;
return (CameraDistortionType)-1;
}
// Cheapest tier that still represents `coeffs` exactly, given the tier it was
// written in. Zero-extension OpenCV -> ThinPrism is exact, so a ThinPrism
// camera whose k3/k4/sx1/sy1 vanish demotes; a Rational camera whose
// denominator vanishes is a plain polynomial and demotes as well.
inline CameraDistortionType camera_distortion_demote(
CameraDistortionType tier, const float* coeffs, float* out)
{
auto zero = [](float v) { return v == 0.0f; };
if (tier == CameraDistortionType::Rational) {
// 1/(1 + 0) == 1, so an all-zero denominator is the polynomial form
// with k1..k3 and no k4 term.
if (zero(coeffs[3]) && zero(coeffs[4]) && zero(coeffs[5])) {
float k1 = coeffs[0], k2 = coeffs[1], k3 = coeffs[2];
float p1 = coeffs[6], p2 = coeffs[7];
if (zero(k3)) {
out[0] = k1; out[1] = k2; out[2] = p1; out[3] = p2;
for (int i = 4; i < kCameraDistortionParams; i++) out[i] = 0.0f;
return CameraDistortionType::OpenCV;
}
out[0] = k1; out[1] = k2; out[2] = k3; out[3] = 0.0f;
out[4] = p1; out[5] = p2; out[6] = 0.0f; out[7] = 0.0f;
return CameraDistortionType::ThinPrism;
}
} else if (tier == CameraDistortionType::ThinPrism) {
if (zero(coeffs[2]) && zero(coeffs[3]) && zero(coeffs[6]) && zero(coeffs[7])) {
float k1 = coeffs[0], k2 = coeffs[1], p1 = coeffs[4], p2 = coeffs[5];
out[0] = k1; out[1] = k2; out[2] = p1; out[3] = p2;
for (int i = 4; i < kCameraDistortionParams; i++) out[i] = 0.0f;
return camera_distortion_demote(CameraDistortionType::OpenCV, out, out);
}
} else if (tier == CameraDistortionType::OpenCV) {
if (zero(coeffs[0]) && zero(coeffs[1]) && zero(coeffs[2]) && zero(coeffs[3])) {
for (int i = 0; i < kCameraDistortionParams; i++) out[i] = 0.0f;
return CameraDistortionType::None;
}
} else {
for (int i = 0; i < kCameraDistortionParams; i++) out[i] = 0.0f;
return CameraDistortionType::None;
}
if (out != coeffs)
for (int i = 0; i < kCameraDistortionParams; i++) out[i] = coeffs[i];
return tier;
}
// Rewrite `coeffs` from `from` into `to`, which must be a tier that contains it
// (see camera_distortion_kernel_tier). Returns false when it does not.
inline bool camera_distortion_promote(CameraDistortionType from,
CameraDistortionType to,
const float* coeffs, float* out) {
if (from == to) {
if (out != coeffs)
for (int i = 0; i < kCameraDistortionParams; i++) out[i] = coeffs[i];
return true;
}
float in[kCameraDistortionParams];
for (int i = 0; i < kCameraDistortionParams; i++) in[i] = coeffs[i];
for (int i = 0; i < kCameraDistortionParams; i++) out[i] = 0.0f;
if (from == CameraDistortionType::None)
return true; // all-zero coefficients are the identity in every tier
if (from == CameraDistortionType::OpenCV && to == CameraDistortionType::ThinPrism) {
out[0] = in[0]; out[1] = in[1]; // k1 k2
out[4] = in[2]; out[5] = in[3]; // p1 p2
return true;
}
if (from == CameraDistortionType::OpenCV && to == CameraDistortionType::Rational) {
out[0] = in[0]; out[1] = in[1]; // k1 k2 (numerator)
out[6] = in[2]; out[7] = in[3]; // p1 p2
return true;
}
// ThinPrism -> Rational would need a 4th numerator term and drop sx1/sy1;
// Rational -> ThinPrism cannot express the denominator at all.
return false;
}
// Which (camera model, distortion tier) pairs the CUDA kernels are instantiated
// for. Every tier is available on Vulkan (a specialization constant costs no
// SPIR-V), so this bounds the CUDA binary only, and it must match
// kCameraVariants in tools/codegen/generate_kernel_instantiation.py and the
// export lists in shaders/primitive_3dgs.slang.
//
// The gaps are not arbitrary: no COLMAP fisheye model is rational, and
// EQUIRECTANGULAR has no lens distortion.
inline bool camera_distortion_is_compiled(CameraModelType m, CameraDistortionType d) {
switch (m) {
case CameraModelType::PINHOLE: return true;
case CameraModelType::FISHEYE:
case CameraModelType::EQUISOLID: return d != CameraDistortionType::Rational;
case CameraModelType::EQUIRECTANGULAR: return d == CameraDistortionType::None;
default: return false;
}
}
// COLMAP / NerfStudio camera-model string -> CameraModelType.
// Returns CameraModelType(-1) for unknown / unsupported models; callers
// should validate and raise. Mirrors Camera.h:90-105.
+73 -36
View File
@@ -87,44 +87,8 @@ struct FixedArray
#endif // #ifdef __CUDACC__
#ifdef __CUDACC__
// k1 k2 k3 k4 p1 p2 sx1 sy1 b1 b2
typedef FixedArray<float, 10> CameraDistortionCoeffs;
#endif
#include <core/Tensor.h>
struct CameraDistortionCoeffsBuffer {
float* __restrict__ coeffs;
CameraDistortionCoeffsBuffer(const TorchTensorView &tensor) {
if (std::get<2>(tensor).size() != 2 || std::get<2>(tensor)[1] != 10)
throw std::runtime_error("dist coeffs must have shape (C, 10)");
if (std::get<1>(tensor) != sizeof(float))
throw std::runtime_error("dist coeffs must be float");
coeffs = (float*)std::get<0>(tensor);
}
CameraDistortionCoeffsBuffer(float* ptr) : coeffs(ptr) {}
#ifdef __CUDACC__
__device__ CameraDistortionCoeffs load(long idx) const {
CameraDistortionCoeffs res;
if (coeffs == nullptr) {
#pragma unroll
for (int i = 0; i < 10; i++)
res[i] = 0.0f;
} else {
float* c = coeffs + 10 * idx;
#pragma unroll
for (int i = 0; i < 10; i++)
res[i] = c[i];
}
return res;
}
#endif
};
// Camera Types
// This must match projection_utils.slang
enum class CameraModelType {
@@ -134,6 +98,71 @@ enum class CameraModelType {
EQUIRECTANGULAR = 3,
};
// Lens distortion tier, orthogonal to CameraModelType and a COMPILE-TIME axis
// in every kernel that projects. Must match core/CameraModel.h and
// projection_utils.slang; the per-tier coefficient order is documented there.
enum class CameraDistortionType {
None = 0,
OpenCV = 1,
ThinPrism = 2,
Rational = 3,
};
// Storage width of one camera's coefficient row. Each tier reads a prefix.
inline constexpr int kCameraDistortionParams = 8;
inline constexpr int camera_distortion_num_params(CameraDistortionType d) {
return d == CameraDistortionType::None ? 0 :
d == CameraDistortionType::OpenCV ? 4 : 8;
}
#ifdef __CUDACC__
// Per-tier coefficient pack. Sized to the tier, not to the storage row, so an
// undistorted camera costs no registers at all. DistNone in Slang carries one
// unread slot (Slang has no zero-length array), which the launchers mirror.
template<CameraDistortionType D>
struct CameraDistortionCoeffsT {
static constexpr int kNum = camera_distortion_num_params(D);
FixedArray<float, (kNum > 0 ? kNum : 1)> v;
};
#endif
struct CameraDistortionCoeffsBuffer {
float* __restrict__ coeffs;
CameraDistortionCoeffsBuffer(const TorchTensorView &tensor) {
if (std::get<2>(tensor).size() != 2 ||
std::get<2>(tensor)[1] != kCameraDistortionParams)
throw std::runtime_error("dist coeffs must have shape (C, 8)");
if (std::get<1>(tensor) != sizeof(float))
throw std::runtime_error("dist coeffs must be float");
coeffs = (float*)std::get<0>(tensor);
}
CameraDistortionCoeffsBuffer(float* ptr) : coeffs(ptr) {}
#ifdef __CUDACC__
template<CameraDistortionType D>
__device__ CameraDistortionCoeffsT<D> load(long idx) const {
CameraDistortionCoeffsT<D> res;
constexpr int kNum = CameraDistortionCoeffsT<D>::kNum;
if constexpr (kNum == 0) {
res.v[0] = 0.0f;
} else if (coeffs == nullptr) {
#pragma unroll
for (int i = 0; i < kNum; i++)
res.v[i] = 0.0f;
} else {
const float* c = coeffs + kCameraDistortionParams * idx;
#pragma unroll
for (int i = 0; i < kNum; i++)
res.v[i] = c[i];
}
return res;
}
#endif
};
inline CameraModelType cmt(const std::string &s) {
return (s == "PINHOLE") ? CameraModelType::PINHOLE :
(s == "FISHEYE") ? CameraModelType::FISHEYE :
@@ -142,6 +171,14 @@ inline CameraModelType cmt(const std::string &s) {
(CameraModelType)-1;
}
inline CameraDistortionType cdt(const std::string &s) {
return (s == "NONE") ? CameraDistortionType::None :
(s == "OPENCV") ? CameraDistortionType::OpenCV :
(s == "THIN_PRISM") ? CameraDistortionType::ThinPrism :
(s == "RATIONAL") ? CameraDistortionType::Rational :
(CameraDistortionType)-1;
}
// Kernel launcher
+2
View File
@@ -288,6 +288,8 @@ enum class SaveClass : uint8_t {
/* ---- warped-setup staging ---- */ \
X(WarpInputIntrins , "warp.input_intrins", Other , Never) \
X(WarpInputDistCoeffs , "warp.input_dist_coeffs", Other , Never) \
X(WarpSourceModels , "warp.source_models", Other , Never) \
X(WarpSourceParams , "warp.source_params", Other , Never) \
/* ---- data-manager scratch ---- */ \
X(DmAxesFisheye5 , "dm.axes.fisheye5", Other , Never) \
X(DmAxesEquirect6 , "dm.axes.equirect6", Other , Never) \
+69 -17
View File
@@ -100,6 +100,12 @@ struct IndexGroup {
int32_t width = 0;
int32_t height = 0;
CameraModelType model = (CameraModelType)-1; // uniform within a group
CameraDistortionType distortion = CameraDistortionType::None; // likewise
// Whether this group's images must be resampled from a fitted source
// camera. Part of the group key: the kernels take it as a compile-time
// axis, so a group that mixes fitted and exact cameras would project the
// exact ones through source model -1 and blank them.
bool redistort = false;
int32_t mask_h = 0, mask_w = 0;
int32_t depth_h = 0, depth_w = 0;
int32_t normal_h = 0, normal_w = 0;
@@ -495,14 +501,21 @@ void DecodedBatch::build_views() {
int64_t B_post = num;
viewmats_view = mk(viewmats.data(), 4, {B_post, 4LL, 4LL});
intrins_view = mk(intrins.data(), 4, {B_post, 4LL});
dist_coeffs_view = mk(dist_coeffs.data(), 4, {B_post, 10LL});
dist_coeffs_view = mk(dist_coeffs.data(), 4,
{B_post, (long long)kCameraDistortionParams});
// Per-INPUT intrins / dist_coeffs views (size B_in). Empty when the
// warp kernel doesn't need them.
int64_t B_in = input_num;
if (!input_intrins.empty()) {
input_intrins_view = mk(input_intrins.data(), 4, {B_in, 4LL});
input_dist_coeffs_view = mk(input_dist_coeffs.data(), 4, {B_in, 10LL});
input_dist_coeffs_view = mk(input_dist_coeffs.data(), 4,
{B_in, (long long)kCameraDistortionParams});
if (!input_source_models.empty()) {
input_source_models_view = TorchTensorView(
(uint64_t)input_source_models.data(), 4, {B_in});
input_source_params_view = mk(input_source_params.data(), 4, {B_in, 16LL});
}
}
// Image / modality views stay at INPUT shape. The engine warps on the
@@ -535,7 +548,8 @@ public:
DataManagerImpl(
DataManagerConfig config,
std::vector<int32_t> camera_models, // per-camera enum int
std::vector<int32_t> camera_models, // per-camera enum int
std::vector<int32_t> camera_distortions, // per-camera tier int
std::vector<std::string> image_filenames,
std::vector<std::string> mask_filenames,
std::vector<std::string> depth_filenames,
@@ -548,7 +562,9 @@ public:
std::vector<float> intrins, // post-split
std::vector<float> dist_coeffs, // post-split
std::vector<float> input_intrins, // per-input
std::vector<float> input_dist_coeffs, // per-input
std::vector<float> input_dist_coeffs,
std::vector<int32_t> redistort_models,
std::vector<float> redistort_params, // per-input
std::vector<int32_t> train_indices,
std::vector<int32_t> val_indices);
@@ -591,6 +607,9 @@ private:
// partitioned by this so a mixed pinhole + fisheye dataset just yields
// two extra groups; batches stay homogeneous.
std::vector<int32_t> _camera_models;
std::vector<int32_t> _camera_distortions;
std::vector<int32_t> _redistort_models;
std::vector<float> _redistort_params;
// Per-input K and post-split offset. Length N. K[i] is the split factor
// for input camera i (1 / 5 / 6). post_offsets[i] is the starting index
// in _viewmats / _intrins / _dist_coeffs (which are now POST-split).
@@ -771,6 +790,7 @@ private:
DataManagerImpl::DataManagerImpl(
DataManagerConfig config,
std::vector<int32_t> camera_models,
std::vector<int32_t> camera_distortions,
std::vector<std::string> image_filenames,
std::vector<std::string> mask_filenames,
std::vector<std::string> depth_filenames,
@@ -784,10 +804,15 @@ DataManagerImpl::DataManagerImpl(
std::vector<float> dist_coeffs,
std::vector<float> input_intrins,
std::vector<float> input_dist_coeffs,
std::vector<int32_t> redistort_models,
std::vector<float> redistort_params,
std::vector<int32_t> train_indices,
std::vector<int32_t> val_indices)
: _cfg(config),
_camera_models(std::move(camera_models)),
_camera_distortions(std::move(camera_distortions)),
_redistort_models(std::move(redistort_models)),
_redistort_params(std::move(redistort_params)),
_K_per_camera(std::move(K_per_camera)),
_post_offsets(std::move(post_offsets)),
_image_filenames(std::move(image_filenames)),
@@ -830,14 +855,14 @@ DataManagerImpl::DataManagerImpl(
(int64_t)_heights.size() != N ||
(int64_t)_viewmats.size() != n_post * 16 ||
(int64_t)_intrins.size() != n_post * 4 ||
(int64_t)_dist_coeffs.size() != n_post * 10) {
(int64_t)_dist_coeffs.size() != n_post * kCameraDistortionParams) {
throw std::runtime_error(
"DataManager: per-camera array length mismatch (expected widths/heights "
"of length N and viewmats/intrins/dist_coeffs of length N_post = sum(K))");
}
if (!_input_intrins.empty() &&
((int64_t)_input_intrins.size() != N * 4 ||
(int64_t)_input_dist_coeffs.size() != N * 10)) {
(int64_t)_input_dist_coeffs.size() != N * kCameraDistortionParams)) {
throw std::runtime_error(
"DataManager: input_intrins / input_dist_coeffs length mismatch "
"(expected length 4*N / 10*N respectively, or both empty)");
@@ -1032,19 +1057,26 @@ std::vector<IndexGroup> DataManagerImpl::build_index_groups_member(
// Group key: (W, H, camera_model). std::map handles tuple keys natively,
// and group build happens once at construction, so we don't need an
// unordered_map's hash machinery here.
std::map<std::tuple<int32_t, int32_t, int32_t>, IndexGroup> by_shape;
std::map<std::tuple<int32_t, int32_t, int32_t, int32_t, int32_t>,
IndexGroup> by_shape;
// Track first per-modality mismatch for a one-shot warning. Mutable so
// this const method can update them; semantically they're cache.
static bool warned_mask = false, warned_depth = false, warned_normal = false;
for (int32_t i : flat_indices) {
auto key = std::make_tuple(_widths[i], _heights[i], _camera_models[i]);
const bool redistort_i =
!_redistort_models.empty() && _redistort_models[i] >= 0;
auto key = std::make_tuple(_widths[i], _heights[i], _camera_models[i],
_camera_distortions[i],
(int32_t)redistort_i);
auto& g = by_shape[key];
if (g.indices.empty()) {
g.width = _widths[i];
g.height = _heights[i];
g.model = (CameraModelType)_camera_models[i];
g.distortion = (CameraDistortionType)_camera_distortions[i];
g.redistort = redistort_i;
g.K = _K_per_camera[i];
// Pick the cubemap axes corresponding to this group's split factor.
if (g.K == 5) g.axes_dev = _axes_fisheye5_dev;
@@ -1252,6 +1284,7 @@ void DataManagerImpl::allocate_batch(
b.height = g.out_h;
b.num = B_post;
b.model = (K > 1) ? CameraModelType::PINHOLE : g.model;
b.distortion = (K > 1) ? CameraDistortionType::None : g.distortion;
b.indices = ds_indices;
b.post_offsets.assign((size_t)B, 0);
@@ -1262,18 +1295,26 @@ void DataManagerImpl::allocate_batch(
b.input_num = B;
b.K = K;
b.input_model = g.model;
b.input_distortion = g.distortion;
b.axes_dev = g.axes_dev;
b.viewmats.assign((size_t)B_post * 16, 0.0f);
b.intrins.assign((size_t)B_post * 4, 0.0f);
b.dist_coeffs.assign((size_t)B_post * 10, 0.0f);
b.dist_coeffs.assign((size_t)B_post * kCameraDistortionParams, 0.0f);
// Per-INPUT intrins / dist_coeffs (needed by the wide warp kernel for
// fisheye / equisolid). Allocate only when K > 1 and the source arrays
// are present.
if (K > 1 && !_input_intrins.empty()) {
if ((K > 1 || g.redistort) && !_input_intrins.empty()) {
b.input_intrins.assign((size_t)B * 4, 0.0f);
b.input_dist_coeffs.assign((size_t)B * 10, 0.0f);
b.input_dist_coeffs.assign((size_t)B * kCameraDistortionParams, 0.0f);
if (g.redistort) {
b.input_source_models.assign((size_t)B, -1);
b.input_source_params.assign((size_t)B * 16, 0.0f);
} else {
b.input_source_models.clear();
b.input_source_params.clear();
}
} else {
b.input_intrins.clear();
b.input_dist_coeffs.clear();
@@ -1338,16 +1379,22 @@ void DataManagerImpl::fill_camera_params(DecodedBatch& b) {
std::memcpy(&b.intrins[(size_t)j * K * 4],
&_intrins[(size_t)off * 4],
(size_t)K * 4 * sizeof(float));
std::memcpy(&b.dist_coeffs[(size_t)j * K * 10],
&_dist_coeffs[(size_t)off * 10],
(size_t)K * 10 * sizeof(float));
std::memcpy(&b.dist_coeffs[(size_t)j * K * kCameraDistortionParams],
&_dist_coeffs[(size_t)off * kCameraDistortionParams],
(size_t)K * kCameraDistortionParams * sizeof(float));
if (have_in) {
std::memcpy(&b.input_intrins[(size_t)j * 4],
&_input_intrins[(size_t)i_in * 4],
4 * sizeof(float));
std::memcpy(&b.input_dist_coeffs[(size_t)j * 10],
&_input_dist_coeffs[(size_t)i_in * 10],
10 * sizeof(float));
std::memcpy(&b.input_dist_coeffs[(size_t)j * kCameraDistortionParams],
&_input_dist_coeffs[(size_t)i_in * kCameraDistortionParams],
kCameraDistortionParams * sizeof(float));
if (!b.input_source_models.empty()) {
b.input_source_models[j] = _redistort_models[i_in];
std::memcpy(&b.input_source_params[(size_t)j * 16],
&_redistort_params[(size_t)i_in * 16],
16 * sizeof(float));
}
}
}
}
@@ -1957,6 +2004,7 @@ void DataManagerImpl::fetch_one(int32_t index, DecodedBatch& out) {
DataManager::DataManager(
DataManagerConfig config,
std::vector<int32_t> camera_models,
std::vector<int32_t> camera_distortions,
std::vector<std::string> image_filenames,
std::vector<std::string> mask_filenames,
std::vector<std::string> depth_filenames,
@@ -1970,17 +2018,21 @@ DataManager::DataManager(
std::vector<float> dist_coeffs,
std::vector<float> input_intrins,
std::vector<float> input_dist_coeffs,
std::vector<int32_t> redistort_models,
std::vector<float> redistort_params,
std::vector<int32_t> train_indices,
std::vector<int32_t> val_indices)
{
_impl = std::make_unique<DataManagerImpl>(
std::move(config), std::move(camera_models),
std::move(camera_distortions),
std::move(image_filenames), std::move(mask_filenames),
std::move(depth_filenames), std::move(normal_filenames),
std::move(widths), std::move(heights),
std::move(K_per_camera), std::move(post_offsets),
std::move(viewmats), std::move(intrins), std::move(dist_coeffs),
std::move(input_intrins), std::move(input_dist_coeffs),
std::move(redistort_models), std::move(redistort_params),
std::move(train_indices), std::move(val_indices));
}
+19 -4
View File
@@ -125,12 +125,13 @@ struct DecodedBatch {
int32_t height = 0; // post-split H
int32_t num = 0; // post-split B (= input B * K)
CameraModelType model = (CameraModelType)-1; // PINHOLE when K>1
CameraDistortionType distortion = CameraDistortionType::None; // None when K>1
// Selected camera indices, in input batch order (length = input B).
std::vector<int32_t> indices;
// Camera parameters at POST-split resolution, host-contiguous.
// Length = 16 / 4 / 10 * num (= B*K).
// Length = 16 / 4 / 8 * num (= B*K).
std::vector<float> viewmats;
std::vector<float> intrins;
std::vector<float> dist_coeffs;
@@ -179,15 +180,24 @@ struct DecodedBatch {
int32_t input_num = 0; // = num / K
int32_t K = 1;
CameraModelType input_model = (CameraModelType)-1;
CameraDistortionType input_distortion = CameraDistortionType::None;
const float* axes_dev = nullptr;
// Per-INPUT intrins / dist_coeffs (length input_num). Populated when
// K > 1 and the wide warp kernel (fisheye/equisolid) needs them. The
// equirectangular path ignores these.
std::vector<float> input_intrins; // 4 * input_num
std::vector<float> input_dist_coeffs; // 10 * input_num
std::vector<float> input_dist_coeffs; // 8 * input_num
// Per-INPUT source camera for the images that must be re-distorted.
// Empty when the dataset has none; see ParsedDataset::redistort.
std::vector<int32_t> input_source_models; // input_num
std::vector<float> input_source_params; // 16 * input_num
TorchTensorView input_intrins_view{0, 0, {}};
TorchTensorView input_dist_coeffs_view{0, 0, {}};
TorchTensorView input_source_models_view{0, 0, {}};
TorchTensorView input_source_params_view{0, 0, {}};
// Engine-facing TorchTensorViews. Lazily filled by `build_views()` once
// the buffers are populated. The Engine consumes these directly via
@@ -250,6 +260,7 @@ public:
DataManagerConfig config,
// Per-INPUT-camera (length N) ---------------------------------------
std::vector<int32_t> camera_models,
std::vector<int32_t> camera_distortions,
std::vector<std::string> image_filenames,
std::vector<std::string> mask_filenames,
std::vector<std::string> depth_filenames,
@@ -272,13 +283,17 @@ public:
// (bake_post_split in DatasetCommon.cpp).
std::vector<float> viewmats, // [N_post, 4, 4]
std::vector<float> intrins, // [N_post, 4]
std::vector<float> dist_coeffs, // [N_post, 10]
std::vector<float> dist_coeffs, // [N_post, 8]
// Per-INPUT intrins/dist_coeffs (length N). Needed by the wide warp
// kernel (fisheye/equisolid projection). Pass empty vectors when
// no fisheye-warp camera is in the dataset -- the kernel only reads
// them on the fisheye path.
std::vector<float> input_intrins, // [N, 4]
std::vector<float> input_dist_coeffs, // [N, 10]
std::vector<float> input_dist_coeffs, // [N, 8]
// Per-INPUT source camera for images that must be re-distorted;
// empty when the dataset has none. See PostSplitCameras.
std::vector<int32_t> redistort_models, // [N]
std::vector<float> redistort_params, // [N, 16]
std::vector<int32_t> train_indices,
std::vector<int32_t> val_indices);
+34 -5
View File
@@ -77,6 +77,17 @@ ColmapPoints3D read_points3D_text(const std::string& recon_dir)
ColmapPoints3D read_ply_points(const std::string& path);
// The exotic camera a fitted camera stands in for, so the re-distort kernel
// can evaluate the true source projection rather than an approximation of it.
// `source_model` and `params` are as data/SourceCamera.h defines them; ignored
// when `source_model < 0`.
struct RedistortSource {
int32_t source_model = -1;
float params[16]{};
float fit_max_px = 0.0f; // reported near-minimax error of the fit
};
// ===========================================================================
// Parser config + baked dataset
// ===========================================================================
@@ -150,9 +161,11 @@ struct DatasetParserConfig {
struct ParsedDataset {
int64_t num_cameras = 0;
// CameraModelType as int (Camera.h camera_model_from_name over the
// nerfstudio-normalized model name).
// CameraModelType / CameraDistortionType as int, per input camera. The
// distortion tier is the cheapest one that represents the source camera
// exactly; `redistort` says when that required resampling the images.
std::vector<int32_t> camera_models;
std::vector<int32_t> camera_distortions;
// Absolute file paths. mask/depth/normal are all-N with "" for images
// that have no such auxiliary file, or empty vectors when no image has
@@ -169,7 +182,14 @@ struct ParsedDataset {
std::vector<float> c2w;
std::vector<float> intrins; // [N, 4] (fx, fy, cx, cy)
std::vector<float> dist_coeffs; // [N, 10] (k1 k2 k3 k4 p1 p2 sx1 sy1 b1 b2)
// [N, 8]; slot meaning is per-tier, see core/CameraModel.h
std::vector<float> dist_coeffs;
// Cameras whose source model no tier represents exactly (COLMAP FOV /
// DIVISION / EUCM / RAD_TAN_THIN_PRISM_FISHEYE, Metashape affinity-skew).
// Empty when every camera mapped exactly. Indexed like the arrays above;
// `source_model < 0` marks a camera that needs no resampling.
std::vector<RedistortSource> redistort;
// Per-INPUT train/val partition (validation_fraction).
std::vector<int32_t> train_indices;
@@ -237,7 +257,8 @@ struct PostSplitCameras {
// POST-split.
std::vector<float> viewmats; // [N_post, 4, 4]
std::vector<float> intrins; // [N_post, 4]
std::vector<float> dist_coeffs; // [N_post, 10]
std::vector<float> dist_coeffs; // [N_post, 8]
std::vector<int32_t> post_distortions; // [N_post] CameraDistortionType
// Viewer (engine_viewer_init) arrays, POST-split: camera-to-world in the
// y/z-flipped form the blit kernel expects, plus per-post W/H/model.
@@ -248,7 +269,15 @@ struct PostSplitCameras {
// Per-INPUT copies for the wide-warp kernel; empty when !any_warp.
std::vector<float> input_intrins; // [N, 4]
std::vector<float> input_dist_coeffs; // [N, 10]
std::vector<float> input_dist_coeffs; // [N, 8]
std::vector<int32_t> input_distortions; // [N] CameraDistortionType
// Flattened ParsedDataset::redistort, per INPUT camera. Empty when no
// camera needs resampling; -1 in `redistort_models` marks one that does
// not. A dataset with any of these sets any_warp, because the re-distort
// shares the warp path's staging even at K == 1.
std::vector<int32_t> redistort_models; // [N]
std::vector<float> redistort_params; // [N, 16]
};
PostSplitCameras bake_post_split(const ParsedDataset& ds,
+643
View File
@@ -0,0 +1,643 @@
#include "data/DistortionFit.h"
#include <algorithm>
#include <cmath>
#include <vector>
// Method, in one place:
//
// 1. Scan the source's field of view by bisecting theta along 128 azimuths of
// the target's own axis, giving the valid domain as a star region.
// 2. Sample a tensor-product Chebyshev-Gauss grid over that region's bounding
// box in the TARGET's undistorted normalized coordinates -- theta-space for
// FISHEYE/EQUISOLID, tan-space for PINHOLE (projection_utils.slang). Equal
// weights at those nodes integrate against 1/sqrt(1-x^2), which is what
// makes the L2 solution track the L-infinity one.
// 3. The residual is bilinear -- linear in k1..k4/p1/p2/sx1/sy1 at fixed
// intrinsics, linear in fx/fy/cx/cy at fixed coefficients -- so a linear
// solve with c = 0 gives the intrinsics, then Levenberg-Marquardt over all
// 12 unknowns converges to machine precision. Alternating the two exact
// blocks instead looks tempting and is not: fx and k1..k4 are strongly
// coupled and it stalls near 2 px on a source the tier represents exactly.
// 4. A few Lawson rounds (w <- w * |r|) push that toward minimax; the best
// max-error iterate is kept.
// 5. If the fitted distortion turns out not to be invertible over the domain,
// the high-order coefficients are masked off and 1-4 repeated. A slightly
// worse camera the kernels accept beats an exact one they reject.
namespace dsfit {
namespace {
constexpr double kPi = 3.14159265358979323846;
constexpr int kNC = 8; // ThinPrism coefficients
constexpr int kNU = 12; // ... plus fx, cx, fy, cy
struct Model {
double fx = 1.0, fy = 1.0, cx = 0.0, cy = 0.0;
double c[kNC] = {};
};
struct Sample {
double u = 0.0, v = 0.0; // target undistorted normalized
double us = 0.0, vs = 0.0; // source pixel
double w = 1.0;
double gx[kNC] = {}, gy[kNC] = {};
};
// Past 175 degrees a lens is not something this fits, and tan(85 deg) = 11.4
// is already as far as a polynomial in tan-space can be pushed.
constexpr double kWidestTheta = 175.0 * kPi / 180.0;
double theta_cap(CameraModelType m) {
return m == CameraModelType::PINHOLE ? 85.0 * kPi / 180.0 : kWidestTheta;
}
double rho_of_theta(CameraModelType m, double th) {
switch (m) {
case CameraModelType::PINHOLE: return std::tan(th);
case CameraModelType::FISHEYE: return th;
case CameraModelType::EQUISOLID: return 2.0 * std::sin(0.5 * th);
default: return 0.0;
}
}
bool unproject(CameraModelType m, double u, double v, double d[3]) {
if (m == CameraModelType::PINHOLE) {
d[0] = u; d[1] = v; d[2] = 1.0;
return true;
}
double r = std::sqrt(u * u + v * v), th;
if (m == CameraModelType::FISHEYE) {
th = r;
} else if (m == CameraModelType::EQUISOLID) {
if (r > 2.0) return false;
th = 2.0 * std::asin(0.5 * r);
} else {
return false;
}
if (th > kPi) return false;
double s = r > 1e-12 ? std::sin(th) / r : 1.0;
d[0] = u * s; d[1] = v * s; d[2] = std::cos(th);
return true;
}
// Column basis of DistThinPrism::distort, matching the slot order
// k1 k2 k3 k4 p1 p2 sx1 sy1.
void distort_basis(double u, double v, double gx[kNC], double gy[kNC]) {
double r2 = u * u + v * v, r4 = r2 * r2, r6 = r4 * r2, r8 = r4 * r4;
gx[0] = u * r2; gx[1] = u * r4; gx[2] = u * r6; gx[3] = u * r8;
gx[4] = 2.0 * u * v; gx[5] = r2 + 2.0 * u * u; gx[6] = r2; gx[7] = 0.0;
gy[0] = v * r2; gy[1] = v * r4; gy[2] = v * r6; gy[3] = v * r8;
gy[4] = r2 + 2.0 * v * v; gy[5] = 2.0 * u * v; gy[6] = 0.0; gy[7] = r2;
}
// Mirrors is_valid_distortion<DistThinPrism>: the distortion must stay locally
// orientation-preserving or the kernels drop the primitive.
bool distortion_invertible(double u, double v, const double c[kNC]) {
double r2 = u * u + v * v, r4 = r2 * r2, r6 = r4 * r2;
double R = 1.0 + r2 * (c[0] + r2 * (c[1] + r2 * (c[2] + r2 * c[3])));
double Rp = c[0] + 2.0 * c[1] * r2 + 3.0 * c[2] * r4 + 4.0 * c[3] * r6;
double p1 = c[4], p2 = c[5], sx = c[6], sy = c[7];
double j00 = R + 2.0 * u * u * Rp + 2.0 * p1 * v + 6.0 * p2 * u + 2.0 * sx * u;
double j01 = 2.0 * u * v * Rp + 2.0 * p1 * u + 2.0 * p2 * v + 2.0 * sx * v;
double j10 = 2.0 * u * v * Rp + 2.0 * p2 * v + 2.0 * p1 * u + 2.0 * sy * u;
double j11 = R + 2.0 * v * v * Rp + 2.0 * p2 * u + 6.0 * p1 * v + 2.0 * sy * v;
return std::min(j00 * j11 - j01 * j10, std::min(j00, j11)) > 0.0;
}
// Cholesky of the lower triangle of A (row major, n <= kNU), then solve into b.
bool solve_spd(int n, double* A, double* b) {
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
double s = A[i * n + j];
for (int k = 0; k < j; k++) s -= A[i * n + k] * A[j * n + k];
if (i == j) {
if (!(s > 0.0)) return false;
A[i * n + i] = std::sqrt(s);
} else {
A[i * n + j] = s / A[j * n + j];
}
}
}
for (int i = 0; i < n; i++) {
double s = b[i];
for (int k = 0; k < i; k++) s -= A[i * n + k] * b[k];
b[i] = s / A[i * n + i];
}
for (int i = n - 1; i >= 0; i--) {
double s = b[i];
for (int k = i + 1; k < n; k++) s -= A[k * n + i] * b[k];
b[i] = s / A[i * n + i];
}
return true;
}
// Undistorted-then-distorted normalized point of `m` at sample `p`.
void distorted(const Model& m, const Sample& p, double* dx, double* dy) {
double x = p.u, y = p.v;
for (int j = 0; j < kNC; j++) {
x += m.c[j] * p.gx[j];
y += m.c[j] * p.gy[j];
}
*dx = x;
*dy = y;
}
double cost(const std::vector<Sample>& s, const Model& m) {
double f = 0.0;
for (const Sample& p : s) {
double dx, dy;
distorted(m, p, &dx, &dy);
double ru = m.fx * dx + m.cx - p.us;
double rv = m.fy * dy + m.cy - p.vs;
f += p.w * (ru * ru + rv * rv);
}
return f;
}
// Levenberg-Marquardt on the weighted least squares. Unknown order:
// c[0..7], then fx, cx, fy, cy; `act` lists the ones that may move, so a
// masked-off coefficient keeps whatever it was initialized to (zero).
void optimize(const std::vector<Sample>& s, Model& m,
const std::vector<int>& act) {
const int nu = (int)act.size();
if (nu == 0) return;
double lambda = 1e-6;
double f0 = cost(s, m);
for (int it = 0; it < 200 && lambda < 1e14; it++) {
double jtj[kNU * kNU] = {}, jtr[kNU] = {};
for (const Sample& p : s) {
double dx, dy;
distorted(m, p, &dx, &dy);
double ru = m.fx * dx + m.cx - p.us;
double rv = m.fy * dy + m.cy - p.vs;
double ju[kNU] = {}, jv[kNU] = {};
for (int j = 0; j < kNC; j++) {
ju[j] = m.fx * p.gx[j];
jv[j] = m.fy * p.gy[j];
}
ju[8] = dx; ju[9] = 1.0;
jv[10] = dy; jv[11] = 1.0;
for (int i = 0; i < nu; i++) {
const int ai = act[i];
jtr[i] += p.w * (ju[ai] * ru + jv[ai] * rv);
for (int j = 0; j <= i; j++) {
const int aj = act[j];
jtj[i * nu + j] += p.w * (ju[ai] * ju[aj] + jv[ai] * jv[aj]);
}
}
}
bool stepped = false;
for (int attempt = 0; attempt < 24 && !stepped && lambda < 1e14; attempt++) {
double A[kNU * kNU], b[kNU];
std::copy(jtj, jtj + nu * nu, A);
for (int i = 0; i < nu; i++) {
// Marquardt scaling: fx ~ 1e3 and k1 ~ 1e-1 in one system.
A[i * nu + i] += lambda * std::max(jtj[i * nu + i], 1e-300);
b[i] = -jtr[i];
}
if (!solve_spd(nu, A, b)) { lambda *= 10.0; continue; }
Model t = m;
for (int i = 0; i < nu; i++) {
switch (act[i]) {
case 8: t.fx += b[i]; break;
case 9: t.cx += b[i]; break;
case 10: t.fy += b[i]; break;
case 11: t.cy += b[i]; break;
default: t.c[act[i]] += b[i]; break;
}
}
double f1 = cost(s, t);
if (f1 < f0) {
bool done = f0 - f1 <= 1e-14 * f0;
m = t;
f0 = f1;
lambda = std::max(lambda * 0.1, 1e-12);
stepped = true;
if (done) return;
} else {
lambda *= 10.0;
}
}
if (!stepped) return;
}
}
void solve_intrinsics(const std::vector<Sample>& s, Model& m) {
double sw = 0.0;
double sxx = 0.0, sx = 0.0, sxu = 0.0, su = 0.0;
double syy = 0.0, sy = 0.0, syv = 0.0, sv = 0.0;
for (const Sample& p : s) {
double dx, dy;
distorted(m, p, &dx, &dy);
sw += p.w;
sxx += p.w * dx * dx; sx += p.w * dx; sxu += p.w * dx * p.us; su += p.w * p.us;
syy += p.w * dy * dy; sy += p.w * dy; syv += p.w * dy * p.vs; sv += p.w * p.vs;
}
double dx_det = sxx * sw - sx * sx;
if (std::fabs(dx_det) > 1e-30 * (sxx * sw + 1.0)) {
m.fx = (sxu * sw - sx * su) / dx_det;
m.cx = (sxx * su - sx * sxu) / dx_det;
}
double dy_det = syy * sw - sy * sy;
if (std::fabs(dy_det) > 1e-30 * (syy * sw + 1.0)) {
m.fy = (syv * sw - sy * sv) / dy_det;
m.cy = (syy * sv - sy * syv) / dy_det;
}
}
void errors(const std::vector<Sample>& s, const Model& m,
std::vector<double>* e, double* rms, double* mx) {
if (e) e->resize(s.size());
double sum2 = 0.0, worst = 0.0;
for (size_t i = 0; i < s.size(); i++) {
const Sample& p = s[i];
double dx, dy;
distorted(m, p, &dx, &dy);
double ru = m.fx * dx + m.cx - p.us;
double rv = m.fy * dy + m.cy - p.vs;
double d = std::sqrt(ru * ru + rv * rv);
if (e) (*e)[i] = d;
sum2 += ru * ru + rv * rv;
worst = std::max(worst, d);
}
*rms = s.empty() ? 0.0 : std::sqrt(sum2 / (double)s.size());
*mx = worst;
}
// The source's valid domain as theta_max per azimuth: star-shaped about the
// target axis, which every lens model satisfies on its FIRST branch. Only the
// first branch counts -- EUCM and the unified models fold back and re-enter the
// image mirrored, and fitting both branches at once is meaningless.
struct Domain {
static constexpr int kAz = 128;
double theta[kAz] = {};
double limit(double phi) const {
double t = phi * (kAz / (2.0 * kPi));
t -= std::floor(t / kAz) * kAz;
int i = (int)t;
double f = t - i;
return theta[i % kAz] * (1.0 - f) + theta[(i + 1) % kAz] * f;
}
};
void scan_domain(const SourceProject& src, double w, double h, double cap,
Domain* dom) {
// Where the optical axis lands, so "outward" can be measured.
double cu = 0.5 * w, cv = 0.5 * h;
src(0.0, 0.0, 1.0, &cu, &cv);
for (int a = 0; a < Domain::kAz; a++) {
double phi = 2.0 * kPi * a / Domain::kAz;
const double cp = std::cos(phi), sp = std::sin(phi);
auto radius = [&](double th, double* r) {
double st = std::sin(th), ct = std::cos(th), u, v;
if (!src(st * cp, st * sp, ct, &u, &v)) return false;
if (!(u >= 0.0 && u <= w && v >= 0.0 && v <= h)) return false;
*r = std::hypot(u - cu, v - cv);
return true;
};
// The domain ends where the source leaves the image AND where its
// image radius stops growing fast enough. Without the second test a
// model that folds back INSIDE the frame -- r_d peaks and comes back,
// which the division and unified models do -- is fitted across the
// fold, and fitting a two-to-one map is meaningless.
//
// "Fast enough" is is_valid_distortion's Jdet > 0.25 read in
// theta-space: the derivative is zero AT the fold, so any coefficient
// error flips its sign and the ladder discards coefficients the source
// needs. The kernels drop those pixels either way.
const double back = cap * 1e-3;
double r_ax = 0.0;
const bool have_ax = radius(back, &r_ax); // radius(0) is 0 by
const double min_growth = 0.25 * r_ax; // construction
auto inside = [&](double th) {
double r1, r0;
if (!radius(th, &r1)) return false;
if (th <= back) return true;
if (!radius(th - back, &r0)) return false;
return have_ax ? (r1 - r0 > min_growth) : (r1 > r0);
};
const int kSteps = 48;
double lo = -1.0, hi = -1.0;
for (int i = 0; i <= kSteps; i++) {
double th = cap * i / kSteps;
if (inside(th)) lo = th;
else if (lo >= 0.0) { hi = th; break; }
}
if (lo >= 0.0 && hi >= 0.0) {
for (int i = 0; i < 40; i++) {
double mid = 0.5 * (lo + hi);
if (inside(mid)) lo = mid; else hi = mid;
}
}
dom->theta[a] = std::max(lo, 0.0);
}
}
double domain_max(const Domain& d) {
double m = 0.0;
for (double t : d.theta) m = std::max(m, t);
return m;
}
std::vector<Sample> build_samples(const SourceProject& src, CameraModelType m,
double w, double h, const double box[4],
const Domain& dom, int n, bool chebyshev) {
std::vector<double> xs(n), ys(n);
for (int i = 0; i < n; i++) {
double t = chebyshev ? std::cos(kPi * (2 * i + 1) / (2.0 * n))
: (n == 1 ? 0.0 : -1.0 + 2.0 * i / (n - 1));
xs[i] = 0.5 * (box[0] + box[1]) + 0.5 * (box[1] - box[0]) * t;
ys[i] = 0.5 * (box[2] + box[3]) + 0.5 * (box[3] - box[2]) * t;
}
std::vector<Sample> out;
out.reserve((size_t)n * n);
for (int j = 0; j < n; j++) {
for (int i = 0; i < n; i++) {
Sample p;
p.u = xs[i];
p.v = ys[j];
double d[3], us, vs;
if (!unproject(m, p.u, p.v, d)) continue;
double th = std::atan2(std::sqrt(d[0] * d[0] + d[1] * d[1]), d[2]);
if (th > dom.limit(std::atan2(p.v, p.u))) continue;
if (!src(d[0], d[1], d[2], &us, &vs)) continue;
if (!(us >= 0.0 && us <= w && vs >= 0.0 && vs <= h)) continue;
p.us = us;
p.vs = vs;
distort_basis(p.u, p.v, p.gx, p.gy);
out.push_back(p);
}
}
return out;
}
// The rim of the valid domain falls between grid nodes, and a near-minimax
// residual peaks there, so the reported max is only honest with it sampled.
void append_rim(const SourceProject& src, CameraModelType m, double w, double h,
const Domain& dom, std::vector<Sample>* out) {
const int kN = 4 * Domain::kAz;
for (int a = 0; a < kN; a++) {
double phi = 2.0 * kPi * a / kN;
double rho = rho_of_theta(m, dom.limit(phi) * 0.999);
Sample p;
p.u = rho * std::cos(phi);
p.v = rho * std::sin(phi);
double d[3], us, vs;
if (!unproject(m, p.u, p.v, d)) continue;
if (!src(d[0], d[1], d[2], &us, &vs)) continue;
if (!(us >= 0.0 && us <= w && vs >= 0.0 && vs <= h)) continue;
p.us = us;
p.vs = vs;
distort_basis(p.u, p.v, p.gx, p.gy);
out->push_back(p);
}
}
// Coefficient sets tried in turn until the fitted distortion is invertible:
// everything, then no thin prism, then no k3/k4, then radial only, then k1
// alone, then none. Each rung is a subset of the one above it.
constexpr unsigned kCoeffLadder[] = {0xFFu, 0x3Fu, 0x33u, 0x03u, 0x01u, 0x00u};
std::vector<int> active_unknowns(unsigned mask, bool refine) {
std::vector<int> act;
for (int j = 0; j < kNC; j++)
if (mask & (1u << j)) act.push_back(j);
if (refine) { act.push_back(8); act.push_back(9); act.push_back(10); act.push_back(11); }
return act;
}
// One (model, coefficient mask) attempt over an already-scanned domain.
FitResult fit_one(const SourceProject& src, double w, double h,
CameraModelType model, const FitOptions& opt, unsigned mask,
const Domain& dom) {
FitResult res;
res.target.model = model;
res.target.distortion = CameraDistortionType::ThinPrism;
double box[4] = {0.0, 0.0, 0.0, 0.0}; // xmin xmax ymin ymax
for (int a = 0; a < Domain::kAz; a++) {
double phi = 2.0 * kPi * a / Domain::kAz;
double rho = rho_of_theta(model, dom.theta[a]);
double x = rho * std::cos(phi), y = rho * std::sin(phi);
box[0] = std::min(box[0], x); box[1] = std::max(box[1], x);
box[2] = std::min(box[2], y); box[3] = std::max(box[3], y);
}
if (!(box[1] > box[0]) || !(box[3] > box[2]))
return res;
const int n = std::min(512, std::max(8, opt.grid));
std::vector<Sample> fit = build_samples(src, model, w, h, box, dom, n, true);
if ((int)fit.size() < 4 * kNC)
return res;
Model m;
solve_intrinsics(fit, m);
if (!(m.fx > 0.0) || !(m.fy > 0.0))
return res;
const std::vector<int> act = active_unknowns(mask, opt.refine_intrinsics);
Model best = m;
double best_max = 1e300;
std::vector<double> e;
const int lawson = std::max(0, opt.lawson_iters);
for (int round = 0; round <= lawson; round++) {
optimize(fit, m, act);
double rms, mx;
errors(fit, m, &e, &rms, &mx);
if (mx < best_max) { best_max = mx; best = m; }
if (round == lawson) break;
// Lawson: reweight by residual, floored so a node cannot be retired for
// good, then renormalized to keep the ridge scale meaningful.
double floor_e = 1e-3 * mx, sum = 0.0;
for (size_t i = 0; i < fit.size(); i++) {
fit[i].w *= e[i] + floor_e;
sum += fit[i].w;
}
if (!(sum > 0.0)) break;
double scale = (double)fit.size() / sum;
for (Sample& p : fit) p.w *= scale;
}
std::vector<Sample> check = build_samples(src, model, w, h, box, dom,
std::min(1024, 2 * n + 1), false);
append_rim(src, model, w, h, dom, &check);
if (check.empty()) check = fit;
double rms = 0.0, mx = 0.0;
errors(check, best, nullptr, &rms, &mx);
bool invertible = true;
for (const Sample& p : check)
invertible = invertible && distortion_invertible(p.u, p.v, best.c);
res.target.fx = (float)best.fx;
res.target.fy = (float)best.fy;
res.target.cx = (float)best.cx;
res.target.cy = (float)best.cy;
for (int j = 0; j < kNC; j++) res.target.coeffs[j] = (float)best.c[j];
res.rms_px = rms;
res.max_px = mx;
res.samples = (int)check.size();
res.invertible = invertible;
res.ok = invertible && rms <= opt.max_rms_px;
return res;
}
// Walk the ladder until the distortion is invertible, keeping the best rung
// reached. `wide` is the domain scanned at the widest cap; it is narrowed to
// what `model` can address.
FitResult fit_model(const SourceProject& src, double w, double h,
CameraModelType model, const FitOptions& opt,
const Domain& wide) {
FitResult res;
res.target.model = model;
res.target.distortion = CameraDistortionType::ThinPrism;
if (!camera_distortion_is_compiled(model, CameraDistortionType::ThinPrism))
return res;
Domain dom = wide;
const double cap = theta_cap(model);
for (int a = 0; a < Domain::kAz; a++) dom.theta[a] = std::min(dom.theta[a], cap);
unsigned prev = ~0u;
for (unsigned rung : kCoeffLadder) {
unsigned mask = rung & opt.coeff_mask;
if (mask == prev) continue;
prev = mask;
FitResult r = fit_one(src, w, h, model, opt, mask, dom);
// A rung that failed to solve at all says nothing about the next one.
if (r.samples > 0 && (r.invertible || res.samples == 0)) res = r;
if (r.invertible) break;
}
return res;
}
} // namespace
FitResult fit_camera(const SourceProject& src, int width, int height,
CameraModelType target_model, const FitOptions& opt) {
FitResult res;
res.target.model = target_model;
res.target.distortion = CameraDistortionType::ThinPrism;
if (!src || width <= 0 || height <= 0)
return res;
const double w = (double)width, h = (double)height;
Domain dom;
scan_domain(src, w, h, theta_cap(target_model), &dom);
res = fit_model(src, w, h, target_model, opt, dom);
res.fov_deg = 2.0 * domain_max(dom) * 180.0 / kPi;
return res;
}
FitResult fit_camera_auto(const SourceProject& src, int width, int height,
const FitOptions& opt) {
FitResult res;
res.target.distortion = CameraDistortionType::ThinPrism;
if (!src || width <= 0 || height <= 0)
return res;
const double w = (double)width, h = (double)height;
Domain dom;
scan_domain(src, w, h, kWidestTheta, &dom);
const double half_fov = domain_max(dom);
res.fov_deg = 2.0 * half_fov * 180.0 / kPi;
// Preference order, widest usable model last. A perspective target keeps
// the straight lines straight but its tan() blows the polynomial up past
// ~60 degrees, and equisolid only earns its keep on a true ultra-wide.
CameraModelType cands[3];
int nc = 0;
if (half_fov < 60.0 * kPi / 180.0) cands[nc++] = CameraModelType::PINHOLE;
cands[nc++] = CameraModelType::FISHEYE;
if (half_fov > 70.0 * kPi / 180.0) cands[nc++] = CameraModelType::EQUISOLID;
// Sub-tenth-of-a-pixel is below what bilinear resampling can resolve, so
// the first candidate that reaches it wins outright. Past that, a later
// candidate has to be clearly better to displace the preferred one --
// swapping a perspective camera for a fisheye to shave 10% off the
// residual is not worth the change of character.
constexpr double kGoodPx = 0.1;
bool have = false;
for (int i = 0; i < nc; i++) {
FitResult r = fit_model(src, w, h, cands[i], opt, dom);
if (r.samples == 0) continue;
bool better = !have || (r.invertible && !res.invertible) ||
(r.invertible == res.invertible &&
r.max_px < 0.5 * res.max_px);
if (better) {
double fov = res.fov_deg;
res = r;
res.fov_deg = fov;
have = true;
}
if (r.invertible && r.max_px <= kGoodPx) break;
}
if (have)
return res;
// Nothing projected. Rather than fail the load, hand back a plain fisheye
// spanning the image; the caller warns and the dataset still opens.
res.target.model = CameraModelType::FISHEYE;
res.target.distortion = CameraDistortionType::None;
res.target.fx = res.target.fy = (float)(0.5 * std::max(w, h));
res.target.cx = (float)(0.5 * w);
res.target.cy = (float)(0.5 * h);
for (int j = 0; j < kNC; j++) res.target.coeffs[j] = 0.0f;
res.invertible = true;
res.ok = false;
return res;
}
} // namespace dsfit
// Self-check against two lens models no tier represents exactly, at 1600x1200:
// g++ -std=c++17 -I src -DDSFIT_SELFTEST src/data/DistortionFit.cpp -o /tmp/dfit
#ifdef DSFIT_SELFTEST
#include <cstdio>
int main() {
auto run = [](const char* name, const dsfit::SourceProject& s, CameraModelType m) {
dsfit::FitResult r = dsfit::fit_camera(s, 1600, 1200, m);
std::printf("%-22s -> %-9s rms %.3e px max %.3e px n %d inv %d ok %d\n",
name, camera_model_to_string(m), r.rms_px, r.max_px,
r.samples, (int)r.invertible, (int)r.ok);
std::printf(" f %.3f %.3f c %.3f %.3f k %.5g %.5g %.5g %.5g"
" p %.5g %.5g s %.5g %.5g\n",
r.target.fx, r.target.fy, r.target.cx, r.target.cy,
r.target.coeffs[0], r.target.coeffs[1], r.target.coeffs[2],
r.target.coeffs[3], r.target.coeffs[4], r.target.coeffs[5],
r.target.coeffs[6], r.target.coeffs[7]);
};
// COLMAP FOV: r_d = atan(2 r tan(omega/2)) / omega on the pinhole plane.
const double omega = 0.9;
dsfit::SourceProject fov = [&](double x, double y, double z, double* u, double* v) {
if (z <= 1e-9) return false;
double a = x / z, b = y / z, r = std::sqrt(a * a + b * b);
double f = r < 1e-9 ? 1.0
: std::atan(2.0 * r * std::tan(0.5 * omega)) / (r * omega);
*u = 1000.0 * a * f + 800.0;
*v = 1000.0 * b * f + 600.0;
return true;
};
run("COLMAP FOV w=0.9", fov, CameraModelType::PINHOLE);
run("COLMAP FOV w=0.9", fov, CameraModelType::FISHEYE);
// EUCM: d = sqrt(beta*(x^2+y^2) + z^2), denom = alpha*d + (1-alpha)*z.
// Deliberately unguarded past its fold-back angle; Domain must find it.
const double alpha = 0.6, beta = 1.1;
dsfit::SourceProject eucm = [&](double x, double y, double z, double* u, double* v) {
double d = std::sqrt(beta * (x * x + y * y) + z * z);
double den = alpha * d + (1.0 - alpha) * z;
if (den <= 1e-9) return false;
*u = 600.0 * x / den + 800.0;
*v = 600.0 * y / den + 600.0;
return true;
};
run("EUCM a=0.6 b=1.1", eucm, CameraModelType::FISHEYE);
run("EUCM a=0.6 b=1.1", eucm, CameraModelType::EQUISOLID);
run("EUCM a=0.6 b=1.1", eucm, CameraModelType::PINHOLE);
return 0;
}
#endif
+76
View File
@@ -0,0 +1,76 @@
#pragma once
// Fit an arbitrary source camera onto a compiled (CameraModelType,
// CameraDistortionType) pair on the CPU.
//
// Used when a dataset carries a lens model no tier represents exactly (COLMAP
// FOV, Metashape affinity/skew, EUCM/UCM, ...). The fit is in PIXELS against
// the source's own pixel map over its whole valid domain, so the fitted camera
// keeps the source image size and the same solid angle -- no inscribed-rectangle
// crop. `fit_camera` is pure; cache the result per camera group.
#include "core/CameraModel.h"
#include <functional>
namespace dsfit {
// A fit closer than this reproduces the source camera to better than bilinear
// resampling can resolve, so a parser that reaches it can keep the images as
// they are instead of re-distorting them.
constexpr double kExactFitPx = 0.1;
// Forward map of the SOURCE camera: a view-space direction (need not be
// normalized) -> pixel. false where the source has no image: behind the camera,
// or outside its valid domain.
using SourceProject = std::function<bool(double x, double y, double z,
double* u, double* v)>;
struct FitTarget {
CameraModelType model = CameraModelType::PINHOLE;
CameraDistortionType distortion = CameraDistortionType::ThinPrism;
float fx = 0.0f, fy = 0.0f, cx = 0.0f, cy = 0.0f;
float coeffs[kCameraDistortionParams] = {};
};
struct FitOptions {
int grid = 64; // Chebyshev nodes per axis
bool refine_intrinsics = true; // false: fx/fy/cx/cy from the undistorted fit only
double max_rms_px = 0.5; // decides FitResult::ok, nothing else
int lawson_iters = 8; // 0 = plain Chebyshev-weighted least squares
// Which of the 8 ThinPrism slots the fit may use, low bit = k1, in the
// order k1 k2 k3 k4 p1 p2 sx1 sy1. Retrying with the high-order terms
// masked off is how a non-invertible fit is recovered.
unsigned coeff_mask = 0xFFu;
};
struct FitResult {
FitTarget target;
// Measured on an independent uniform grid twice as dense as the fit grid,
// not on the nodes the fit optimized.
double rms_px = 0.0;
double max_px = 0.0; // the near-minimax objective
int samples = 0;
double fov_deg = 0.0; // full angle the source images, 2x the largest theta
bool invertible = true; // fitted distortion passes is_valid_distortion everywhere sampled
bool ok = false; // solved, invertible, and rms_px <= max_rms_px
};
// Fit `target_model` + ThinPrism coefficients to `src` over a `width` x `height`
// image. Returns ok == false for EQUIRECTANGULAR (carries no distortion) and
// when the source has no image around the axis.
FitResult fit_camera(const SourceProject& src, int width, int height,
CameraModelType target_model,
const FitOptions& opt = FitOptions());
// Same, choosing the camera model from the source's measured field of view and
// degrading the coefficient set until the distortion is invertible.
//
// Always returns a camera the engine can train with -- a dataset that took
// hours to reconstruct must not fail to load over a lens model. Read `max_px`
// for how faithful the choice is; `ok` is false only when the source projects
// nothing at all, and even then the target is a usable (if arbitrary) camera.
FitResult fit_camera_auto(const SourceProject& src, int width, int height,
const FitOptions& opt = FitOptions());
} // namespace dsfit
+185
View File
@@ -0,0 +1,185 @@
#include "data/SourceCamera.h"
#include <cmath>
// Transcribed from colmap/src/colmap/sensor/models.h (FOVCameraModel,
// SimpleDivisionCameraModel, DivisionCameraModel, EUCMCameraModel,
// RadTanThinPrismFisheyeModel::Distortion) and, for kSkewed, from
// shaders/camera_source.slang. Only the forward direction is needed: the
// fitter samples it and the re-distort kernel re-evaluates it.
namespace srccam {
namespace {
bool project_fov(const float* prm, double X, double Y, double Z,
double* u, double* v) {
if (Z < 1e-12) return false;
double x = X / Z, y = Y / Z, omega = prm[4];
double r2 = x*x + y*y, om2 = omega * omega;
constexpr double kEps = 1e-4;
double factor;
if (om2 < kEps) {
factor = (om2 * r2) / 3.0 - om2 / 12.0 + 1.0;
} else if (r2 < kEps) {
double t = std::tan(omega / 2.0);
factor = (-2.0 * t * (4.0 * r2 * t * t - 3.0)) / (3.0 * omega);
} else {
double r = std::sqrt(r2);
factor = std::atan(r * 2.0 * std::tan(omega / 2.0)) / (r * omega);
}
*u = prm[0] * x * factor + prm[2];
*v = prm[1] * y * factor + prm[3];
return true;
}
bool project_division(const float* prm, bool simple, double X, double Y, double Z,
double* u, double* v) {
double fx = prm[0], fy = simple ? prm[0] : prm[1];
double cx = simple ? prm[1] : prm[2], cy = simple ? prm[2] : prm[3];
double k = simple ? prm[3] : prm[4];
double rho2 = X*X + Y*Y;
double disc = Z*Z - 4.0 * rho2 * k;
if (disc < 0.0) return false;
double r = 2.0 / (Z + std::sqrt(disc));
*u = fx * r * X + cx;
*v = fy * r * Y + cy;
return true;
}
bool project_eucm(const float* prm, double X, double Y, double Z,
double* u, double* v) {
if (Z < 1e-12) return false;
double alpha = prm[4], beta = prm[5];
double rho2 = beta * (X*X + Y*Y) + Z*Z;
if (rho2 < 0.0) return false;
double den = alpha * std::sqrt(rho2) + (1.0 - alpha) * Z;
if (den < 1e-12) return false;
*u = prm[0] * X / den + prm[2];
*v = prm[1] * Y / den + prm[3];
return true;
}
// Aria Fisheye624. Unlike THIN_PRISM_FISHEYE, the tangential and thin-prism
// terms act on the ALREADY radially distorted point.
bool project_rad_tan_thin_prism(const float* prm, double X, double Y, double Z,
double* u, double* v) {
if (Z < 1e-12) return false;
double xn = X / Z, yn = Y / Z;
double r = std::sqrt(xn*xn + yn*yn);
double uu = xn, vv = yn;
if (r > 1e-12) {
double th = std::atan(r);
uu *= th / r; vv *= th / r;
}
double th2 = uu*uu + vv*vv, pw = 1.0, rad = 1.0;
for (int i = 0; i < 6; i++) { pw *= th2; rad += prm[4 + i] * pw; }
double x = rad * uu, y = rad * vv;
double p0 = prm[10], p1 = prm[11];
double s0 = prm[12], s1 = prm[13], s2 = prm[14], s3 = prm[15];
double x2 = x*x, y2 = y*y, xy = x*y, r2 = x2 + y2, r4 = r2*r2;
double xd = x + 2.0*p1*xy + p0*(r2 + 2.0*x2) + s0*r2 + s1*r4;
double yd = y + 2.0*p0*xy + p1*(r2 + 2.0*y2) + s2*r2 + s3*r4;
*u = prm[0] * xd + prm[2];
*v = prm[1] * yd + prm[3];
return true;
}
bool project_skewed(const float* p, double X, double Y, double Z,
double* u, double* v) {
double qx, qy;
const int base = (int)p[13];
if (base == (int)kSkewBasePerspective) {
if (Z < 1e-12) return false;
qx = X / Z; qy = Y / Z;
} else {
double r = std::sqrt(X*X + Y*Y);
double theta = std::atan2(r, Z), k;
if (base == (int)kSkewBaseFisheye)
k = theta < 1e-3 ? (1.0 - theta*theta/3.0) / Z : theta / r;
else
k = r < 1e-6 ? (1.0 - theta*theta/24.0) / Z
: (2.0 * std::sin(0.5 * theta)) / r;
qx = X * k; qy = Y * k;
}
double r2 = qx*qx + qy*qy, dx, dy;
if (p[14] != 0.0f) {
double radial = (1.0 + r2*(p[5] + r2*(p[6] + r2*p[7])))
/ (1.0 + r2*(p[8] + r2*(p[9] + r2*p[10])));
dx = qx * radial + 2.0*p[11]*qx*qy + p[12]*(r2 + 2.0*qx*qx);
dy = qy * radial + 2.0*p[12]*qx*qy + p[11]*(r2 + 2.0*qy*qy);
} else {
double radial = 1.0 + r2*(p[5] + r2*(p[6] + r2*(p[7] + r2*p[8])));
dx = qx * radial + 2.0*p[9]*qx*qy + p[10]*(r2 + 2.0*qx*qx) + p[11]*r2;
dy = qy * radial + 2.0*p[10]*qx*qy + p[9]*(r2 + 2.0*qy*qy) + p[12]*r2;
}
*u = p[0] * dx + p[4] * dy + p[2];
*v = p[1] * dy + p[3];
return true;
}
// The model's own formula, with no check that it still describes a lens.
bool project_raw(int model_id, const float* params,
double X, double Y, double Z, double* u, double* v) {
switch (model_id) {
case kSkewed:
return project_skewed(params, X, Y, Z, u, v);
case kColmapFOV:
return project_fov(params, X, Y, Z, u, v);
case kColmapSimpleDivision:
return project_division(params, true, X, Y, Z, u, v);
case kColmapDivision:
return project_division(params, false, X, Y, Z, u, v);
case kColmapEUCM:
return project_eucm(params, X, Y, Z, u, v);
case kColmapRadTanThinPrismFisheye:
return project_rad_tan_thin_prism(params, X, Y, Z, u, v);
default:
return false;
}
}
// source_unfolded mirror; camera_source.slang has the why.
bool unfolded(int model_id, const float* params, double X, double Y, double Z,
double u, double v) {
double l = std::sqrt(X*X + Y*Y + Z*Z);
if (!(l > 0.0)) return false;
double n[3] = {X / l, Y / l, Z / l};
double t[3] = {1.0, 0.0, 0.0};
if (!(std::abs(n[0]) < 0.9)) { t[0] = 0.0; t[1] = 1.0; }
double e1[3] = {t[1]*n[2] - t[2]*n[1], t[2]*n[0] - t[0]*n[2],
t[0]*n[1] - t[1]*n[0]};
double e1l = std::sqrt(e1[0]*e1[0] + e1[1]*e1[1] + e1[2]*e1[2]);
for (double& c : e1) c /= e1l;
double e2[3] = {n[1]*e1[2] - n[2]*e1[1], n[2]*e1[0] - n[0]*e1[2],
n[0]*e1[1] - n[1]*e1[0]};
constexpr double kStep = 1e-3; // radians
double au, av, bu, bv;
if (!project_raw(model_id, params, n[0] + kStep*e1[0], n[1] + kStep*e1[1],
n[2] + kStep*e1[2], &au, &av)) return false;
if (!project_raw(model_id, params, n[0] + kStep*e2[0], n[1] + kStep*e2[1],
n[2] + kStep*e2[2], &bu, &bv)) return false;
return (au - u) * (bv - v) - (av - v) * (bu - u) > 0.0;
}
} // namespace
void rescale(int model_id, float* params, double s) {
if (!(s > 0.0) || s == 1.0) return;
// Everything else is on the normalized plane and scale-free: FOV's omega,
// the division models' k, EUCM's alpha/beta, the radial and tangential
// coefficients. SIMPLE_DIVISION is the one model with a single focal
// length, which shifts its principal point down a slot.
int n = 4;
if (model_id == kColmapSimpleDivision) n = 3;
if (model_id == kSkewed) n = 5; // ... plus the skew
for (int i = 0; i < n; i++) params[i] = (float)(params[i] / s);
}
bool project(int model_id, const float* params,
double X, double Y, double Z, double* u, double* v) {
return project_raw(model_id, params, X, Y, Z, u, v) &&
unfolded(model_id, params, X, Y, Z, *u, *v);
}
} // namespace srccam
+48
View File
@@ -0,0 +1,48 @@
#pragma once
// Forward projection of the camera models no (CameraModelType,
// CameraDistortionType) pair represents, on the CPU.
//
// Host mirror of shaders/camera_source.slang. The fitter measures against this
// one and the re-distort kernel resamples through that one, so the two must
// agree exactly or the images land in a different camera than the one fitted.
namespace srccam {
// Model ids. 0..17 are COLMAP's own CameraModelId values (models.h), and their
// parameters are COLMAP's array verbatim. Ours are numbered from 1000, leaving
// COLMAP room to keep appending to its enum.
constexpr int kColmapFOV = 7;
constexpr int kColmapRadTanThinPrismFisheye = 11;
constexpr int kColmapSimpleDivision = 12;
constexpr int kColmapDivision = 13;
constexpr int kColmapEUCM = 16;
// Any supported camera plus a sensor skew, which no tier carries: Agisoft
// Metashape's b2. Parameter layout in camera_source.slang.
constexpr int kSkewed = 1000;
// kSkewed's base camera, params[13].
constexpr float kSkewBasePerspective = 0.0f;
constexpr float kSkewBaseFisheye = 1.0f;
constexpr float kSkewBaseEquisolid = 2.0f;
// kSkewed's radial form, params[14].
constexpr float kSkewRadialPolynomial = 0.0f; // DistThinPrism slot order
constexpr float kSkewRadialRational = 1.0f; // DistRational slot order
constexpr int kMaxParams = 16;
// View-space direction (need not be normalized) -> source pixel. false where
// the source camera has no image for that direction, including past the angle
// where the model folds back over itself.
bool project(int model_id, const float* params,
double X, double Y, double Z, double* u, double* v);
// Divide the pixel-valued parameters by `s`, for a parser that downscales the
// camera it fitted. The re-distort kernels take the source parameters in the
// same pixel space as the fitted intrinsics, so the two must be scaled
// together; which entries are pixels differs per model.
void rescale(int model_id, float* params, double s);
} // namespace srccam
+227 -53
View File
@@ -7,6 +7,8 @@
#include "data/FastFloat.h"
#include "core/CameraModel.h" // camera_model_from_name (CUDA-free)
#include "data/DistortionFit.h"
#include "data/SourceCamera.h"
#include <algorithm>
#include <cctype>
@@ -90,6 +92,12 @@ const std::map<int, ColmapModelInfo>& colmap_model_table() {
return t;
}
int colmap_model_id(const std::string& name) {
for (const auto& [id, info] : colmap_model_table())
if (name == info.name) return id;
return -1;
}
} // namespace
@@ -270,77 +278,223 @@ ColmapPoints3D read_points3D_text(const std::string& recon_dir) {
// ===========================================================================
// Camera-param normalization + engine dist_coeffs layout
// (k1 k2 k3 k4 p1 p2 sx1 sy1 b1 b2).
// COLMAP camera model -> (CameraModelType, CameraDistortionType, coefficients)
//
// Every one of COLMAP's 18 models is accepted. Fourteen map exactly onto a
// tier; the remaining four (FOV, SIMPLE_DIVISION, DIVISION, EUCM) and
// RAD_TAN_THIN_PRISM_FISHEYE have no exact representation and are fitted, with
// the source model recorded so the images can be re-distorted to match.
//
// COLMAP's parameter ORDER is not ours: it interleaves p1,p2 between k2 and k3
// (models.h FullOpenCVCameraModel / ThinPrismFisheyeCameraModel), and its
// FULL_OPENCV k4..k6 are DENOMINATOR terms, not further radial terms.
// ===========================================================================
namespace {
struct BakedIntrins {
float fx, fy, cx, cy;
std::array<float, 10> dist{}; // k1 k2 k3 k4 p1 p2 sx1 sy1 b1 b2
std::string model_name; // nerfstudio-normalized: OPENCV / OPENCV_FISHEYE / ...
CameraModelType model = CameraModelType::PINHOLE;
CameraDistortionType distortion = CameraDistortionType::None;
std::array<float, kCameraDistortionParams> dist{};
RedistortSource source; // source_model < 0 unless fitted
};
BakedIntrins bake_colmap_intrins(const ColmapCamera& cam) {
const auto& p = cam.params;
auto P = [&](size_t i) { return (float)p[i]; };
auto need = [&](size_t n) {
if (p.size() < n)
throw std::runtime_error(
"ColmapParser: camera model " + cam.model + " needs " +
std::to_string(n) + " parameters, got " +
std::to_string(p.size()));
};
BakedIntrins o;
if (cam.model == "SIMPLE_PINHOLE" || cam.model == "SIMPLE_RADIAL" ||
cam.model == "RADIAL") {
o.fx = o.fy = P(0); o.cx = P(1); o.cy = P(2);
if (cam.model != "SIMPLE_PINHOLE") o.dist[0] = P(3); // k1
if (cam.model == "RADIAL") o.dist[1] = P(4); // k2
o.model_name = "OPENCV";
// ---- one focal length, principal point, no distortion ----------------
if (cam.model == "SIMPLE_PINHOLE") {
need(3); o.fx = o.fy = P(0); o.cx = P(1); o.cy = P(2);
} else if (cam.model == "PINHOLE") {
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.model_name = "OPENCV";
} else if (cam.model == "OPENCV") {
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.dist[0] = P(4); o.dist[1] = P(5); // k1 k2
o.dist[4] = P(6); o.dist[5] = P(7); // p1 p2
o.model_name = "OPENCV";
} else if (cam.model == "FULL_OPENCV") {
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.dist[0] = P(4); o.dist[1] = P(5); // k1 k2
o.dist[4] = P(6); o.dist[5] = P(7); // p1 p2
o.dist[2] = P(8); o.dist[3] = P(9); // k3 k4
// k5/k6 have no slot in the engine's 10-coeff layout; the Python
// dataparser drops them too (DISTORTION_KEYS has no k5/k6).
o.model_name = "FULL_OPENCV";
} else if (cam.model == "OPENCV_FISHEYE" || cam.model == "THIN_PRISM_FISHEYE") {
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.dist[0] = P(4); o.dist[1] = P(5); // k1 k2
if (cam.model == "OPENCV_FISHEYE") {
o.dist[2] = P(6); o.dist[3] = P(7); // k3 k4
} else {
o.dist[4] = P(6); o.dist[5] = P(7); // p1 p2
o.dist[2] = P(8); o.dist[3] = P(9); // k3 k4
o.dist[6] = P(10); o.dist[7] = P(11); // sx1 sy1
}
o.model_name = "OPENCV_FISHEYE";
} else if (cam.model == "SIMPLE_RADIAL_FISHEYE" || cam.model == "RADIAL_FISHEYE") {
need(4); o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
} else if (cam.model == "SIMPLE_FISHEYE") {
need(3); o.fx = o.fy = P(0); o.cx = P(1); o.cy = P(2);
o.model = CameraModelType::FISHEYE;
} else if (cam.model == "FISHEYE") {
need(4); o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.model = CameraModelType::FISHEYE;
// ---- radial-only, one focal length -> OpenCV tier with zero p1,p2 ----
} else if (cam.model == "SIMPLE_RADIAL" || cam.model == "RADIAL" ||
cam.model == "SIMPLE_RADIAL_FISHEYE" || cam.model == "RADIAL_FISHEYE") {
bool two = (cam.model == "RADIAL" || cam.model == "RADIAL_FISHEYE");
need(two ? 5 : 4);
o.fx = o.fy = P(0); o.cx = P(1); o.cy = P(2);
o.dist[0] = P(3); // k1
if (cam.model == "RADIAL_FISHEYE") o.dist[1] = P(4); // k2
o.model_name = "OPENCV_FISHEYE";
} else if (cam.model == "SIMPLE_FISHEYE" || cam.model == "FISHEYE") {
if (cam.model == "SIMPLE_FISHEYE") { o.fx = o.fy = P(0); o.cx = P(1); o.cy = P(2); }
else { o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3); }
o.model_name = "OPENCV_FISHEYE";
o.distortion = CameraDistortionType::OpenCV;
o.dist[0] = P(3); // k1
if (two) o.dist[1] = P(4); // k2
if (cam.model == "SIMPLE_RADIAL_FISHEYE" || cam.model == "RADIAL_FISHEYE")
o.model = CameraModelType::FISHEYE;
// ---- fx, fy, cx, cy + k1 k2 p1 p2 ------------------------------------
} else if (cam.model == "OPENCV") {
need(8);
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.distortion = CameraDistortionType::OpenCV;
o.dist[0] = P(4); o.dist[1] = P(5); // k1 k2
o.dist[2] = P(6); o.dist[3] = P(7); // p1 p2
// ---- the rational model ----------------------------------------------
} else if (cam.model == "FULL_OPENCV") {
need(12);
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.distortion = CameraDistortionType::Rational;
o.dist[0] = P(4); o.dist[1] = P(5); // k1 k2 numerator
o.dist[2] = P(8); // k3 numerator
o.dist[3] = P(9); o.dist[4] = P(10); o.dist[5] = P(11); // k4 k5 k6 denominator
o.dist[6] = P(6); o.dist[7] = P(7); // p1 p2
// ---- fisheye radial in theta-space -----------------------------------
} else if (cam.model == "OPENCV_FISHEYE") {
need(8);
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.model = CameraModelType::FISHEYE;
o.distortion = CameraDistortionType::ThinPrism;
o.dist[0] = P(4); o.dist[1] = P(5); o.dist[2] = P(6); o.dist[3] = P(7);
} else if (cam.model == "THIN_PRISM_FISHEYE") {
need(12);
o.fx = P(0); o.fy = P(1); o.cx = P(2); o.cy = P(3);
o.model = CameraModelType::FISHEYE;
o.distortion = CameraDistortionType::ThinPrism;
o.dist[0] = P(4); o.dist[1] = P(5); // k1 k2
o.dist[2] = P(8); o.dist[3] = P(9); // k3 k4
o.dist[4] = P(6); o.dist[5] = P(7); // p1 p2
o.dist[6] = P(10); o.dist[7] = P(11); // sx1 sy1
} else if (cam.model == "EQUIRECTANGULAR") {
need(2);
o.fx = (float)(p[0] / (2.0 * kPi));
o.fy = (float)(p[1] / kPi);
o.cx = (float)(p[0] / 2.0);
o.cy = (float)(p[1] / 2.0);
o.model_name = "EQUIRECTANGULAR";
o.model = CameraModelType::EQUIRECTANGULAR;
// ---- no exact tier: fit and re-distort --------------------------------
} else {
throw std::runtime_error("ColmapParser: unsupported camera model " + cam.model);
int id = colmap_model_id(cam.model);
if (id < 0)
throw std::runtime_error("ColmapParser: unknown camera model " + cam.model);
need((size_t)colmap_model_table().at(id).num_params);
o.source.source_model = id;
for (size_t i = 0; i < p.size() && i < 16; i++)
o.source.params[i] = (float)p[i];
// Camera model, intrinsics and coefficients all come from the fit
// below. Which model suits depends on the parameters, not the name:
// a FOV lens is perspective at omega 0.3 and a full fisheye at 0.87.
return o;
}
// Drop to the cheapest tier the coefficients actually need.
o.distortion = camera_distortion_demote(o.distortion, o.dist.data(), o.dist.data());
return o;
}
// One line per distinct outcome rather than per camera record: an image
// collection run through COLMAP without --ImageReader.single_camera has one
// camera record per photo, and the same sentence a thousand times is noise.
struct FitReport {
std::string source; // COLMAP model name
CameraModelType model;
CameraDistortionType distortion;
enum { Redistorted, Exact, Failed } kind;
double max_px = 0.0; // worst in the group
int count = 0;
std::string key() const {
return source + "/" + camera_model_to_string(model) + "/" +
camera_distortion_to_string(distortion) + "/" +
std::to_string((int)kind);
}
};
// Replace an unrepresentable camera with the nearest supported one. The images
// are resampled to match later (DataManager's re-distort pass); what is chosen
// here is only the target camera.
void fit_colmap_source(const ColmapCamera& cam, BakedIntrins& bi,
std::map<std::string, FitReport>& reports) {
const RedistortSource src = bi.source;
dsfit::SourceProject project =
[&src](double x, double y, double z, double* u, double* v) {
return srccam::project(src.source_model, src.params, x, y, z, u, v);
};
dsfit::FitResult fit = dsfit::fit_camera_auto(
project, (int)cam.width, (int)cam.height);
bi.model = fit.target.model;
bi.fx = fit.target.fx; bi.fy = fit.target.fy;
bi.cx = fit.target.cx; bi.cy = fit.target.cy;
for (int i = 0; i < kCameraDistortionParams; i++)
bi.dist[i] = fit.target.coeffs[i];
bi.distortion = camera_distortion_demote(
fit.target.distortion, bi.dist.data(), bi.dist.data());
bi.source.fit_max_px = (float)fit.max_px;
FitReport r;
r.source = cam.model;
r.model = bi.model;
r.distortion = bi.distortion;
r.max_px = fit.max_px;
if (!fit.ok && fit.samples == 0) {
// Only reachable when the source projected nothing anywhere -- a
// camera record this reader cannot interpret at all. Loading a wrong
// camera beats refusing to open a reconstruction that took hours.
r.kind = FitReport::Failed;
bi.source.source_model = -1;
} else if (fit.max_px < dsfit::kExactFitPx) {
// The fitted camera and the source agree to well under what bilinear
// resampling can resolve, so re-distorting would only cost VRAM and
// blur the images.
r.kind = FitReport::Exact;
bi.source.source_model = -1;
} else {
r.kind = FitReport::Redistorted;
}
auto [it, fresh] = reports.emplace(r.key(), r);
it->second.count++;
if (!fresh) it->second.max_px = std::max(it->second.max_px, r.max_px);
}
void print_fit_reports(const std::map<std::string, FitReport>& reports) {
namespace dm = spirula::i18n::msg::data;
for (const auto& [key, r] : reports) {
(void)key;
switch (r.kind) {
case FitReport::Failed:
std::printf("%s %s\n", dm::word_warning.get(),
spirula::i18n::format(dm::camera_model_fit_failed,
{r.source, r.count,
camera_model_to_string(r.model)}).c_str());
break;
case FitReport::Exact:
std::printf("%s\n", spirula::i18n::format(
dm::camera_model_fitted_exact,
{r.source, r.count, camera_model_to_string(r.model),
camera_distortion_to_string(r.distortion),
dsfit::kExactFitPx}).c_str());
break;
case FitReport::Redistorted:
std::printf("%s\n", spirula::i18n::format(
dm::camera_model_fitted,
{r.source, r.count, camera_model_to_string(r.model),
camera_distortion_to_string(r.distortion),
r.max_px}).c_str());
break;
}
}
}
// colmap_utils.py qvec2rotmat (world->camera rotation from (w,x,y,z)).
void qvec2rotmat(const std::array<double, 4>& q, double R[3][3]) {
double w = q[0], x = q[1], y = q[2], z = q[3];
@@ -594,12 +748,30 @@ ParsedDataset parse_colmap_dataset(const std::string& dataset_dir,
ds.train_frame_scale = train_frame_scale;
for (int k = 0; k < 16; k++) ds.train_to_normalized[k] = (float)T_inv[k];
ds.camera_models.reserve(N);
ds.camera_distortions.reserve(N);
ds.image_filenames.reserve(N);
ds.widths.reserve(N);
ds.heights.reserve(N);
ds.c2w.resize(N * 12);
ds.intrins.resize(N * 4);
ds.dist_coeffs.resize(N * 10);
ds.dist_coeffs.resize(N * kCameraDistortionParams);
// One bake per COLMAP camera record, not per frame: a record is one
// physical camera, and a fitted one costs a least-squares solve.
std::map<int32_t, BakedIntrins> baked;
std::map<std::string, FitReport> fit_reports;
bool any_redistort = false;
for (const auto& [id, cam] : cameras) {
BakedIntrins bi = bake_colmap_intrins(cam);
if (bi.source.source_model >= 0) {
// May clear source_model again when the fit turned out exact.
fit_colmap_source(cam, bi, fit_reports);
any_redistort |= (bi.source.source_model >= 0);
}
baked.emplace(id, bi);
}
print_fit_reports(fit_reports);
if (any_redistort) ds.redistort.resize(N);
std::vector<std::string> mask_files(N), depth_files(N), normal_files(N);
bool any_mask = false, any_depth = false, any_normal = false;
@@ -620,11 +792,13 @@ ParsedDataset parse_colmap_dataset(const std::string& dataset_dir,
" does not exist (set --image-dir if needed)");
ds.image_filenames.push_back(img_path.string());
BakedIntrins bi = bake_colmap_intrins(cam);
BakedIntrins bi = baked.at(im.camera_id);
float W = (float)cam.width, H = (float)cam.height;
if (cfg.rescale_camera_to_fit > 0.0f) {
float s = cfg.rescale_camera_to_fit;
bi.fx /= s; bi.fy /= s; bi.cx /= s; bi.cy /= s;
if (bi.source.source_model >= 0)
srccam::rescale(bi.source.source_model, bi.source.params, s);
auto round_dim = [&](float v) {
if (cfg.downscale_rounding_mode == "ceil") return std::ceil(v / s);
if (cfg.downscale_rounding_mode == "round") return std::round(v / s);
@@ -638,12 +812,12 @@ ParsedDataset parse_colmap_dataset(const std::string& dataset_dir,
ds.intrins[j*4 + 1] = bi.fy;
ds.intrins[j*4 + 2] = bi.cx;
ds.intrins[j*4 + 3] = bi.cy;
std::copy(bi.dist.begin(), bi.dist.end(), ds.dist_coeffs.begin() + j*10);
std::copy(bi.dist.begin(), bi.dist.end(),
ds.dist_coeffs.begin() + j*kCameraDistortionParams);
CameraModelType model = camera_model_from_name(bi.model_name);
if ((int)model < 0)
throw std::runtime_error("ColmapParser: unmapped camera model " + bi.model_name);
ds.camera_models.push_back((int32_t)model);
ds.camera_models.push_back((int32_t)bi.model);
ds.camera_distortions.push_back((int32_t)bi.distortion);
if (any_redistort) ds.redistort[j] = bi.source;
std::copy(&c2w_all[i*12], &c2w_all[i*12] + 12, &ds.c2w[j*12]);
+27 -3
View File
@@ -358,11 +358,14 @@ PostSplitCameras bake_post_split(const ParsedDataset& ds,
out.viewmats.assign(n_post * 16, 0.f);
out.intrins.assign(n_post * 4, 0.f);
out.dist_coeffs.assign(n_post * 10, 0.f);
out.dist_coeffs.assign(n_post * kCameraDistortionParams, 0.f);
out.c2w_flip.assign(n_post * 12, 0.f);
out.post_widths.assign(n_post, 0);
out.post_heights.assign(n_post, 0);
out.post_models.assign(n_post, PINHOLE_V);
// Cubemap faces are canonical pinhole with zero coefficients; only a K == 1
// camera keeps the tier the parser chose.
out.post_distortions.assign(n_post, (int32_t)CameraDistortionType::None);
// POST-split c2w staging (double).
std::vector<double> post_c2w(n_post * 12);
@@ -393,8 +396,12 @@ PostSplitCameras bake_post_split(const ParsedDataset& ds,
std::copy(&ds.intrins[i*4], &ds.intrins[i*4] + 4,
&out.intrins[off*4]);
}
std::copy(&ds.dist_coeffs[i*10], &ds.dist_coeffs[i*10] + 10,
&out.dist_coeffs[off*10]);
if (ds.camera_models[i] != EQUIRECT_V) {
std::copy(&ds.dist_coeffs[i*kCameraDistortionParams],
&ds.dist_coeffs[i*kCameraDistortionParams] + kCameraDistortionParams,
&out.dist_coeffs[off*kCameraDistortionParams]);
out.post_distortions[off] = ds.camera_distortions[i];
}
continue;
}
@@ -452,9 +459,26 @@ PostSplitCameras bake_post_split(const ParsedDataset& ds,
vm[15] = 1.f;
}
// A camera whose lens model had to be fitted needs its images resampled,
// which runs on the warp path's staging even when K == 1.
bool any_redistort = false;
for (const RedistortSource& r : ds.redistort)
any_redistort |= (r.source_model >= 0);
if (any_redistort) {
out.any_warp = true;
out.redistort_models.assign(N, -1);
out.redistort_params.assign((size_t)N * 16, 0.0f);
for (int64_t i = 0; i < N && i < (int64_t)ds.redistort.size(); i++) {
out.redistort_models[i] = ds.redistort[i].source_model;
for (int k = 0; k < 16; k++)
out.redistort_params[i*16 + k] = ds.redistort[i].params[k];
}
}
if (out.any_warp) {
out.input_intrins = ds.intrins;
out.input_dist_coeffs = ds.dist_coeffs;
out.input_distortions = ds.camera_distortions;
}
return out;
}
+12
View File
@@ -385,6 +385,18 @@ ParsedDataset parse_metashape_dataset(const std::string& dataset_dir,
jset(s, "p2", jnum(child_double(*calib, "p1")));
jset(s, "b1", jnum(child_double(*calib, "b1") / fl));
jset(s, "b2", jnum(child_double(*calib, "b2") / fl));
// Metashape's k4 is the 4th RADIAL term, not OpenCV's first
// rational denominator, so say so rather than let the nerfstudio
// back end guess from which keys are present.
jset(s, "camera_distortion", jstr("THIN_PRISM"));
// PhotoScan <= 1.5 multiplied the tangential terms by
// (1 + P3 r^2 + P4 r^4); nothing here carries that.
if (child_double(*calib, "p3") != 0.0 ||
child_double(*calib, "p4") != 0.0)
throw std::runtime_error(
"MetashapeParser: sensor " + *idp + " has nonzero p3/p4 "
"(the pre-1.6 tangential scaling), which no supported "
"distortion model carries");
}
sensor_dict.emplace(*idp, std::move(s));
}
+163 -7
View File
@@ -8,6 +8,8 @@
#include "data/Json.h"
#include "core/CameraModel.h" // camera_model_from_name (CUDA-free)
#include "data/DistortionFit.h"
#include "data/SourceCamera.h"
#include <algorithm>
#include <cmath>
@@ -15,7 +17,9 @@
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <map>
#include <stdexcept>
#include <string>
namespace dmsg = spirula::i18n::msg::data;
@@ -259,9 +263,12 @@ ColmapPoints3D read_ply_points(const std::string& path) {
namespace {
// Distortion keys, in engine dist_coeffs order.
const char* kDistortionKeys[10] = {
"k1", "k2", "k3", "k4", "p1", "p2", "sx1", "sy1", "b1", "b2"};
// transforms.json distortion keys. k4..k6 mean different things either side of
// the fisheye divide: on a perspective camera they are OpenCV's RATIONAL
// denominator, on a fisheye they are further theta-space radial terms.
struct RawDistortion {
double k1, k2, k3, k4, k5, k6, p1, p2, sx1, sy1, b1, b2;
};
// frame-then-meta numeric lookup; throws when required and absent in both.
double frame_or_meta(const JsonValue& frame, const JsonValue& meta,
@@ -274,6 +281,73 @@ double frame_or_meta(const JsonValue& frame, const JsonValue& meta,
return def;
}
// A sensor skew (Metashape b2) is an off-diagonal pixel term, and every tier's
// pixel map is diagonal. So the camera is fitted without it and the images are
// resampled from the true skewed projection -- unless the skew turns out to be
// smaller than resampling can express, in which case it is simply dropped.
struct SkewFit {
CameraModelType model;
CameraDistortionType tier;
double fx, fy, cx, cy;
float coeffs[kCameraDistortionParams];
RedistortSource source; // source_model < 0 when the skew was negligible
};
// Keyed on everything the fit depends on: a transforms.json repeats the same
// intrinsics on every frame and each fit is a least-squares solve.
using SkewCache = std::map<std::string, SkewFit>;
const SkewFit& fit_skewed_sensor(SkewCache& cache, CameraModelType model,
CameraDistortionType tier,
double fx, double fy, double cx, double cy,
double skew_px, const float* coeffs,
double W, double H, const std::string& label) {
RedistortSource src;
src.source_model = srccam::kSkewed;
src.params[0] = (float)fx; src.params[1] = (float)fy;
src.params[2] = (float)cx; src.params[3] = (float)cy;
src.params[4] = (float)skew_px;
for (int k = 0; k < kCameraDistortionParams; k++)
src.params[5 + k] = coeffs[k];
src.params[13] = model == CameraModelType::FISHEYE ? srccam::kSkewBaseFisheye
: model == CameraModelType::EQUISOLID ? srccam::kSkewBaseEquisolid
: srccam::kSkewBasePerspective;
src.params[14] = tier == CameraDistortionType::Rational
? srccam::kSkewRadialRational : srccam::kSkewRadialPolynomial;
std::string key((const char*)src.params, sizeof(src.params));
key += std::string((const char*)&W, sizeof(W));
key += std::string((const char*)&H, sizeof(H));
auto it = cache.find(key);
if (it != cache.end())
return it->second;
dsfit::SourceProject project =
[&src](double x, double y, double z, double* u, double* v) {
return srccam::project(src.source_model, src.params, x, y, z, u, v);
};
// The same camera model reproduces everything but the skew, so try it
// before letting the fitter pick one it likes better.
dsfit::FitResult fit = dsfit::fit_camera(project, (int)W, (int)H, model);
if (!fit.invertible || fit.samples == 0)
fit = dsfit::fit_camera_auto(project, (int)W, (int)H);
SkewFit f{};
f.model = fit.target.model;
f.tier = fit.target.distortion;
f.fx = fit.target.fx; f.fy = fit.target.fy;
f.cx = fit.target.cx; f.cy = fit.target.cy;
for (int k = 0; k < kCameraDistortionParams; k++) f.coeffs[k] = fit.target.coeffs[k];
if (fit.max_px >= dsfit::kExactFitPx) {
f.source = src;
f.source.fit_max_px = (float)fit.max_px;
std::printf("%s\n", spirula::i18n::format(dmsg::camera_sensor_skew,
{label, skew_px, camera_model_to_string(f.model),
camera_distortion_to_string(f.tier), fit.max_px}).c_str());
}
return cache.emplace(std::move(key), f).first->second;
}
// 3x3 inverse (adjugate); used for applied_transform^-1.
void invert3x3d(const double m[3][3], double out[3][3]) {
double a = m[0][0], b = m[0][1], c = m[0][2],
@@ -401,8 +475,9 @@ ParsedDataset parse_nerfstudio_meta(const JsonValue& meta,
ds.train_frame_scale = (float)(scale_factor != 0.0 ? 1.0 / scale_factor : 1.0);
ds.c2w.resize(N * 12);
ds.intrins.resize(N * 4);
ds.dist_coeffs.resize(N * 10);
ds.dist_coeffs.resize(N * kCameraDistortionParams);
ds.camera_models.reserve(N);
ds.camera_distortions.reserve(N);
ds.image_filenames.reserve(N);
ds.widths.reserve(N);
ds.heights.reserve(N);
@@ -410,6 +485,8 @@ ParsedDataset parse_nerfstudio_meta(const JsonValue& meta,
std::vector<std::string> mask_files(N), depth_files(N), normal_files(N);
bool any_mask = false, any_depth = false, any_normal = false;
const int EQUIRECT_V = (int)camera_model_from_name("EQUIRECTANGULAR");
const int PINHOLE_V = (int)camera_model_from_name("PINHOLE");
SkewCache skew_cache;
for (int64_t j = 0; j < N; j++) {
const Frame& F = frames[subset[j]];
@@ -431,13 +508,92 @@ ParsedDataset parse_nerfstudio_meta(const JsonValue& meta,
throw std::runtime_error("NerfstudioParser: unsupported camera model " +
model_name);
for (int k = 0; k < 10; k++)
ds.dist_coeffs[j*10 + k] =
(float)frame_or_meta(fr, meta, kDistortionKeys[k], false, 0.0);
RawDistortion rd{};
auto get = [&](const char* key) {
return frame_or_meta(fr, meta, key, false, 0.0);
};
rd.k1 = get("k1"); rd.k2 = get("k2"); rd.k3 = get("k3");
rd.k4 = get("k4"); rd.k5 = get("k5"); rd.k6 = get("k6");
rd.p1 = get("p1"); rd.p2 = get("p2");
rd.sx1 = get("sx1"); rd.sy1 = get("sy1");
rd.b1 = get("b1"); rd.b2 = get("b2");
// b1/b2 arrive already converted, NOT as Metashape writes them:
// metashape_utils.py (and MetashapeParser, which mirrors it) divides
// both by fl_x, and swaps p1/p2 into OpenCV order on the way. So here
// they are affinity and skew relative to fl_x. The affinity is an fx
// correction and folds in exactly; the skew is off-diagonal, so it is
// handled after the tier is known, below.
const double skew_px = rd.b2 * fx;
if (rd.b1 != 0.0) fx *= 1.0 + rd.b1;
// An explicit "camera_distortion" resolves what k4 means; without one,
// a perspective camera follows OpenCV (k4..k6 are the rational
// denominator) and a fisheye follows Kannala-Brandt (k4 is radial).
// MetashapeParser always writes the key, because its 4th radial term
// would otherwise be read as a denominator.
CameraDistortionType hint = (CameraDistortionType)-1;
if (const JsonValue* v = fr.find("camera_distortion"))
hint = camera_distortion_from_name(v->as_string());
else if (const JsonValue* v2 = meta.find("camera_distortion"))
hint = camera_distortion_from_name(v2->as_string());
// b1/b2 are Metashape's affinity and skew and sx1/sy1 are thin-prism
// terms; a rational camera has none of them, so their mere PRESENCE
// resolves what k4 means for a file that omits "camera_distortion" --
// which is what a transforms.json converted from Metashape looks like.
// k5/k6 exist only in the rational model and decide on their own.
auto has = [&](const char* key) {
return fr.find(key) != nullptr || meta.find(key) != nullptr;
};
bool thin_prism_shaped =
has("b1") || has("b2") || has("sx1") || has("sy1");
float* dst = &ds.dist_coeffs[j*kCameraDistortionParams];
CameraDistortionType tier;
bool fisheye = ((int)model != PINHOLE_V);
bool rational = (hint == CameraDistortionType::Rational) ||
((int)hint < 0 && !fisheye &&
(rd.k5 != 0.0 || rd.k6 != 0.0 ||
(rd.k4 != 0.0 && !thin_prism_shaped)));
if (rational) {
tier = CameraDistortionType::Rational;
dst[0] = (float)rd.k1; dst[1] = (float)rd.k2; dst[2] = (float)rd.k3;
dst[3] = (float)rd.k4; dst[4] = (float)rd.k5; dst[5] = (float)rd.k6;
dst[6] = (float)rd.p1; dst[7] = (float)rd.p2;
} else {
tier = CameraDistortionType::ThinPrism;
dst[0] = (float)rd.k1; dst[1] = (float)rd.k2;
dst[2] = (float)rd.k3; dst[3] = (float)rd.k4;
dst[4] = (float)rd.p1; dst[5] = (float)rd.p2;
dst[6] = (float)rd.sx1; dst[7] = (float)rd.sy1;
}
if ((int)model == EQUIRECT_V) {
// A panorama has no lens, so it has no skew either; b2 on one is
// meaningless and ignored along with the rest of the coefficients.
tier = CameraDistortionType::None;
for (int k = 0; k < kCameraDistortionParams; k++) dst[k] = 0.0f;
} else if (skew_px != 0.0) {
const SkewFit& f = fit_skewed_sensor(skew_cache, model, tier, fx, fy,
cx, cy, skew_px, dst, W, H, F.abs);
model = f.model;
tier = f.tier;
fx = f.fx; fy = f.fy; cx = f.cx; cy = f.cy;
std::copy(f.coeffs, f.coeffs + kCameraDistortionParams, dst);
if (f.source.source_model >= 0) {
if (ds.redistort.empty()) ds.redistort.resize(N);
ds.redistort[j] = f.source;
}
}
ds.camera_distortions.push_back(
(int32_t)camera_distortion_demote(tier, dst, dst));
if (cfg.rescale_camera_to_fit > 0.0f) {
double s = cfg.rescale_camera_to_fit;
fx /= s; fy /= s; cx /= s; cy /= s;
if (!ds.redistort.empty() && ds.redistort[j].source_model >= 0)
srccam::rescale(ds.redistort[j].source_model,
ds.redistort[j].params, s);
auto round_dim = [&](double v) {
if (cfg.downscale_rounding_mode == "ceil") return std::ceil(v / s);
if (cfg.downscale_rounding_mode == "round") return std::round(v / s);
+14 -2
View File
@@ -60,6 +60,7 @@ void set_camera_params(
int width,
int height,
std::string camera_model,
std::string distortion,
TorchTensorView viewmats,
TorchTensorView intrins,
TorchTensorView dist_coeffs
@@ -92,6 +93,7 @@ void set_training_data(
// gt_depth / gt_normal to disable those.
void set_training_data_warped(
std::string input_model_name, // "FISHEYE" / "EQUISOLID" / "EQUIRECTANGULAR"
std::string input_distortion,
int B_in, int in_H, int in_W,
int K, int out_H, int out_W,
TorchTensorView gt_rgb, // [B_in, in_H, in_W, 3] byte
@@ -103,7 +105,9 @@ void set_training_data_warped(
int normal_in_H, int normal_in_W,
bool input_depth_is_ray_depth, // interpretation of the wide GT depth
TorchTensorView input_intrins, // [B_in, 4] float
TorchTensorView input_dist_coeffs,// [B_in, 10] float
TorchTensorView input_dist_coeffs,// [B_in, 8] float
TorchTensorView input_source_models, // [B_in] int32 (nullable)
TorchTensorView input_source_params, // [B_in, 16] float
uint64_t axes_dev // device float ptr [K, 3, 3]
);
@@ -282,7 +286,7 @@ std::map<std::string, float> engine_train_step(
std::string primitive,
int sh_degree,
bool packed,
int width, int height, std::string camera_model,
int width, int height, std::string camera_model, std::string distortion,
TorchTensorView viewmats,
TorchTensorView intrins,
TorchTensorView dist_coeffs,
@@ -307,9 +311,12 @@ std::map<std::string, float> engine_train_step_warped(
TorchTensorView post_intrins,
TorchTensorView post_dist_coeffs,
std::string input_camera_model,
std::string input_distortion,
int B_in, int in_H, int in_W, int K,
TorchTensorView input_intrins,
TorchTensorView input_dist_coeffs,
TorchTensorView input_source_models,
TorchTensorView input_source_params,
TorchTensorView gt_rgb_byte,
TorchTensorView gt_alpha_byte,
int mask_in_H, int mask_in_W,
@@ -332,6 +339,7 @@ struct HeteroSubBatch {
int height = 0;
int num = 0; // number of cameras in this sub-batch
std::string camera_model;
std::string distortion;
TorchTensorView viewmats{0, 0, {}};
TorchTensorView intrins{0, 0, {}};
TorchTensorView dist_coeffs{0, 0, {}};
@@ -377,6 +385,7 @@ void engine_setup_data_manager(
// Per-camera model enum value (int; cast to CameraModelType internally).
// Mixed pinhole + fisheye datasets just produce extra index groups.
std::vector<int32_t> camera_models,
std::vector<int32_t> camera_distortions,
std::vector<std::string> image_filenames,
std::vector<std::string> mask_filenames,
std::vector<std::string> depth_filenames,
@@ -397,6 +406,8 @@ void engine_setup_data_manager(
// camera is in the dataset.
std::vector<float> input_intrins,
std::vector<float> input_dist_coeffs,
std::vector<int32_t> redistort_models,
std::vector<float> redistort_params,
std::vector<int32_t> train_indices,
std::vector<int32_t> val_indices);
@@ -555,6 +566,7 @@ void engine_blit_view(
TorchTensorView render_depth, // [H,W,1] float, may be null when buffer_key=="alpha"
TorchTensorView render_alpha, // [H,W,1] float
int view_camera_model,
std::string distortion,
TorchTensorView view_intrins, // [1,4] float
TorchTensorView view_viewmat, // [4,4] float
TorchTensorView view_dist_coeffs,
+4 -2
View File
@@ -174,7 +174,8 @@ void _engine_background_forward() {
TorchTensorView bg_image_tv = _dt3d_tv(bg.fwd_background);
BgShViews vs = _engine_bg_sh_views(C_batch);
render_background_sh_forward(
W, H, engine().camera.model_str, bg.sh_degree,
W, H, engine().camera.model_str,
engine().camera.distortion_str, bg.sh_degree,
vs.viewmats, vs.intrins, vs.dist_coeffs,
vs.sh_coeffs, bg_image_tv);
@@ -268,7 +269,8 @@ void _engine_background_backward_hook(
BgShViews vs = _engine_bg_sh_views(C_batch);
render_background_sh_backward(
W, H, engine().camera.model_str, bg.sh_degree,
W, H, engine().camera.model_str,
engine().camera.distortion_str, bg.sh_degree,
vs.viewmats, vs.intrins, vs.dist_coeffs,
vs.sh_coeffs,
bg_image_tv, v_bg_tv2,
+18 -4
View File
@@ -26,6 +26,7 @@
void engine_setup_data_manager(
DataManagerConfig cfg,
std::vector<int32_t> camera_models,
std::vector<int32_t> camera_distortions,
std::vector<std::string> image_filenames,
std::vector<std::string> mask_filenames,
std::vector<std::string> depth_filenames,
@@ -39,6 +40,8 @@ void engine_setup_data_manager(
std::vector<float> dist_coeffs,
std::vector<float> input_intrins,
std::vector<float> input_dist_coeffs,
std::vector<int32_t> redistort_models,
std::vector<float> redistort_params,
std::vector<int32_t> train_indices,
std::vector<int32_t> val_indices)
{
@@ -47,7 +50,7 @@ void engine_setup_data_manager(
engine().dm.reset();
engine().dm = std::make_unique<DataManager>(
std::move(cfg), std::move(camera_models),
std::move(cfg), std::move(camera_models), std::move(camera_distortions),
std::move(image_filenames), std::move(mask_filenames),
std::move(depth_filenames), std::move(normal_filenames),
std::move(widths), std::move(heights),
@@ -55,6 +58,7 @@ void engine_setup_data_manager(
std::move(viewmats), std::move(intrins),
std::move(dist_coeffs),
std::move(input_intrins), std::move(input_dist_coeffs),
std::move(redistort_models), std::move(redistort_params),
std::move(train_indices), std::move(val_indices));
}
@@ -148,13 +152,14 @@ std::map<std::string, float> engine_train_step_managed(
TorchTensorView bilagrid_cam_indices(
(uint64_t)_bg_idx_buf.data(), 4, {(int64_t)b.num, 1LL});
if (b.K <= 1) {
if (b.K <= 1 && b.input_source_models.empty()) {
// Standard path: GT is already at engine shape, no warp needed.
return engine_train_step(
step, max_steps,
std::move(primitive), sh_degree, packed,
(int)b.width, (int)b.height,
camera_model_to_string(b.model),
camera_distortion_to_string(b.distortion),
b.viewmats_view, b.intrins_view, b.dist_coeffs_view,
b.rgb_view, b.depth_view, b.normal_view, b.mask_view,
bilagrid_cam_indices,
@@ -170,8 +175,10 @@ std::map<std::string, float> engine_train_step_managed(
(int)b.width, (int)b.height,
b.viewmats_view, b.intrins_view, b.dist_coeffs_view,
camera_model_to_string(b.input_model),
camera_distortion_to_string(b.input_distortion),
b.input_num, b.input_height, b.input_width, b.K,
b.input_intrins_view, b.input_dist_coeffs_view,
b.input_source_models_view, b.input_source_params_view,
b.rgb_view, b.mask_view,
b.mask_height, b.mask_width,
b.depth_view, b.depth_height, b.depth_width,
@@ -232,19 +239,25 @@ static TorchTensorView _tv_null() { return {0, 0, {}}; }
// mask and warp training used, and neither wants loss, backward or optim.
static void _install_and_forward(const DecodedBatch& b, std::string primitive,
int sh_degree, bool packed) {
if (b.K <= 1) {
if (b.K <= 1 && b.input_source_models.empty()) {
set_camera_params((int)b.width, (int)b.height,
camera_model_to_string(b.model),
camera_distortion_to_string(b.distortion),
b.viewmats_view, b.intrins_view, b.dist_coeffs_view);
// No depth/normal: both callers compare RGB only, and skipping them
// avoids the linear->ray depth conversion pass.
set_training_data(b.rgb_view, _tv_null(), _tv_null(),
b.mask_view, true);
} else {
set_camera_params((int)b.width, (int)b.height, "PINHOLE",
// b.model / b.distortion are already PINHOLE / NONE when K > 1; at
// K == 1 (re-distort) they are the camera the parser fitted.
set_camera_params((int)b.width, (int)b.height,
camera_model_to_string(b.model),
camera_distortion_to_string(b.distortion),
b.viewmats_view, b.intrins_view, b.dist_coeffs_view);
set_training_data_warped(
camera_model_to_string(b.input_model),
camera_distortion_to_string(b.input_distortion),
b.input_num, (int)b.input_height, (int)b.input_width,
b.K, (int)b.height, (int)b.width,
b.rgb_view, b.mask_view, (int)b.mask_height, (int)b.mask_width,
@@ -252,6 +265,7 @@ static void _install_and_forward(const DecodedBatch& b, std::string primitive,
_tv_null(), 0, 0,
true,
b.input_intrins_view, b.input_dist_coeffs_view,
b.input_source_models_view, b.input_source_params_view,
(uint64_t)b.axes_dev);
}
+14 -7
View File
@@ -126,7 +126,8 @@ void forward_3dgs(
engine().cur_num_splats, sh_degree, in_splats,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().optim.radii,
sh_value_packed_opt, sh_value_bounds_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
cam_ids = a; gauss_ids = b; aabb_vec = c; depths_vec = d;
@@ -136,7 +137,8 @@ void forward_3dgs(
engine().cur_num_splats, sh_degree, in_splats,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().optim.radii,
sh_value_packed_opt, sh_value_bounds_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
cam_ids = a; gauss_ids = b; aabb_vec = c; depths_vec = d;
@@ -146,7 +148,8 @@ void forward_3dgs(
engine().cur_num_splats, sh_degree, in_splats,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().optim.radii,
sh_value_packed_opt, sh_value_bounds_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
cam_ids = a; gauss_ids = b; aabb_vec = c; depths_vec = d;
@@ -169,7 +172,8 @@ void forward_3dgs(
engine().cur_num_splats, sh_degree, in_splats,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().optim.radii,
sh_value_packed_opt, sh_value_bounds_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
aabb_2d = a; depths_2d = b;
@@ -179,7 +183,8 @@ void forward_3dgs(
engine().cur_num_splats, sh_degree, in_splats,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().optim.radii,
sh_value_packed_opt, sh_value_bounds_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
aabb_2d = a; depths_2d = b;
@@ -189,7 +194,8 @@ void forward_3dgs(
engine().cur_num_splats, sh_degree, in_splats,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().optim.radii,
sh_value_packed_opt, sh_value_bounds_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
aabb_2d = a; depths_2d = b;
@@ -267,7 +273,8 @@ void forward_3dgs(
engine().cur_num_splats,
in_splats, engine().fwd.splats_s, engine().fwd.gaussian_ids,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().fwd.aabb,
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
tile_offsets, flatten_ids, dist_type, output_median);
+13 -4
View File
@@ -248,6 +248,7 @@ static void _engine_raster_proj_backward(
_dt2d_tv(engine().camera.viewmats),
_dv_tv(engine().camera.intrins),
engine().camera.model_str,
engine().camera.distortion_str,
_dt2d_tv(engine().camera.dist_coeffs),
engine().fwd.aabb,
(uint32_t)engine().camera.width,
@@ -336,7 +337,8 @@ static void _engine_raster_proj_backward(
fn(engine().cur_num_splats, engine().sh_degree, engine().fwd.splats_w,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().fwd.camera_ids, engine().fwd.gaussian_ids, engine().fwd.aabb,
v_splats_s_out, v_splats_w_out, gq,
vp_opt, vb_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
@@ -350,7 +352,8 @@ static void _engine_raster_proj_backward(
engine().cur_num_splats, engine().sh_degree, engine().fwd.splats_w,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().fwd.camera_ids, engine().fwd.gaussian_ids,
engine().fwd.aabb, v_splats_s_out, v_splats_w_out, nullptr,
vp_opt, vb_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
@@ -359,7 +362,8 @@ static void _engine_raster_proj_backward(
engine().cur_num_splats, engine().sh_degree, engine().fwd.splats_w,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().fwd.camera_ids, engine().fwd.gaussian_ids,
engine().fwd.aabb, v_splats_s_out, v_splats_w_out, nullptr,
vp_opt, vb_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
@@ -368,7 +372,8 @@ static void _engine_raster_proj_backward(
engine().cur_num_splats, engine().sh_degree, engine().fwd.splats_w,
_dt2d_tv(engine().camera.viewmats), _dv_tv(engine().camera.intrins),
(uint32_t)engine().camera.width, (uint32_t)engine().camera.height,
engine().camera.model_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().camera.model_str,
engine().camera.distortion_str, _dt2d_tv(engine().camera.dist_coeffs),
engine().fwd.camera_ids, engine().fwd.gaussian_ids,
engine().fwd.aabb, v_splats_s_out, v_splats_w_out, nullptr,
vp_opt, vb_opt, num_sh_buffer, sh_value_bits, sh_bounds_stride);
@@ -526,6 +531,7 @@ std::map<std::string, float> engine_compute_loss_backward(
depth_normal = _pool_tv(PoolSlot::EngDepthNormal, C, H, W, 3);
depth_to_normal_forward(
engine().camera.model_str,
engine().camera.distortion_str,
_dv_tv(engine().camera.intrins),
_dt2d_tv(engine().camera.dist_coeffs),
is_ray_depth,
@@ -552,6 +558,7 @@ std::map<std::string, float> engine_compute_loss_backward(
median_normal = _pool_tv(PoolSlot::EngMedianNormal, C, H, W, 3);
depth_to_normal_forward(
engine().camera.model_str,
engine().camera.distortion_str,
_dv_tv(engine().camera.intrins),
_dt2d_tv(engine().camera.dist_coeffs),
is_ray_depth,
@@ -781,6 +788,7 @@ std::map<std::string, float> engine_compute_loss_backward(
if (compute_depth_normal) {
depth_to_normal_backward(
engine().camera.model_str,
engine().camera.distortion_str,
_dv_tv(engine().camera.intrins),
_dt2d_tv(engine().camera.dist_coeffs),
is_ray_depth,
@@ -795,6 +803,7 @@ std::map<std::string, float> engine_compute_loss_backward(
if (has_median && median_normal_active) {
depth_to_normal_backward(
engine().camera.model_str,
engine().camera.distortion_str,
_dv_tv(engine().camera.intrins),
_dt2d_tv(engine().camera.dist_coeffs),
is_ray_depth,
+1
View File
@@ -444,6 +444,7 @@ void engine_fused_proj_bwd_optim_step(int step, const OptimConfig& cfg) {
(uint32_t)engine().camera.width,
(uint32_t)engine().camera.height,
engine().camera.model_str,
engine().camera.distortion_str,
_dt2d_tv(engine().camera.dist_coeffs),
engine().fwd.camera_ids,
engine().fwd.gaussian_ids,
+4
View File
@@ -51,6 +51,7 @@ void set_camera_params(
int width,
int height,
std::string camera_model,
std::string distortion,
TorchTensorView viewmats,
TorchTensorView intrins,
TorchTensorView dist_coeffs
@@ -59,6 +60,8 @@ void set_camera_params(
engine().camera.height = height;
engine().camera.model = cmt(camera_model);
engine().camera.model_str = camera_model;
engine().camera.distortion = cdt(distortion);
engine().camera.distortion_str = distortion;
engine().camera.num = std::get<2>(viewmats)[0];
if (std::get<2>(intrins)[0] != engine().camera.num ||
@@ -108,6 +111,7 @@ void set_training_data(
if (!input_depth_is_ray_depth && engine().gt.depth.data_ptr() != nullptr) {
linear_depth_to_ray_depth_inplace(
engine().camera.model_str,
engine().camera.distortion_str,
_dv_tv(engine().camera.intrins),
_dt2d_tv(engine().camera.dist_coeffs),
engine().camera.width, engine().camera.height,
+70 -9
View File
@@ -54,6 +54,20 @@ static const void* _h2d_stage_byte(
// views point at host std::vector memory (DecodedBatch hands out host
// TorchTensorViews), so they must be copied to device first -- otherwise the
// kernel faults on an illegal address. Zero-copy when already a device ptr.
static const int32_t* _h2d_stage_ints(
const TorchTensorView& src_tv, size_t numel, PoolSlot slot)
{
uint64_t src_ptr = std::get<0>(src_tv);
if (src_ptr == 0 || numel == 0) return nullptr;
if (_is_device_ptr((void*)src_ptr)) {
return (const int32_t*)src_ptr;
}
int32_t* p = DevicePool::global().acquire<int32_t>(slot, numel);
backend::memcpy_sync(p, (void*)src_ptr, numel * sizeof(int32_t),
backend::MemcpyKind::HostToDevice);
return p;
}
static const float* _h2d_stage_floats(
const TorchTensorView& src_tv, size_t numel, PoolSlot slot)
{
@@ -72,6 +86,7 @@ void set_training_data_warped(
// Input-side camera model name (FISHEYE / EQUISOLID / EQUIRECTANGULAR).
// The kernel dispatcher uses this to pick wide vs equirectangular warp.
std::string input_model_name,
std::string input_distortion,
int B_in, int in_H, int in_W,
int K, int out_H, int out_W,
// GT RGB at INPUT shape, byte (uint8 or uint16). The kernel fuses
@@ -94,6 +109,14 @@ void set_training_data_warped(
// be zero-copy when already on device.
TorchTensorView input_intrins,
TorchTensorView input_dist_coeffs,
// Per-INPUT source camera, for the cameras whose lens model no tier
// represents: [B_in] COLMAP model id and [B_in, 16] its own parameters.
// Null unless the dataset carries one. With K > 1 the wide warp projects
// straight through this instead of the fitted camera, so the two passes
// fuse and no intermediate image is allocated; with K == 1 it selects the
// re-distort kernels below.
TorchTensorView input_source_models,
TorchTensorView input_source_params,
// Device pointer to the [K, 3, 3] cubemap axes table (lifetime managed
// by DataManager).
uint64_t axes_dev)
@@ -136,10 +159,26 @@ void set_training_data_warped(
const float* d_intrins = _h2d_stage_floats(
input_intrins, (size_t)B_in * 4, PoolSlot::WarpInputIntrins);
const float* d_dist = _h2d_stage_floats(
input_dist_coeffs, (size_t)B_in * 10, PoolSlot::WarpInputDistCoeffs);
input_dist_coeffs, (size_t)B_in * kCameraDistortionParams,
PoolSlot::WarpInputDistCoeffs);
const int* d_src_models = nullptr;
const float* d_src_params = nullptr;
if (std::get<0>(input_source_models) != 0) {
d_src_models = (const int*)_h2d_stage_ints(
input_source_models, (size_t)B_in, PoolSlot::WarpSourceModels);
d_src_params = _h2d_stage_floats(
input_source_params, (size_t)B_in * 16, PoolSlot::WarpSourceParams);
}
const bool redistort_only = (K == 1 && d_src_models != nullptr);
CameraModelType cm = cmt(input_model_name);
if (cm == CameraModelType::EQUIRECTANGULAR) {
if (redistort_only) {
launch_redistort_byte_to_float(
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params, d_rgb_byte, rgb_u16,
B_in, in_H, in_W, 3, d_rgb_float, out_H, out_W, in_H, in_W, 0.5f);
} else if (cm == CameraModelType::EQUIRECTANGULAR) {
launch_warp_byte_to_float_equi(
d_rgb_byte, rgb_u16, B_in, in_H, in_W, 3,
d_rgb_float, K, out_H, out_W,
@@ -149,7 +188,8 @@ void set_training_data_warped(
// projection dispatch internally on `cm`. (PINHOLE doesn't normally
// hit this path -- K==1 there -- but the kernel handles it anyway.)
launch_warp_byte_to_float_wide(
input_model_name, d_intrins, d_dist,
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params,
d_rgb_byte, rgb_u16, B_in, in_H, in_W, 3,
d_rgb_float, K, out_H, out_W,
(const float*)axes_dev);
@@ -175,13 +215,20 @@ void set_training_data_warped(
uint8_t* d_mask_out = DevicePool::global().acquire<uint8_t>(
PoolSlot::GtAlpha,
(size_t)B_post * out_H * out_W);
if (cm == CameraModelType::EQUIRECTANGULAR) {
if (redistort_only) {
launch_redistort_mask(
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params,
(const uint8_t*)d_mask_in, B_in, mask_in_H, mask_in_W,
d_mask_out, out_H, out_W, in_H, in_W);
} else if (cm == CameraModelType::EQUIRECTANGULAR) {
launch_warp_mask_equi(
(const uint8_t*)d_mask_in, B_in, mask_in_H, mask_in_W,
d_mask_out, K, out_H, out_W, (const float*)axes_dev);
} else {
launch_warp_mask_wide(
input_model_name, d_intrins, d_dist,
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params,
(const uint8_t*)d_mask_in, B_in, mask_in_H, mask_in_W,
d_mask_out, K, out_H, out_W, (const float*)axes_dev);
}
@@ -211,14 +258,21 @@ void set_training_data_warped(
}
float* d_depth_out = DevicePool::global().acquire<float>(
PoolSlot::GtDepth, (size_t)B_post * out_H * out_W);
if (cm == CameraModelType::EQUIRECTANGULAR) {
if (redistort_only) {
launch_redistort_depth(
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params, d_depth_in, d_elem,
B_in, depth_in_H, depth_in_W, 1,
d_depth_out, out_H, out_W, in_H, in_W, 0.0f);
} else if (cm == CameraModelType::EQUIRECTANGULAR) {
launch_warp_depth_equi(
d_depth_in, d_elem, B_in, depth_in_H, depth_in_W,
d_depth_out, K, out_H, out_W,
(const float*)axes_dev, input_depth_is_ray_depth);
} else {
launch_warp_depth_wide(
input_model_name, d_intrins, d_dist,
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params,
d_depth_in, d_elem, B_in, depth_in_H, depth_in_W,
in_H, in_W, d_depth_out, K, out_H, out_W,
(const float*)axes_dev, input_depth_is_ray_depth);
@@ -247,13 +301,20 @@ void set_training_data_warped(
}
float* d_normal_out = DevicePool::global().acquire<float>(
PoolSlot::GtNormal, (size_t)B_post * out_H * out_W * 3);
if (cm == CameraModelType::EQUIRECTANGULAR) {
if (redistort_only) {
launch_redistort_normal(
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params, d_normal_in, n_elem == 4,
B_in, normal_in_H, normal_in_W,
d_normal_out, out_H, out_W, in_H, in_W);
} else if (cm == CameraModelType::EQUIRECTANGULAR) {
launch_warp_normal_equi(
d_normal_in, n_elem, B_in, normal_in_H, normal_in_W,
d_normal_out, K, out_H, out_W, (const float*)axes_dev);
} else {
launch_warp_normal_wide(
input_model_name, d_intrins, d_dist,
input_model_name, input_distortion, d_intrins, d_dist,
d_src_models, d_src_params,
d_normal_in, n_elem, B_in, normal_in_H, normal_in_W,
in_H, in_W, d_normal_out, K, out_H, out_W,
(const float*)axes_dev);
+4 -2
View File
@@ -115,10 +115,12 @@ struct CameraTable {
int32_t width = 0;
int32_t height = 0;
CameraModelType model = (CameraModelType)-1;
CameraDistortionType distortion = CameraDistortionType::None;
std::string model_str;
std::string distortion_str = "NONE";
DeviceTensor2D<float4> viewmats; // [C, 4]
DeviceVector<float4> intrins; // [C]
DeviceTensor2D<float> dist_coeffs; // [C, 10]
DeviceTensor2D<float> dist_coeffs; // [C, 8]
};
// Forward-pass intermediates retained for backward.
@@ -450,7 +452,7 @@ struct EngineViewerState {
DeviceVector<int32_t> d_widths; // [N_post]
DeviceVector<int32_t> d_heights; // [N_post]
DeviceVector<int32_t> d_camera_models; // [N_post]
DeviceVector<float> d_dist_coeffs; // [N_post, 10]
DeviceVector<float> d_dist_coeffs; // [N_post, 8]
DeviceVector<float> d_camera_to_worlds; // [N_post, 3, 4] (y/z-flipped form)
float camera_size = 0.0f; // frustum render scale, from knn-dist
+45 -20
View File
@@ -216,7 +216,7 @@ static std::map<std::string, float> _engine_train_step_split_one_per_camera(
std::string primitive,
int sh_degree,
bool packed,
int width, int height, std::string camera_model,
int width, int height, std::string camera_model, std::string distortion,
TorchTensorView viewmats, // [B, 4, 4]
TorchTensorView intrins, // [B, 4]
TorchTensorView dist_coeffs, // [B, K]
@@ -244,7 +244,7 @@ static std::map<std::string, float> _engine_train_step_split_one_per_camera(
// Single-camera batch -> no point splitting; fall through to the
// standard path with grad_scale = 1.
if (B == 1) {
set_camera_params(width, height, camera_model,
set_camera_params(width, height, camera_model, distortion,
viewmats, intrins, dist_coeffs);
set_training_data(gt_rgb, gt_depth, gt_normal, gt_alpha,
cfg.loss.input_depth_is_ray_depth);
@@ -305,7 +305,7 @@ static std::map<std::string, float> _engine_train_step_split_one_per_camera(
TorchTensorView aph_k = _slice_tv_first_dim(gt_alpha, k);
TorchTensorView bgi_k = _slice_tv_first_dim(bilagrid_cam_indices, k);
set_camera_params(width, height, camera_model, vmt_k, itr_k, dst_k);
set_camera_params(width, height, camera_model, distortion, vmt_k, itr_k, dst_k);
set_training_data(rgb_k, dep_k, nrm_k, aph_k,
cfg.loss.input_depth_is_ray_depth);
@@ -443,7 +443,7 @@ std::map<std::string, float> engine_train_step_hetero(
TorchTensorView aph_c = _slice_tv_first_dim(s.gt_alpha, c);
TorchTensorView bgi_c = _slice_tv_first_dim(s.bilagrid_cam_indices, c);
set_camera_params(s.width, s.height, s.camera_model,
set_camera_params(s.width, s.height, s.camera_model, s.distortion,
vmt_c, itr_c, dst_c);
set_training_data(rgb_c, dep_c, nrm_c, aph_c,
cfg.loss.input_depth_is_ray_depth);
@@ -495,7 +495,7 @@ std::map<std::string, float> engine_train_step(
std::string primitive,
int sh_degree,
bool packed,
int width, int height, std::string camera_model,
int width, int height, std::string camera_model, std::string distortion,
TorchTensorView viewmats,
TorchTensorView intrins,
TorchTensorView dist_coeffs,
@@ -509,12 +509,12 @@ std::map<std::string, float> engine_train_step(
if (cfg.optim.split_batch) {
return _engine_train_step_split_one_per_camera(
step, max_steps, std::move(primitive), sh_degree, packed,
width, height, std::move(camera_model),
width, height, std::move(camera_model), std::move(distortion),
viewmats, intrins, dist_coeffs,
gt_rgb, gt_depth, gt_normal, gt_alpha,
bilagrid_cam_indices, cfg);
}
set_camera_params(width, height, camera_model, viewmats, intrins, dist_coeffs);
set_camera_params(width, height, camera_model, distortion, viewmats, intrins, dist_coeffs);
set_training_data(gt_rgb, gt_depth, gt_normal, gt_alpha,
cfg.loss.input_depth_is_ray_depth);
return _engine_train_step_after_setup(
@@ -539,10 +539,13 @@ static std::map<std::string, float> _engine_train_step_split_warped(
TorchTensorView post_intrins,
TorchTensorView post_dist_coeffs,
std::string input_camera_model,
std::string input_distortion,
int B_in, int in_H, int in_W,
int K,
TorchTensorView input_intrins,
TorchTensorView input_dist_coeffs,
TorchTensorView input_source_models,
TorchTensorView input_source_params,
TorchTensorView gt_rgb_byte,
TorchTensorView gt_alpha_byte,
int mask_in_H, int mask_in_W,
@@ -564,20 +567,27 @@ static std::map<std::string, float> _engine_train_step_split_warped(
if (K <= 0)
throw std::runtime_error("split_batch (warped): K must be positive");
// Cubemap faces are canonical pinhole. K == 1 is the re-distort path,
// whose destination is the camera the parser fitted -- the input one.
const std::string post_model = K > 1 ? "PINHOLE" : input_camera_model;
const std::string post_dist = K > 1 ? "NONE" : input_distortion;
// Single input image (B_in == 1) -> nothing to split; route through the
// standard warped path so K cams are processed in one shot. grad_scale
// stays at 1.0 (the normal post-batch normalization is correct).
if (B_in == 1) {
set_camera_params(out_W, out_H, "PINHOLE",
set_camera_params(out_W, out_H, post_model, post_dist,
post_viewmats, post_intrins, post_dist_coeffs);
set_training_data_warped(input_camera_model,
set_training_data_warped(input_camera_model, input_distortion,
B_in, in_H, in_W, K, out_H, out_W,
gt_rgb_byte, gt_alpha_byte,
mask_in_H, mask_in_W,
gt_depth_byte, depth_in_H, depth_in_W,
gt_normal_byte, normal_in_H, normal_in_W,
cfg.loss.input_depth_is_ray_depth,
input_intrins, input_dist_coeffs, axes_dev);
input_intrins, input_dist_coeffs,
input_source_models, input_source_params,
axes_dev);
return _engine_train_step_after_setup(
step, max_steps, std::move(primitive), sh_degree, packed,
bilagrid_cam_indices, cfg);
@@ -613,6 +623,10 @@ static std::map<std::string, float> _engine_train_step_split_warped(
TorchTensorView nrm_k = _slice_tv_first_dim(gt_normal_byte, k);
TorchTensorView i_itr_k = _slice_tv_first_dim(input_intrins, k);
TorchTensorView i_dst_k = _slice_tv_first_dim(input_dist_coeffs, k);
TorchTensorView i_src_m_k = std::get<0>(input_source_models) == 0
? input_source_models : _slice_tv_first_dim(input_source_models, k);
TorchTensorView i_src_p_k = std::get<0>(input_source_params) == 0
? input_source_params : _slice_tv_first_dim(input_source_params, k);
// Per-input-image POST-split slices (B_post axis, K consecutive rows
// per input).
@@ -621,15 +635,17 @@ static std::map<std::string, float> _engine_train_step_split_warped(
TorchTensorView p_dst_k = _slice_tv_range_first_dim(post_dist_coeffs, k * K, K);
TorchTensorView bgi_k = _slice_tv_range_first_dim(bilagrid_cam_indices, k * K, K);
set_camera_params(out_W, out_H, "PINHOLE", p_vmt_k, p_itr_k, p_dst_k);
set_training_data_warped(input_camera_model,
set_camera_params(out_W, out_H, post_model, post_dist,
p_vmt_k, p_itr_k, p_dst_k);
set_training_data_warped(input_camera_model, input_distortion,
/*B_in=*/1, in_H, in_W, K, out_H, out_W,
rgb_k, mask_k,
mask_in_H, mask_in_W,
dep_k, depth_in_H, depth_in_W,
nrm_k, normal_in_H, normal_in_W,
cfg.loss.input_depth_is_ray_depth,
i_itr_k, i_dst_k, axes_dev);
i_itr_k, i_dst_k, i_src_m_k, i_src_p_k,
axes_dev);
_set_cur_cam_indices(bgi_k);
engine_viewer_capture_thumbnails(bgi_k);
@@ -681,13 +697,16 @@ std::map<std::string, float> engine_train_step_warped(
int out_W, int out_H,
TorchTensorView post_viewmats, // [B*K, 4, 4]
TorchTensorView post_intrins, // [B*K, 4]
TorchTensorView post_dist_coeffs, // [B*K, 10]
TorchTensorView post_dist_coeffs, // [B*K, 8]
// Warp inputs (operate on INPUT shape).
std::string input_camera_model, // "FISHEYE" / "EQUISOLID" / "EQUIRECTANGULAR"
std::string input_distortion,
int B_in, int in_H, int in_W,
int K,
TorchTensorView input_intrins, // [B_in, 4]
TorchTensorView input_dist_coeffs, // [B_in, 10]
TorchTensorView input_dist_coeffs, // [B_in, 8]
TorchTensorView input_source_models, // [B_in] int32 (nullable)
TorchTensorView input_source_params, // [B_in, 16]
TorchTensorView gt_rgb_byte, // [B_in, in_H, in_W, 3] u8/u16
TorchTensorView gt_alpha_byte, // [B_in, mask_in_H, mask_in_W, 1] u8 (nullable)
int mask_in_H, int mask_in_W,
@@ -704,25 +723,31 @@ std::map<std::string, float> engine_train_step_warped(
return _engine_train_step_split_warped(
step, max_steps, std::move(primitive), sh_degree, packed,
out_W, out_H, post_viewmats, post_intrins, post_dist_coeffs,
std::move(input_camera_model), B_in, in_H, in_W, K,
std::move(input_camera_model), std::move(input_distortion), B_in, in_H, in_W, K,
input_intrins, input_dist_coeffs,
input_source_models, input_source_params,
gt_rgb_byte, gt_alpha_byte, mask_in_H, mask_in_W,
gt_depth_byte, depth_in_H, depth_in_W,
gt_normal_byte, normal_in_H, normal_in_W,
axes_dev, bilagrid_cam_indices, cfg);
}
// Camera table is set up at POST-split resolution + PINHOLE.
set_camera_params(out_W, out_H, "PINHOLE",
// Cubemap faces are canonical pinhole; K == 1 (re-distort) keeps the
// camera the parser fitted, which is the input one.
set_camera_params(out_W, out_H,
K > 1 ? "PINHOLE" : input_camera_model,
K > 1 ? "NONE" : input_distortion,
post_viewmats, post_intrins, post_dist_coeffs);
// GT is warped on the fly into a float [B*K, out_H, out_W, 3] buffer.
set_training_data_warped(input_camera_model,
set_training_data_warped(input_camera_model, input_distortion,
B_in, in_H, in_W, K, out_H, out_W,
gt_rgb_byte, gt_alpha_byte,
mask_in_H, mask_in_W,
gt_depth_byte, depth_in_H, depth_in_W,
gt_normal_byte, normal_in_H, normal_in_W,
cfg.loss.input_depth_is_ray_depth,
input_intrins, input_dist_coeffs, axes_dev);
input_intrins, input_dist_coeffs,
input_source_models, input_source_params,
axes_dev);
return _engine_train_step_after_setup(
step, max_steps, std::move(primitive), sh_degree, packed,
bilagrid_cam_indices, cfg);
+850
View File
@@ -0,0 +1,850 @@
#pragma once
#include "generated/slang.cuh"
inline __device__ float dot_0(float2 x_0, float2 y_0)
{
int i_0 = int(0);
float result_0 = 0.0f;
for(;;)
{
if(i_0 < int(2))
{
}
else
{
break;
}
float result_1 = result_0 + _slang_vector_get_element(x_0, i_0) * _slang_vector_get_element(y_0, i_0);
i_0 = i_0 + int(1);
result_0 = result_1;
}
return result_0;
}
inline __device__ float dot_1(float3 x_1, float3 y_1)
{
int i_1 = int(0);
float result_2 = 0.0f;
for(;;)
{
if(i_1 < int(3))
{
}
else
{
break;
}
float result_3 = result_2 + _slang_vector_get_element(x_1, i_1) * _slang_vector_get_element(y_1, i_1);
i_1 = i_1 + int(1);
result_2 = result_3;
}
return result_2;
}
inline __device__ float length_0(float2 x_2)
{
return (F32_sqrt((dot_0(x_2, x_2))));
}
inline __device__ float length_1(float3 x_3)
{
return (F32_sqrt((dot_1(x_3, x_3))));
}
inline __device__ float3 normalize_0(float3 x_4)
{
return x_4 / make_float3 (length_1(x_4));
}
inline __device__ float3 cross_0(float3 left_0, float3 right_0)
{
float _S1 = left_0.y;
float _S2 = right_0.z;
float _S3 = left_0.z;
float _S4 = right_0.y;
float _S5 = right_0.x;
float _S6 = left_0.x;
return make_float3 (_S1 * _S2 - _S3 * _S4, _S3 * _S5 - _S6 * _S2, _S6 * _S4 - _S1 * _S5);
}
inline __device__ bool source_project(int model_id_0, FixedArray<float, 16> params_0, float3 ray_0, float2 * uv_0)
{
float2 a_0;
bool _S7;
float dy_0;
float dx_0;
bool _S8;
bool _S9;
bool _S10;
bool _S11;
bool _S12;
bool _S13;
bool _S14;
for(;;)
{
bool _S15 = model_id_0 == int(1000);
_S8 = _S15;
if(_S15)
{
for(;;)
{
*uv_0 = make_float2 (0.0f);
int base_0 = int(params_0[int(13)]);
if(base_0 == int(0))
{
float _S16 = ray_0.z;
if(_S16 < 9.999999960041972e-13f)
{
_S7 = false;
break;
}
a_0 = float2 {ray_0.x, ray_0.y} / make_float2 (_S16);
}
else
{
float2 _S17 = float2 {ray_0.x, ray_0.y};
float r_0 = length_0(_S17);
float _S18 = ray_0.z;
float theta_0 = (F32_atan2((r_0), (_S18)));
if(base_0 == int(1))
{
if(theta_0 < 0.00100000004749745f)
{
dx_0 = (1.0f - theta_0 * theta_0 / 3.0f) / _S18;
}
else
{
dx_0 = theta_0 / r_0;
}
}
else
{
if(r_0 < 9.99999997475242708e-07f)
{
dx_0 = (1.0f - theta_0 * theta_0 / 24.0f) / _S18;
}
else
{
dx_0 = 2.0f * (F32_sin((0.5f * theta_0))) / r_0;
}
}
a_0 = _S17 * make_float2 (dx_0);
}
float u_0 = a_0.x;
float v_0 = a_0.y;
float r2_0 = u_0 * u_0 + v_0 * v_0;
if((params_0[int(14)]) != 0.0f)
{
float radial_0 = (1.0f + r2_0 * (params_0[int(5)] + r2_0 * (params_0[int(6)] + r2_0 * params_0[int(7)]))) / (1.0f + r2_0 * (params_0[int(8)] + r2_0 * (params_0[int(9)] + r2_0 * params_0[int(10)])));
float _S19 = v_0 * radial_0 + 2.0f * params_0[int(12)] * u_0 * v_0 + params_0[int(11)] * (r2_0 + 2.0f * v_0 * v_0);
dx_0 = u_0 * radial_0 + 2.0f * params_0[int(11)] * u_0 * v_0 + params_0[int(12)] * (r2_0 + 2.0f * u_0 * u_0);
dy_0 = _S19;
}
else
{
float radial_1 = 1.0f + r2_0 * (params_0[int(5)] + r2_0 * (params_0[int(6)] + r2_0 * (params_0[int(7)] + r2_0 * params_0[int(8)])));
float _S20 = v_0 * radial_1 + 2.0f * params_0[int(10)] * u_0 * v_0 + params_0[int(9)] * (r2_0 + 2.0f * v_0 * v_0) + params_0[int(12)] * r2_0;
dx_0 = u_0 * radial_1 + 2.0f * params_0[int(9)] * u_0 * v_0 + params_0[int(10)] * (r2_0 + 2.0f * u_0 * u_0) + params_0[int(11)] * r2_0;
dy_0 = _S20;
}
*uv_0 = make_float2 (params_0[int(0)] * dx_0 + params_0[int(4)] * dy_0 + params_0[int(2)], params_0[int(1)] * dy_0 + params_0[int(3)]);
_S7 = true;
break;
}
break;
}
if(model_id_0 == int(7))
{
for(;;)
{
*uv_0 = make_float2 (0.0f);
float _S21 = ray_0.z;
if(_S21 < 9.999999960041972e-13f)
{
_S7 = false;
break;
}
float x_5 = ray_0.x / _S21;
float y_2 = ray_0.y / _S21;
float r2_1 = x_5 * x_5 + y_2 * y_2;
float om2_0 = params_0[int(4)] * params_0[int(4)];
if(om2_0 < 0.00009999999747379f)
{
dx_0 = om2_0 * r2_1 / 3.0f - om2_0 / 12.0f + 1.0f;
}
else
{
if(r2_1 < 0.00009999999747379f)
{
float t_0 = (F32_tan((params_0[int(4)] * 0.5f)));
dx_0 = -2.0f * t_0 * (4.0f * r2_1 * t_0 * t_0 - 3.0f) / (3.0f * params_0[int(4)]);
}
else
{
float r_1 = (F32_sqrt((r2_1)));
dx_0 = (F32_atan((r_1 * 2.0f * (F32_tan((params_0[int(4)] * 0.5f)))))) / (r_1 * params_0[int(4)]);
}
}
*uv_0 = make_float2 (params_0[int(0)] * x_5 * dx_0 + params_0[int(2)], params_0[int(1)] * y_2 * dx_0 + params_0[int(3)]);
_S7 = true;
break;
}
break;
}
if(model_id_0 == int(12))
{
for(;;)
{
*uv_0 = make_float2 (0.0f);
float _S22 = ray_0.x;
float _S23 = ray_0.y;
float _S24 = ray_0.z;
float disc_0 = _S24 * _S24 - 4.0f * (_S22 * _S22 + _S23 * _S23) * params_0[int(3)];
bool _S25 = disc_0 < 0.0f;
_S9 = _S25;
if(_S25)
{
break;
}
float _S26 = params_0[int(0)] * (2.0f / (_S24 + (F32_sqrt((disc_0)))));
*uv_0 = make_float2 (_S26 * _S22 + params_0[int(1)], _S26 * _S23 + params_0[int(2)]);
break;
}
_S7 = !_S9;
break;
}
if(model_id_0 == int(13))
{
for(;;)
{
*uv_0 = make_float2 (0.0f);
float _S27 = ray_0.x;
float _S28 = ray_0.y;
float _S29 = ray_0.z;
float disc_1 = _S29 * _S29 - 4.0f * (_S27 * _S27 + _S28 * _S28) * params_0[int(4)];
bool _S30 = disc_1 < 0.0f;
_S10 = _S30;
if(_S30)
{
break;
}
float r_2 = 2.0f / (_S29 + (F32_sqrt((disc_1))));
*uv_0 = make_float2 (params_0[int(0)] * r_2 * _S27 + params_0[int(2)], params_0[int(1)] * r_2 * _S28 + params_0[int(3)]);
break;
}
_S7 = !_S10;
break;
}
if(model_id_0 == int(16))
{
for(;;)
{
*uv_0 = make_float2 (0.0f);
float _S31 = ray_0.z;
if(_S31 < 9.999999960041972e-13f)
{
_S7 = false;
break;
}
float _S32 = ray_0.x;
float _S33 = ray_0.y;
float rho2_0 = params_0[int(5)] * (_S32 * _S32 + _S33 * _S33) + _S31 * _S31;
if(rho2_0 < 0.0f)
{
_S7 = false;
break;
}
float den_0 = params_0[int(4)] * (F32_sqrt((rho2_0))) + (1.0f - params_0[int(4)]) * _S31;
if(den_0 < 9.999999960041972e-13f)
{
_S7 = false;
break;
}
*uv_0 = make_float2 (params_0[int(0)] * _S32 / den_0 + params_0[int(2)], params_0[int(1)] * _S33 / den_0 + params_0[int(3)]);
_S7 = true;
break;
}
break;
}
if(model_id_0 == int(11))
{
for(;;)
{
*uv_0 = make_float2 (0.0f);
float _S34 = ray_0.z;
if(_S34 < 9.999999960041972e-13f)
{
_S7 = false;
break;
}
float xn_0 = ray_0.x / _S34;
float yn_0 = ray_0.y / _S34;
float r_3 = (F32_sqrt((xn_0 * xn_0 + yn_0 * yn_0)));
if(r_3 > 9.999999960041972e-13f)
{
float th_0 = (F32_atan((r_3)));
float vv_0 = yn_0 * (th_0 / r_3);
dx_0 = xn_0 * (th_0 / r_3);
dy_0 = vv_0;
}
else
{
dx_0 = xn_0;
dy_0 = yn_0;
}
float _S35 = dx_0 * dx_0 + dy_0 * dy_0;
float pw_0 = _S35 * _S35;
float pw_1 = pw_0 * _S35;
float pw_2 = pw_1 * _S35;
float pw_3 = pw_2 * _S35;
float rad_0 = 1.0f + params_0[int(4)] * _S35 + params_0[int(5)] * pw_0 + params_0[int(6)] * pw_1 + params_0[int(7)] * pw_2 + params_0[int(8)] * pw_3 + params_0[int(9)] * (pw_3 * _S35);
float x_6 = rad_0 * dx_0;
float y_3 = rad_0 * dy_0;
float x2_0 = x_6 * x_6;
float y2_0 = y_3 * y_3;
float xy_0 = x_6 * y_3;
float r2_2 = x2_0 + y2_0;
float r4_0 = r2_2 * r2_2;
*uv_0 = make_float2 (params_0[int(0)] * (x_6 + 2.0f * params_0[int(11)] * xy_0 + params_0[int(10)] * (r2_2 + 2.0f * x2_0) + params_0[int(12)] * r2_2 + params_0[int(13)] * r4_0) + params_0[int(2)], params_0[int(1)] * (y_3 + 2.0f * params_0[int(10)] * xy_0 + params_0[int(11)] * (r2_2 + 2.0f * y2_0) + params_0[int(14)] * r2_2 + params_0[int(15)] * r4_0) + params_0[int(3)]);
_S7 = true;
break;
}
break;
}
*uv_0 = make_float2 (0.0f);
_S7 = false;
break;
}
if(!_S7)
{
return false;
}
float2 _S36 = *uv_0;
for(;;)
{
float3 n_0 = normalize_0(ray_0);
float3 t_1;
if((F32_abs((n_0.x))) < 0.89999997615814209f)
{
t_1 = make_float3 (1.0f, 0.0f, 0.0f);
}
else
{
t_1 = make_float3 (0.0f, 1.0f, 0.0f);
}
float3 e1_0 = normalize_0(cross_0(t_1, n_0));
float3 e2_0 = cross_0(n_0, e1_0);
float3 _S37 = n_0 + make_float3 (0.00100000004749745f) * e1_0;
for(;;)
{
if(_S8)
{
for(;;)
{
float2 _S38 = make_float2 (0.0f);
int base_1 = int(params_0[int(13)]);
if(base_1 == int(0))
{
float _S39 = _S37.z;
if(_S39 < 9.999999960041972e-13f)
{
_S7 = false;
a_0 = _S38;
break;
}
a_0 = float2 {_S37.x, _S37.y} / make_float2 (_S39);
}
else
{
float2 _S40 = float2 {_S37.x, _S37.y};
float r_4 = length_0(_S40);
float _S41 = _S37.z;
float theta_1 = (F32_atan2((r_4), (_S41)));
if(base_1 == int(1))
{
if(theta_1 < 0.00100000004749745f)
{
dx_0 = (1.0f - theta_1 * theta_1 / 3.0f) / _S41;
}
else
{
dx_0 = theta_1 / r_4;
}
}
else
{
if(r_4 < 9.99999997475242708e-07f)
{
dx_0 = (1.0f - theta_1 * theta_1 / 24.0f) / _S41;
}
else
{
dx_0 = 2.0f * (F32_sin((0.5f * theta_1))) / r_4;
}
}
a_0 = _S40 * make_float2 (dx_0);
}
float u_1 = a_0.x;
float v_1 = a_0.y;
float r2_3 = u_1 * u_1 + v_1 * v_1;
if((params_0[int(14)]) != 0.0f)
{
float radial_2 = (1.0f + r2_3 * (params_0[int(5)] + r2_3 * (params_0[int(6)] + r2_3 * params_0[int(7)]))) / (1.0f + r2_3 * (params_0[int(8)] + r2_3 * (params_0[int(9)] + r2_3 * params_0[int(10)])));
float _S42 = v_1 * radial_2 + 2.0f * params_0[int(12)] * u_1 * v_1 + params_0[int(11)] * (r2_3 + 2.0f * v_1 * v_1);
dx_0 = u_1 * radial_2 + 2.0f * params_0[int(11)] * u_1 * v_1 + params_0[int(12)] * (r2_3 + 2.0f * u_1 * u_1);
dy_0 = _S42;
}
else
{
float radial_3 = 1.0f + r2_3 * (params_0[int(5)] + r2_3 * (params_0[int(6)] + r2_3 * (params_0[int(7)] + r2_3 * params_0[int(8)])));
float _S43 = v_1 * radial_3 + 2.0f * params_0[int(10)] * u_1 * v_1 + params_0[int(9)] * (r2_3 + 2.0f * v_1 * v_1) + params_0[int(12)] * r2_3;
dx_0 = u_1 * radial_3 + 2.0f * params_0[int(9)] * u_1 * v_1 + params_0[int(10)] * (r2_3 + 2.0f * u_1 * u_1) + params_0[int(11)] * r2_3;
dy_0 = _S43;
}
float2 _S44 = make_float2 (params_0[int(0)] * dx_0 + params_0[int(4)] * dy_0 + params_0[int(2)], params_0[int(1)] * dy_0 + params_0[int(3)]);
_S7 = true;
a_0 = _S44;
break;
}
break;
}
if(model_id_0 == int(7))
{
for(;;)
{
float2 _S45 = make_float2 (0.0f);
float _S46 = _S37.z;
if(_S46 < 9.999999960041972e-13f)
{
_S7 = false;
a_0 = _S45;
break;
}
float x_7 = _S37.x / _S46;
float y_4 = _S37.y / _S46;
float r2_4 = x_7 * x_7 + y_4 * y_4;
float om2_1 = params_0[int(4)] * params_0[int(4)];
if(om2_1 < 0.00009999999747379f)
{
dx_0 = om2_1 * r2_4 / 3.0f - om2_1 / 12.0f + 1.0f;
}
else
{
if(r2_4 < 0.00009999999747379f)
{
float t_2 = (F32_tan((params_0[int(4)] * 0.5f)));
dx_0 = -2.0f * t_2 * (4.0f * r2_4 * t_2 * t_2 - 3.0f) / (3.0f * params_0[int(4)]);
}
else
{
float r_5 = (F32_sqrt((r2_4)));
dx_0 = (F32_atan((r_5 * 2.0f * (F32_tan((params_0[int(4)] * 0.5f)))))) / (r_5 * params_0[int(4)]);
}
}
float2 _S47 = make_float2 (params_0[int(0)] * x_7 * dx_0 + params_0[int(2)], params_0[int(1)] * y_4 * dx_0 + params_0[int(3)]);
_S7 = true;
a_0 = _S47;
break;
}
break;
}
if(model_id_0 == int(12))
{
for(;;)
{
float2 _S48 = make_float2 (0.0f);
float _S49 = _S37.x;
float _S50 = _S37.y;
float _S51 = _S37.z;
float disc_2 = _S51 * _S51 - 4.0f * (_S49 * _S49 + _S50 * _S50) * params_0[int(3)];
bool _S52 = disc_2 < 0.0f;
_S11 = _S52;
if(_S52)
{
a_0 = _S48;
break;
}
float _S53 = params_0[int(0)] * (2.0f / (_S51 + (F32_sqrt((disc_2)))));
a_0 = make_float2 (_S53 * _S49 + params_0[int(1)], _S53 * _S50 + params_0[int(2)]);
break;
}
_S7 = !_S11;
break;
}
if(model_id_0 == int(13))
{
for(;;)
{
float2 _S54 = make_float2 (0.0f);
float _S55 = _S37.x;
float _S56 = _S37.y;
float _S57 = _S37.z;
float disc_3 = _S57 * _S57 - 4.0f * (_S55 * _S55 + _S56 * _S56) * params_0[int(4)];
bool _S58 = disc_3 < 0.0f;
_S12 = _S58;
if(_S58)
{
a_0 = _S54;
break;
}
float r_6 = 2.0f / (_S57 + (F32_sqrt((disc_3))));
a_0 = make_float2 (params_0[int(0)] * r_6 * _S55 + params_0[int(2)], params_0[int(1)] * r_6 * _S56 + params_0[int(3)]);
break;
}
_S7 = !_S12;
break;
}
if(model_id_0 == int(16))
{
for(;;)
{
float2 _S59 = make_float2 (0.0f);
float _S60 = _S37.z;
if(_S60 < 9.999999960041972e-13f)
{
_S7 = false;
a_0 = _S59;
break;
}
float _S61 = _S37.x;
float _S62 = _S37.y;
float rho2_1 = params_0[int(5)] * (_S61 * _S61 + _S62 * _S62) + _S60 * _S60;
if(rho2_1 < 0.0f)
{
_S7 = false;
a_0 = _S59;
break;
}
float den_1 = params_0[int(4)] * (F32_sqrt((rho2_1))) + (1.0f - params_0[int(4)]) * _S60;
if(den_1 < 9.999999960041972e-13f)
{
_S7 = false;
a_0 = _S59;
break;
}
float2 _S63 = make_float2 (params_0[int(0)] * _S61 / den_1 + params_0[int(2)], params_0[int(1)] * _S62 / den_1 + params_0[int(3)]);
_S7 = true;
a_0 = _S63;
break;
}
break;
}
if(model_id_0 == int(11))
{
for(;;)
{
float2 _S64 = make_float2 (0.0f);
float _S65 = _S37.z;
if(_S65 < 9.999999960041972e-13f)
{
_S7 = false;
a_0 = _S64;
break;
}
float xn_1 = _S37.x / _S65;
float yn_1 = _S37.y / _S65;
float r_7 = (F32_sqrt((xn_1 * xn_1 + yn_1 * yn_1)));
if(r_7 > 9.999999960041972e-13f)
{
float th_1 = (F32_atan((r_7)));
float vv_1 = yn_1 * (th_1 / r_7);
dx_0 = xn_1 * (th_1 / r_7);
dy_0 = vv_1;
}
else
{
dx_0 = xn_1;
dy_0 = yn_1;
}
float _S66 = dx_0 * dx_0 + dy_0 * dy_0;
float pw_4 = _S66 * _S66;
float pw_5 = pw_4 * _S66;
float pw_6 = pw_5 * _S66;
float pw_7 = pw_6 * _S66;
float rad_1 = 1.0f + params_0[int(4)] * _S66 + params_0[int(5)] * pw_4 + params_0[int(6)] * pw_5 + params_0[int(7)] * pw_6 + params_0[int(8)] * pw_7 + params_0[int(9)] * (pw_7 * _S66);
float x_8 = rad_1 * dx_0;
float y_5 = rad_1 * dy_0;
float x2_1 = x_8 * x_8;
float y2_1 = y_5 * y_5;
float xy_1 = x_8 * y_5;
float r2_5 = x2_1 + y2_1;
float r4_1 = r2_5 * r2_5;
float2 _S67 = make_float2 (params_0[int(0)] * (x_8 + 2.0f * params_0[int(11)] * xy_1 + params_0[int(10)] * (r2_5 + 2.0f * x2_1) + params_0[int(12)] * r2_5 + params_0[int(13)] * r4_1) + params_0[int(2)], params_0[int(1)] * (y_5 + 2.0f * params_0[int(10)] * xy_1 + params_0[int(11)] * (r2_5 + 2.0f * y2_1) + params_0[int(14)] * r2_5 + params_0[int(15)] * r4_1) + params_0[int(3)]);
_S7 = true;
a_0 = _S67;
break;
}
break;
}
float2 _S68 = make_float2 (0.0f);
_S7 = false;
a_0 = _S68;
break;
}
if(!_S7)
{
_S7 = false;
break;
}
float2 b_0;
float3 _S69 = n_0 + make_float3 (0.00100000004749745f) * e2_0;
for(;;)
{
if(_S8)
{
for(;;)
{
float2 _S70 = make_float2 (0.0f);
int base_2 = int(params_0[int(13)]);
if(base_2 == int(0))
{
float _S71 = _S69.z;
if(_S71 < 9.999999960041972e-13f)
{
_S7 = false;
b_0 = _S70;
break;
}
b_0 = float2 {_S69.x, _S69.y} / make_float2 (_S71);
}
else
{
float2 _S72 = float2 {_S69.x, _S69.y};
float r_8 = length_0(_S72);
float _S73 = _S69.z;
float theta_2 = (F32_atan2((r_8), (_S73)));
if(base_2 == int(1))
{
if(theta_2 < 0.00100000004749745f)
{
dx_0 = (1.0f - theta_2 * theta_2 / 3.0f) / _S73;
}
else
{
dx_0 = theta_2 / r_8;
}
}
else
{
if(r_8 < 9.99999997475242708e-07f)
{
dx_0 = (1.0f - theta_2 * theta_2 / 24.0f) / _S73;
}
else
{
dx_0 = 2.0f * (F32_sin((0.5f * theta_2))) / r_8;
}
}
b_0 = _S72 * make_float2 (dx_0);
}
float u_2 = b_0.x;
float v_2 = b_0.y;
float r2_6 = u_2 * u_2 + v_2 * v_2;
if((params_0[int(14)]) != 0.0f)
{
float radial_4 = (1.0f + r2_6 * (params_0[int(5)] + r2_6 * (params_0[int(6)] + r2_6 * params_0[int(7)]))) / (1.0f + r2_6 * (params_0[int(8)] + r2_6 * (params_0[int(9)] + r2_6 * params_0[int(10)])));
float _S74 = v_2 * radial_4 + 2.0f * params_0[int(12)] * u_2 * v_2 + params_0[int(11)] * (r2_6 + 2.0f * v_2 * v_2);
dx_0 = u_2 * radial_4 + 2.0f * params_0[int(11)] * u_2 * v_2 + params_0[int(12)] * (r2_6 + 2.0f * u_2 * u_2);
dy_0 = _S74;
}
else
{
float radial_5 = 1.0f + r2_6 * (params_0[int(5)] + r2_6 * (params_0[int(6)] + r2_6 * (params_0[int(7)] + r2_6 * params_0[int(8)])));
float _S75 = v_2 * radial_5 + 2.0f * params_0[int(10)] * u_2 * v_2 + params_0[int(9)] * (r2_6 + 2.0f * v_2 * v_2) + params_0[int(12)] * r2_6;
dx_0 = u_2 * radial_5 + 2.0f * params_0[int(9)] * u_2 * v_2 + params_0[int(10)] * (r2_6 + 2.0f * u_2 * u_2) + params_0[int(11)] * r2_6;
dy_0 = _S75;
}
float2 _S76 = make_float2 (params_0[int(0)] * dx_0 + params_0[int(4)] * dy_0 + params_0[int(2)], params_0[int(1)] * dy_0 + params_0[int(3)]);
_S7 = true;
b_0 = _S76;
break;
}
break;
}
if(model_id_0 == int(7))
{
for(;;)
{
float2 _S77 = make_float2 (0.0f);
float _S78 = _S69.z;
if(_S78 < 9.999999960041972e-13f)
{
_S7 = false;
b_0 = _S77;
break;
}
float x_9 = _S69.x / _S78;
float y_6 = _S69.y / _S78;
float r2_7 = x_9 * x_9 + y_6 * y_6;
float om2_2 = params_0[int(4)] * params_0[int(4)];
if(om2_2 < 0.00009999999747379f)
{
dx_0 = om2_2 * r2_7 / 3.0f - om2_2 / 12.0f + 1.0f;
}
else
{
if(r2_7 < 0.00009999999747379f)
{
float t_3 = (F32_tan((params_0[int(4)] * 0.5f)));
dx_0 = -2.0f * t_3 * (4.0f * r2_7 * t_3 * t_3 - 3.0f) / (3.0f * params_0[int(4)]);
}
else
{
float r_9 = (F32_sqrt((r2_7)));
dx_0 = (F32_atan((r_9 * 2.0f * (F32_tan((params_0[int(4)] * 0.5f)))))) / (r_9 * params_0[int(4)]);
}
}
float2 _S79 = make_float2 (params_0[int(0)] * x_9 * dx_0 + params_0[int(2)], params_0[int(1)] * y_6 * dx_0 + params_0[int(3)]);
_S7 = true;
b_0 = _S79;
break;
}
break;
}
if(model_id_0 == int(12))
{
for(;;)
{
float2 _S80 = make_float2 (0.0f);
float _S81 = _S69.x;
float _S82 = _S69.y;
float _S83 = _S69.z;
float disc_4 = _S83 * _S83 - 4.0f * (_S81 * _S81 + _S82 * _S82) * params_0[int(3)];
bool _S84 = disc_4 < 0.0f;
_S13 = _S84;
if(_S84)
{
b_0 = _S80;
break;
}
float _S85 = params_0[int(0)] * (2.0f / (_S83 + (F32_sqrt((disc_4)))));
b_0 = make_float2 (_S85 * _S81 + params_0[int(1)], _S85 * _S82 + params_0[int(2)]);
break;
}
_S7 = !_S13;
break;
}
if(model_id_0 == int(13))
{
for(;;)
{
float2 _S86 = make_float2 (0.0f);
float _S87 = _S69.x;
float _S88 = _S69.y;
float _S89 = _S69.z;
float disc_5 = _S89 * _S89 - 4.0f * (_S87 * _S87 + _S88 * _S88) * params_0[int(4)];
bool _S90 = disc_5 < 0.0f;
_S14 = _S90;
if(_S90)
{
b_0 = _S86;
break;
}
float r_10 = 2.0f / (_S89 + (F32_sqrt((disc_5))));
b_0 = make_float2 (params_0[int(0)] * r_10 * _S87 + params_0[int(2)], params_0[int(1)] * r_10 * _S88 + params_0[int(3)]);
break;
}
_S7 = !_S14;
break;
}
if(model_id_0 == int(16))
{
for(;;)
{
float2 _S91 = make_float2 (0.0f);
float _S92 = _S69.z;
if(_S92 < 9.999999960041972e-13f)
{
_S7 = false;
b_0 = _S91;
break;
}
float _S93 = _S69.x;
float _S94 = _S69.y;
float rho2_2 = params_0[int(5)] * (_S93 * _S93 + _S94 * _S94) + _S92 * _S92;
if(rho2_2 < 0.0f)
{
_S7 = false;
b_0 = _S91;
break;
}
float den_2 = params_0[int(4)] * (F32_sqrt((rho2_2))) + (1.0f - params_0[int(4)]) * _S92;
if(den_2 < 9.999999960041972e-13f)
{
_S7 = false;
b_0 = _S91;
break;
}
float2 _S95 = make_float2 (params_0[int(0)] * _S93 / den_2 + params_0[int(2)], params_0[int(1)] * _S94 / den_2 + params_0[int(3)]);
_S7 = true;
b_0 = _S95;
break;
}
break;
}
if(model_id_0 == int(11))
{
for(;;)
{
float2 _S96 = make_float2 (0.0f);
float _S97 = _S69.z;
if(_S97 < 9.999999960041972e-13f)
{
_S7 = false;
b_0 = _S96;
break;
}
float xn_2 = _S69.x / _S97;
float yn_2 = _S69.y / _S97;
float r_11 = (F32_sqrt((xn_2 * xn_2 + yn_2 * yn_2)));
if(r_11 > 9.999999960041972e-13f)
{
float th_2 = (F32_atan((r_11)));
float vv_2 = yn_2 * (th_2 / r_11);
dx_0 = xn_2 * (th_2 / r_11);
dy_0 = vv_2;
}
else
{
dx_0 = xn_2;
dy_0 = yn_2;
}
float _S98 = dx_0 * dx_0 + dy_0 * dy_0;
float pw_8 = _S98 * _S98;
float pw_9 = pw_8 * _S98;
float pw_10 = pw_9 * _S98;
float pw_11 = pw_10 * _S98;
float rad_2 = 1.0f + params_0[int(4)] * _S98 + params_0[int(5)] * pw_8 + params_0[int(6)] * pw_9 + params_0[int(7)] * pw_10 + params_0[int(8)] * pw_11 + params_0[int(9)] * (pw_11 * _S98);
float x_10 = rad_2 * dx_0;
float y_7 = rad_2 * dy_0;
float x2_2 = x_10 * x_10;
float y2_2 = y_7 * y_7;
float xy_2 = x_10 * y_7;
float r2_8 = x2_2 + y2_2;
float r4_2 = r2_8 * r2_8;
float2 _S99 = make_float2 (params_0[int(0)] * (x_10 + 2.0f * params_0[int(11)] * xy_2 + params_0[int(10)] * (r2_8 + 2.0f * x2_2) + params_0[int(12)] * r2_8 + params_0[int(13)] * r4_2) + params_0[int(2)], params_0[int(1)] * (y_7 + 2.0f * params_0[int(10)] * xy_2 + params_0[int(11)] * (r2_8 + 2.0f * y2_2) + params_0[int(14)] * r2_8 + params_0[int(15)] * r4_2) + params_0[int(3)]);
_S7 = true;
b_0 = _S99;
break;
}
break;
}
float2 _S100 = make_float2 (0.0f);
_S7 = false;
b_0 = _S100;
break;
}
if(!_S7)
{
_S7 = false;
break;
}
float2 j1_0 = a_0 - _S36;
float2 j2_0 = b_0 - _S36;
_S7 = (j1_0.x * j2_0.y - j1_0.y * j2_0.x) > 0.0f;
break;
}
return _S7;
}
+6419 -1961
View File
File diff suppressed because it is too large Load Diff
+25170 -8729
View File
File diff suppressed because it is too large Load Diff
+3732 -1212
View File
File diff suppressed because it is too large Load Diff
+155
View File
@@ -117,6 +117,161 @@ SS_MSG(equirect_not_2to1,
TR("EQUIRECTANGULAR kamera {0} {1}x{2} boyutunda, yani 2:1 değil. Motor tam "
"bir 360x180 panorama varsaydığı için dikey ölçeği yanlış alacak."));
SS_MSG(camera_model_fitted,
EN("no exact match here for the {0} camera model ({1} in this dataset); "
"fitted as {2} with {3} distortion, max error {4} px. Its images are "
"re-distorted to match."),
JA("{0} カメラモデル(このデータセットに {1} 台)には厳密に一致するものがないため、"
"{2} と {3} 歪みで近似しました(最大誤差 {4} px)。画像はそれに合わせて"
"再歪曲されます。"),
ZH_HANS("{0} 相机模型(本数据集中 {1} 台)没有精确对应的模型,已用 {2} 与 {3} "
"畸变拟合,最大误差 {4} 像素。其图像会相应重新畸变。"),
ZH_HANT("{0} 相機模型(本資料集中 {1} 台)沒有精確對應的模型,已用 {2} 與 {3} "
"畸變擬合,最大誤差 {4} 像素。其影像會相應重新畸變。"),
KO("{0} 카메라 모델(이 데이터셋에 {1} 대)은 정확히 일치하는 모델이 없어 {2} 와 "
"{3} 왜곡으로 근사했습니다. 최대 오차 {4} px. 해당 이미지는 그에 맞게 다시 "
"왜곡됩니다."),
ES("el modelo de cámara {0} ({1} en este conjunto) no tiene equivalente "
"exacto; ajustado como {2} con distorsión {3}, error máximo {4} px. Sus "
"imágenes se redistorsionan."),
FR("le modèle de caméra {0} ({1} dans ce jeu de données) n'a pas "
"d'équivalent exact ; ajusté en {2} avec la distorsion {3}, erreur "
"maximale {4} px. Ses images sont redistordues."),
DE("für das Kameramodell {0} ({1} in diesem Datensatz) gibt es hier keine "
"exakte Entsprechung; angepasst als {2} mit {3}-Verzeichnung, maximaler "
"Fehler {4} px. Ihre Bilder werden entsprechend neu verzeichnet."),
PT("o modelo de câmera {0} ({1} neste conjunto) não tem equivalente exato; "
"ajustado como {2} com distorção {3}, erro máximo {4} px. As imagens são "
"redistorcidas."),
IT("il modello di camera {0} ({1} in questo dataset) non ha un equivalente "
"esatto; approssimato come {2} con distorsione {3}, errore massimo {4} "
"px. Le immagini vengono ridistorte di conseguenza."),
NL("het cameramodel {0} ({1} in deze dataset) heeft hier geen exacte "
"tegenhanger; benaderd als {2} met {3}-vervorming, maximale fout {4} px. "
"De beelden worden opnieuw vervormd."),
RU("модель камеры {0} ({1} в этом наборе) не имеет точного соответствия; "
"приближена как {2} с искажением {3}, максимальная ошибка {4} пикс. Её "
"изображения переискажаются соответственно."),
TR("{0} kamera modeli (bu veri kumesinde {1} adet) icin birebir karsilik "
"yok; {2} ve {3} bozulmasi ile yaklasildi, en buyuk hata {4} px. "
"Goruntuleri buna gore yeniden bozuluyor."));
SS_MSG(camera_model_fitted_exact,
EN("no exact match here for the {0} camera model ({1} in this dataset); "
"fitted as {2} with {3} distortion to within {4} px, so its images are "
"used as they are."),
JA("{0} カメラモデル(このデータセットに {1} 台)には厳密に一致するものがないため、"
"{2} と {3} 歪みで近似しました(誤差 {4} px 以内)。画像はそのまま使います。"),
ZH_HANS("{0} 相机模型(本数据集中 {1} 台)没有精确对应的模型,已用 {2} 与 {3} "
"畸变拟合,误差在 {4} 像素以内,因此其图像按原样使用。"),
ZH_HANT("{0} 相機模型(本資料集中 {1} 台)沒有精確對應的模型,已用 {2} 與 {3} "
"畸變擬合,誤差在 {4} 像素以內,因此其影像按原樣使用。"),
KO("{0} 카메라 모델(이 데이터셋에 {1} 대)은 정확히 일치하는 모델이 없어 {2} 와 "
"{3} 왜곡으로 근사했습니다. 오차 {4} px 이내이므로 이미지는 그대로 사용합니다."),
ES("el modelo de cámara {0} ({1} en este conjunto) no tiene equivalente "
"exacto; ajustado como {2} con distorsión {3} con un error de {4} px, "
"así que sus imágenes se usan tal cual."),
FR("le modèle de caméra {0} ({1} dans ce jeu de données) n'a pas "
"d'équivalent exact ; ajusté en {2} avec la distorsion {3} à {4} px "
"près, donc ses images sont utilisées telles quelles."),
DE("für das Kameramodell {0} ({1} in diesem Datensatz) gibt es hier keine "
"exakte Entsprechung; angepasst als {2} mit {3}-Verzeichnung auf {4} px "
"genau, ihre Bilder werden daher unverändert verwendet."),
PT("o modelo de câmera {0} ({1} neste conjunto) não tem equivalente exato; "
"ajustado como {2} com distorção {3} com erro de {4} px, então as "
"imagens são usadas como estão."),
IT("il modello di camera {0} ({1} in questo dataset) non ha un equivalente "
"esatto; approssimato come {2} con distorsione {3} entro {4} px, quindi "
"le immagini sono usate così come sono."),
NL("het cameramodel {0} ({1} in deze dataset) heeft hier geen exacte "
"tegenhanger; benaderd als {2} met {3}-vervorming tot op {4} px, dus de "
"beelden worden ongewijzigd gebruikt."),
RU("модель камеры {0} ({1} в этом наборе) не имеет точного соответствия; "
"приближена как {2} с искажением {3} с точностью {4} пикс., поэтому её "
"изображения используются как есть."),
TR("{0} kamera modeli (bu veri kumesinde {1} adet) icin birebir karsilik "
"yok; {2} ve {3} bozulmasi ile {4} px hata payiyla yaklasildi, bu "
"yuzden goruntuleri oldugu gibi kullaniliyor."));
SS_MSG(camera_sensor_skew,
EN("the camera for {0} has a {1} px sensor skew, which no supported camera "
"model carries; its images are re-distorted onto a {2} camera with {3} "
"distortion, max error {4} px."),
JA("{0} のカメラには {1} px のセンサースキューがあり、対応するモデルがありません。"
"画像は {2} カメラ({3} 歪み)に合わせて再歪曲します(最大誤差 {4} px)。"),
ZH_HANS("{0} 的相机存在 {1} 像素的传感器切变,没有支持的相机模型能表示;其图像会"
"重新畸变到 {2} 相机与 {3} 畸变上,最大误差 {4} 像素。"),
ZH_HANT("{0} 的相機存在 {1} 像素的感光元件切變,沒有支援的相機模型能表示;其影像會"
"重新畸變到 {2} 相機與 {3} 畸變上,最大誤差 {4} 像素。"),
KO("{0} 의 카메라에 {1} px 센서 스큐가 있는데 이를 담는 카메라 모델이 없습니다. "
"이미지는 {2} 카메라와 {3} 왜곡에 맞춰 다시 왜곡됩니다. 최대 오차 {4} px."),
ES("la cámara de {0} tiene una inclinación de sensor de {1} px que ningún "
"modelo admitido representa; sus imágenes se redistorsionan a una cámara "
"{2} con distorsión {3}, error máximo {4} px."),
FR("la caméra de {0} a un cisaillement de capteur de {1} px qu'aucun modèle "
"pris en charge ne porte ; ses images sont redistordues vers une caméra "
"{2} avec la distorsion {3}, erreur maximale {4} px."),
DE("die Kamera von {0} hat eine Sensorscherung von {1} px, die kein "
"unterstütztes Kameramodell trägt; ihre Bilder werden auf eine "
"{2}-Kamera mit {3}-Verzeichnung umverzeichnet, maximaler Fehler {4} px."),
PT("a câmera de {0} tem uma inclinação de sensor de {1} px que nenhum modelo "
"suportado carrega; suas imagens são redistorcidas para uma câmera {2} "
"com distorção {3}, erro máximo {4} px."),
IT("la camera di {0} ha uno scorrimento del sensore di {1} px che nessun "
"modello supportato porta; le sue immagini vengono ridistorte su una "
"camera {2} con distorsione {3}, errore massimo {4} px."),
NL("de camera van {0} heeft een sensorschuining van {1} px die geen enkel "
"ondersteund cameramodel draagt; de beelden worden opnieuw vervormd naar "
"een {2}-camera met {3}-vervorming, maximale fout {4} px."),
RU("камера для {0} имеет наклон матрицы {1} пикс., которого нет ни в одной "
"поддерживаемой модели; её изображения переискажаются в камеру {2} с "
"искажением {3}, максимальная ошибка {4} пикс."),
TR("{0} icin kamerada {1} px sensor egimi var, bunu tasiyan desteklenen bir "
"kamera modeli yok; goruntuleri {3} bozulmali bir {2} kameraya yeniden "
"bozuluyor, en buyuk hata {4} px."));
SS_MSG(camera_model_fit_failed,
EN("the {0} camera model ({1} in this dataset) projects nothing this reader "
"understands, so it could not be fitted; falling back to a plain {2}. "
"What is reconstructed from those cameras will be wrong."),
JA("{0} カメラモデル(このデータセットに {1} 台)はこのリーダーが解釈できる投影を"
"返さず、近似できませんでした。素の {2} で代用します。これらのカメラからの"
"復元は正しくなりません。"),
ZH_HANS("{0} 相机模型(本数据集中 {1} 台)未给出本读取器能理解的投影,无法拟合;"
"改用普通的 {2}。由这些相机重建的结果会是错的。"),
ZH_HANT("{0} 相機模型(本資料集中 {1} 台)未給出本讀取器能理解的投影,無法擬合;"
"改用普通的 {2}。由這些相機重建的結果會是錯的。"),
KO("{0} 카메라 모델(이 데이터셋에 {1} 대)은 이 리더가 이해할 수 있는 투영을 "
"내놓지 않아 근사할 수 없었습니다. 기본 {2} 로 대체합니다. 이 카메라들로부터의 "
"복원은 잘못됩니다."),
ES("el modelo de cámara {0} ({1} en este conjunto) no proyecta nada que "
"este lector entienda, así que no se pudo ajustar; se usa una {2} "
"simple. Lo que se reconstruya desde esas cámaras estará mal."),
FR("le modèle de caméra {0} ({1} dans ce jeu de données) ne projette rien "
"que ce lecteur comprenne, il n'a donc pas pu être ajusté ; repli sur "
"une {2} simple. Ce qui sera reconstruit depuis ces caméras sera faux."),
DE("das Kameramodell {0} ({1} in diesem Datensatz) liefert keine Projektion, "
"die dieser Leser versteht, und ließ sich daher nicht anpassen; "
"ersatzweise eine schlichte {2}. Was aus diesen Kameras rekonstruiert "
"wird, ist falsch."),
PT("o modelo de câmera {0} ({1} neste conjunto) não projeta nada que este "
"leitor entenda, então não pôde ser ajustado; usando uma {2} simples. O "
"que for reconstruído a partir dessas câmeras ficará errado."),
IT("il modello di camera {0} ({1} in questo dataset) non proietta nulla che "
"questo lettore capisca, quindi non è stato possibile approssimarlo; si "
"ripiega su una {2} semplice. Ciò che viene ricostruito da queste camere "
"sarà sbagliato."),
NL("het cameramodel {0} ({1} in deze dataset) projecteert niets wat deze "
"lezer begrijpt en kon dus niet benaderd worden; er wordt teruggevallen "
"op een gewone {2}. Wat uit die camera's gereconstrueerd wordt, klopt "
"niet."),
RU("модель камеры {0} ({1} в этом наборе) не даёт проекции, понятной этому "
"загрузчику, поэтому приблизить её не удалось; берётся обычная {2}. "
"Всё, что будет восстановлено с этих камер, окажется неверным."),
TR("{0} kamera modeli (bu veri kumesinde {1} adet) bu okuyucunun anladigi "
"bir izdusum vermiyor, bu yuzden yaklasilamadi; duz bir {2} "
"kullaniliyor. Bu kameralardan yeniden olusturulan sey yanlis olacak."));
SS_MSG(colmap_parse_failed,
EN("the COLMAP data could not be read: {0}"),
JA("COLMAP のデータを読めませんでした: {0}"),
+10 -1
View File
@@ -7,6 +7,7 @@
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
true,
0
@@ -64,6 +65,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
true,
1
@@ -121,6 +123,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
false,
0
@@ -178,6 +181,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
false,
1
@@ -235,6 +239,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
true,
0
@@ -292,6 +297,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
true,
1
@@ -349,6 +355,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
false,
0
@@ -406,6 +413,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
false,
1
@@ -462,7 +470,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
true,
0
+18 -9
View File
@@ -6,7 +6,8 @@
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
true,
1
@@ -63,7 +64,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
false,
0
@@ -120,7 +122,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
false,
1
@@ -177,7 +180,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
true,
0
@@ -234,7 +238,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
true,
1
@@ -291,7 +296,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
false,
0
@@ -348,7 +354,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::FISHEYE,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
false,
1
@@ -405,7 +412,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::EQUISOLID,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
true,
0
@@ -462,7 +470,8 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<0>,
CameraModelType::EQUISOLID,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
true,
1
+471 -462
View File
@@ -5,464 +5,9 @@
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<1>,
CameraModelType::EQUIRECTANGULAR,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGS<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGS<1>::WorldBuffer v_splats_world,
Vanilla3DGS<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGS<1>::WorldBuffer g1_splats_world,
Vanilla3DGS<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<1>,
CameraModelType::EQUIRECTANGULAR,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGS<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGS<1>::WorldBuffer v_splats_world,
Vanilla3DGS<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGS<1>::WorldBuffer g1_splats_world,
Vanilla3DGS<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<1>,
CameraModelType::EQUIRECTANGULAR,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGS<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGS<1>::WorldBuffer v_splats_world,
Vanilla3DGS<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGS<1>::WorldBuffer g1_splats_world,
Vanilla3DGS<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<1>,
CameraModelType::EQUIRECTANGULAR,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGS<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGS<1>::WorldBuffer v_splats_world,
Vanilla3DGS<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGS<1>::WorldBuffer g1_splats_world,
Vanilla3DGS<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<1>,
CameraModelType::EQUIRECTANGULAR,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGS<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGS<1>::WorldBuffer v_splats_world,
Vanilla3DGS<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGS<1>::WorldBuffer g1_splats_world,
Vanilla3DGS<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGS<1>,
CameraModelType::EQUIRECTANGULAR,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGS<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGS<1>::WorldBuffer v_splats_world,
Vanilla3DGS<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGS<1>::WorldBuffer g1_splats_world,
Vanilla3DGS<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
CameraModelType::PINHOLE,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
CameraModelType::PINHOLE,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
false,
0
@@ -472,7 +17,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -484,11 +29,475 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::None,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::OpenCV,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::FISHEYE,
CameraDistortionType::ThinPrism,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::None,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::OpenCV,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUISOLID,
CameraDistortionType::ThinPrism,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<0>,
CameraModelType::EQUIRECTANGULAR,
CameraDistortionType::None,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<0>::WorldBuffer v_splats_world,
Vanilla3DGUT<0>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<0>::WorldBuffer g1_splats_world,
Vanilla3DGUT<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::None,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
+67 -58
View File
@@ -5,8 +5,9 @@
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
true,
false,
1
@@ -16,7 +17,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -28,11 +29,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -62,8 +63,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
true,
0
@@ -73,7 +75,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -85,11 +87,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -119,8 +121,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
true,
1
@@ -130,7 +133,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -142,11 +145,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -176,8 +179,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
false,
0
@@ -187,7 +191,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -199,11 +203,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -233,8 +237,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::OpenCV,
false,
false,
1
@@ -244,7 +249,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -256,11 +261,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -290,8 +295,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
CameraModelType::FISHEYE,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
true,
0
@@ -301,7 +307,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -313,11 +319,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -347,8 +353,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
CameraModelType::FISHEYE,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
true,
1
@@ -358,7 +365,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -370,11 +377,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -404,8 +411,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
CameraModelType::FISHEYE,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
false,
0
@@ -415,7 +423,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -427,11 +435,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
@@ -461,8 +469,9 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
MipSplatting<1>,
CameraModelType::FISHEYE,
MipSplatting<0>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
true,
false,
1
@@ -472,7 +481,7 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
MipSplatting<1>::WorldBuffer splats_world,
MipSplatting<0>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
@@ -484,11 +493,11 @@ template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
MipSplatting<1>::WorldBuffer v_splats_world,
MipSplatting<1>::ScreenBuffer v_splats_screen,
MipSplatting<0>::WorldBuffer v_splats_world,
MipSplatting<0>::ScreenBuffer v_splats_screen,
// optimizer states
MipSplatting<1>::WorldBuffer g1_splats_world,
MipSplatting<1>::WorldBuffer g2_splats_world,
MipSplatting<0>::WorldBuffer g1_splats_world,
MipSplatting<0>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
+527
View File
@@ -0,0 +1,527 @@
// This file is auto generated by `generate_kernel_instantiation.py`
#define NO_TORCH
#include "primitives/Primitive3DGUT.cuh"
#include "kernels/optim/FusedProjectionBwdOptim_kernel.cuh"
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::ThinPrism,
false,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
true,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
false,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
true,
false,
1
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);
template void fused_projection_bwd_optimizer_3dgs_kernel_wrapper<
Vanilla3DGUT<1>,
CameraModelType::PINHOLE,
CameraDistortionType::Rational,
false,
true,
0
>(
cudaStream_t stream,
// fwd inputs
const uint32_t C,
const uint32_t N,
const uint32_t num_sh_buffer,
Vanilla3DGUT<1>::WorldBuffer splats_world,
const float *__restrict__ viewmats, // [C, 4, 4]
const float4 *__restrict__ intrins, // [C, 4], fx, fy, cx, cy
const CameraDistortionCoeffsBuffer dist_coeffs_buffer,
const uint32_t image_width,
const uint32_t image_height,
// fwd outputs
const int32_t *__restrict__ camera_id_bounds, // [N+1]
const int32_t *__restrict__ camera_ids, // [nnz] -- ORIGINAL (unsorted) order
const int32_t *__restrict__ perm, // [nnz] -- sorted_pos -> original_pos
const float4 *__restrict__ aabb, // [C, N, 4] or [nnz, 4]
// grad outputs from rasterization
Vanilla3DGUT<1>::WorldBuffer v_splats_world,
Vanilla3DGUT<1>::ScreenBuffer v_splats_screen,
// optimizer states
Vanilla3DGUT<1>::WorldBuffer g1_splats_world,
Vanilla3DGUT<1>::WorldBuffer g2_splats_world,
const uint8_t* __restrict__ sh_packed, // AoS (u, sqrt_g2) packed SH state
float4* __restrict__ sh_quant_bounds,
const uint8_t* __restrict__ sh_value_packed,
float2* __restrict__ sh_value_bounds,
NonShQuantState non_sh,
// float *__restrict__ v_viewmats // [C, 4, 4] optional
// optimizer params
const float* __restrict__ radii,
float* __restrict__ densify_score,
const float lr_means,
const float lr_quats,
const float lr_scales,
const float lr_opacs,
const float lr_features_dc,
const float lr_features_sh,
const float max_gauss_ratio,
const float scale_regularization_weight,
const float mcmc_opacity_reg_weight,
const float mcmc_scale_reg_weight,
const float erank_reg_weight,
const float erank_reg_weight_s3,
const float quat_norm_reg_weight,
const float sh_reg_weight,
const float eps_tr,
const int32_t scalar_step,
const int32_t* __restrict__ steps
);

Some files were not shown because too many files have changed in this diff Show More