Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

`cutensornetTensorSVD` returns `CUTENSORNET_STATUS_INTERNAL_ERROR` with missing host workspace

Đang mở
#230 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
48/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
c, linux
Lĩnh vực
quantum-computing

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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;
}
Ngôn ngữ chính
Jupyter Notebook
Star
503
Fork
102
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của NVIDIA/cuQuantum

Tất cả issue của NVIDIA/cuQuantum

Issue tương tự

Thêm issue về Quantum Computing

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.