Example repository for custom C++/CUDA operators for TorchScript

Overview

Custom TorchScript Operators Example

This repository contains examples for writing, compiling and using custom TorchScript operators. See here for the accompanying tutorial.

Contents

There a few monuments in this repository you can visit. They are described in context in the tutorial, which you are encouraged to read. These monuments are:

  • example_app/warp_perspective/op.cpp: The custom operator implementation,
  • example_app/main.cpp: An example application that loads and executes a serialized TorchScript model, which uses the custom operator, in C++,
  • script.py: Example of using the custom operator in a scripted model,
  • trace.py: Example of using the custom operator in a traced model,
  • eager.py: Example of using the custom operator in vanilla eager PyTorch,
  • load.py: Example of using torch.utils.cpp_extension.load to build the custom operator,
  • load.py: Example of using torch.utils.cpp_extension.load_inline to build the custom operator,
  • setup.py: Example of using setuptools to build the custom operator,
  • test_setup.py: Example of using the custom operator built using setup.py.

To execute the C++ application, first run script.py to serialize a TorchScript model to a file called example.pt, then pass that file to the example_app/build/example_app binary.

Setup

For the smoothest experience when trying out these examples, we recommend building a docker container from this repository's Dockerfile. This will give you a clean, isolated Ubuntu Linux environment in which we guarantee everything to work perfectly. These steps should get you started:

$ git clone https://github.com/pytorch/extension-script

$ cd extension-script

$ docker build -t extension-script .

$ docker run -v $PWD:/home -it extension-script

$ root@2f00feefe46a:/home# source /activate # Activate the Conda environment

$ cd example_app && mkdir build && cd build

$ cmake -DCMAKE_PREFIX_PATH=/libtorch ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found torch: /libtorch/lib/libtorch.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/example_app/build

$ make -j
Scanning dependencies of target warp_perspective
[ 25%] Building CXX object warp_perspective/CMakeFiles/warp_perspective.dir/op.cpp.o
[ 50%] Linking CXX shared library libwarp_perspective.so
[ 50%] Built target warp_perspective
Scanning dependencies of target example_app
[ 75%] Building CXX object CMakeFiles/example_app.dir/main.cpp.o
[100%] Linking CXX executable example_app
[100%] Built target example_app

This will create a shared library under /home/example_app/build/warp_perspective/libwarp_perspective.so containing the custom operator defined in example_app/warp_perspective/op.cpp. Then, you can run the examples, e.g.:

(base) root@2f00feefe46a:/home# python script.py
graph(%x.1 : Dynamic
      %y : Dynamic) {
  %20 : int = prim::Constant[value=1]()
  %16 : int[] = prim::Constant[value=[0, -1]]()
  %14 : int = prim::Constant[value=6]()
  %2 : int = prim::Constant[value=0]()
  %7 : int = prim::Constant[value=42]()
  %z.1 : int = prim::Constant[value=5]()
  %z.2 : int = prim::Constant[value=10]()
  %13 : int = prim::Constant[value=3]()
  %4 : Dynamic = aten::select(%x.1, %2, %2)
  %6 : Dynamic = aten::select(%4, %2, %2)
  %8 : Dynamic = aten::eq(%6, %7)
  %9 : bool = prim::TensorToBool(%8)
  %z : int = prim::If(%9)
    block0() {
      -> (%z.1)
    }
    block1() {
      -> (%z.2)
    }
  %17 : Dynamic = aten::eye(%13, %14, %2, %16)
  %x : Dynamic = my_ops::warp_perspective(%x.1, %17)
  %19 : Dynamic = aten::matmul(%x, %y)
  %21 : Dynamic = aten::add(%19, %z, %20)
  return (%21);
}

tensor([[11.6196, 12.0056, 11.6122, 12.9298,  7.0649],
        [ 8.5063,  9.0621,  9.9925,  6.3741,  8.9668],
        [12.5898,  6.5872,  8.1511, 10.0806, 11.9829],
        [ 4.9142, 11.6614, 15.7161, 17.0538, 11.7243],
        [10.0000, 10.0000, 10.0000, 10.0000, 10.0000],
        [10.0000, 10.0000, 10.0000, 10.0000, 10.0000],
        [10.0000, 10.0000, 10.0000, 10.0000, 10.0000],
        [10.0000, 10.0000, 10.0000, 10.0000, 10.0000]])
Comments
  • Dockerfile to work with new packages

    Dockerfile to work with new packages

    The current Dockerfile is broken because pytorch changed the names of package pytorch-nightly-cpu; see here: https://github.com/pytorch/pytorch/issues/23778

    cla signed 
    opened by clark-hive 3
  • OSError while loading library.

    OSError while loading library.

    I changed some code as bellow:

    1. You need C++14 to compile PyTorch

    If you got errors like C++ 14 is required, you can add set(CMAKE_CXX_STANDARD 14) to example/CMakeLists.txt, like this:

    cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
    project(example_app)
    set(CMAKE_CXX_STANDARD 14)
    SET(Torch_DIR /libtorch/share/cmake/Torch)
    find_package(Torch REQUIRED)
    add_subdirectory(warp_perspective)
    add_executable(example_app main.cpp)
    target_link_libraries(example_app "${TORCH_LIBRARIES}")
    target_link_libraries(example_app -Wl,--no-as-needed warp_perspective)
    target_compile_features(example_app PRIVATE cxx_range_for)
    

    2. no matching function for call to 'torch::jit::RegisterOperators::RegisterOperators

    Use torch::RegisterOperators() instead of torch::jit::RegisterOperator(), it will be ok.

    3. Docker download fail

    If the downloading speed of PyTorch is too slow , you can change line 18 in your Dockerfile as follows:

    RUN . /activate && conda install pytorch torchvision cpuonly -c pytorch

    But when I ran python script.py, I got the same error as #4

    What is the version of pytorch and libtorch used in this project ?

    opened by Arctanxy 3
  • setuptools extension

    setuptools extension

    When building C extensions with Cython, it also creates an .so file, but I don't have to load that manually. Is this planned for TorchScript?

    For context, I am exploring to convert all Cython from OpenPifPaf to TorchScript in this branch: https://github.com/vita-epfl/openpifpaf/tree/torchscript-extension So I am not using the TorchScript modules in a script but in a Python module. This is not one of the use cases in this repo either, right?

    opened by svenkreiss 1
  • You need C++14 to compile PyTorch.

    You need C++14 to compile PyTorch.

    I changed the version of PyTorch because my network speed is poor. My Dockerfile is as follows:

    FROM ubuntu:xenial
    
    RUN apt-get update  -y \
      && apt-get install -y git cmake vim make wget gnupg build-essential software-properties-common gdb zip
    
    # Install OpenCV
    RUN apt-get install -y libopencv-dev
    
    # Install Miniconda
    RUN wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh \
      && chmod +x miniconda.sh \
      && ./miniconda.sh -b -p ~/local/miniconda \
      && rm ./miniconda.sh
    
    # Symlink the Miniconda activation script to /activate
    RUN ln -s ~/local/miniconda/bin/activate /activate
    # Install PyTorch
    RUN . /activate && conda install pytorch torchvision cpuonly -c pytorch
    
    # Download LibTorch
    RUN wget https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip
    RUN unzip libtorch-shared-with-deps-latest.zip && rm libtorch-shared-with-deps-latest.zip
    
    WORKDIR /home
    
    

    I changed this line: RUN . /activate && conda install pytorch torchvision cpuonly -c pytorch

    When I run : make -j, I got following error:

    (base) root@4c6b54e7fed4:/home/example_app/build# make -j
    Scanning dependencies of target warp_perspective
    [ 25%] Building CXX object warp_perspective/CMakeFiles/warp_perspective.dir/op.cpp.o
    In file included from /libtorch/include/c10/util/ArrayRef.h:19:0,
                     from /libtorch/include/c10/core/MemoryFormat.h:5,
                     from /libtorch/include/ATen/core/TensorBody.h:5,
                     from /libtorch/include/ATen/Tensor.h:11,
                     from /libtorch/include/ATen/Context.h:4,
                     from /libtorch/include/ATen/ATen.h:5,
                     from /libtorch/include/torch/csrc/api/include/torch/types.h:3,
                     from /libtorch/include/torch/script.h:3,
                     from /home/example_app/warp_perspective/op.cpp:2:
    /libtorch/include/c10/util/C++17.h:20:2: error: #error You need C++14 to compile PyTorch
     #error You need C++14 to compile PyTorch
      ^
    /home/example_app/warp_perspective/op.cpp: In function 'at::Tensor warp_perspective(at::Tensor, at::Tensor)':
    /home/example_app/warp_perspective/op.cpp:54:48: warning: 'T* at::Tensor::data() const [with T = float]' is deprecated [-Wdeprecated-declarations]
                         /*data=*/image.data<float>());
                                                    ^
    In file included from /libtorch/include/ATen/Tensor.h:11:0,
                     from /libtorch/include/ATen/Context.h:4,
                     from /libtorch/include/ATen/ATen.h:5,
                     from /libtorch/include/torch/csrc/api/include/torch/types.h:3,
                     from /libtorch/include/torch/script.h:3,
                     from /home/example_app/warp_perspective/op.cpp:2:
    /libtorch/include/ATen/core/TensorBody.h:322:7: note: declared here
       T * data() const {
           ^
    /home/example_app/warp_perspective/op.cpp:58:46: warning: 'T* at::Tensor::data() const [with T = float]' is deprecated [-Wdeprecated-declarations]
                        /*data=*/warp.data<float>());
                                                  ^
    In file included from /libtorch/include/ATen/Tensor.h:11:0,
                     from /libtorch/include/ATen/Context.h:4,
                     from /libtorch/include/ATen/ATen.h:5,
                     from /libtorch/include/torch/csrc/api/include/torch/types.h:3,
                     from /libtorch/include/torch/script.h:3,
                     from /home/example_app/warp_perspective/op.cpp:2:
    /libtorch/include/ATen/core/TensorBody.h:322:7: note: declared here
       T * data() const {
           ^
    /home/example_app/warp_perspective/op.cpp: At global scope:
    /home/example_app/warp_perspective/op.cpp:69:78: error: no matching function for call to 'torch::jit::RegisterOperators::RegisterOperators(const char [25], at::Tensor (*)(at::Tensor, at::Tensor))'
       torch::jit::RegisterOperators("my_ops::warp_perspective", &warp_perspective);
                                                                                  ^
    In file included from /libtorch/include/torch/script.h:6:0,
                     from /home/example_app/warp_perspective/op.cpp:2:
    /libtorch/include/torch/csrc/jit/custom_operator.h:20:3: note: candidate: torch::jit::RegisterOperators::RegisterOperators(std::vector<torch::jit::Operator>)
       RegisterOperators(std::vector<Operator> operators) {
       ^
    /libtorch/include/torch/csrc/jit/custom_operator.h:20:3: note:   candidate expects 1 argument, 2 provided
    /libtorch/include/torch/csrc/jit/custom_operator.h:17:3: note: candidate: constexpr torch::jit::RegisterOperators::RegisterOperators()
       RegisterOperators() = default;
       ^
    /libtorch/include/torch/csrc/jit/custom_operator.h:17:3: note:   candidate expects 0 arguments, 2 provided
    /libtorch/include/torch/csrc/jit/custom_operator.h:16:18: note: candidate: constexpr torch::jit::RegisterOperators::RegisterOperators(const torch::jit::RegisterOperators&)
     struct TORCH_API RegisterOperators {
                      ^
    /libtorch/include/torch/csrc/jit/custom_operator.h:16:18: note:   candidate expects 1 argument, 2 provided
    /libtorch/include/torch/csrc/jit/custom_operator.h:16:18: note: candidate: constexpr torch::jit::RegisterOperators::RegisterOperators(torch::jit::RegisterOperators&&)
    /libtorch/include/torch/csrc/jit/custom_operator.h:16:18: note:   candidate expects 1 argument, 2 provided
    warp_perspective/CMakeFiles/warp_perspective.dir/build.make:62: recipe for target 'warp_perspective/CMakeFiles/warp_perspective.dir/op.cpp.o' failed
    make[2]: *** [warp_perspective/CMakeFiles/warp_perspective.dir/op.cpp.o] Error 1
    CMakeFiles/Makefile2:122: recipe for target 'warp_perspective/CMakeFiles/warp_perspective.dir/all' failed
    make[1]: *** [warp_perspective/CMakeFiles/warp_perspective.dir/all] Error 2
    Makefile:83: recipe for target 'all' failed
    make: *** [all] Error 2
    

    How can I fix this problem? Looking forward to your replay.

    opened by Arctanxy 0
  • Adding Code of Conduct file

    Adding Code of Conduct file

    This is pull request was created automatically because we noticed your project was missing a Code of Conduct file.

    Code of Conduct files facilitate respectful and constructive communities by establishing expected behaviors for project contributors.

    This PR was crafted with love by Facebook's Open Source Team.

    cla signed 
    opened by facebook-github-bot 0
  • Adding Contributing file

    Adding Contributing file

    This is pull request was created automatically because we noticed your project was missing a Contributing file.

    CONTRIBUTING files explain how a developer can contribute to the project - which you should actively encourage.

    This PR was crafted with love by Facebook's Open Source Team.

    cla signed 
    opened by facebook-github-bot 0
  • Error when build with docker, please specify the dependencies version

    Error when build with docker, please specify the dependencies version

    I tried the following: ### 1. Build on Host gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609 first I got #error You need C++14 to compile PyTorch So I set c++ 14 in CMakeLists.txt and it worked. set(CMAKE_CXX_STANDARD 14) But got error while running the script.py. With pytorch=1.3.1:

    Traceback (most recent call last):
      File "test.py", line 4, in <module>
        print(torch.ops.my_ops.warp_perspective)
      File "/home/miniconda3/lib/python3.7/site-packages/torch/_ops.py", line 61, in __getattr__
        op = torch._C._jit_get_operation(qualified_op_name)
    RuntimeError: No such operator my_ops::warp_perspective
    

    with pytorch=1.2.0:

    Traceback (most recent call last):
      File "test.py", line 3, in <module>
        torch.ops.load_library("/home/LiRuMei/cpp_pytorch/build/libwarp_perspective.so")
      File "/home/anaconda3/envs/torch/lib/python3.7/site-packages/torch/_ops.py", line 106, in load_library
        ctypes.CDLL(path)
      File "/home/anaconda3/envs/torch/lib/python3.7/ctypes/__init__.py", line 356, in __init__
        self._handle = _dlopen(self._name, mode)
    OSError: /home/cpp_pytorch/build/libwarp_perspective.so: undefined symbol: _ZN5torch3jit17parseSchemaOrNameERKSs
    

    ### 2. Build with Docker In docker the version is pytorch-nightly-cpu=1.2.0. I also had an error about

    static auto registry =
      torch::jit::RegisterOperators("my_ops::warp_perspective", &warp_perspective);
    

    I modified it as in the tutorial:

    static auto registry =
      torch::RegisterOperators("my_ops::warp_perspective", &warp_perspective);
    

    Then I successfully built the .so, but still got:

    Traceback (most recent call last):
      File "script.py", line 3, in <module>
        torch.ops.load_library("example_app/build/warp_perspective/libwarp_perspective.so")
      File "/root/local/miniconda/lib/python3.7/site-packages/torch/_ops.py", line 106, in load_library
        ctypes.CDLL(path)
      File "/root/local/miniconda/lib/python3.7/ctypes/__init__.py", line 364, in __init__
        self._handle = _dlopen(self._name, mode)
    OSError: /libtorch/lib/libtorch_cpu.so: undefined symbol: _ZN6caffe28TypeMeta21_typeMetaDataInstanceIcEEPKNS_6detail12TypeMetaDataEv
    

    I think the problem is about the version of pytorch & libtorch, as the Dockerfile you committed a year ago always installed the latest version. So please try again if the Docker still works or indicate the version you used, thanks a lot.

    opened by leerumor 2
  • Under Ubuntu18.04。When I compile the number, there is an error calling the libwarp_perspective.so file。

    Under Ubuntu18.04。When I compile the number, there is an error calling the libwarp_perspective.so file。

    OSError: /home/huang/vsopencv/extension-script/example_app/build/warp_perspective/libwarp_perspective.so: undefined symbol: _ZN3c1017RegisterOperators25checkSchemaAndRegisterOp_ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEONS0_7OptionsE

    opened by huang229 4
  • Do you have an example under windows?

    Do you have an example under windows?

    The custom layer uses JIT mechanism to invoke on the c++ side, which seems to require registration in scripts, such as: .# include <torch/script.h> Torch:: Tensor warp_perspective (torch:: Tensor image, torch:: Tensor warp){ Torch:: Tensor output = torch:: add (image, warp); Return output. clone (); } Static auto registry= Torch:: jit:: Register Operators ("my_ops:: warp_perspective", & warp_perspective);

    This is the application under Ubuntu. Do you have an example under windows?I don't know how to run the example provided in extension-script under Windows.

    opened by huang229 17
Owner
null
Example-custom-ml-block-keras - Custom Keras ML block example for Edge Impulse

Custom Keras ML block example for Edge Impulse This repository is an example on

Edge Impulse 8 Nov 2, 2022
Extending JAX with custom C++ and CUDA code

Extending JAX with custom C++ and CUDA code This repository is meant as a tutorial demonstrating the infrastructure required to provide custom ops in

Dan Foreman-Mackey 237 Dec 23, 2022
Learning nonlinear operators via DeepONet

DeepONet: Learning nonlinear operators The source code for the paper Learning nonlinear operators via DeepONet based on the universal approximation th

Lu Lu 239 Jan 2, 2023
Jittor is a high-performance deep learning framework based on JIT compiling and meta-operators.

Jittor: a Just-in-time(JIT) deep learning framework Quickstart | Install | Tutorial | Chinese Jittor is a high-performance deep learning framework bas

null 2.7k Jan 3, 2023
Sparse-dense operators implementation for Paddle

Sparse-dense operators implementation for Paddle This module implements coo, csc and csr matrix formats and their inter-ops with dense matrices. Feel

北海若 3 Dec 17, 2022
Neon-erc20-example - Example of creating SPL token and wrapping it with ERC20 interface in Neon EVM

Example of wrapping SPL token by ERC2-20 interface in Neon Requirements Install

null 7 Mar 28, 2022
Python-kafka-reset-consumergroup-offset-example - Python Kafka reset consumergroup offset example

Python Kafka reset consumergroup offset example This is a simple example of how

Willi Carlsen 1 Feb 16, 2022
Picasso: A CUDA-based Library for Deep Learning over 3D Meshes

The Picasso Library is intended for complex real-world applications with large-scale surfaces, while it also performs impressively on the small-scale applications over synthetic shape manifolds. We have upgraded the point cloud modules of SPH3D-GCN from homogeneous to heterogeneous representations, and included the upgraded modules into this latest work as well. We are happy to announce that the work is accepted to IEEE CVPR2021.

null 97 Dec 1, 2022
This Repo is the official CUDA implementation of ICCV 2019 Oral paper for CARAFE: Content-Aware ReAssembly of FEatures

Introduction This Repo is the official CUDA implementation of ICCV 2019 Oral paper for CARAFE: Content-Aware ReAssembly of FEatures. @inproceedings{Wa

Jiaqi Wang 42 Jan 7, 2023
PyTorch implementation of Soft-DTW: a Differentiable Loss Function for Time-Series in CUDA

Soft DTW Loss Function for PyTorch in CUDA This is a Pytorch Implementation of Soft-DTW: a Differentiable Loss Function for Time-Series which is batch

Keon Lee 76 Dec 20, 2022
Convert Python 3 code to CUDA code.

Py2CUDA Convert python code to CUDA. Usage To convert a python file say named py_file.py to CUDA, run python generate_cuda.py --file py_file.py --arch

Yuval Rosen 3 Jul 14, 2021
This demo showcase the use of onnxruntime-rs with a GPU on CUDA 11 to run Bert in a data pipeline with Rust.

Demo BERT ONNX pipeline written in rust This demo showcase the use of onnxruntime-rs with a GPU on CUDA 11 to run Bert in a data pipeline with Rust. R

Xavier Tao 14 Dec 17, 2022
Bytedance Inc. 2.5k Jan 6, 2023
CUDA Python Low-level Bindings

CUDA Python Low-level Bindings

NVIDIA Corporation 529 Jan 3, 2023
Time-stretch audio clips quickly with PyTorch (CUDA supported)! Additional utilities for searching efficient transformations are included.

Time-stretch audio clips quickly with PyTorch (CUDA supported)! Additional utilities for searching efficient transformations are included.

Kento Nishi 22 Jul 7, 2022
A dead simple python wrapper for darknet that works with OpenCV 4.1, CUDA 10.1

What Dead simple python wrapper for Yolo V3 using AlexyAB's darknet fork. Works with CUDA 10.1 and OpenCV 4.1 or later (I use OpenCV master as of Jun

Pliable Pixels 6 Jan 12, 2022
Prevent `CUDA error: out of memory` in just 1 line of code.

?? Koila Koila solves CUDA error: out of memory error painlessly. Fix it with just one line of code, and forget it. ?? Features ?? Prevents CUDA error

RenChu Wang 1.7k Jan 2, 2023
An addernet CUDA version

Training addernet accelerated by CUDA Usage cd adder_cuda python setup.py install cd .. python main.py Environment pytorch 1.10.0 CUDA 11.3 benchmark

LingXY 4 Jun 20, 2022
Neural network for digit classification powered by cuda

cuda_nn_mnist Neural network library for digit classification powered by cuda Resources The library was built to work with MNIST dataset. python-mnist

Nikita Ardashev 1 Dec 20, 2021