Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

`cutensornetTensorSVD` returns `CUTENSORNET_STATUS_INTERNAL_ERROR` with missing host workspace

Aperta
#230 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
c, linux

Direzione di ricerca

Start with the repro.c program and its cutensornetTensorSVD, workspace sizing, and cutensornetGetLastError calls; run it against the listed cuSOLVER versions to reproduce the differing results. Done means missing host memory reports CUTENSORNET_STATUS_INSUFFICIENT_WORKSPACE with a useful error, workspace size and alignment behavior is consistent or documented, and the host-related status text is accurate.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Software stack: cuQuantum 26.09.0 (cuTensorNet 2.14.0), CUDA 13.4 Update 1 (cuSOLVER 12.3.4.7), RTX 5080 (sm_120), driver 610.57.04, Linux x86_64.

Since CUDA 13.4 Update 1, cusolverDnXgesvd_bufferSize reports a host workspace (8×8 FP32: 0 B with cuSOLVER
12.3.2, 14368 B with 12.3.4; the release notes' "hybrid host/device Givens update"), and cuTensorNet forwards it as
CUTENSORNET_MEMSPACE_HOST scratch for the default GESVD algorithm. That is fine, but an application that attached
only a device workspace, which was enough with every earlier CUDA, now gets:

  • no host workspace: CUTENSORNET_STATUS_INTERNAL_ERROR (14); the log says only [Error][cutensornetTensorSVD] Internal error.
  • host workspace one alignment-slack short: CUTENSORNET_STATUS_INSUFFICIENT_WORKSPACE (19), log says
    Insufficient host workspace (14336 bytes) provided for tensorSVD (14592 bytes needed)., which is the helpful behaviour.

In both cases cutensornetGetLastError() returns an empty string. This was annoying to debug, and could be made better:

  1. Report a missing host workspace as CUTENSORNET_STATUS_INSUFFICIENT_WORKSPACE, like a too-small one (the device
    side already does), and fill cutensornetGetLastError().
  2. The deprecated cutensornetWorkspaceGetSize returns the bare requirement (14592 B), while
    cutensornetWorkspaceGetMemorySize returns it plus 256 B of alignment slack (14848 B). A buffer of the deprecated
    size that isn't 256-byte aligned (e.g. from malloc, 16-byte aligned) is then rejected as insufficient. Either make
    the deprecated query include the slack or document the alignment it assumes.
  3. The status string for 19 says "the workspace on the device is too small" even when the host workspace is the
    problem.

Reproducer (output with each cuSOLVER, all other libraries identical):

=== libcusolver.so.12.3.2.15            (CUDA 13.4.1)
device workspace only:
  host scratch: GetMemorySize 0 B, deprecated GetSize 0 B; provided 0 B
  OK
...
=== libcusolver.so.12.3.4.7             (CUDA 13.4.2)
device workspace only:
  host scratch: GetMemorySize 14848 B, deprecated GetSize 14592 B; provided 0 B
  cutensornetTensorSVD(...) -> 14 (CUTENSORNET_STATUS_INTERNAL_ERROR), cutensornetGetLastError() = ""
+ host workspace, deprecated GetSize size:
  host scratch: GetMemorySize 14848 B, deprecated GetSize 14592 B; provided 14592 B
  cutensornetTensorSVD(...) -> 19 (CUTENSORNET_STATUS_INSUFFICIENT_WORKSPACE), cutensornetGetLastError() = ""
+ host workspace, GetMemorySize size:
  host scratch: GetMemorySize 14848 B, deprecated GetSize 14592 B; provided 14848 B
  OK
// cutensornetTensorSVD without a host workspace: CUDA 13.4.1 OK, CUDA 13.4.2 (cuSOLVER 12.3.4) INTERNAL_ERROR.
// Build: gcc -o repro repro.c -I$CUDA_HOME/include -I$CUQUANTUM_ROOT/include -L$CUQUANTUM_ROOT/lib -lcutensornet -lcudart
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime.h>
#include <cutensornet.h>

#define CHK(x) do { cutensornetStatus_t s_ = (x); if (s_ != CUTENSORNET_STATUS_SUCCESS) { \
    printf("  %s -> %d (%s), cutensornetGetLastError() = \"%s\"\n", #x, (int)s_, cutensornetGetErrorString(s_), \
           cutensornetGetLastError()); return s_; } } while (0)

static int svd(cutensornetHandle_t h, int host_mode) {
    // host_mode: 0 = no host workspace, 1 = exact size from the deprecated cutensornetWorkspaceGetSize,
    //            2 = size from cutensornetWorkspaceGetMemorySize; host buffers are deliberately 64-byte aligned
    const int64_t n = 8, ext[] = {n, n};
    int32_t mA[] = {'n', 'm'}, mU[] = {'n', 'o'}, mV[] = {'o', 'm'};
    float hA[64]; for (int i = 0; i < 64; i++) hA[i] = (float)rand() / RAND_MAX;
    float *A, *U, *S, *V; void *dw, *hbase, *hw = NULL;
    cudaMalloc((void**)&A, sizeof hA); cudaMalloc((void**)&U, sizeof hA);
    cudaMalloc((void**)&V, sizeof hA); cudaMalloc((void**)&S, n * sizeof(float));
    cudaMemcpy(A, hA, sizeof hA, cudaMemcpyHostToDevice);

    cutensornetTensorDescriptor_t dA, dU, dV;
    CHK(cutensornetCreateTensorDescriptor(h, 2, ext, NULL, mA, CUDA_R_32F, &dA));
    CHK(cutensornetCreateTensorDescriptor(h, 2, ext, NULL, mU, CUDA_R_32F, &dU));
    CHK(cutensornetCreateTensorDescriptor(h, 2, ext, NULL, mV, CUDA_R_32F, &dV));
    cutensornetWorkspaceDescriptor_t ws; CHK(cutensornetCreateWorkspaceDescriptor(h, &ws));
    CHK(cutensornetWorkspaceComputeSVDSizes(h, dA, dU, dV, NULL, ws));   // default config: GESVD

    int64_t dsz = 0, hsz = 0; uint64_t hsz_old = 0;
    CHK(cutensornetWorkspaceGetMemorySize(h, ws, CUTENSORNET_WORKSIZE_PREF_RECOMMENDED, CUTENSORNET_MEMSPACE_DEVICE, CUTENSORNET_WORKSPACE_SCRATCH, &dsz));
    CHK(cutensornetWorkspaceGetMemorySize(h, ws, CUTENSORNET_WORKSIZE_PREF_RECOMMENDED, CUTENSORNET_MEMSPACE_HOST, CUTENSORNET_WORKSPACE_SCRATCH, &hsz));
    CHK(cutensornetWorkspaceGetSize(h, ws, CUTENSORNET_WORKSIZE_PREF_RECOMMENDED, CUTENSORNET_MEMSPACE_HOST, &hsz_old));
    cudaMalloc(&dw, dsz);
    CHK(cutensornetWorkspaceSetMemory(h, ws, CUTENSORNET_MEMSPACE_DEVICE, CUTENSORNET_WORKSPACE_SCRATCH, dw, dsz));
    int64_t give = host_mode == 1 ? (int64_t)hsz_old : hsz;
    if (host_mode && give > 0) {
        posix_memalign(&hbase, 256, give + 256); hw = (char*)hbase + 64;
        CHK(cutensornetWorkspaceSetMemory(h, ws, CUTENSORNET_MEMSPACE_HOST, CUTENSORNET_WORKSPACE_SCRATCH, hw, give));
    }
    printf("  host scratch: GetMemorySize %ld B, deprecated GetSize %lu B; provided %ld B\n",
           (long)hsz, (unsigned long)hsz_old, hw ? (long)give : 0L);
    CHK(cutensornetTensorSVD(h, dA, A, dU, U, S, dV, V, NULL, NULL, ws, 0));
    cudaDeviceSynchronize();
    printf("  OK\n");
    return 0;
}

int main(void) {
    printf("cuTensorNet %zu, cudart %zu\n", cutensornetGetVersion(), cutensornetGetCudartVersion());
    cutensornetHandle_t h; cutensornetCreate(&h);
    const char *what[] = {"device workspace only", "+ host workspace, deprecated GetSize size", "+ host workspace, GetMemorySize size"};
    for (int m = 0; m < 3; m++) { printf("%s:\n", what[m]); svd(h, m); }
    return 0;
}
Lingua principale
Jupyter Notebook
Stelle
500
Fork
102
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di NVIDIA/cuQuantum

Tutte le issue di NVIDIA/cuQuantum

Issue simili

Altre issue su Quantum Computing

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.