Clear windows branch; preserve previous contents in win-old
This commit is contained in:
1 parent
f0c881985b
commit
73994d4634
311 files changed
-57018
No files matched your search
@@ -1,199 +0,0 @@
|
||||
"""CPU checks for accuracy policy, config precedence and native-set selection.
|
||||
|
||||
Run: python3 -m unittest discover -s tests -v
|
||||
Kernel arithmetic additionally needs kernel/model replays and an RTX reference.
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
POLICY = ("D4R_ZLUDA_IGNORE_DENORMAL", "D4R_ZLUDA_WMMA_F32ACC", "D4R_ZLUDA_FAST_MATH",
|
||||
"D4R_ZLUDA_WAVE64", "D4R_ELIDE_NGX_SYNC")
|
||||
|
||||
|
||||
class AccuracyTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.build = tempfile.TemporaryDirectory()
|
||||
cls.runner = Path(cls.build.name) / "selection"
|
||||
source = r'''
|
||||
#include "d4r_native_selection.h"
|
||||
int main(int argc, char** argv) {
|
||||
if (argc == 2 && strcmp(argv[1], "policy") == 0) {
|
||||
printf("%d", d4r_apply_accuracy_policy());
|
||||
const char* keys[] = {"D4R_ZLUDA_IGNORE_DENORMAL", "D4R_ZLUDA_WMMA_F32ACC",
|
||||
"D4R_ZLUDA_FAST_MATH", "D4R_ZLUDA_WAVE64", "D4R_ELIDE_NGX_SYNC"};
|
||||
for (unsigned i = 0; i < sizeof(keys) / sizeof(keys[0]); ++i)
|
||||
printf(" %s", getenv(keys[i]) ? getenv(keys[i]) : "unset");
|
||||
puts("");
|
||||
return 0;
|
||||
}
|
||||
if (argc == 3 && strcmp(argv[1], "kernel") == 0) {
|
||||
printf("%d\n", d4r_native_kernel_allowed(argv[2])); return 0;
|
||||
}
|
||||
if (argc != 5) return 2;
|
||||
char path[1024] = {0};
|
||||
int kind = d4r_select_native_source(argv[1], argv[2], atoi(argv[3]), atoi(argv[4]), path, sizeof(path));
|
||||
printf("%d %s\n", kind, path);
|
||||
return 0;
|
||||
}
|
||||
'''
|
||||
subprocess.run(["cc", "-x", "c", "-std=gnu11", "-Wall", "-Wextra", "-Werror",
|
||||
"-I", str(ROOT / "tools"), "-o", str(cls.runner), "-"],
|
||||
input=source, text=True, check=True, capture_output=True)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.build.cleanup()
|
||||
|
||||
def setUp(self):
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.temp.cleanup)
|
||||
self.root = Path(self.temp.name)
|
||||
|
||||
def native(self, directory, accuracy=False, manifest=True):
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
(directory / "kernel.hsaco").write_bytes(b"fixture")
|
||||
if manifest:
|
||||
(directory / "d4r-kernels.txt").write_text("kernel 1234\n")
|
||||
if accuracy:
|
||||
(directory / "d4r-accuracy.txt").write_text("1\n")
|
||||
|
||||
def select(self, architecture="gfx1101", accuracy=True, fp8=True, directory=None):
|
||||
output = subprocess.check_output([str(self.runner), str(directory or self.root), architecture,
|
||||
str(int(accuracy)), str(int(fp8))], text=True).strip()
|
||||
kind, _, path = output.partition(" ")
|
||||
return int(kind), Path(path)
|
||||
|
||||
def test_select_accuracy_for_every_release_target(self):
|
||||
for arch in ("gfx1100", "gfx1101", "gfx1102", "gfx1103", "gfx1200", "gfx1201"):
|
||||
self.native(self.root / arch)
|
||||
accurate = self.root / "accuracy" / arch
|
||||
self.native(accurate, accuracy=True)
|
||||
self.assertEqual(self.select(arch), (1, accurate))
|
||||
self.assertEqual(self.select(arch, accuracy=False), (1, self.root / arch))
|
||||
|
||||
def test_rdna4_fp8_selection_and_widened_fallback(self):
|
||||
for arch in ("gfx1200", "gfx1201"):
|
||||
accurate = self.root / "accuracy" / arch
|
||||
fp8 = self.root / "accuracy" / (arch + "-fp8")
|
||||
self.native(accurate, accuracy=True)
|
||||
self.assertEqual(self.select(arch), (1, accurate))
|
||||
self.native(fp8, accuracy=True)
|
||||
self.assertEqual(self.select(arch), (1, fp8))
|
||||
self.assertEqual(self.select(arch, fp8=False), (1, accurate))
|
||||
|
||||
def test_missing_accuracy_never_selects_fast_or_wrong_gpu(self):
|
||||
self.native(self.root / "gfx1101")
|
||||
self.native(self.root / "accuracy" / "gfx1201", accuracy=True)
|
||||
self.assertEqual(self.select()[0], 0)
|
||||
self.native(self.root / "accuracy" / "gfx1101") # unmarked binaries
|
||||
self.assertEqual(self.select()[0], 0)
|
||||
|
||||
def test_flat_accuracy_developer_set_requires_valid_marker(self):
|
||||
self.native(self.root, manifest=False)
|
||||
self.assertEqual(self.select()[0], 0)
|
||||
self.assertEqual(self.select(accuracy=False), (2, self.root))
|
||||
(self.root / "d4r-accuracy.txt").write_text("1\n")
|
||||
self.assertEqual(self.select(), (2, self.root))
|
||||
(self.root / "d4r-accuracy.txt").write_text("0\n")
|
||||
self.assertEqual(self.select()[0], 0)
|
||||
|
||||
def test_missing_fast_target_does_not_select_release_root(self):
|
||||
self.native(self.root / "gfx1201")
|
||||
self.assertEqual(self.select(accuracy=False)[0], 0)
|
||||
|
||||
def test_accuracy_policy_overrides_conflicting_fast_settings(self):
|
||||
env = dict(os.environ, D4R_PREFER_ACCURACY="1", **dict.fromkeys(POLICY, "1"))
|
||||
output = subprocess.check_output([str(self.runner), "policy"], env=env, text=True).strip()
|
||||
self.assertEqual(output, "1 0 0 0 0 0")
|
||||
|
||||
def test_default_off_preserves_existing_policy(self):
|
||||
env = {k: v for k, v in os.environ.items() if k != "D4R_PREFER_ACCURACY"}
|
||||
env.update(dict.fromkeys(POLICY, "1"))
|
||||
output = subprocess.check_output([str(self.runner), "policy"], env=env, text=True).strip()
|
||||
self.assertEqual(output, "0 1 1 1 1 1")
|
||||
|
||||
def config(self, text, extra_env=None, expected=0):
|
||||
path = self.root / "d4r.ini"
|
||||
path.write_text(text)
|
||||
env = {k: v for k, v in os.environ.items() if not k.startswith("D4R_")}
|
||||
env.update(extra_env or {})
|
||||
result = subprocess.run(["python3", str(ROOT / "scripts/d4r_config.py"), "--config", str(path)],
|
||||
env=env, text=True, capture_output=True)
|
||||
self.assertEqual(result.returncode, expected, result.stderr)
|
||||
return result
|
||||
|
||||
def test_config_default_and_boolean_spellings(self):
|
||||
self.assertIn("export D4R_PREFER_ACCURACY=0", self.config("").stdout)
|
||||
for value in ("true", "on", "yes", "1"):
|
||||
result = self.config(f"[Kernels]\nPreferAccuracy = {value}\nNativeKernels = off\n")
|
||||
self.assertIn("export D4R_PREFER_ACCURACY=1", result.stdout)
|
||||
self.assertNotIn("D4R_ZLUDA_NATIVE_DIR", result.stdout)
|
||||
for value in ("false", "off", "no", "0"):
|
||||
self.assertIn("export D4R_PREFER_ACCURACY=0",
|
||||
self.config(f"[Kernels]\nPreferAccuracy = {value}\n").stdout)
|
||||
|
||||
def test_explicit_environment_wins_and_invalid_setting_is_reported(self):
|
||||
self.assertNotIn("export D4R_PREFER_ACCURACY",
|
||||
self.config("[Kernels]\nPreferAccuracy=true\n", {"D4R_PREFER_ACCURACY": "0"}).stdout)
|
||||
result = self.config("[Kernels]\nPreferAccuracy=perhaps\n", expected=2)
|
||||
self.assertIn("PreferAccuracy must be true or false", result.stderr)
|
||||
|
||||
def test_swin_encoder_fallback_keeps_other_layers(self):
|
||||
encoders = ("rrlite_enc1_4x4", "rrlite_enc2_4x4")
|
||||
others = ("rrlite_enc3_tube_4x4", "rrlite_dec1_4x4", "rrlite_dec2_4x4",
|
||||
"rrlite_enc0_4x4_mvhi_hdr", "rrlite_post_3_1_mvhi_hdr", "dltss_pwin_enc1_layer")
|
||||
for value in ("0", "1", None):
|
||||
env = {k: v for k, v in os.environ.items() if k != "D4R_NATIVE_SWIN_ENCODERS"}
|
||||
if value is not None:
|
||||
env["D4R_NATIVE_SWIN_ENCODERS"] = value
|
||||
for name in encoders + others:
|
||||
got = subprocess.check_output([str(self.runner), "kernel", name], env=env, text=True).strip()
|
||||
self.assertEqual(got, "0" if value == "0" and name in encoders else "1")
|
||||
|
||||
def test_swin_encoder_config_and_environment_override(self):
|
||||
for value, expected in (("false", "0"), ("true", "1"), ("auto", "1")):
|
||||
self.assertIn(f"export D4R_NATIVE_SWIN_ENCODERS={expected}",
|
||||
self.config(f"[Kernels]\nNativeSwinEncoders = {value}\n").stdout)
|
||||
result = self.config("[Kernels]\nNativeSwinEncoders = false\n",
|
||||
{"D4R_NATIVE_SWIN_ENCODERS": "1"})
|
||||
self.assertNotIn("export D4R_NATIVE_SWIN_ENCODERS", result.stdout)
|
||||
self.config("[Kernels]\nNativeSwinEncoders = maybe\n", expected=2)
|
||||
|
||||
def test_motion_dilation_config_bounds_and_environment_precedence(self):
|
||||
for value, expected in (("0", "0"), ("1", "1"), ("2", "2"), ("auto", "0")):
|
||||
self.assertIn(f"export D4R_MOTION_DILATION={expected}",
|
||||
self.config(f"[Interop]\nMotionVectorDilation = {value}\n").stdout)
|
||||
for value in ("-1", "3", "true", "1.5"):
|
||||
self.config(f"[Interop]\nMotionVectorDilation = {value}\n", expected=2)
|
||||
self.assertNotIn("export D4R_MOTION_DILATION",
|
||||
self.config("[Interop]\nMotionVectorDilation = 2\n",
|
||||
{"D4R_MOTION_DILATION": "0"}).stdout)
|
||||
|
||||
def test_shipped_configs_default_off(self):
|
||||
for file in ("config/d4r.ini.default", "packaging/d4r.ini"):
|
||||
self.assertRegex((ROOT / file).read_text(), r"(?m)^PreferAccuracy\s*=\s*false$")
|
||||
|
||||
def test_builder_refuses_to_certify_mixed_fast_binaries(self):
|
||||
compiler = self.root / "rocm/lib/llvm/bin/clang++"
|
||||
compiler.parent.mkdir(parents=True)
|
||||
compiler.write_text("#!/bin/sh\nexit 99\n")
|
||||
compiler.chmod(0o755)
|
||||
output = self.root / "mixed"
|
||||
self.native(output, manifest=False)
|
||||
env = dict(os.environ, D4R_PREFER_ACCURACY="1", D4R_ROCM_DIR=str(self.root / "rocm"))
|
||||
for marker in (None, "0\n"):
|
||||
if marker is not None:
|
||||
(output / "d4r-accuracy.txt").write_text(marker)
|
||||
result = subprocess.run(["bash", str(ROOT / "kernels/build.sh"), "k", str(output)],
|
||||
env=env, text=True, capture_output=True)
|
||||
self.assertEqual(result.returncode, 2)
|
||||
self.assertIn("accuracy kernels need an empty output directory", result.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,36 +0,0 @@
|
||||
"""Completion/error contracts for the sleeping CUDA event wait (no GPU needed)."""
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class EventWaitTests(unittest.TestCase):
|
||||
def test_completion_pending_and_error(self):
|
||||
source = r'''
|
||||
#include "d4r_event_wait.h"
|
||||
#include <cassert>
|
||||
int main() {
|
||||
int sleeps = 0, queries = 0;
|
||||
assert(d4r_wait_event([] { return 0; }, [&] { ++sleeps; }) == 0);
|
||||
assert(sleeps == 0);
|
||||
assert(d4r_wait_event([&] { return ++queries <= 7 ? 600 : 0; },
|
||||
[&] { ++sleeps; }) == 0);
|
||||
assert(queries == 8 && sleeps == 7);
|
||||
sleeps = 0;
|
||||
assert(d4r_wait_event([] { return 719; }, [&] { ++sleeps; }) == 719);
|
||||
assert(sleeps == 0);
|
||||
queries = 0;
|
||||
assert(d4r_wait_event([&] { return ++queries == 1 ? 600 : 700; },
|
||||
[&] { ++sleeps; }) == 700);
|
||||
assert(sleeps == 1);
|
||||
}
|
||||
'''
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
runner = Path(tmp) / "wait"
|
||||
subprocess.run(["c++", "-x", "c++", "-std=c++17", "-Wall", "-Wextra", "-Werror",
|
||||
"-I", str(ROOT / "tools"), "-o", str(runner), "-"],
|
||||
input=source, text=True, check=True, capture_output=True)
|
||||
subprocess.run([str(runner)], check=True, timeout=5)
|
||||
@@ -1,48 +0,0 @@
|
||||
"""L must retain its unfolded neural math when native surface stores are substituted."""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class ModelLTests(unittest.TestCase):
|
||||
def test_model_l_config_and_environment_precedence(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
ini = Path(directory) / 'd4r.ini'
|
||||
ini.write_text('[DLSS]\nModel = L\n')
|
||||
env = dict(os.environ)
|
||||
env.pop('D4R_DLSS_PRESET', None)
|
||||
cmd = ['python3', str(ROOT / 'scripts/d4r_config.py'), '--config', str(ini)]
|
||||
self.assertIn('export D4R_DLSS_PRESET=12', subprocess.check_output(cmd, env=env, text=True))
|
||||
env['D4R_DLSS_PRESET'] = '11'
|
||||
self.assertNotIn('export D4R_DLSS_PRESET=', subprocess.check_output(cmd, env=env, text=True))
|
||||
|
||||
def test_unfolded_variants_preserve_neural_arithmetic(self):
|
||||
names = ['rrlite_dec0_4x4']
|
||||
for mv in ('mvhi', 'mvlo'):
|
||||
for dynamic_range in ('hdr', 'ldr'):
|
||||
names.append(f'rrlite_enc0_4x4_{mv}_{dynamic_range}')
|
||||
names.extend(f'rrlite_post_{v}_{mv}_{dynamic_range}' for v in ('3_1', '3_2'))
|
||||
math = 'mma.sync.aligned.m16n8k32.row.col.f16.e4m3.e4m3.f16 {%r1, %r2}, {%r3, %r4, %r5, %r6}, {%r7, %r8}, {%r9, %r10};'
|
||||
store = 'sust.b.2d.v2.b16.zero [%rd1, {%r1,%r2}], {%rs1,%rs2};'
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
ptx = Path(directory)
|
||||
env = dict(os.environ, D4R_DLSS_PTX_DIR=directory, D4R_SUST_KINDS='b16,p,b32')
|
||||
for name in names:
|
||||
with self.subTest(kernel=name):
|
||||
(ptx / 'input.ptx').write_text(f'.visible .entry {name}(\n)\n{{\n{math}\n{store}\nret;\n}}\n')
|
||||
subprocess.run(['python3', str(ROOT / 'kernels/tex/make_ptx.py'), name, str(ptx / 'out.ptx')],
|
||||
env=env, check=True, capture_output=True)
|
||||
output = (ptx / 'out.ptx').read_text()
|
||||
self.assertIn(math, output)
|
||||
self.assertNotIn(store, output)
|
||||
self.assertIn('call d4r_sust_v2b16', output)
|
||||
self.assertNotIn('d4r_enc0_tail', output)
|
||||
self.assertNotIn('d4r_dec0_head', output)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,45 +0,0 @@
|
||||
"""Motion-grid selection and padded low-resolution allocation regression."""
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class MotionGeometryTests(unittest.TestCase):
|
||||
def test_low_res_padding_flags_and_display_res_mapping(self):
|
||||
source = r'''
|
||||
#include "d4r_motion_dilation.h"
|
||||
#include <cassert>
|
||||
int main() {
|
||||
D4rMotionDilationParams p = {};
|
||||
p.render_width = 854; p.render_height = 480;
|
||||
p.motion_width = 856; p.motion_height = 480;
|
||||
p.motion_pitch = 4096; p.jitter_x = 0.375f; p.jitter_y = -0.25f;
|
||||
auto low = p;
|
||||
assert(d4r_motion_dilation_geometry(&low, 0xb, 2560, 1440));
|
||||
assert(low.motion_width == 854 && low.motion_height == 480);
|
||||
assert(low.motion_pitch == 4096 && low.jitter_x == 0 && low.jitter_y == 0);
|
||||
low = p;
|
||||
assert(d4r_motion_dilation_geometry(&low, 0x4b, 2560, 1440));
|
||||
low = p; low.motion_width = 853;
|
||||
assert(!d4r_motion_dilation_geometry(&low, 0xb, 2560, 1440));
|
||||
low = p; low.motion_height = 479;
|
||||
assert(!d4r_motion_dilation_geometry(&low, 0xb, 2560, 1440));
|
||||
low = p;
|
||||
assert(!d4r_motion_dilation_geometry(&low, 0xf, 2560, 1440));
|
||||
assert(!d4r_motion_dilation_geometry(&p, 0x49, 2560, 1440));
|
||||
p.motion_width = 2560; p.motion_height = 1440;
|
||||
assert(d4r_motion_dilation_geometry(&p, 0x49, 2560, 1440));
|
||||
assert(p.jitter_x == 0.375f && p.jitter_y == -0.25f);
|
||||
p.render_width = 0;
|
||||
assert(!d4r_motion_dilation_geometry(&p, 0x49, 2560, 1440));
|
||||
}
|
||||
'''
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
runner = Path(tmp) / "geometry"
|
||||
subprocess.run(["c++", "-x", "c++", "-std=c++17", "-Wall", "-Wextra", "-Werror",
|
||||
"-I", str(ROOT / "tools"), "-o", str(runner), "-"],
|
||||
input=source, text=True, check=True, capture_output=True)
|
||||
subprocess.run([str(runner)], check=True, timeout=5)
|
||||
@@ -1,123 +0,0 @@
|
||||
"""Optional GPU regression: independently specified thin-foreground velocity coverage.
|
||||
|
||||
D4R_RUN_GPU_TESTS=1 D4R_DUMP_RUNNER=/path/to/dump_runner python3 -m unittest discover -s tests -v
|
||||
Build the embedded kernels first with scripts/build_d4r_motion_kernels.sh.
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import struct
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get('D4R_RUN_GPU_TESTS') == '1', 'opt-in GPU test')
|
||||
class MotionKernelGpuTests(unittest.TestCase):
|
||||
def test_low_resolution_opaque_edges_and_padded_rows(self):
|
||||
runner = os.environ['D4R_DUMP_RUNNER']
|
||||
kernel = ROOT / 'build/wine-nvcuda/generated' / (os.environ.get('D4R_GPU_ARCH', 'gfx1101') + '.hsaco')
|
||||
width, height, stride = 5, 3, 8
|
||||
sentinel = 0xA5A5A5A5
|
||||
for reversed_depth in (False, True):
|
||||
for radius in (1, 2):
|
||||
with self.subTest(reversed_depth=reversed_depth, radius=radius), tempfile.TemporaryDirectory() as t:
|
||||
directory = Path(t); output = directory / 'out'; output.mkdir()
|
||||
depth = [0.1 if reversed_depth else 0.9] * (stride*height)
|
||||
depth[stride+2] = 0.9 if reversed_depth else 0.1
|
||||
motion = list(range(stride*height))
|
||||
arrays = [struct.pack('<24f', *depth), struct.pack('<24I', *motion), struct.pack('<24I', *([sentinel]*24))]
|
||||
addresses = (0x100000000, 0x200000000, 0x300000000)
|
||||
args = struct.pack('<5Q4I2f2I', *addresses, stride*4, stride*4,
|
||||
width, height, width, height, 0.0, 0.0, radius, reversed_depth)
|
||||
(directory/'args.bin').write_bytes(args)
|
||||
manifest = ['kernel d4r_motion_dilate', 'launch 1 1 1 128 1 1 0', 'args 72']
|
||||
for i, data in enumerate(arrays):
|
||||
(directory/f'alloc-{i}.bin').write_bytes(data)
|
||||
manifest += [f'alloc {i} {hex(addresses[i])} {len(data)}', f'pointer {i*8} {i} 0']
|
||||
(directory/'manifest.txt').write_text('\n'.join(manifest)+'\n')
|
||||
subprocess.run([runner, str(kernel), 'd4r_motion_dilate', str(directory), str(output), '1'], check=True, capture_output=True)
|
||||
self.assertEqual((output/'alloc-0.bin').read_bytes(), arrays[0])
|
||||
self.assertEqual((output/'alloc-1.bin').read_bytes(), arrays[1])
|
||||
expected = [sentinel] * 24
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
expected[y*stride+x] = motion[stride+2] if abs(x-2) <= radius and abs(y-1) <= radius else motion[y*stride+x]
|
||||
self.assertEqual((output/'alloc-2.bin').read_bytes(), struct.pack('<24I', *expected))
|
||||
|
||||
def test_foreground_coverage_padding_and_input_immutability(self):
|
||||
runner = os.environ['D4R_DUMP_RUNNER']
|
||||
kernel = ROOT / 'build/wine-nvcuda/generated' / (os.environ.get('D4R_GPU_ARCH', 'gfx1101') + '.hsaco')
|
||||
sentinel = 0xA5A5A5A5
|
||||
for reversed_depth in (False, True):
|
||||
for radius in (1, 2):
|
||||
for jitter in ((0.0, 0.0), (0.25, -0.25)):
|
||||
with self.subTest(reversed_depth=reversed_depth, radius=radius, jitter=jitter), tempfile.TemporaryDirectory() as t:
|
||||
directory = Path(t); output = directory / 'out'; output.mkdir()
|
||||
depth = [1000.0] * 16
|
||||
for y in range(2):
|
||||
for x in range(3):
|
||||
depth[y*8+x] = 0.1 if reversed_depth else 0.9
|
||||
depth[1] = 0.9 if reversed_depth else 0.1
|
||||
motion = list(range(96))
|
||||
arrays = [struct.pack('<16f', *depth), struct.pack('<96I', *motion), struct.pack('<96I', *([sentinel]*96))]
|
||||
addresses = (0x100000000, 0x200000000, 0x300000000)
|
||||
args = struct.pack('<5Q4I2f2I', *addresses, 32, 64, 3, 2, 9, 6, *jitter, radius, reversed_depth)
|
||||
(directory/'args.bin').write_bytes(args)
|
||||
manifest = ['kernel d4r_motion_dilate', 'launch 1 1 1 128 1 1 0', 'args 72']
|
||||
for i, data in enumerate(arrays):
|
||||
(directory/f'alloc-{i}.bin').write_bytes(data)
|
||||
manifest += [f'alloc {i} {hex(addresses[i])} {len(data)}', f'pointer {i*8} {i} 0']
|
||||
(directory/'manifest.txt').write_text('\n'.join(manifest)+'\n')
|
||||
subprocess.run([runner, str(kernel), 'd4r_motion_dilate', str(directory), str(output), '1'], check=True, capture_output=True)
|
||||
self.assertEqual((output/'alloc-0.bin').read_bytes(), arrays[0])
|
||||
self.assertEqual((output/'alloc-1.bin').read_bytes(), arrays[1])
|
||||
expected = [sentinel] * 96
|
||||
# Known single foreground cell: all neighbouring background follows its velocity.
|
||||
# Foreground itself preserves its original per-pixel velocity; row padding is untouched.
|
||||
for y in range(6):
|
||||
for x in range(9):
|
||||
inside = (3 <= x <= 5 and y <= 2) if jitter == (0.0, 0.0) else (2 <= x <= 4 and y <= 3)
|
||||
expected[y*16+x] = motion[y*16+x] if inside else motion[1*16+4] if jitter == (0.0, 0.0) else motion[2*16+3]
|
||||
self.assertEqual((output/'alloc-2.bin').read_bytes(), struct.pack('<96I', *expected))
|
||||
|
||||
def test_automatic_sky_fill_circle_nearest_ties_and_empty_sky(self):
|
||||
runner = os.environ['D4R_DUMP_RUNNER']
|
||||
kernel = ROOT / 'build/wine-nvcuda/generated' / (os.environ.get('D4R_GPU_ARCH', 'gfx1101') + '.hsaco')
|
||||
width, height, stride = 23, 23, 32
|
||||
sentinel = 0xA5A5A5A5
|
||||
for reversed_depth in (False, True):
|
||||
for radius in (1, 2):
|
||||
for empty, near_far in ((False, False), (True, False), (False, True)):
|
||||
with self.subTest(reversed_depth=reversed_depth, radius=radius, empty=empty, near_far=near_far), tempfile.TemporaryDirectory() as t:
|
||||
directory = Path(t); output = directory / 'out'; output.mkdir()
|
||||
depth = [1000.0] * (stride*height)
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
depth[y*stride+x] = (1.e-7 if near_far else 0.0) if reversed_depth else 1.0
|
||||
sources = [] if empty else [(8, 11), (14, 11)]
|
||||
for x, y in sources:
|
||||
depth[y*stride+x] = (1.5e-7 if near_far else 0.9) if reversed_depth else (0.99 if near_far else 0.1)
|
||||
motion = list(range(stride*height))
|
||||
arrays = [struct.pack(f'<{len(depth)}f', *depth), struct.pack(f'<{len(motion)}I', *motion), struct.pack(f'<{len(motion)}I', *([sentinel]*len(motion)))]
|
||||
addresses = (0x100000000, 0x200000000, 0x300000000)
|
||||
args = struct.pack('<5Q4I2f2I', *addresses, stride*4, stride*4, width, height, width, height, 0.0, 0.0, radius, reversed_depth)
|
||||
(directory/'args.bin').write_bytes(args)
|
||||
manifest = ['kernel d4r_motion_dilate', 'launch 5 1 1 128 1 1 0', 'args 72']
|
||||
for i, data in enumerate(arrays):
|
||||
(directory/f'alloc-{i}.bin').write_bytes(data)
|
||||
manifest += [f'alloc {i} {hex(addresses[i])} {len(data)}', f'pointer {i*8} {i} 0']
|
||||
(directory/'manifest.txt').write_text('\n'.join(manifest)+'\n')
|
||||
subprocess.run([runner, str(kernel), 'd4r_motion_dilate', str(directory), str(output), '1'], check=True, capture_output=True)
|
||||
self.assertEqual((output/'alloc-0.bin').read_bytes(), arrays[0])
|
||||
self.assertEqual((output/'alloc-1.bin').read_bytes(), arrays[1])
|
||||
expected = [sentinel] * len(motion)
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
candidates = sorted(((x-sx)**2+(y-sy)**2, sx, sy) for sx, sy in sources)
|
||||
expected[y*stride+x] = motion[y*stride+x]
|
||||
if candidates and candidates[0][0] <= 64:
|
||||
_, sx, sy = candidates[0]
|
||||
expected[y*stride+x] = motion[sy*stride+sx]
|
||||
self.assertEqual((output/'alloc-2.bin').read_bytes(), struct.pack(f'<{len(expected)}I', *expected))
|
||||
Reference in new issue
Block a user