Add explicit gfx1200/gfx1201 builds, runtime selection and per-target code objects. Guard staging, packaging and installation against mixed architectures; retain gfx1201 compatibility and strict K/M arithmetic. Adapt realdody's target configuration and MSVC binary16/BOOL portability fixes from ae530b0. Do not import its forced gfx12 layout on RDNA3. Add exhaustive binary16 and C++/PowerShell target contract regressions. Validation: 20 CTest gates on RX 9070 XT; four software-only gfx1200 gates; MSVC portability compile checks; exact 4K K async and M control outputs; isolated package install/restore and mixed-target rejection tests. No physical gfx1200 validation is claimed. Co-authored-by: realdody <[email protected]>
61 lines
2.9 KiB
C++
61 lines
2.9 KiB
C++
#include "hip_api.h"
|
|
|
|
// Isolate Windows HIP stream lifetime from D3D12 and external-resource imports.
|
|
int main(int argc, char** argv)
|
|
{
|
|
using namespace d4r::diag;
|
|
start();
|
|
try {
|
|
Args args(argc, argv);
|
|
HipApi hip(args.hip_root);
|
|
hipDeviceProp_t props{};
|
|
hip.select_architecture(args.device, props);
|
|
hipModule_t module = nullptr;
|
|
hipFunction_t kernel = nullptr;
|
|
void* output = nullptr;
|
|
struct ResourceCleanup {
|
|
HipApi& hip; hipModule_t& module; void*& output;
|
|
~ResourceCleanup() {
|
|
if (output) (void)hip.hipFree(output);
|
|
if (module) (void)hip.hipModuleUnload(module);
|
|
}
|
|
} resources{hip, module, output};
|
|
if (!args.module.empty()) {
|
|
hip.check(hip.hipModuleLoad(&module, args.module.c_str()), "hipModuleLoad");
|
|
hip.check(hip.hipModuleGetFunction(&kernel, module, "d4r_probe_pattern"), "hipModuleGetFunction");
|
|
hip.check(hip.hipMalloc(&output, 128 * sizeof(uint32_t)), "hipMalloc");
|
|
}
|
|
DWORD baseline = 0, count = 0;
|
|
for (unsigned i = 0; i < args.iterations; ++i) {
|
|
hipStream_t stream = nullptr;
|
|
hip.check(hip.hipStreamCreateWithFlags(&stream, hipStreamNonBlocking), "hipStreamCreateWithFlags");
|
|
struct StreamCleanup {
|
|
HipApi& hip; hipStream_t& stream;
|
|
~StreamCleanup() { if (stream) { (void)hip.hipStreamSynchronize(stream); (void)hip.hipStreamDestroy(stream); } }
|
|
} cleanup{hip, stream};
|
|
if (kernel) {
|
|
uint32_t n = 128, seed = i;
|
|
void* parameters[] = {&output, &n, &seed};
|
|
hip.check(hip.hipModuleLaunchKernel(kernel, 1, 1, 1, 128, 1, 1, 0,
|
|
stream, parameters, nullptr), "hipModuleLaunchKernel");
|
|
}
|
|
hip.check(hip.hipStreamSynchronize(stream), "hipStreamSynchronize");
|
|
hip.check(hip.hipStreamDestroy(stream), "hipStreamDestroy");
|
|
stream = nullptr;
|
|
if (!GetProcessHandleCount(GetCurrentProcess(), &count))
|
|
throw std::runtime_error("GetProcessHandleCount failed");
|
|
if (i == 1 || (args.iterations == 1 && i == 0)) baseline = count;
|
|
std::printf("STREAM_CLEANUP iteration=%u handles=%lu baseline=%lu\n", i, count, baseline);
|
|
}
|
|
if (output) { hip.check(hip.hipFree(output), "hipFree"); output = nullptr; }
|
|
if (module) { hip.check(hip.hipModuleUnload(module), "hipModuleUnload"); module = nullptr; }
|
|
if (count > baseline + 4) throw std::runtime_error("HIP stream lifecycle handle growth");
|
|
std::printf("PASS HIP_STREAM iterations=%u handles=%lu\n", args.iterations, count);
|
|
return 0;
|
|
} catch (const std::exception& e) {
|
|
std::fprintf(stderr, "FAIL HIP_STREAM %s\n", e.what());
|
|
loaded_modules();
|
|
return 4;
|
|
}
|
|
}
|