前言
pybind11 — Seamless operability between C++11 and Python
pybind11 官方文档: https://pybind11.readthedocs.io/en/latest/ .
操作系统:Ubuntu 20.04.4 LTS
参考文档
pybind11 官方文档
安装
传递 numpy 数组
arr.cpp
文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #include <iostream> #include <thread> #include <vector> #include <pybind11/pybind11.h> #include <pybind11/numpy.h> namespace py = pybind11;void update (unsigned long id, py::array_t <int64_t > x) { auto r = x.mutable_unchecked <1 >(); for (int i = 1 ; i < r.shape (0 ); i++) { if (i % id == 0 ) { r (i) = id; } } } void launch (py::array_t <int64_t > x) { unsigned long const hardware_threads = std::thread::hardware_concurrency (); std::cout << "cpus: " << hardware_threads << std::endl; std::vector<std::thread> threads; for (unsigned long i = 0 ; i < hardware_threads; i++) { threads.emplace_back (update, i+1 , x); } for (auto & entry: threads) entry.join (); } int bernFlag = 0 ;void setBern (int con) { bernFlag = con; std::cout << "Bern: " << bernFlag << std::endl; } std::string inPath = "../data/FB15K/" ; void setInPath (std::string path) { inPath = std::move (path); std::cout << "Input Files Path : " << inPath << std::endl; } PYBIND11_MODULE (arr, m) { m.def ("assign" , [](py::array_t <int64_t > x) { auto r = x.mutable_unchecked <1 >(); for (py::ssize_t i = 0 ; i < r.shape (0 ); i++) r (i) = i; }, py::arg ().noconvert ()); m.def ("assign" , [](py::array_t <float > x) { auto r = x.mutable_unchecked <1 >(); for (py::ssize_t i = 0 ; i < r.shape (0 ); i++) r (i) = i; }, py::arg ().noconvert ()); m.def ("launch" , &launch, py::arg ().noconvert (), py::call_guard <py::gil_scoped_release>()); m.def ("setBern" , &setBern); m.def ("setInPath" , &setInPath); }
test_arr.py
文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import numpy as npimport arr as mdef test_from_python (): int64_arr = np.zeros(3 , dtype=np.int64) float32_arr = np.zeros(3 , dtype=np.float32) print (int64_arr) print (float32_arr) m.assign(int64_arr) m.assign(float32_arr) print (int64_arr) print (float32_arr) large = np.zeros(10 **8 , dtype=np.int64) print (large.size) print (large) m.launch(large) print (large) path = "/home/luyanfeng/my_code/temp" m.setInPath(path) m.setBern(100 ) test_from_python()
编译脚本 compile.sh
:
1 c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) arr.cpp -o arr$(python3-config --extension-suffix)
结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 (test) luyanfeng@amax:~/my_code/temp$ ls arr.cpp compile.sh test_arr.py (test) luyanfeng@amax:~/my_code/temp$ bash compile.sh /usr/bin/ld: warning: /usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so: unsupported GNU_PROPERTY_TYPE (5) type: 0xc0010001 /usr/bin/ld: warning: /usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so: unsupported GNU_PROPERTY_TYPE (5) type: 0xc0010002 (test) luyanfeng@amax:~/my_code/temp$ python test_arr.py [0 0 0] [0. 0. 0.] [0 1 2] [0. 1. 2.] 100000000 [0 0 0 ... 0 0 0] cpus: 32 [ 0 1 1 ... 1 23 11] Input Files Path : /home/luyanfeng/my_code/temp Bern: 100 (test) luyanfeng@amax:~/my_code/temp$
打包项目
Setuptools Quickstart: https://setuptools.pypa.io/en/latest/userguide/quickstart.html .
pybind11 官方例子: https://github.com/pybind/python_example .
复杂项目例子: https://github.com/LuYF-Lemon-love/pybind11-OpenKE/blob/pybind11-OpenKE-PyTorch/setup.py .
结语
第七十篇博文写完,开心!!!!
今天,也是充满希望的一天。