diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index f753719f..b45633a2 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -23,10 +23,9 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install -r requirements.txt pip install cmake build # or other tools you need - - name: Configure CMake + - name: Build wheel run: | # Grab the path to the "python" selected by setup-python export PYTHON_EXECUTABLE="$(which python)" @@ -36,42 +35,14 @@ jobs: echo "Python version: $PYTHON_VERSION" echo "Python executable: $PYTHON_EXECUTABLE" - - cmake \ - -DPYBIND11_PYTHON_VERSION="${PYTHON_VERSION}" \ - -DPython3_EXECUTABLE="${PYTHON_EXECUTABLE}" \ - -DPython_FIND_STRATEGY=LOCATION \ - -DPython_FIND_REGISTRY=NEVER \ - -DPython_FIND_FRAMEWORK=NEVER \ - -S . \ - -B build \ - -DCMAKE_BUILD_TYPE=Release - - - name: Build - run: cmake --build build --config Release - - - name: Fix library pathing - run: | - # Find the shared object file under the Python/TensorFrost folder. - # This command will locate any *.so file - SO_FILE=$(find Python/TensorFrost -type f -name "*.so") - if [ -z "$SO_FILE" ]; then - echo "No shared library found!" - exit 1 - fi - echo "Found shared library: $SO_FILE" - # Add the rpath relative to the shared library’s loader - install_name_tool -add_rpath @loader_path/. "$SO_FILE" + + ${PYTHON_EXECUTABLE} -m pip wheel ./Python -w Python/dist --verbose - name: Check Folder run: ls -R ./Python - - name: Build wheel - run: | - python -m build -w ./Python - - name: Upload wheels as artifact uses: actions/upload-artifact@v4 with: name: macos-wheels-py${{ matrix.python-version }} - path: Python/dist/*.whl + path: Python/dist/tensorfrost-*.whl diff --git a/.github/workflows/build_manylinux.yml b/.github/workflows/build_manylinux.yml index 94c23018..c15ad372 100644 --- a/.github/workflows/build_manylinux.yml +++ b/.github/workflows/build_manylinux.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['cp37-cp37m', 'cp38-cp38', 'cp39-cp39', 'cp310-cp310', 'cp311-cp311', 'cp312-cp312', 'cp313-cp313'] + python-version: ['cp38-cp38', 'cp39-cp39', 'cp310-cp310', 'cp311-cp311', 'cp312-cp312', 'cp313-cp313'] steps: - uses: actions/checkout@v4 with: @@ -22,6 +22,9 @@ jobs: docker build -t tensorfrost-manylinux . docker run --rm -e PYTHON_VERSION=${{ matrix.python-version }} -v $(pwd):/io tensorfrost-manylinux + - name: Check Folder + run: ls -R ./wheelhouse + - name: Upload wheels as artifact uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/build_windows.yaml b/.github/workflows/build_windows.yaml index 1b1db712..a2f881ad 100644 --- a/.github/workflows/build_windows.yaml +++ b/.github/workflows/build_windows.yaml @@ -11,7 +11,7 @@ jobs: runs-on: windows-latest strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 with: @@ -25,8 +25,15 @@ jobs: - name: Build and Package run: .\build_windows.ps1 + - name: Check Folder + run: | + echo "Contents of Python directory:" + ls -R ./Python + echo "Contents of dist directory:" + ls -R ./Python/dist + - name: Upload wheels as artifact uses: actions/upload-artifact@v4 with: name: windows-wheels-py${{ matrix.python-version }} - path: Python/dist/*.whl + path: Python/dist/tensorfrost-*.whl diff --git a/.idea/editor.xml b/.idea/editor.xml index b0d69ef6..6692539a 100644 --- a/.idea/editor.xml +++ b/.idea/editor.xml @@ -1,483 +1,342 @@ - \ No newline at end of file diff --git a/.run/TensorFrost.run.xml b/.run/TensorFrost.run.xml index 966b7b84..97e80504 100644 --- a/.run/TensorFrost.run.xml +++ b/.run/TensorFrost.run.xml @@ -1,5 +1,5 @@ - + diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b49070b..3c927cf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.15) project(TensorFrost) if(NOT CMAKE_BUILD_TYPE) diff --git a/Python/pyproject.toml b/Python/pyproject.toml index 193ee228..bb45d3ca 100644 --- a/Python/pyproject.toml +++ b/Python/pyproject.toml @@ -1,10 +1,14 @@ [build-system] -requires = ["setuptools>=64", "wheel"] -build-backend = "setuptools.build_meta" +requires = [ + "scikit-build-core>=0.11", + "pybind11>=2.12", + "jinja2>=3.1" +] +build-backend = "scikit_build_core.build" [project] name = "TensorFrost" -version = "0.7.3" +version = "0.7.3dev1" description = "A static optimizing tensor compiler with a Python frontend…" authors = [{name = "Mykhailo Moroz", email = "michael08840884@gmail.com"}] requires-python = ">=3.7" @@ -28,6 +32,15 @@ classifiers = [ "Environment :: X11 Applications", "Environment :: GPU", ] +readme = "../README.md" [tool.setuptools.package-data] -"TensorFrost" = ["*.so", "*.pyd", "*.dll", "*.dylib"] \ No newline at end of file +"TensorFrost" = ["*.so", "*.pyd", "*.dll", "*.dylib"] + +[tool.scikit-build] + +[tool.scikit-build.cmake] +source-dir = ".." + +[tool.scikit-build.logging] +level = "INFO" diff --git a/README.md b/README.md index b19fde8e..dd9a14a3 100644 --- a/README.md +++ b/README.md @@ -54,17 +54,22 @@ git clone --recurse-submodules https://github.com/MichaelMoroz/TensorFrost.git cd TensorFrost ``` -Then run cmake to build the library. +Then you can either install the library for development. ```bash -cmake -S . -B build && cmake --build build +py -$YOUR_PYTHON_VERSION$ -m pip install --upgrade pip setuptools wheel +py -$YOUR_PYTHON_VERSION$ -m pip install -e Python/ -v # install the library for development +``` +This will link the build folder to Python, so any changes you make to the source code will be reflected in the installed library, in case of changed CPP code you need to rebuild the file library files using `cmake --build . --config Release` command, or by using any IDE. + +You can also build a wheel file for distribution. This will create a wheel file in the `dist` folder. +```bash +py -$YOUR_PYTHON_VERSION$ -m pip wheel ./Python -w dist -v # build a wheel file ``` > [!TIP] > If you are using a Linux distribution that doesn't support installing packages through pip (e.g. Arch Linux), read **[Using a Virtual Environment](#using-a-virtual-environment)**. -The cmake script will automatically install the compiled python module into your python environment. - ### Using a Virtual Environment Certain Linux distributions (e.g. Arch Linux) want you to use their package manager to manage system-wide Python packages instead of pip. TensorFrost uses pip to install itself once built, so before running CMake you will need to activate a Virtual Environment. @@ -81,16 +86,13 @@ Certain Linux distributions (e.g. Arch Linux) want you to use their package mana source venv/bin/activate ``` -3. Install `jinja` (required for building) - - ```sh - pip install jinja - ``` -4. Now, you can use CMake as usual. +4. Now, you can use pip to install the library: ```bash - cmake -S . -B build && cmake --build build + python -m pip install --upgrade pip setuptools wheel + python -m pip install -e Python/ -v # install the library for development + python -m pip wheel ./Python -w dist -v # build a wheel file ``` > [!TIP] diff --git a/TensorFrost/CMakeLists.txt b/TensorFrost/CMakeLists.txt index 50a51762..db1ea482 100644 --- a/TensorFrost/CMakeLists.txt +++ b/TensorFrost/CMakeLists.txt @@ -3,6 +3,14 @@ file(GLOB_RECURSE TENSORFROST_HEADER_LIST CONFIGURE_DEPENDS *.h *.hpp) pybind11_add_module(TensorFrost ${TENSORFROST_SOURCE_LIST} ${TENSORFROST_HEADER_LIST}) +if(APPLE) + set(CMAKE_MACOSX_RPATH ON) + set_target_properties(TensorFrost PROPERTIES + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH "@loader_path/." + ) +endif() + # Add GLFW target_link_libraries(TensorFrost PRIVATE glfw) @@ -29,12 +37,6 @@ target_sources(TensorFrost PRIVATE ${IMGUI_SOURCE_LIST} ${IMGUI_BACKEND_SOURCE_L #add renderdoc headers target_include_directories(TensorFrost PRIVATE ${CMAKE_SOURCE_DIR}/external/renderdoc) -add_custom_command( - TARGET TensorFrost - POST_BUILD - COMMAND ${Python3_EXECUTABLE} -m pip install -e Python/ - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -) add_custom_target(install_python_package ALL DEPENDS TensorFrost diff --git a/TensorFrost/Compiler/KernelGen.cpp b/TensorFrost/Compiler/KernelGen.cpp index 6d23e7f0..4c0cd3e1 100644 --- a/TensorFrost/Compiler/KernelGen.cpp +++ b/TensorFrost/Compiler/KernelGen.cpp @@ -4,7 +4,7 @@ namespace TensorFrost { Program* GenerateProgram(IR* ir) { - ir->CompileIR(); + ir->CompileIR(); auto* program = new Program(ir); diff --git a/TensorFrost/Frontend/Python/Definitions/PyTensor.cpp b/TensorFrost/Frontend/Python/Definitions/PyTensor.cpp index bb779c4c..750b8c02 100644 --- a/TensorFrost/Frontend/Python/Definitions/PyTensor.cpp +++ b/TensorFrost/Frontend/Python/Definitions/PyTensor.cpp @@ -88,6 +88,15 @@ void PyTensorDefinition(py::module& /*m*/, py::class_& py_tensor) { } return indices; }); + py_tensor.def_property_readonly("op_name", [](const PyTensor& t) { + return T(t).node_->name; + }); + py_tensor.def("try_get_constant", [](const PyTensor& t) { + if(T(t).node_->name != "const") { + throw std::runtime_error("Can not get constant from non-constant tensor"); + } + return T(t).TryGetConstant(); + }); py_tensor.def("index",[](const PyTensor& t, int dim) { int dims = T(t).GetDimension(); return PT(T(t).Index(dims - dim - 1)); diff --git a/build.sh b/build.sh deleted file mode 100644 index 7f7e615d..00000000 --- a/build.sh +++ /dev/null @@ -1,3 +0,0 @@ -sudo apt-get install xorg-dev -pip install jinja2 -cmake -S . -B build && cmake --build build \ No newline at end of file diff --git a/build_all.sh b/build_all.sh deleted file mode 100644 index c3b11446..00000000 --- a/build_all.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash - -export PATH="$HOME/.pyenv/bin:$PATH" -eval "$(pyenv init --path)" -eval "$(pyenv init -)" - -# Define the list of Python versions -PYTHON_VERSIONS="3.7 3.8 3.9 3.10 3.11 3.12" - -# Function to check if a specific Python version is installed -check_python_version() { - if ! pyenv versions | grep -q "$1"; then - echo "Python $1 not found, attempting to install..." - pyenv install "$1" - fi -} - -clean_rebuild() { - # Set the Python version for pyenv - pyenv local "$1" - - # Reload the shell environment - eval "$(pyenv init -)" - - # Refresh the shell environment to ensure pyenv shims are used - export PATH="$(pyenv root)/shims:$PATH" - - # Get the path of the current Python interpreter - PYTHON_PATH=$(pyenv which python) - - # Rest of your build commands - git clean -d -x -f -e Python/dist - cmake -DPYBIND11_PYTHON_VERSION="$1" -DPYTHON_EXECUTABLE="$PYTHON_PATH" -S . -B build -DCMAKE_BUILD_TYPE=Release - cmake --build build - "$PYTHON_PATH" -m pip install build - "$PYTHON_PATH" -m build -w ./Python -} - -# Main loop -for VERSION in $PYTHON_VERSIONS; do - echo "Building for Python $VERSION" - check_python_version "$VERSION" - clean_rebuild "$VERSION" -done diff --git a/build_all_python_versions.cmd b/build_all_python_versions.cmd deleted file mode 100644 index d008ca7c..00000000 --- a/build_all_python_versions.cmd +++ /dev/null @@ -1,12 +0,0 @@ -@echo off -setlocal - -REM Define the list of Python versions -set PYTHON_VERSIONS=3.7 3.8 3.9 3.10 3.11 3.12 - -for %%v in (%PYTHON_VERSIONS%) do ( - echo Building for Python %%v - call clean_rebuild %%v -) - -endlocal \ No newline at end of file diff --git a/build_manylinux.sh b/build_manylinux.sh index a298a37f..17f396ad 100644 --- a/build_manylinux.sh +++ b/build_manylinux.sh @@ -20,27 +20,8 @@ export PYTHON_ROOT=/opt/python/$PYTHON_VERSION export PATH=$PYTHON_ROOT/bin:$PATH export PYTHON_EXECUTABLE=$PYTHON_ROOT/bin/python -$PYTHON_EXECUTABLE -m pip install --upgrade pip -r requirements.txt cmake build auditwheel +$PYTHON_EXECUTABLE -m pip wheel ./Python -w Python/dist --verbose -# Extract Python version (e.g., 3.7, 3.8, etc.) -PY_VERSION=$($PYTHON_EXECUTABLE -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') - -echo "Python version: $PY_VERSION" -echo "Python executable: $PYTHON_EXECUTABLE" - -$PYTHON_EXECUTABLE -m cmake \ - -DPython3_ROOT_DIR=$PYTHON_ROOT \ - -DPython3_EXECUTABLE=$PYTHON_EXECUTABLE \ - -DPython_FIND_STRATEGY=LOCATION \ - -DPython_FIND_REGISTRY=NEVER \ - -DPython_FIND_FRAMEWORK=NEVER \ - -DPYBIND11_PYTHON_VERSION=$PY_VERSION \ - -DCMAKE_C_FLAGS="-D_POSIX_C_SOURCE=200809L -Wno-deprecated-declarations" \ - -DCMAKE_CXX_FLAGS="-D_POSIX_C_SOURCE=200809L -Wno-deprecated-declarations" \ - -S . -B build -DCMAKE_BUILD_TYPE=Release - -$PYTHON_EXECUTABLE -m cmake --build build --config Release -$PYTHON_EXECUTABLE -m build -w ./Python -for whl in Python/dist/*.whl; do +for whl in Python/dist/tensorfrost-*.whl; do auditwheel repair "$whl" -w ./wheelhouse/ done \ No newline at end of file diff --git a/build_windows.ps1 b/build_windows.ps1 index 141047ec..28efec29 100644 --- a/build_windows.ps1 +++ b/build_windows.ps1 @@ -1,25 +1,2 @@ -# Install dependencies python -m pip install --upgrade pip -pip install -r requirements.txt -pip install build twine - -# Configure CMake -$env:PYTHON_EXECUTABLE = (Get-Command python).Path -$env:PYTHON_VERSION = (python -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") -echo "Python version: $env:PYTHON_VERSION" -echo "Python executable: $env:PYTHON_EXECUTABLE" - -cmake -DPYBIND11_PYTHON_VERSION="$env:PYTHON_VERSION" ` - -DPython3_ROOT_DIR="$env:PYTHONLOCATION" ` - -DPython3_EXECUTABLE="$env:PYTHON_EXECUTABLE" ` - -DPython_FIND_STRATEGY=LOCATION ` - -DPython_FIND_REGISTRY=NEVER ` - -DPython_FIND_FRAMEWORK=NEVER ` - -S . -B build -DCMAKE_BUILD_TYPE=Release - -# Build the project with parallel jobs -$env:NUMBER_OF_PROCESSORS = (Get-WmiObject -Class Win32_ComputerSystem).NumberOfLogicalProcessors -cmake --build build --config Release --parallel $env:NUMBER_OF_PROCESSORS - -# Build the wheel -python -m build -w ./Python \ No newline at end of file +python -m pip wheel ./Python -w Python/dist --verbose diff --git a/clean_rebuild.cmd b/clean_rebuild.cmd index 56e837f0..b1ac24c3 100644 --- a/clean_rebuild.cmd +++ b/clean_rebuild.cmd @@ -3,8 +3,4 @@ set PYTHON_VERSION=%1 if "%PYTHON_VERSION%"=="" set PYTHON_VERSION=3.12 git clean -d -x -f -e Python/dist -py -%PYTHON_VERSION% -m pip install jinja2 -cmake -DPYBIND11_PYTHON_VERSION=%PYTHON_VERSION% -S . -B build -DCMAKE_BUILD_TYPE=Release -cmake --build build --config Release -py -%PYTHON_VERSION% -m pip install build -py -%PYTHON_VERSION% -m build -w ./Python \ No newline at end of file +py -%PYTHON_VERSION% -m pip install -e Python/ -v \ No newline at end of file diff --git a/examples/Algorithms/fft_group.ipynb b/examples/Algorithms/fft_group.ipynb index d8aac54b..61472ada 100644 --- a/examples/Algorithms/fft_group.ipynb +++ b/examples/Algorithms/fft_group.ipynb @@ -16,10 +16,10 @@ " Host readbacks: 0\n", " Host writes: 0\n", " Lines of generated code: 542\n", - " IR Compile time: 11.146700 ms\n", - " Codegen time: 1.679300 ms\n", - " Host Compile time: 1387.222168 ms\n", - " Shader Compile time: 44.394798 ms\n", + " IR Compile time: 11.621900 ms\n", + " Codegen time: 1.764100 ms\n", + " Host Compile time: 1346.780518 ms\n", + " Shader Compile time: 0.715000 ms\n", "\n" ] } @@ -64,7 +64,6 @@ " temp[2*k2] = v1[0] - v2[0]\n", " temp[2*k2 + 1] = v1[1] - v2[1]\n", "\n", - " #2d local + group tiled version\n", " with tf.kernel([N], group_size=[BK]) as group_index:\n", " temp = tf.group_buffer(N*2, tf.float32)\n", " tx = group_index.block_thread_index(0)\n", diff --git a/examples/Rendering/fft3d.py b/examples/Rendering/fft3d.py new file mode 100644 index 00000000..e69de29b diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index fe8e6064..00000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -jinja2==3.1.4 \ No newline at end of file