Add MicroCUDA backend, adaptive output wait, wider native K coverage (improve perf)
Shim - Adaptive output-event wait: sleep to ~120 us before the predicted completion (smoothed per wait site), spin near it, back off when late. D4R_SHIM_OUTPUT_POLL_US restores a fixed interval. - Defer the input-marker wait into the worker thread with VRAM interop (D4R_SHIM_DEFER_MARKER, default on), taking the host setup off the critical path. MicroCUDA - Experimental ZLUDA-free backend in wine_nvcuda_bridge, plus tools/microcuda and scripts/build_microcuda.sh. Serves accuracy, fast and native kernels; unregistered modules fall back to the reference path. Unclassified writes invalidate prepared weights. M kernels - SWIN_PREP_IDENTITY_AT: key weight prep by allocation identity (MicroCUDA); enc3 tube uses it with 8 slots. ZLUDA ignores it. - dec2 (gfx1101): SWIN_PACKED_RESIDUAL, byte-identical, ~1.6% faster. - Opt-in gfx12 hardware fp8 conversion (SWIN_FP8_HWCVT), unverified on hardware. Native K translators - ctile: handle variants that re-materialize the parameter base (mvlo). - rewrite_output: check live-in registers, not just outputs. - build.sh: native input covers all 8 flag variants, output the 4 HDR "max" variants; depth-tile skip stays mvhi-only. Tools - dump_runner and bench_dlss_kernel harness additions.
This commit is contained in:
1 parent
7c60d53cd0
commit
a627439025
20 files changed
+2186
-44
No files matched your search
@@ -133,17 +133,87 @@ int main(int argc, char** argv)
|
||||
size_t argSize = args.size();
|
||||
void* cfg[] = {HIP_LAUNCH_PARAM_BUFFER_POINTER, args.data(), HIP_LAUNCH_PARAM_BUFFER_SIZE, &argSize,
|
||||
HIP_LAUNCH_PARAM_END};
|
||||
// phase kernels NAME_post1..NAME_post8, launched after the main kernel with the same parameters, exactly as
|
||||
// the ZLUDA hook and MicroCUDA do: u32 globals d4r_postK_grid_x/_grid_y (0 = the launch's grid; if either is
|
||||
// set, grid z is 1) and d4r_postK_block_x/_y/_z (0 = 32/1/1)
|
||||
struct Post { hipFunction_t fn; unsigned gx, gy, gz, bx, by, bz; };
|
||||
std::vector<Post> posts;
|
||||
auto global_u32 = [&](const std::string& name) -> uint32_t {
|
||||
hipDeviceptr_t p;
|
||||
size_t n = 0;
|
||||
uint32_t v = 0;
|
||||
if (hipModuleGetGlobal(&p, &n, mod, name.c_str()) == hipSuccess && n == 4 && hipMemcpyDtoH(&v, p, 4) != hipSuccess)
|
||||
v = 0;
|
||||
return v;
|
||||
};
|
||||
for (int k = 1; k <= 8; ++k)
|
||||
{
|
||||
Post q{};
|
||||
const std::string name = std::string(argv[2]) + "_post" + std::to_string(k);
|
||||
if (hipModuleGetFunction(&q.fn, mod, name.c_str()) != hipSuccess)
|
||||
break;
|
||||
const std::string g = "d4r_post" + std::to_string(k) + "_";
|
||||
const uint32_t px = global_u32(g + "grid_x"), py = global_u32(g + "grid_y");
|
||||
q.gx = px ? px : grid[0];
|
||||
q.gy = py ? py : grid[1];
|
||||
q.gz = (px || py) ? 1 : grid[2];
|
||||
q.bx = global_u32(g + "block_x");
|
||||
q.by = global_u32(g + "block_y");
|
||||
q.bz = global_u32(g + "block_z");
|
||||
if (!q.bx) q.bx = 32;
|
||||
if (!q.by) q.by = 1;
|
||||
if (!q.bz) q.bz = 1;
|
||||
posts.push_back(q);
|
||||
}
|
||||
if (!posts.empty())
|
||||
printf("%s: %zu post phase(s)\n", argv[2], posts.size());
|
||||
const bool prepOnce = getenv("PREP_ONCE") != nullptr;
|
||||
int launches = 0;
|
||||
auto launch = [&]() {
|
||||
// PHASE_TIMES=1: an event before and after every phase (prep, main, post1..) for per-phase GPU times
|
||||
const bool phaseTimes = getenv("PHASE_TIMES") != nullptr;
|
||||
std::vector<hipEvent_t> marks(posts.size() + 3);
|
||||
for (auto& m : marks)
|
||||
CHECK(hipEventCreate(&m));
|
||||
std::vector<std::vector<float>> phaseMs(posts.size() + 2);
|
||||
bool recordPhases = false;
|
||||
auto launch = [&]() -> hipError_t {
|
||||
bool prepped = false;
|
||||
if (recordPhases) (void)hipEventRecord(marks[0]);
|
||||
if (prep != nullptr && !(prepOnce && launches++ > 0))
|
||||
{
|
||||
hipError_t e = hipModuleLaunchKernel(prep, prepGrid, 1, 1, 128, 1, 1, 0, nullptr, nullptr, cfg);
|
||||
if (e != hipSuccess)
|
||||
return e;
|
||||
prepped = true;
|
||||
}
|
||||
return hipModuleLaunchKernel(fn, grid[0], grid[1], grid[2], block[0], block[1], block[2], shared, nullptr,
|
||||
nullptr, cfg);
|
||||
if (recordPhases) (void)hipEventRecord(marks[1]);
|
||||
hipError_t e = hipModuleLaunchKernel(fn, grid[0], grid[1], grid[2], block[0], block[1], block[2], shared,
|
||||
nullptr, nullptr, cfg);
|
||||
if (e != hipSuccess)
|
||||
return e;
|
||||
if (recordPhases) (void)hipEventRecord(marks[2]);
|
||||
for (size_t k = 0; k < posts.size(); ++k)
|
||||
{
|
||||
const Post& q = posts[k];
|
||||
e = hipModuleLaunchKernel(q.fn, q.gx, q.gy, q.gz, q.bx, q.by, q.bz, 0, nullptr, nullptr, cfg);
|
||||
if (e != hipSuccess)
|
||||
return e;
|
||||
if (recordPhases) (void)hipEventRecord(marks[3 + k]);
|
||||
}
|
||||
if (recordPhases)
|
||||
{
|
||||
if (hipError_t w = hipEventSynchronize(marks.back()); w != hipSuccess)
|
||||
return w;
|
||||
for (size_t k = 0; k < phaseMs.size(); ++k)
|
||||
{
|
||||
if (k == 0 && !prepped)
|
||||
continue;
|
||||
float t;
|
||||
if (hipEventElapsedTime(&t, marks[k], marks[k + 1]) == hipSuccess)
|
||||
phaseMs[k].push_back(t);
|
||||
}
|
||||
}
|
||||
return hipSuccess;
|
||||
};
|
||||
CHECK(launch());
|
||||
CHECK(hipDeviceSynchronize());
|
||||
@@ -178,6 +248,22 @@ int main(int argc, char** argv)
|
||||
CHECK(hipEventElapsedTime(&t, a, b));
|
||||
ms.push_back(t);
|
||||
}
|
||||
if (phaseTimes)
|
||||
{
|
||||
recordPhases = true;
|
||||
for (int i = 0; i < iters; ++i)
|
||||
CHECK(launch());
|
||||
CHECK(hipDeviceSynchronize());
|
||||
for (size_t k = 0; k < phaseMs.size(); ++k)
|
||||
{
|
||||
auto& v = phaseMs[k];
|
||||
if (v.empty())
|
||||
continue;
|
||||
std::sort(v.begin(), v.end());
|
||||
const std::string phase = k == 0 ? "prep" : k == 1 ? "main" : "post" + std::to_string(k - 1);
|
||||
printf("%s %s: median %.4f ms, min %.4f ms\n", argv[2], phase.c_str(), v[v.size() / 2], v[0]);
|
||||
}
|
||||
}
|
||||
std::sort(ms.begin(), ms.end());
|
||||
if (!ms.empty())
|
||||
printf("%s: median %.4f ms, min %.4f ms over %d launches\n", argv[2], ms[ms.size() / 2], ms[0], iters);
|
||||
|
||||
Reference in new issue
Block a user