Skip to content

Create nvfuser_next extension #4156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 7, 2025
Merged

Create nvfuser_next extension #4156

merged 9 commits into from
May 7, 2025

Conversation

rdspring1
Copy link
Collaborator

@rdspring1 rdspring1 commented Mar 30, 2025

This PR creates a new Pybind11 extension for the direct bindings API. The bindings does not have any functionality.

Key Build Details:

  • The python extension name is PYTHON_NEXT_EXTENSION=_C_NEXT.
  • It is used to create a new shared library titled libnvfuser_next.so
  • Installed as separate module named nvfuser_next.

@rdspring1 rdspring1 added Python API Issues related to the Python API Direct Bindings Python extension with direct mapping to NvFuser CPP objects. labels Mar 30, 2025
Copy link

github-actions bot commented Mar 30, 2025

Review updated until commit 2266039

Description

  • Create nvfuser_next Pybind11 extension

  • Add import conflict checks between nvfuser and nvfuser_next

  • Update build_ext to handle nvfuser_next library

  • Add tests for import conflicts


Changes walkthrough 📝

Relevant files
Enhancement
6 files
bindings.cpp
Add bindings initialization for nvfuser_next                         
+17/-0   
extension.cpp
Define nvfuser_next module entry point                                     
+14/-0   
__init__.py
Add import conflict check for nvfuser_next                             
+6/-1     
__init__.py
Initialize nvfuser_next module with import conflict check
+20/-0   
utils.py
Update build_ext to handle nvfuser_next                                   
+21/-13 
bindings.h
Declare bindings initialization function for nvfuser_next
+17/-0   
Tests
2 files
test_python_frontend.py
Add test for import conflict between nvfuser and nvfuser_next
+12/-0   
test_python_next.py
Add test for import conflict between nvfuser_next and nvfuser
+24/-0   
Configuration changes
1 files
CMakeLists.txt
Add build rules for nvfuser_next extension                             
+76/-3   

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🧪 PR contains tests
⚡ Recommended focus areas for review

Functionality

The initNvFuserPythonBindings function does not currently add any bindings. Ensure that this function is implemented to include the necessary bindings for the nvfuser_next module.

void initNvFuserPythonBindings(PyObject* module) {
  auto python_bindings = py::handle(module).cast<py::module>();
}
Dependency

The pytorch_lib_dir is added to sys.path unconditionally. Verify if this is necessary and consider potential side effects on the environment.

pytorch_lib_dir = os.path.join(os.path.dirname(torch.__file__), "lib")
if pytorch_lib_dir not in sys.path:
    sys.path.append(pytorch_lib_dir)
Redundancy

The target_compile_definitions and set_target_properties for nvf_py_next_internal and nvfuser_next are nearly identical. Consider refactoring to avoid redundancy.

target_compile_definitions(nvf_py_next_internal PRIVATE
  "-DTORCH_CUDA_BUILD_MAIN_LIB"
  "-DC10_BUILD_MAIN_LIB=1"
  PYTHON_NEXT_EXTENSION=_C_NEXT
)

add_library(nvfuser_next MODULE $<TARGET_OBJECTS:nvf_py_next_internal>)
target_compile_definitions(nvfuser_next PRIVATE
  "-DTORCH_CUDA_BUILD_MAIN_LIB"
  "-DC10_BUILD_MAIN_LIB=1"
  PYTHON_NEXT_EXTENSION=_C_NEXT
)

if(NOT MSVC)
  target_compile_options(nvf_py_next_internal PRIVATE -Wall -Wno-unused-function)
  target_compile_options(nvf_py_next_internal PRIVATE -Werror)
  set(NVF_LIB_SUFFIX ".so")
else()
  set(NVF_LIB_SUFFIX ".pyd")
endif()

set_target_properties(nvf_py_next_internal PROPERTIES
  C_STANDARD ${NVFUSER_C_STANDARD}
  CUDA_STANDARD ${NVFUSER_CUDA_STANDARD}
  CXX_STANDARD ${NVFUSER_CPP_STANDARD}
  CXX_STANDARD_REQUIRED ON
  CXX_VISIBILITY_PRESET hidden
  INSTALL_RPATH
  "$ORIGIN/lib:$ORIGIN/../nvidia/cuda_runtime/lib:$ORIGIN/../nvidia/cuda_nvrtc/lib:$ORIGIN/../../nvidia/cuda_cupti/lib:$ORIGIN/../torch/lib"
  POSITION_INDEPENDENT_CODE Yes
  VISIBILITY_INLINES_HIDDEN Yes
)
set_target_properties(nvfuser_next PROPERTIES
  C_STANDARD ${NVFUSER_C_STANDARD}
  CUDA_STANDARD ${NVFUSER_CUDA_STANDARD}
  CXX_STANDARD ${NVFUSER_CPP_STANDARD}
  CXX_STANDARD_REQUIRED ON
  CXX_VISIBILITY_PRESET hidden
  INSTALL_RPATH
  "$ORIGIN/lib:$ORIGIN/../nvidia/cuda_runtime/lib:$ORIGIN/../nvidia/cuda_nvrtc/lib:$ORIGIN/../../nvidia/cuda_cupti/lib:$ORIGIN/../torch/lib"
  POSITION_INDEPENDENT_CODE Yes
  SUFFIX ${NVF_LIB_SUFFIX}
  VISIBILITY_INLINES_HIDDEN Yes
)

@wujingyue
Copy link
Collaborator

Context? How is this related to the existing python api in csrc?

@rdspring1
Copy link
Collaborator Author

Context? How is this related to the existing python api in csrc?

TL;DR: Direct bindings API maps directly to CPP Fusion objects. It doesn't rely on the FusionCache. e.g., You can make Fusions just like in CPP if desired.The end goal is for direct bindings to completely replace the existing python API.

I've been working on a prototype for direct bindings. #4077 This PR is the first to start integrating the changes into main.

Full design doc: https://docs.google.com/document/d/1ftdNKu952EFmLANa36g0IrVaqAJ0eLKzgJESkQFnuVI/edit?usp=sharing

Copy link
Collaborator

@jacobhinkle jacobhinkle left a comment

Choose a reason for hiding this comment

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

LGTM

@kevinstephano
Copy link
Collaborator

I am suggesting that we modify this to appear as we would want it for a new Python API. Therefore, there should not be a reference to "direct" in the code as a user would not care.

The main changes I am suggesting is to change the direct from direct_bindings_api to python/src as the place to contain the C++ files for our binding code.

@kevinstephano kevinstephano marked this pull request as draft April 3, 2025 15:01
@rdspring1 rdspring1 changed the base branch from main to next_pt0 April 26, 2025 04:03
@rdspring1 rdspring1 changed the title Create direct_bindings_api extension Create nvfuser_next extension Apr 26, 2025
@rdspring1 rdspring1 marked this pull request as ready for review April 26, 2025 17:27
@rdspring1 rdspring1 force-pushed the next_pt0 branch 4 times, most recently from 23b5223 to ccad78d Compare May 2, 2025 00:00
Base automatically changed from next_pt0 to main May 6, 2025 18:12
@rdspring1
Copy link
Collaborator Author

!test

Copy link
Collaborator

@jjsjann123 jjsjann123 left a comment

Choose a reason for hiding this comment

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

LGTM.

Should we also add a python test file to verify the import would work?

codegen_internal
Python::Module
)
install(TARGETS nvfuser_next DESTINATION lib)
Copy link
Collaborator

Choose a reason for hiding this comment

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

my nitpick on this PR is that, we would want to avoid duplicate the code that's shared between the two pybind module.

I'm also leaning towards moving this down to the ./python/CMakeLists.txt.
But we don't have to do that in this PR. We can leave that as a follow up clean PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What do you want to move to .python/CMakeLists.txt?

Build engineer is on the case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

just simply for logic separation.
If I'm adding another python module. I don't need to see the entire build files for nvfuser core lib.

ext_modules=[
Extension(name="nvfuser._C", sources=[]),
Extension(name="nvfuser_next._C_NEXT", sources=[]),
],
Copy link
Collaborator

Choose a reason for hiding this comment

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

👏 I like how clean & easy the setup part is.

pytorch_lib_dir = os.path.join(os.path.dirname(torch.__file__), "lib")
if pytorch_lib_dir not in sys.path:
sys.path.append(pytorch_lib_dir)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Naive question. Are we expecting people to import both nvfuser and nvfuser_next?

The way things are imported makes me worried about name conflicts.
i.e. should we assert on not seeing nvfuser in sys.modules when importing nvfuser_next?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Are we expecting people to import both nvfuser and nvfuser_next?

No.

should we assert on not seeing nvfuser in sys.modules when importing nvfuser_next?

Yes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@jjsjann123 I added assertions to nvfuser/__init__.py and nvfuser_next/__init__.py and python tests to check for the conflicts.

Copy link
Collaborator

@kevinstephano kevinstephano left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Collaborator

@kevinstephano kevinstephano left a comment

Choose a reason for hiding this comment

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

LGTM

@rdspring1
Copy link
Collaborator Author

!test

@rdspring1
Copy link
Collaborator Author

Should we also add a python test file to verify the import would work?

I created test_import_correct for this.

@rdspring1 rdspring1 merged commit 815d40a into main May 7, 2025
53 checks passed
@rdspring1 rdspring1 deleted the direct_pt0 branch May 7, 2025 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Direct Bindings Python extension with direct mapping to NvFuser CPP objects. Python API Issues related to the Python API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants