From 55c064de28d9a9ac6ddc305dba45f449d81a70ea Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Fri, 14 Aug 2026 17:51:40 -0400 Subject: [PATCH] Batch blas test extension --- tests/debug/Test_batched_blas.cc | 78 ++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/tests/debug/Test_batched_blas.cc b/tests/debug/Test_batched_blas.cc index 474dcaf5a..243b94ac0 100644 --- a/tests/debug/Test_batched_blas.cc +++ b/tests/debug/Test_batched_blas.cc @@ -250,6 +250,84 @@ int main (int argc, char ** argv) GRID_ASSERT(rel < 1.0e-4); } + //////////////////////////////////////////////////////////////// + // T3 : ComplexD explicit-ld gemmBatched (the RecursiveSchurInverse + // merge primitive): same split-K miniature as T2, double precision. + // On device builds this is the FIRST exercise of hipblasZ/cublasZ + // gemmBatched through the strided overload. + //////////////////////////////////////////////////////////////// + { + const int nrows = 8; + const int nrhs = 4; + const int K = 256; + const int NK = 8; // split-K chunks + const int Kc = K/NK; + + std::vector Ahost((uint64_t)K*nrows); + std::vector Xhost((uint64_t)K*nrhs); + for(auto &z : Ahost) z = ComplexD(dist(rng),dist(rng)); + for(auto &z : Xhost) z = ComplexD(dist(rng),dist(rng)); + + deviceVector Adev(Ahost.size()); + deviceVector Xdev(Xhost.size()); + deviceVector Yref((uint64_t)nrows*nrhs); + deviceVector Ypart((uint64_t)NK*nrows*nrhs); + acceleratorCopyToDevice(&Ahost[0],&Adev[0],Ahost.size()*sizeof(ComplexD)); + acceleratorCopyToDevice(&Xhost[0],&Xdev[0],Xhost.size()*sizeof(ComplexD)); + + ComplexD one (1.0,0.0); + ComplexD zero(0.0,0.0); + + // (a) reference: one compact batch=1 call (compact lda == K for OP_T) + { + deviceVector Ap(1), Xp(1), Yp(1); + std::vector h(1); + h[0]=&Adev[0]; acceleratorCopyToDevice(&h[0],&Ap[0],sizeof(ComplexD*)); + h[0]=&Xdev[0]; acceleratorCopyToDevice(&h[0],&Xp[0],sizeof(ComplexD*)); + h[0]=&Yref[0]; acceleratorCopyToDevice(&h[0],&Yp[0],sizeof(ComplexD*)); + blas.gemmBatched(GridBLAS_OP_T,GridBLAS_OP_N, + nrows,nrhs,K, + one, Ap, Xp, zero, Yp); + blas.synchronise(); + } + + // (b) split-K: NK chunk-pointers into the SAME allocations, lda/ldb = K + { + deviceVector Ap(NK), Xp(NK), Yp(NK); + std::vector h(NK); + for(int j=0;j Yref_h((uint64_t)nrows*nrhs); + std::vector Ypart_h((uint64_t)NK*nrows*nrhs); + acceleratorCopyFromDevice(&Yref[0], &Yref_h[0], Yref_h.size()*sizeof(ComplexD)); + acceleratorCopyFromDevice(&Ypart[0],&Ypart_h[0],Ypart_h.size()*sizeof(ComplexD)); + + double maxdev = 0.0; + double maxval = 0.0; + for(int i=0;i