diff --git a/tests/hash/CMakeLists.txt b/tests/hash/CMakeLists.txt index 995bb090d..ce3757b4e 100644 --- a/tests/hash/CMakeLists.txt +++ b/tests/hash/CMakeLists.txt @@ -62,7 +62,8 @@ if (WBAG_CUDA) CUDA_STANDARD 17 CUDA_STANDARD_REQUIRED YES POSITION_INDEPENDENT_CODE ON) - target_link_libraries(wbag_gpu_bench PRIVATE CUDA::cudart common cncrypto cryptonote_basic) + target_link_libraries(wbag_gpu_bench PRIVATE CUDA::cudart CUDA::cuda_driver common cncrypto cryptonote_basic) + target_compile_definitions(hash-tests PRIVATE WBAG_HAVE_WBAG_GPU_BENCH=1) target_link_libraries(hash-tests PRIVATE wbag_gpu_bench) diff --git a/tests/hash/wbag_gpu_bench.cu b/tests/hash/wbag_gpu_bench.cu index aa6f105fd..d77baa671 100644 --- a/tests/hash/wbag_gpu_bench.cu +++ b/tests/hash/wbag_gpu_bench.cu @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -130,6 +131,14 @@ static inline int parse_resident_mode_env() { #endif } +static inline int cu_fail(CUresult r, const char* where){ + if (r == CUDA_SUCCESS) return 0; + const char* name = nullptr; const char* desc = nullptr; + cuGetErrorName(r, &name); cuGetErrorString(r, &desc); + std::fprintf(stderr, "CUDA driver %s: %s (%s)\n", where, name ? name : "err", desc ? desc : ""); + return 1; +} + int wbag_gpu_bench_once(const cryptonote::wbag::CacheView& view, int threads, int trials, double& hashes_per_sec_out) { if (threads <= 0 || trials <= 0) return 1; @@ -137,14 +146,16 @@ int wbag_gpu_bench_once(const cryptonote::wbag::CacheView& view, int threads, in int devs = 0; cudaError_t st = cudaGetDeviceCount(&devs); if (st != cudaSuccess || devs <= 0) { - std::fprintf(stderr, "CUDA get device count: %s\n", cudaGetErrorString(st)); - return 100; + if (cu_fail(cuInit(0), "cuInit")) return 100; + int dcount = 0; + if (cu_fail(cuDeviceGetCount(&dcount), "cuDeviceGetCount")) return 100; + if (dcount <= 0) { std::fprintf(stderr, "CUDA driver reports 0 devices\n"); return 100; } + CUdevice dev; if (cu_fail(cuDeviceGet(&dev, 0), "cuDeviceGet(0)")) return 101; + CUcontext ctx; if (cu_fail(cuDevicePrimaryCtxRetain(&ctx, dev), "cuDevicePrimaryCtxRetain")) return 101; + if (cu_fail(cuCtxSetCurrent(ctx), "cuCtxSetCurrent")) return 101; } st = cudaSetDevice(0); - if (st != cudaSuccess) { - std::fprintf(stderr, "CUDA set device: %s\n", cudaGetErrorString(st)); - return 101; - } + if (st != cudaSuccess) { std::fprintf(stderr, "CUDA set device: %s\n", cudaGetErrorString(st)); return 101; } const size_t entry_bytes = WBAG_entry_bytes(); const size_t cache_bytes = view.size(); @@ -160,16 +171,9 @@ int wbag_gpu_bench_once(const cryptonote::wbag::CacheView& view, int threads, in if (!d_cache || d_cache_size != cache_bytes) { if (d_cache) { cudaFree(d_cache); d_cache = nullptr; d_cache_size = 0; } st = cudaMalloc(&d_cache, cache_bytes); - if (st != cudaSuccess) { - std::fprintf(stderr, "GPU: cache alloc failed (%zu bytes): %s\n", cache_bytes, cudaGetErrorString(st)); - return 2; - } + if (st != cudaSuccess) { std::fprintf(stderr, "GPU: cache alloc failed (%zu bytes): %s\n", cache_bytes, cudaGetErrorString(st)); return 2; } st = cudaMemcpy(d_cache, view.data(), cache_bytes, cudaMemcpyHostToDevice); - if (st != cudaSuccess) { - std::fprintf(stderr, "GPU: cache memcpy failed: %s\n", cudaGetErrorString(st)); - cudaFree(d_cache); d_cache = nullptr; d_cache_size = 0; - return 3; - } + if (st != cudaSuccess) { std::fprintf(stderr, "GPU: cache memcpy failed: %s\n", cudaGetErrorString(st)); cudaFree(d_cache); d_cache = nullptr; d_cache_size = 0; return 3; } d_cache_size = cache_bytes; } @@ -178,10 +182,7 @@ int wbag_gpu_bench_once(const cryptonote::wbag::CacheView& view, int threads, in size_t free_b = 0, total_b = 0; st = cudaMemGetInfo(&free_b, &total_b); - if (st != cudaSuccess) { - std::fprintf(stderr, "GPU: mem info failed: %s\n", cudaGetErrorString(st)); - return 4; - } + if (st != cudaSuccess) { std::fprintf(stderr, "GPU: mem info failed: %s\n", cudaGetErrorString(st)); return 4; } if (need_resident + (64ULL << 20) > free_b) { std::fprintf(stderr, "GPU: not enough VRAM for resident (%zu MiB needed, %zu MiB free). Set WBAG_GPU_RESIDENT=shared or reduce --threads.\n", need_resident >> 20, free_b >> 20); return 5; @@ -189,10 +190,7 @@ int wbag_gpu_bench_once(const cryptonote::wbag::CacheView& view, int threads, in uint8_t* d_resident = nullptr; st = cudaMalloc(&d_resident, need_resident); - if (st != cudaSuccess) { - std::fprintf(stderr, "GPU: resident alloc failed (%zu bytes): %s\n", need_resident, cudaGetErrorString(st)); - return 6; - } + if (st != cudaSuccess) { std::fprintf(stderr, "GPU: resident alloc failed (%zu bytes): %s\n", need_resident, cudaGetErrorString(st)); return 6; } const uint64_t base_seed = WBAG_resident_seed_from_cache(view.data(), view.size());