Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions recipes/transformer-engine/001-cmake.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- a/build_tools/build_ext.py
+++ b/build_tools/build_ext.py
@@ -56,7 +56,7 @@ class CMakeExtension(setuptools.Extension):
cmake_path,
"-B",
build_dir,
- f"-DPython_EXECUTABLE={sys.executable}",
+ "-DPython_EXECUTABLE=$PYTHON",

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.

Think we can do this in a more Pythonic way

Suggested change
+ "-DPython_EXECUTABLE=$PYTHON",
+ "-DPython_EXECUTABLE={os.environ['PYTHON']}",

Also what happens when sys.executable is here?

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.

sys.executable led to this failure during build:

      CMake Error at /home/conda/staged-recipes/build_artifacts/transformer-engine_1745610886178/_build_env/share/cmake-4.0/Modules/FindPackageHandleStandardArgs.cmake:227 (message):
        Could NOT find Python (missing: Interpreter Development.Module) (found
        version "3.11.12")

@pstjohn pstjohn May 1, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Think we can do this in a more Pythonic way

No oddly, I get the same missing: Interpreter Development.Module when I do f"-DPython_EXECUTABLE={os.environ['PYTHON']}",; at least locally. Not sure why these would be different?

f"-DPython_INCLUDE_DIR={sysconfig.get_path('include')}",
f"-DCMAKE_BUILD_TYPE={build_type}",
f"-DCMAKE_INSTALL_PREFIX={install_dir}",
5 changes: 5 additions & 0 deletions recipes/transformer-engine/activate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if [[ -n "${CUDA_HOME:-}" ]]
then
export CUDA_HOME_BACKUP="${CUDA_HOME}"
fi
export CUDA_HOME="${CONDA_PREFIX}"
30 changes: 30 additions & 0 deletions recipes/transformer-engine/build_te.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash
set -euxo pipefail

cat > $RECIPE_DIR/gcc_shim <<"EOF"
#!/bin/sh
exec $GCC -I$PREFIX/include "$@"
EOF

chmod +x $RECIPE_DIR/gcc_shim
export CC="$RECIPE_DIR/gcc_shim"

# Re-arrange build files to match the expected layout.
ln -s $PREFIX/nvvm $PREFIX/targets/x86_64-linux/nvvm
cp $BUILD_PREFIX/targets/x86_64-linux/include/fatbinary_section.h $PREFIX/targets/x86_64-linux/include
cp $PREFIX/include/cudnn*.h $PREFIX/targets/x86_64-linux/include

echo "Installing transformer-engine"
NVTE_NO_LOCAL_VERSION=1 ${PYTHON} -m pip install .

# Remove re-arranged files.
rm -rf $PREFIX/targets/x86_64-linux/nvvm
rm -rf $PREFIX/targets/x86_64-linux/include/fatbinary_section.h
rm -rf $PREFIX/targets/x86_64-linux/include/cudnn*.h


mkdir -p $PREFIX/etc/conda/activate.d
cp $RECIPE_DIR/activate.sh $PREFIX/etc/conda/activate.d/transformer-engine-activate.sh

mkdir -p $PREFIX/etc/conda/deactivate.d
cp $RECIPE_DIR/deactivate.sh $PREFIX/etc/conda/deactivate.d/transformer-engine-deactivate.sh
5 changes: 5 additions & 0 deletions recipes/transformer-engine/deactivate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if [[ -n "${CUDA_HOME_BACKUP:-}" ]]
then
export CUDA_HOME="${CUDA_HOME_BACKUP}"
unset CUDA_HOME_BACKUP
fi
106 changes: 106 additions & 0 deletions recipes/transformer-engine/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{% set version = "1.13" %}
{% set torch_proc_type = "cuda" if cuda_compiler_version != "None" else "cpu" %}

{% if cuda_compiler_version in (None, "None", True, False) %}
{% set cuda_major = 0 %}
{% else %}
{% set cuda_major = environ.get("cuda_compiler_version", "11.8").split(".")[0] | int %}
{% endif %}

package:
name: transformer-engine
version: {{ version }}

source:
- url: https://github.com/NVIDIA/TransformerEngine/archive/refs/tags/v{{ version }}.tar.gz
sha256: 90dd8f694cba29707c502a4f4d12871cb9d4c1f157d329f22cb3d382de8468ae
patches:
- 001-cmake.patch

- url: https://github.com/NVIDIA/cudnn-frontend/archive/refs/tags/v1.8.0.tar.gz
sha256: 5907bf8baa8f3b74ad430d54027aadd14a0a61166ae4b00c2daece0df384409e
folder: 3rdparty/cudnn-frontend
Comment on lines +20 to +22

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.

Is it ok to vendor cudnn-frontend here? I've packaged this at https://github.com/conda-forge/python-cudnn-frontend-feedstock and have been trying to get it to work (unsuccessfully) at #26296 (comment). But this solution looks much simpler 🙂

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah that's a good question. In conversations with the TE team, they work pretty closely with cudnn-frontend and sometimes have odd tags or versions here. I also don't think the repo is set up to be able to pull these dependencies from a source outside 3rdparty. That might be something we could try to fix in subsequent versions though. cudnn-frontend is a header-only library though, so it should be fairly lightweight.

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.

From https://conda-forge.org/docs/maintainer/guidelines/#generalities

The source should not contain vendored code. If it does:
Package the vendored project separately and specify the needed dependency in the requirements section. Preferred if the vendored code is needed at runtime.
Allow the vendored code, but make sure the license files are included in the about.license field. Usually ok if it's only a build-time dependency (e.g. headers-only library)

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.

Revending headers for compile-time is OK. What's not OK is revending them at runtime. This package is shipping a copy of CUDNN in $PREFIX/targets.

https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=1235681&view=logs&j=df9408f7-e795-500f-143d-aa7735a0ed8b&t=47addc80-ccbf-566b-ee3a-66cdb8436937&l=4381

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, yes, that is a problem. I moved some headers around so the CMAKE command could find them, but didn't realize they were getting re-distributed. Since we're patching those cmake build flags anyways I'll try to point cmake to the right place to find them in these conda builds

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Well it's not easy to get the cmake command to find these in a different location. The alternative could just be to clean these up post-build, right? Let me try doing that.


- url: https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz
sha256: 8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7
folder: 3rdparty/googletest

build:
number: 0

outputs:
- name: transformer-engine-torch
version: {{ version }}
script: build_te.sh

build:
skip: true # [not (cuda_compiler_version or "").startswith("12")]
skip: true # [not (linux64 or aarch64)]
script_env:
- CUDA_HOME={{ BUILD_PREFIX }}
- NVTE_FRAMEWORK=pytorch
run_exports:
- {{ pin_subpackage('transformer-engine-torch', max_pin='x.x') }}

requirements:
build:
- python # [build_platform != target_platform]
- cross-python_{{ target_platform }} # [build_platform != target_platform]
- pytorch # [build_platform != target_platform]
- pytorch =*={{ torch_proc_type }}* # [build_platform != target_platform]
- {{ stdlib('c') }}
- {{ compiler('c') }}
- {{ compiler('cxx') }}
- {{ compiler('cuda') }} # [cuda_compiler_version not in (undefined, 'None')]
- cuda-nvvm
- cmake >=3.21
- ninja

host:
- python
- pip
- pybind11
- pytorch
- pytorch =*={{ torch_proc_type }}*
- setuptools
- pydantic
- importlib-metadata >=1.0
- packaging
- cuda-driver-dev
- cuda-cudart-dev
- cuda-nvrtc-dev
- cuda-nvtx-dev
- cuda-nvml-dev
- libcublas-dev
- libcusparse-dev
- libcusolver-dev
Comment on lines +69 to +76

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.

There are various unused dependencies at runtime from these CUDA libraries. Are we using dlopen or statically linking? Or are the deps actually unused?

https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=1235681&view=logs&j=df9408f7-e795-500f-143d-aa7735a0ed8b&t=47addc80-ccbf-566b-ee3a-66cdb8436937&l=2494

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah good question; they might only be needed at build time. Would I move these from host to build then? I'm pretty sure pydantic just wasn't exercised during the import tests, added an additional import to hopefully hit that.

@carterbox carterbox May 1, 2025

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.

It depends:

statically linked? This should only be cudart. Use the cudart-static package instead.
dlopen'd? Ignore run_exports from these packages and add any relevant constraints to `requirements/run_constrained'
Unused? Remove it.

None of these packages are build tools, so they shouldn't go in requirements/build.

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.

As discussed offline, we are assuming these packages are dlopen'd and will decide whether to make them optional at a later time.

- cudnn
- cuda-profiler-api

run:
- python
- pydantic
- importlib-metadata >=1.0

run_constrained:
# additional run constraint to the one from the (version-only) run_export;
# constraining the CPU builds to CPU pytorch isn't 100% necessary, but cleaner
- pytorch =*={{ torch_proc_type }}*

test:
imports:
- transformer_engine.pytorch
- transformer_engine.common
- transformer_engine.common.recipe

about:
home: https://github.com/NVIDIA/TransformerEngine
summary: A library for accelerating Transformer models on NVIDIA GPUs.
license: Apache-2.0
license_file: LICENSE
dev_url: https://github.com/NVIDIA/TransformerEngine

extra:
feedstock-name: transformer-engine
recipe-maintainers:
- pstjohn