Skip to content

fix(cmake): make cuTENSOR/cuQuantum finders honest and version-aware#993

Open
pcchen wants to merge 2 commits into
masterfrom
split/cuda-finder-modernization
Open

fix(cmake): make cuTENSOR/cuQuantum finders honest and version-aware#993
pcchen wants to merge 2 commits into
masterfrom
split/cuda-finder-modernization

Conversation

@pcchen

@pcchen pcchen commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

First split of #950 (the finder-correctness portion). No CMakeLists.txt or
compiler/version-floor changes — those remain separate follow-up splits.

Changes

  • Honest *_FOUND. CUTENSOR_FOUND/CUQUANTUM_FOUND are now derived from
    the actual find_library results via find_package_handle_standard_args,
    instead of set(... TRUE) unconditionally — which let a NOTFOUND silently
    pass a caller's REQUIRED check and link an empty / -NOTFOUND entry.
  • Version-aware cuTENSOR layout. Search both the cuTENSOR 2.x flat lib/
    and the legacy per-CUDA-major lib/<major> via PATH_SUFFIXES, dropping the
    dead lib/10.2/lib/11 branches; report the directory actually found.
  • cuTENSOR ≥ 2.0 enforced by reading CUTENSOR_MAJOR/MINOR from the headers
    and failing early on the 1.x API.
  • FindCUQUANTUM builds CUQUANTUM_LIBRARIES conditionally (parity).

Addresses the finder portions of #945 / #946.

Verification

Extracted verbatim from the already-reviewed #950 diff; both modules parse
cleanly. These finders only run under USE_CUTENSOR/USE_CUQUANTUM (i.e. a
CUDA build), which can't be exercised on the author's macOS machine — a
reviewer with a CUDA box please sanity-check a -DUSE_CUTENSOR=ON
(and -DUSE_CUQUANTUM=ON) configure.

Posted by Claude Code on behalf of @pcchen

Split out of #950 (finder-correctness portion).

- CUTENSOR_FOUND / CUQUANTUM_FOUND are now derived from the actual
  find_library results via find_package_handle_standard_args, instead of
  being set TRUE unconditionally (which let a NOTFOUND silently pass a
  caller's REQUIRED check and link an empty / -NOTFOUND entry).
- FindCUTENSOR: search both the cuTENSOR 2.x flat lib/ layout and the
  legacy per-CUDA-major lib/<major> layout (PATH_SUFFIXES), dropping the
  dead lib/10.2 and lib/11 branches; report the real found dir.
- FindCUTENSOR: read CUTENSOR_MAJOR/MINOR from the headers and FATAL_ERROR
  on the unsupported 1.x API (Cytnx requires cuTENSOR >= 2.0).
- FindCUQUANTUM: build CUQUANTUM_LIBRARIES conditionally (parity).

Addresses the finder portions of #945 / #946. No CMakeLists.txt or
compiler/version-floor policy changes (those remain separate splits).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the CMake module files FindCUQUANTUM.cmake and FindCUTENSOR.cmake to enforce stricter version requirements (CUDA >= 12 and cuTENSOR >= 2.0) and to use FindPackageHandleStandardArgs for robust package finding. Feedback on these changes suggests handling cases where the cuTENSOR minor version cannot be parsed by defaulting it to 0 to avoid malformed version strings, and dynamically retrieving CUQUANTUM_LIBRARY_DIRS for consistency.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +62 to +65
file(STRINGS "${_cutensor_version_header}" _cutensor_minor_line REGEX "^#define[ \t]+CUTENSOR_MINOR[ \t]+[0-9]+")
string(REGEX REPLACE ".*CUTENSOR_MAJOR[ \t]+([0-9]+).*" "\\1" CUTENSOR_VERSION_MAJOR "${_cutensor_major_line}")
string(REGEX REPLACE ".*CUTENSOR_MINOR[ \t]+([0-9]+).*" "\\1" CUTENSOR_VERSION_MINOR "${_cutensor_minor_line}")
set(CUTENSOR_VERSION "${CUTENSOR_VERSION_MAJOR}.${CUTENSOR_VERSION_MINOR}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If CUTENSOR_MINOR is not found or fails to match the regex, _cutensor_minor_line will be empty. Performing string(REGEX REPLACE) on an empty string will result in CUTENSOR_VERSION_MINOR being empty, which leads to a malformed CUTENSOR_VERSION (e.g., 2.). This can cause version comparison failures in find_package_handle_standard_args or downstream scripts.

We should check if _cutensor_minor_line is non-empty before replacing, and default it to 0 otherwise.

  file(STRINGS "${_cutensor_version_header}" _cutensor_minor_line REGEX "^#define[ \t]+CUTENSOR_MINOR[ \t]+[0-9]+")
  string(REGEX REPLACE ".*CUTENSOR_MAJOR[ \t]+([0-9]+).*" "\\1" CUTENSOR_VERSION_MAJOR "${_cutensor_major_line}")
  if(_cutensor_minor_line)
    string(REGEX REPLACE ".*CUTENSOR_MINOR[ \t]+([0-9]+).*" "\\1" CUTENSOR_VERSION_MINOR "${_cutensor_minor_line}")
  else()
    set(CUTENSOR_VERSION_MINOR "0")
  endif()
  set(CUTENSOR_VERSION "${CUTENSOR_VERSION_MAJOR}.${CUTENSOR_VERSION_MINOR}")

Comment on lines +52 to +58
set(CUQUANTUM_LIBRARIES "")
if(CUQUANTUM_TENSORNET_LIB)
list(APPEND CUQUANTUM_LIBRARIES "${CUQUANTUM_TENSORNET_LIB}")
endif()
if(CUQUANTUM_CUSTATEVEC_LIB)
list(APPEND CUQUANTUM_LIBRARIES "${CUQUANTUM_CUSTATEVEC_LIB}")
endif()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For consistency with FindCUTENSOR.cmake and to ensure that CUQUANTUM_LIBRARY_DIRS accurately reflects the actual location of the found libraries (rather than assuming a hardcoded lib subdirectory), we should dynamically retrieve the directory of the found library using get_filename_component.

if(CUQUANTUM_TENSORNET_LIB)
  get_filename_component(CUQUANTUM_LIBRARY_DIRS "${CUQUANTUM_TENSORNET_LIB}" DIRECTORY)
endif()
set(CUQUANTUM_LIBRARIES "")
if(CUQUANTUM_TENSORNET_LIB)
    list(APPEND CUQUANTUM_LIBRARIES "${CUQUANTUM_TENSORNET_LIB}")
endif()
if(CUQUANTUM_CUSTATEVEC_LIB)
    list(APPEND CUQUANTUM_LIBRARIES "${CUQUANTUM_CUSTATEVEC_LIB}")
endif()

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c19d7e4c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmake/Modules/FindCUTENSOR.cmake Outdated
@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 30.88%. Comparing base (d02cb29) to head (6650adc).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #993   +/-   ##
=======================================
  Coverage   30.88%   30.88%           
=======================================
  Files         229      229           
  Lines       34758    34758           
  Branches    14409    14409           
=======================================
  Hits        10734    10734           
  Misses      16720    16720           
  Partials     7304     7304           
Flag Coverage Δ
cpp 30.39% <ø> (ø)
python 59.41% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
C++ backend 32.21% <ø> (ø)
Python bindings 17.28% <ø> (ø)
Python package 59.41% <ø> (ø)

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d02cb29...6650adc. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…arse

- FindCUTENSOR: drop the CUDA>=12 FATAL_ERROR (a version-floor policy that
  belongs in the separate #962/CMakeLists.txt split and would reject valid
  CUDA 11 + cuTENSOR 2.x installs). The generic lib/<major> suffix already
  covers 11/12/13. This finder now stays policy-free. (codex review)
- FindCUTENSOR: default CUTENSOR_MINOR to 0 when the header line is absent,
  so CUTENSOR_VERSION isn't malformed ("2.") for the VERSION_VAR check.
  (gemini review)
- FindCUQUANTUM: derive CUQUANTUM_LIBRARY_DIRS from the found library via
  get_filename_component, mirroring FindCUTENSOR. (gemini review)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pcchen

pcchen commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks — addressed all three in 6650adc:

Note this PR (first split of #950) intentionally keeps only finder correctness + layout + the cuTENSOR ≥ 2.0 API requirement — no CMakeLists.txt / CUDA-version-floor changes. As before, it can't be built on a CUDA-less machine; a reviewer with a CUDA box please sanity-check a -DUSE_CUTENSOR=ON configure.

Posted by Claude Code on behalf of @pcchen

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6650adcbfd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +75 to +77
message(WARNING
"Could not determine the cuTENSOR version from headers under "
"${CUTENSOR_INCLUDE_DIRS}; Cytnx requires cuTENSOR >= 2.0.")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require a parsed cuTENSOR version before succeeding

When CUTENSOR_ROOT has a libcutensor library but the headers are missing or don't expose CUTENSOR_MAJOR in one of these two searched files, this branch only emits a warning. The subsequent find_package_handle_standard_args(... VERSION_VAR CUTENSOR_VERSION) does not fail because the repo calls find_package(CUTENSOR REQUIRED) without requesting a version, so CUTENSOR_FOUND becomes true with an empty/unknown version and UNI_CUTENSOR is enabled anyway. That defers an invalid cuTENSOR install to compile/link time, and can also let unsupported headers through when the new >=2 check cannot parse them.

Useful? React with 👍 / 👎.

@pcchen
pcchen requested review from IvanaGyro and yingjerkao July 6, 2026 07:21
Comment on lines +30 to +32
# Search both cuTENSOR library layouts: 2.x tarballs place the libraries
# directly under lib/, while older tarballs and apt use a per-CUDA-major
# subdir (lib/<cuda-major>, e.g. lib/11, lib/12, lib/13). Listing both as

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This layout was changed since 2.3 not 2.x

# directly under lib/, while older tarballs and apt use a per-CUDA-major
# subdir (lib/<cuda-major>, e.g. lib/11, lib/12, lib/13). Listing both as
# find_library PATH_SUFFIXES resolves either layout for any CUDA major. The
# older minor-specific lib/10.2 and lib/11.0 special-cases were removed; the

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is not useful for the future. It can be put in the commit message.

# generic lib/<major> covers them (apt multiarch paths remain, issue #946).
# The CUDA-version floor is a separate policy decision (issue #962), enforced
# in CMakeLists.txt rather than gated here, so this finder stays policy-free.
set(CUTNLIB_DIR lib lib/${CUDAToolkit_VERSION_MAJOR})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CUTNLIB_DIR is not used in the new implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants