Unable to setup cuSolver buffer in separate function when calling cuSolver gesvdj

Hi all - I’m attempting to build a program that will setup cuSolver gesvdj once and then run it X amount of times (on dynamically changing data). In order to do that, I would like to the run the buffer setup once and then call cusolverDNCgesvdjBatched as needed. However, if I try to move some of the functionality to a different function the result of the svd is all 0’s, and I get a “CUSOLVER_STATUS_INVALID_VALUE” (3) error from the function call.

I have a minimally reproducible example in the zip file. It’s currently setup to run correctly, but if you change lines 158-177 to :


    // --- Query the SVD workspace 
    // cusolveSafeCall(cusolverDnCgesvdjBatched_bufferSize(
    //     solver_handle,
    //     CUSOLVER_EIG_MODE_NOVECTOR,                                       // --- Compute the singular vectors or not
    //     M,                                          // --- Nubmer of rows of A, 0 <= M
    //     N,                                          // --- Number of columns of A, 0 <= N 
    //     d_A,                                        // --- M x N
    //     LDA,                                        // --- Leading dimension of A
    //     d_S,                                        // --- Square matrix of size min(M, N) x min(M, N)
    //     d_U,                                        // --- M x M if econ = 0, M x min(M, N) if econ = 1
    //     M,                                        // --- Leading dimension of U, ldu >= max(1, M)
    //     d_V,                                        // --- N x N if econ = 0, N x min(M,N) if econ = 1
    //     N,                                        // --- Leading dimension of V, ldv >= max(1, N)
    //     &work_size,
    //     gesvdj_params,
    //     N_MAX_TARGETS));

    // gpuErrchk(cudaMalloc(&d_work, sizeof(float2) * work_size));

    init(&solver_handle, &gesvdj_params, d_work, &streamsvd, work_size, d_U, d_V, numMatrices, d_A, d_S);

then you will see the issue. Thanks in advance for your time.
example.zip (19.3 KB)

you cannot pass d_work to a function:

__host__ void init(cusolverDnHandle_t *solver_handle, gesvdjInfo_t *gesvdj_params,         float2* d_work, cudaStream_t *stream, int work_size, float2* dev_U, float2* dev_V,  uint16_t n_skewers, float2* dev_fb_matrix, float* dev_sv);

like this:

init(..., d_work, ...)

and attempt to allocate in the function like this:

gpuErrchk(cudaMalloc(&d_work, sizeof(float2) * work_size));

You’ll need to learn more about how the C or C++ programming language works with pass-by-value semantics to a function. here is a description.

Thanks Robert. I had tried that but mistakenly didn’t set

gpuErrchk(cudaMalloc(d_work, sizeof(float2) * work_size));

to reference the correct “pointer level” of d_work. No warning message for that!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.