Skip to content

perf: optimize generic tensor conversion - #832

Merged
voltjia merged 4 commits into
masterfrom
perf/optimize-generic-tensor-conversion
Aug 11, 2026
Merged

perf: optimize generic tensor conversion#832
voltjia merged 4 commits into
masterfrom
perf/optimize-generic-tensor-conversion

Conversation

@baominghelly

Copy link
Copy Markdown
Contributor

Summary

  • Cache/intern Python tensor metadata attribute names used by TensorFromPybind11Handle.
  • Use CPython no-argument method, sequence, integer, and UTF-8 APIs to reduce temporary pybind11 objects and string/vector copies in the generic duck-typed tensor conversion path.

Motivation

TensorFromPybind11Handle runs for every tensor argument passed through the generated eager Python bindings. The previous implementation repeatedly created attribute-name objects and converted Python strings/sequences through generic pybind11 casters.

On an NVIDIA A100-SXM4-80GB, an alternating A/B run of the exact patch used FP32 16x16 GEMM with implementation_index=0, 200 warmups, 2,000 calls per repetition, 15 repetitions per process, and four runs per variant:

MetricBaselineCandidateImprovement
Torch tensor conversion4.279 us2.586 us1.693 us (39.6%)
Generic duck tensor conversion3.693 us2.546 us1.147 us (31.1%)
GEMM end-to-end latency19.889 us15.891 us3.997 us (20.1%)

Type of Change

  • feat — new feature / new operator / new platform
  • fix — bug fix
  • perf — performance improvement (no behavioral change)
  • refactor — code restructuring without behavior change
  • test — adding or fixing tests only
  • docs — documentation only
  • build / ci — build system or CI configuration
  • chore — tooling, formatting, or other non-code changes
  • Breaking change (requires a ! in the Conventional Commits prefix or a BREAKING CHANGE: footer)

Platforms Affected

  • CPU (WITH_CPU)
  • NVIDIA (WITH_NVIDIA)
  • Iluvatar (WITH_ILUVATAR)
  • MetaX (WITH_METAX)
  • Cambricon (WITH_CAMBRICON)
  • Moore (WITH_MOORE)
  • Ascend (WITH_ASCEND)
  • PyTorch C++ bindings (WITH_TORCH)
  • Build system / CMake / CI
  • Python bindings / user-facing API

Smoke Test Result

CUDACXX=/usr/local/cuda/bin/nvcc CMAKE_BUILD_PARALLEL_LEVEL=32 \
SKBUILD_BUILD_DIR=build-pr-smoke-cuda13 \
python -m pip install '.[dev]' --no-build-isolation --no-deps \
--config-settings=cmake.define.INFINI_RT_ROOT=/data/shared/baoming/workplace/new_ops/infinirt-prefix \
--config-settings=cmake.define.INFINI_OPS_SMOKE_BUILD=ON \
--config-settings=cmake.define.WITH_NVIDIA=ON \
--config-settings=cmake.define.WITH_CPU=OFF
Successfully built InfiniOps
Successfully installed InfiniOps-0.1.0
CUDA_VISIBLE_DEVICES=4 python -m pytest tests -m smoke -q
2 failed, 91 passed, 19 skipped, 13008 deselected in 16.35s

The two failures are the existing FP32 GEMM tolerance cases for implementations 0 and 1. Both failures reproduce with the same output values on an independently built, unmodified master at 26228d8; the candidate and baseline GEMM smoke subsets each report 2 failed, 8 passed.

Test Results on Supported Platforms

PlatformAffectedBuild / Smoke ResultFull Result / Notes
NVIDIAYesBuild passed; 91 passed, 2 baseline-reproduced failures, 19 skippedFull suite not run
IluvatarYesNot run - no hardware availableShared generic conversion path
MetaXYesNot run - no hardware availableShared generic conversion path
CambriconYesNot run - no hardware availableShared generic conversion path
MooreYesNot run - no hardware availableShared generic conversion path
AscendYesNot run - no hardware availableShared generic conversion path
Full `pytest` output (optional)
Not run - this is a draft performance PR; NVIDIA smoke validation is recorded above.

Benchmark / Performance Impact

  • Harness: out-of-tree tensor-conversion profiler, intentionally excluded from this PR.
  • Hardware: NVIDIA A100-SXM4-80GB; no foreign GPU process was observed during the alternating A/B run.
  • Workload: FP32 16x16 GEMM, explicit implementation index 0.
  • Method: 200 warmups; 2,000 end-to-end iterations; 20,000 conversion iterations; 15 repetitions; four alternating runs per variant; median across run medians.
  • Result: generic tensor conversion improved by 31.1%, direct Torch tensor conversion by 39.6%, and GEMM end-to-end latency by 20.1% (3.997 us).

Notes for Reviewers

  • The optimization remains framework-neutral and preserves the existing duck-typed tensor contract (data_ptr, shape, dtype, device, and stride).
  • Interned Python attribute names intentionally retain one process-lifetime reference to avoid destruction after Python interpreter finalization.
  • This PR does not include ATen tensor reuse, THPVariable_Unpack, Torch wrapper generation changes, CMake toggles, profiling hooks, benchmark scripts, or profiling logs.
  • Non-NVIDIA backend validation and the two pre-existing GEMM tolerance failures remain follow-up items before marking the PR ready.

@baominghelly
baominghelly marked this pull request as ready for review July 29, 2026 02:59
@baominghelly
baominghelly requested review from a team and voltjiaJuly 29, 2026 02:59
@baominghelly
baominghellyforce-pushed the perf/optimize-generic-tensor-conversion branch from 41a0966 to 50f979dCompareAugust 3, 2026 07:45
* refactor: minimize direct Python C API usage
* refactor: clarify integer conversion helper name
* test: drop unrelated tensor conversion coverage
* refactor: consolidate interned Python names
* refactor: simplify interned name access
Comment threadsrc/pybind11_utils.h Outdated
@voltjia
voltjia merged commit 40ab97e into masterAug 11, 2026
20 checks passed
@voltjia
voltjia deleted the perf/optimize-generic-tensor-conversion branch August 11, 2026 01:37
Sign up for freeto 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

@baominghelly@voltjia