mirror of
https://github.com/paboyle/Grid.git
synced 2026-07-18 08:03:27 +01:00
tests/debug: extend hipfft reproducer with Grid-realistic howmany and exec tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
303a4d26e5
commit
74e0f846cb
@@ -35,59 +35,77 @@ static const char *hipfftResultString(hipfftResult r) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try both hipfftPlanMany and hipfftCreate+hipfftMakePlanMany for given G and howmany.
|
// Plan creation + execution for (G, howmany) using hipfftCreate+hipfftMakePlanMany.
|
||||||
static void tryPlans(int G, int howmany) {
|
// This is the path Grid's FFT.h now uses.
|
||||||
|
static void tryPlanAndExec(int G, long howmany) {
|
||||||
int n[] = {G};
|
int n[] = {G};
|
||||||
|
long nelems = (long)G * howmany;
|
||||||
|
|
||||||
printf("--- G=%-4d howmany=%-6d ---\n", G, howmany);
|
printf("--- G=%-4d howmany=%-10ld total_elems=%-12ld ---\n",
|
||||||
|
G, howmany, nelems);
|
||||||
|
|
||||||
// 1. hipfftPlanMany (one-step)
|
// Allocate device buffer (hipfftDoubleComplex = 16 bytes each)
|
||||||
|
hipfftDoubleComplex *dbuf = nullptr;
|
||||||
|
hipError_t herr = hipMalloc(&dbuf, nelems * sizeof(hipfftDoubleComplex));
|
||||||
|
if (herr != hipSuccess) {
|
||||||
|
printf(" hipMalloc failed (%d) for %ld elems — skipping\n\n", (int)herr, nelems);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hipMemset(dbuf, 0, nelems * sizeof(hipfftDoubleComplex));
|
||||||
|
|
||||||
|
// 1. hipfftPlanMany (one-step, nullptr embed) — current Grid path
|
||||||
{
|
{
|
||||||
hipfftHandle p;
|
hipfftHandle p;
|
||||||
hipfftResult rv = hipfftPlanMany(&p, 1, n,
|
hipfftResult rv = hipfftPlanMany(&p, 1, n,
|
||||||
nullptr, 1, G,
|
nullptr, 1, G,
|
||||||
nullptr, 1, G,
|
nullptr, 1, G,
|
||||||
HIPFFT_Z2Z, howmany);
|
HIPFFT_Z2Z, (int)howmany);
|
||||||
printf(" hipfftPlanMany : %d (%s)\n", (int)rv, hipfftResultString(rv));
|
printf(" hipfftPlanMany create : %d (%s)\n", (int)rv, hipfftResultString(rv));
|
||||||
if (rv == HIPFFT_SUCCESS) hipfftDestroy(p);
|
if (rv == HIPFFT_SUCCESS) {
|
||||||
}
|
rv = hipfftExecZ2Z(p, dbuf, dbuf, HIPFFT_FORWARD);
|
||||||
|
hipDeviceSynchronize();
|
||||||
// 2. hipfftPlanMany with inembed=n (old Grid behaviour)
|
printf(" hipfftPlanMany execFwd: %d (%s)\n", (int)rv, hipfftResultString(rv));
|
||||||
{
|
|
||||||
hipfftHandle p;
|
|
||||||
hipfftResult rv = hipfftPlanMany(&p, 1, n,
|
|
||||||
n, 1, G,
|
|
||||||
n, 1, G,
|
|
||||||
HIPFFT_Z2Z, howmany);
|
|
||||||
printf(" hipfftPlanMany(inembed=n): %d (%s)\n", (int)rv, hipfftResultString(rv));
|
|
||||||
if (rv == HIPFFT_SUCCESS) hipfftDestroy(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. hipfftCreate + hipfftMakePlanMany (two-step, nullptr embed)
|
|
||||||
{
|
|
||||||
hipfftHandle p;
|
|
||||||
size_t workSize = 0;
|
|
||||||
hipfftResult rc = hipfftCreate(&p);
|
|
||||||
printf(" hipfftCreate : %d (%s)\n", (int)rc, hipfftResultString(rc));
|
|
||||||
if (rc == HIPFFT_SUCCESS) {
|
|
||||||
hipfftResult rv = hipfftMakePlanMany(p, 1, n,
|
|
||||||
nullptr, 1, G,
|
|
||||||
nullptr, 1, G,
|
|
||||||
HIPFFT_Z2Z, howmany, &workSize);
|
|
||||||
printf(" hipfftMakePlanMany : %d (%s) workSize=%zu\n",
|
|
||||||
(int)rv, hipfftResultString(rv), workSize);
|
|
||||||
hipfftDestroy(p);
|
hipfftDestroy(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. hipfftPlan1d (simplest API)
|
// 2. hipfftCreate + hipfftMakePlanMany (two-step) — also current Grid path
|
||||||
{
|
{
|
||||||
hipfftHandle p;
|
hipfftHandle p;
|
||||||
hipfftResult rv = hipfftPlan1d(&p, G, HIPFFT_Z2Z, howmany);
|
size_t workSize = 0;
|
||||||
printf(" hipfftPlan1d : %d (%s)\n", (int)rv, hipfftResultString(rv));
|
hipfftResult rc = hipfftCreate(&p);
|
||||||
if (rv == HIPFFT_SUCCESS) hipfftDestroy(p);
|
if (rc == HIPFFT_SUCCESS) {
|
||||||
|
hipfftResult rv = hipfftMakePlanMany(p, 1, n,
|
||||||
|
nullptr, 1, G,
|
||||||
|
nullptr, 1, G,
|
||||||
|
HIPFFT_Z2Z, (int)howmany, &workSize);
|
||||||
|
printf(" hipfftMakePlanMany : %d (%s) workSize=%zu\n",
|
||||||
|
(int)rv, hipfftResultString(rv), workSize);
|
||||||
|
if (rv == HIPFFT_SUCCESS) {
|
||||||
|
rv = hipfftExecZ2Z(p, dbuf, dbuf, HIPFFT_FORWARD);
|
||||||
|
hipDeviceSynchronize();
|
||||||
|
printf(" hipfftMakePlanMany exec : %d (%s)\n", (int)rv, hipfftResultString(rv));
|
||||||
|
}
|
||||||
|
hipfftDestroy(p);
|
||||||
|
} else {
|
||||||
|
printf(" hipfftCreate : %d (%s)\n", (int)rc, hipfftResultString(rc));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. hipfftPlan1d (simplest API, batch = howmany)
|
||||||
|
{
|
||||||
|
hipfftHandle p;
|
||||||
|
hipfftResult rv = hipfftPlan1d(&p, G, HIPFFT_Z2Z, (int)howmany);
|
||||||
|
printf(" hipfftPlan1d create : %d (%s)\n", (int)rv, hipfftResultString(rv));
|
||||||
|
if (rv == HIPFFT_SUCCESS) {
|
||||||
|
rv = hipfftExecZ2Z(p, dbuf, dbuf, HIPFFT_FORWARD);
|
||||||
|
hipDeviceSynchronize();
|
||||||
|
printf(" hipfftPlan1d execFwd: %d (%s)\n", (int)rv, hipfftResultString(rv));
|
||||||
|
hipfftDestroy(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hipFree(dbuf);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,24 +117,42 @@ int main(void) {
|
|||||||
hipGetDeviceProperties(&prop, device);
|
hipGetDeviceProperties(&prop, device);
|
||||||
printf("Device %d: %s warpSize=%d\n\n", device, prop.name, prop.warpSize);
|
printf("Device %d: %s warpSize=%d\n\n", device, prop.name, prop.warpSize);
|
||||||
|
|
||||||
// Print hipFFT version if available
|
|
||||||
#ifdef hipfftVersionMinor
|
#ifdef hipfftVersionMinor
|
||||||
printf("hipFFT version: %d.%d.%d\n\n",
|
printf("hipFFT version: %d.%d.%d\n\n",
|
||||||
hipfftVersionMajor, hipfftVersionMinor, hipfftVersionPatch);
|
hipfftVersionMajor, hipfftVersionMinor, hipfftVersionPatch);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Sweep over transform sizes G with a fixed representative howmany
|
// Original sweep with small howmany (these passed first time)
|
||||||
// (512 = typical Nperp*Ncomp for a small lattice)
|
printf("=== Small howmany (original sweep) ===\n\n");
|
||||||
const int howmany = 512;
|
for (int G : {4, 8, 12, 16, 24, 32, 48, 64})
|
||||||
for (int G : {4, 8, 12, 16, 24, 32, 48, 64}) {
|
tryPlanAndExec(G, 512);
|
||||||
tryPlans(G, howmany);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also try the exact parameters from the failing Grid FFT
|
// Grid-realistic howmany values derived from actual lattice geometries.
|
||||||
printf("=== Grid-specific parameters ===\n\n");
|
// howmany = Ncomp * product(ldimensions[d] for d != dim)
|
||||||
tryPlans(8, 512); // Ls=8, small 4D lattice
|
// For LatticeComplexD: Ncomp=1.
|
||||||
tryPlans(16, 512); // 16^4
|
printf("=== Grid-realistic parameters ===\n\n");
|
||||||
tryPlans(32, 512); // 32^4 (known to work)
|
|
||||||
|
// --grid 16.16.16.16 4D FFT (KNOWN TO FAIL in Grid)
|
||||||
|
// Each dim: G=16, Nperp=16^3=4096
|
||||||
|
tryPlanAndExec(16, 4096);
|
||||||
|
|
||||||
|
// --grid 32.32.32.32 4D FFT (KNOWN TO SUCCEED in Grid)
|
||||||
|
// Each dim: G=32, Nperp=32^3=32768
|
||||||
|
tryPlanAndExec(32, 32768);
|
||||||
|
|
||||||
|
// --grid 32.32.32.32 Ls=8 5D DWF FFT (KNOWN TO FAIL on dim 0 in Grid)
|
||||||
|
// dim 0: G=8, Nperp=32^4=1048576
|
||||||
|
tryPlanAndExec(8, 1048576);
|
||||||
|
// dim 1-4: G=32, Nperp=8*32^3=262144
|
||||||
|
tryPlanAndExec(32, 262144);
|
||||||
|
|
||||||
|
// Extra intermediate cases to bracket the failure
|
||||||
|
tryPlanAndExec(16, 1024);
|
||||||
|
tryPlanAndExec(16, 2048);
|
||||||
|
tryPlanAndExec(16, 8192);
|
||||||
|
tryPlanAndExec(8, 4096);
|
||||||
|
tryPlanAndExec(8, 65536);
|
||||||
|
tryPlanAndExec(8, 262144);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user