Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

`cutensornetTensorSVD` returns `CUTENSORNET_STATUS_INTERNAL_ERROR` with missing host workspace

オープン
#230 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
c, linux

調査の方向性

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.

索引モデルが issue の本文から書いたものです。

説明

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;
}
主要言語
Jupyter Notebook
スター
500
フォーク
102
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

NVIDIA/cuQuantum のほかの issue

NVIDIA/cuQuantum の issue をすべて見る

似ている issue

Quantum Computing の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。