10 |
11 |
12 | ## Requirements
13 | - cuda 10.2
14 | - cudnn 8.0
15 | - TensorRT 7.1
16 | - python 3.6
17 | - pytorch = 1.6.0
18 |
19 |
20 | # AdderNetTensorRT
21 | This project implements the Adder Layer mentioned in https://arxiv.org/pdf/1912.13200.pdf using TensorRT custom layer Plugin API.
22 | Original pytorch implementation of the AdderNet is found in https://github.com/huawei-noah/AdderNet/. That is not CUDA or TensoRT capable.
23 |
24 | Execute the following scripts for latency and accuracy calculation.
25 | ```bash
26 | python addernet_mnist.py --> for pytorch results
27 | python addernet_mnist_trt.py --> for tensorrt results
28 | ```
29 |
30 | Execute the following scripts for unit test the adder layer.
31 | Output feature values should be the same from both scripts.
32 | ```bash
33 | cd test
34 | python test_adder_layer.py --> for pytorch results
35 | python test_adder_layer_trt.py --> for tensorrt results
36 | ```
37 |
38 | Any other neural network architectures containing Adder Layers can be implemented in TensorRT using this Adder Layer Plugin.
39 |
40 | addenet_mnist_v1.py is implemented without BatchNormalization layers. If you train this model you'll see the model is not training well.
41 | addenet_mnist_v2.py is also implemented without BatchNormalization layers but tanh activation is used instead of relu to get use of the negative values outputs from Adder layers.
42 | Still the model is not training well.
43 |
44 | # System Requirements
45 | - python 3.6, numpy, matplotlib
46 | - gcc 7.5.0
47 | - cuda 10.2
48 | - cudnn 8.0
49 | - TensorRT 7.1
50 | - PyTorch>=1.5
51 |
52 | # Installation
53 | Make sure you have installed the dependency list above.
54 | ```bash
55 | cd AdderNet_TensorRT/plugin
56 | mkdir build
57 | cd build
58 | cmake ..
59 | make
60 | ```
61 | Following files will be created in the build directory.
62 | - libadder2dtrt.so shared library for cpp unit test cases in the build folder.
63 | - adder2dpytrt.so pybind library to be used when import Adder2dPlugin using python modules.
64 | - Two Unit testing executables named 'TestAdder2dPlugin' and 'TestAdderFilterCudaKernel'.
65 |
66 |
--------------------------------------------------------------------------------
/adder.py:
--------------------------------------------------------------------------------
1 | '''
2 | Copyright (C) 2020. Huawei Technologies Co., Ltd. All rights reserved.
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of BSD 3-Clause License.
5 | This program is distributed in the hope that it will be useful,
6 | but WITHOUT ANY WARRANTY; without even the implied warranty of
7 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 | BSD 3-Clause License for more details.
9 | '''
10 | import torch
11 | import torch.nn as nn
12 | import numpy as np
13 | from torch.autograd import Function
14 | import math
15 |
16 |
17 | def adder2d_function(X, W, stride=1, padding=0):
18 | n_filters, d_filter, h_filter, w_filter = W.size()
19 | n_x, d_x, h_x, w_x = X.size()
20 |
21 | h_out = (h_x - h_filter + 2 * padding) // stride + 1
22 | w_out = (w_x - w_filter + 2 * padding) // stride + 1
23 |
24 | h_out, w_out = int(h_out), int(w_out)
25 | X_col = torch.nn.functional.unfold(X.view(1, -1, h_x, w_x), int(h_filter), dilation=1, padding=padding, stride=stride).view(n_x, -1, h_out*w_out)
26 | X_col = X_col.permute(1,2,0).contiguous().view(X_col.size(1),-1)
27 | W_col = W.view(n_filters, -1)
28 |
29 | out = adder.apply(W_col,X_col)
30 |
31 | out = out.view(n_filters, h_out, w_out, n_x)
32 | out = out.permute(3, 0, 1, 2).contiguous()
33 |
34 | return out
35 |
36 |
37 | class adder(Function):
38 | @staticmethod
39 | def forward(ctx, W_col, X_col):
40 | ctx.save_for_backward(W_col,X_col)
41 | output = -(W_col.unsqueeze(2)-X_col.unsqueeze(0)).abs().sum(1)
42 | return output
43 |
44 | @staticmethod
45 | def backward(ctx,grad_output):
46 | W_col,X_col = ctx.saved_tensors
47 | grad_W_col = ((X_col.unsqueeze(0)-W_col.unsqueeze(2))*grad_output.unsqueeze(1)).sum(2)
48 | grad_W_col = grad_W_col/grad_W_col.norm(p=2).clamp(min=1e-12)*math.sqrt(W_col.size(1)*W_col.size(0))/5
49 | grad_X_col = (-(X_col.unsqueeze(0)-W_col.unsqueeze(2)).clamp(-1,1)*grad_output.unsqueeze(1)).sum(0)
50 |
51 | return grad_W_col, grad_X_col
52 |
53 |
54 | class adder2d(nn.Module):
55 |
56 | def __init__(self,input_channel,output_channel,kernel_size, stride=1, padding=0, bias = False):
57 | super(adder2d, self).__init__()
58 | self.stride = stride
59 | self.padding = padding
60 | self.input_channel = input_channel
61 | self.output_channel = output_channel
62 | self.kernel_size = kernel_size
63 | self.adder = torch.nn.Parameter(nn.init.normal_(torch.randn(output_channel,input_channel,kernel_size,kernel_size)))
64 | self.bias = bias
65 | if bias:
66 | self.b = torch.nn.Parameter(nn.init.uniform_(torch.zeros(output_channel)))
67 |
68 | def forward(self, x):
69 | output = adder2d_function(x,self.adder, self.stride, self.padding)
70 | if self.bias:
71 | output += self.b.unsqueeze(0).unsqueeze(2).unsqueeze(3)
72 |
73 | return output
74 |
75 |
--------------------------------------------------------------------------------
/addernet_mnist_onnx.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import onnx
3 |
4 | from addernet_mnist import MnistModel
5 | OPSET = 12
6 |
7 |
8 | model = MnistModel()
9 | model.network.load_state_dict(torch.load('./saved_models/addernet_mnist.pth'))
10 | model.network.to('cuda')
11 |
12 | dummy_input = torch.randn(1, 1, 28, 28, device='cuda')
13 |
14 | # convert pytorch model to onnx format
15 | torch.onnx.export(model.network, dummy_input, "./saved_models/addernet_mnist.onnx", verbose=True, opset_version=OPSET)
16 |
17 | # Load the ONNX model
18 | model = onnx.load("./saved_models/addernet_mnist.onnx")
19 | # Check that the IR is well formed
20 | onnx.checker.check_model(model)
21 | # Print a human readable representation of the graph
22 | onnx.helper.printable_graph(model.graph)
23 |
--------------------------------------------------------------------------------
/addernet_mnist_v1.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn as nn
3 | import torch.nn.functional as F
4 | import torch.optim as optim
5 | from torchvision import datasets, transforms
6 | from torch.autograd import Variable
7 | from torchsummary import summary
8 |
9 | import numpy as np
10 | from random import randint
11 |
12 | import adder
13 |
14 |
15 | # Network
16 | class Net(nn.Module):
17 | def __init__(self):
18 | super(Net, self).__init__()
19 | self.adder1 = adder.adder2d(1, 20, kernel_size=5, stride=1, padding=0, bias=False)
20 | self.adder2 = adder.adder2d(20, 50, kernel_size=5, stride=1, padding=0, bias=False)
21 | self.fc1 = nn.Linear(800, 500)
22 | self.fc2 = nn.Linear(500, 10)
23 |
24 | def forward(self, x):
25 | x = F.max_pool2d(self.adder1(x), kernel_size=2, stride=2)
26 | x = F.max_pool2d(self.adder2(x), kernel_size=2, stride=2)
27 | x = x.view(-1, 800)
28 | x = F.relu(self.fc1(x))
29 | x = self.fc2(x)
30 | return F.log_softmax(x, dim=1)
31 |
32 |
33 | class MnistModel(object):
34 | def __init__(self):
35 | self.batch_size = 64
36 | self.test_batch_size = 100
37 | self.learning_rate = 0.0025
38 | self.sgd_momentum = 0.9
39 | self.log_interval = 100
40 | # Fetch MNIST data set.
41 | self.train_loader = torch.utils.data.DataLoader(
42 | datasets.MNIST('./data/mnist', train=True, download=True, transform=transforms.Compose([
43 | transforms.ToTensor(),
44 | transforms.Normalize((0.1307,), (0.3081,))
45 | ])),
46 | batch_size=self.batch_size,
47 | shuffle=True)
48 | self.test_loader = torch.utils.data.DataLoader(
49 | datasets.MNIST('./data/mnist', train=False, transform=transforms.Compose([
50 | transforms.ToTensor(),
51 | transforms.Normalize((0.1307,), (0.3081,))
52 | ])),
53 | batch_size=self.test_batch_size,
54 | shuffle=True)
55 | self.network = Net().cpu()
56 | print(self.network)
57 | summary(self.network, (1, 28, 28), device='cpu')
58 |
59 | # Train the network for one or more epochs, validating after each epoch.
60 | def learn(self, num_epochs=2):
61 | # Train the network for a single epoch
62 | def train(epoch):
63 | self.network.train()
64 | optimizer = optim.SGD(self.network.parameters(), lr=self.learning_rate, momentum=self.sgd_momentum)
65 | for batch, (data, target) in enumerate(self.train_loader):
66 | data, target = Variable(data), Variable(target)
67 | optimizer.zero_grad()
68 | output = self.network(data)
69 | loss = F.nll_loss(output, target)
70 | loss.backward()
71 | optimizer.step()
72 | if batch % self.log_interval == 0:
73 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch * len(data), len(self.train_loader.dataset), 100. * batch / len(self.train_loader), loss.data.item()))
74 |
75 | # Test the network
76 | def test(epoch):
77 | self.network.eval()
78 | test_loss = 0
79 | correct = 0
80 | for data, target in self.test_loader:
81 | with torch.no_grad():
82 | data, target = Variable(data), Variable(target)
83 | output = self.network(data)
84 | test_loss += F.nll_loss(output, target).data.item()
85 | pred = output.data.max(1)[1]
86 | correct += pred.eq(target.data).cpu().sum()
87 | test_loss /= len(self.test_loader)
88 | print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(self.test_loader.dataset), 100. * correct / len(self.test_loader.dataset)))
89 |
90 | for e in range(num_epochs):
91 | train(e + 1)
92 | test(e + 1)
93 |
94 | def get_weights(self):
95 | return self.network.state_dict()
96 |
97 | def get_random_testcase(self):
98 | data, target = next(iter(self.test_loader))
99 | case_num = randint(0, len(data) - 1)
100 | test_case = data.numpy()[case_num].ravel().astype(np.float32)
101 | test_name = target.numpy()[case_num]
102 | return test_case, test_name
103 |
104 |
105 | def main():
106 | mnist_model = MnistModel()
107 | mnist_model.learn()
108 | torch.save(mnist_model.get_weights(), './saved_models/addernet_mnist_v1.pth')
109 | # weights = mnist_model.get_weights()
110 | # print(weights)
111 |
112 |
113 | if __name__ == '__main__':
114 | main()
--------------------------------------------------------------------------------
/figures/pytorch_latency.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chinthysl/AdderNetTensorRT/b4164cf9c9fd818430b38344c054ddb49c3a967e/figures/pytorch_latency.jpg
--------------------------------------------------------------------------------
/figures/tensorrt_latency.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chinthysl/AdderNetTensorRT/b4164cf9c9fd818430b38344c054ddb49c3a967e/figures/tensorrt_latency.jpg
--------------------------------------------------------------------------------
/plugin/Adder2dPlugin.h:
--------------------------------------------------------------------------------
1 | #ifndef ADDER2D_PLUGIN_H
2 | #define ADDER2D_PLUGIN_H
3 |
4 | #include "NvInfer.h"
5 | #include "NvInferPlugin.h"
6 |
7 | #include
8 |
9 | class Adder2dPlugin : public nvinfer1::IPluginV2
10 | {
11 | public:
12 | Adder2dPlugin(const nvinfer1::Weights *weights, int nbWeights, int nbInputChannels, int inputHeight,
13 | int inputWidth, int filterSize, int nbFilters, int stride, int padding);
14 |
15 | Adder2dPlugin(const void *data, size_t length);
16 |
17 | ~Adder2dPlugin();
18 |
19 | virtual int getNbOutputs() const override;
20 |
21 | virtual nvinfer1::Dims getOutputDimensions(int index, const nvinfer1::Dims* inputs, int nbInputDims) override;
22 |
23 | virtual bool supportsFormat(nvinfer1::DataType type, nvinfer1::PluginFormat format) const override;
24 |
25 | virtual void configureWithFormat(const nvinfer1::Dims* inputDims, int nbInputs, const nvinfer1::Dims* outputDims,
26 | int nbOutputs, nvinfer1::DataType type, nvinfer1::PluginFormat format,
27 | int maxBatchSize) override;
28 |
29 | virtual int initialize() override;
30 |
31 | virtual void terminate() override;
32 |
33 | virtual size_t getWorkspaceSize(int maxBatchSize) const override;
34 |
35 | virtual int enqueue(int batchSize, const void*const * inputs, void** outputs, void* workspace, cudaStream_t stream) override;
36 |
37 | virtual size_t getSerializationSize() const override;
38 |
39 | virtual void serialize(void* buffer) const override;
40 |
41 | virtual const char* getPluginType() const override;
42 |
43 | virtual const char* getPluginVersion() const override;
44 |
45 | virtual void destroy();
46 |
47 | virtual IPluginV2* clone() const override;
48 |
49 | virtual void setPluginNamespace(const char* pluginNamespace) override;
50 |
51 | virtual const char* getPluginNamespace() const override;
52 |
53 | private:
54 | int mNbWeights, mNbInputChannels, mInputHeight, mInputWidth, mFilterSize, mNbFilters, mStride, mPadding;
55 | nvinfer1::Weights mWeights;
56 | nvinfer1::DataType mDataType{nvinfer1::DataType::kFLOAT};
57 | void* mDeviceWeightPtr{nullptr};
58 | };
59 |
60 |
61 | class Adder2dPluginCreator : public nvinfer1::IPluginCreator {
62 | public:
63 | Adder2dPluginCreator();
64 |
65 | // ------------------inherit from IPluginCreator-------------------
66 | // return the plugin type + plugin namesapce
67 | virtual const char* getPluginName() const override;
68 |
69 | // return the plugin version
70 | virtual const char* getPluginVersion() const override;
71 |
72 | // return a list of fields that needs to be passed to createPlugin
73 | virtual const nvinfer1::PluginFieldCollection* getFieldNames() override;
74 |
75 | // return nullptr in case of error
76 | virtual nvinfer1::IPluginV2* createPlugin(const char* name, const nvinfer1::PluginFieldCollection *fc) override;
77 |
78 | // Called during deserialization of plugin layer. Return a plugin object.
79 | virtual nvinfer1::IPluginV2* deserializePlugin(const char* name, const void* serialData, size_t serialLenth) override;
80 |
81 | // Set the namespace of the plugin creator based on the plugin library it belongs to. This can be set while registering the plugin creator
82 | virtual void setPluginNamespace(const char* pluginNamespace) override {}
83 |
84 | // Return the namespace of the plugin creator object.
85 | virtual const char* getPluginNamespace() const override;
86 |
87 | private:
88 | nvinfer1::PluginFieldCollection mFC;
89 | std::vector mPluginAttributes;
90 | };
91 |
92 |
93 | #endif //ADDER2D_PLUGIN_H
--------------------------------------------------------------------------------
/plugin/Adder2dPyTrt.cpp:
--------------------------------------------------------------------------------
1 | #include "Adder2dPlugin.h"
2 |
3 | #include
4 | namespace py = pybind11;
5 |
6 | PYBIND11_MODULE(adder2dpytrt, m) {
7 | py::class_(m, "Adder2dPlugin")
8 | .def(py::init(),
9 | py::arg("weights"), py::arg("nbWeights"), py::arg("nbInputChannels"), py::arg("inputHeight"), py::arg("inputWidth"),
10 | py::arg("filterSize"), py::arg("nbFilters"), py::arg("stride"), py::arg("padding"))
11 | .def(py::init(), py::arg("data"), py::arg("length"))
12 | .def("getSerializationSize", &Adder2dPlugin::getSerializationSize);
13 | }
14 |
--------------------------------------------------------------------------------
/plugin/PluginUtils.cpp:
--------------------------------------------------------------------------------
1 | #include "PluginUtils.h"
2 |
3 | size_t type2size(nvinfer1::DataType type) {
4 | if(type == nvinfer1::DataType::kFLOAT) {
5 | return 4;
6 | } else if (type == nvinfer1::DataType::kHALF) {
7 | return 2;
8 | } else if (type == nvinfer1::DataType::kINT8) {
9 | return 1;
10 | } else {
11 | ASSERT(false);
12 | }
13 | }
14 |
15 | void* copyToDevice(const void* data, size_t count) {
16 | void *deviceData;
17 | CUDA_CHECK(cudaMalloc(&deviceData, count));
18 | CUDA_CHECK(cudaMemcpy(deviceData, data, count, cudaMemcpyHostToDevice));
19 | return deviceData;
20 | }
21 |
22 | void copyToBuffer(char*& buffer, const void* data, size_t count) {
23 | memcpy(buffer, data, count);
24 | }
25 |
26 | void convertAndCopyToDeivce(void*& deviceWeights, const nvinfer1::Weights &weights,
27 | nvinfer1::DataType datatype) {
28 | size_t size = weights.count * type2size(datatype);
29 | if (weights.type != datatype) // Weights are converted in host memory first, if the type does not match
30 | {
31 | void *buffer = malloc(size);
32 | for (int64_t v = 0; v < weights.count; ++v)
33 | if (datatype == nvinfer1::DataType::kFLOAT)
34 | static_cast(buffer)[v] = __half2float(static_cast(weights.values)[v]);
35 | else
36 | static_cast<__half *>(buffer)[v] = __float2half(static_cast(weights.values)[v]);
37 |
38 | deviceWeights = copyToDevice(buffer, size);
39 | free(buffer);
40 | }
41 | else
42 | deviceWeights = copyToDevice(weights.values, size);
43 | }
44 |
45 | void convertAndCopyToBuffer(char*& buffer, const nvinfer1::Weights weights,
46 | nvinfer1::DataType datatype) {
47 | size_t size = weights.count * type2size(datatype);
48 | if(weights.type != datatype) {
49 | for (int64_t v = 0; v < weights.count; ++v) {
50 | if (datatype == nvinfer1::DataType::kFLOAT)
51 | reinterpret_cast(buffer)[v] = __half2float(static_cast(weights.values)[v]);
52 | else
53 | reinterpret_cast<__half *>(buffer)[v] = __float2half(static_cast(weights.values)[v]);
54 | }
55 | } else {
56 | copyToBuffer(buffer, weights.values, size);
57 | }
58 | buffer += size;
59 | }
60 |
--------------------------------------------------------------------------------
/plugin/PluginUtils.h:
--------------------------------------------------------------------------------
1 | #ifndef PLUGIN_UTILS_H
2 | #define PLUGIN_UTILS_H
3 |
4 | #include "NvInfer.h"
5 | #include "cuda_runtime.h"
6 | #include "cuda_fp16.h"
7 |
8 | #include
9 | #include
10 |
11 | // this is for debug, and you can find a lot assert in plugin implementation,
12 | // it will reduce the time spend on debug
13 | #define ASSERT(assertion) \
14 | { \
15 | if (!(assertion)) \
16 | { \
17 | std::cerr << "#assertion fail " << __FILE__ << " line " << __LINE__ << std::endl; \
18 | abort(); \
19 | } \
20 | }
21 |
22 | #define UNUSED(unusedVariable) (void)(unusedVariable)
23 | // suppress compiler warning: unused parameter
24 |
25 | inline int64_t volume(const nvinfer1::Dims& d){
26 | return std::accumulate(d.d, d.d + d.nbDims, 1, std::multiplies());
27 | }
28 |
29 | inline unsigned int getElementSize(nvinfer1::DataType t){
30 | switch (t)
31 | {
32 | case nvinfer1::DataType::kINT32: return 4;
33 | case nvinfer1::DataType::kFLOAT: return 4;
34 | case nvinfer1::DataType::kHALF: return 2;
35 | case nvinfer1::DataType::kINT8: return 1;
36 | default: throw std::runtime_error("Invalid DataType.");
37 | }
38 | }
39 |
40 |
41 | #ifndef CUDA_CHECK
42 | #define CUDA_CHECK(callstr) \
43 | { \
44 | cudaError_t error_code = callstr; \
45 | if (error_code != cudaSuccess) { \
46 | std::cerr << "CUDA error " << error_code << " at " << __FILE__ << ":" << __LINE__ << std::endl; \
47 | exit(0); \
48 | } \
49 | }
50 | #endif
51 |
52 | inline void* safeCudaMalloc(size_t memSize) {
53 | void* deviceMem;
54 | CUDA_CHECK(cudaMalloc(&deviceMem, memSize));
55 | if (deviceMem == nullptr) {
56 | std::cerr << "Out of memory" << std::endl;
57 | exit(1);
58 | }
59 | return deviceMem;
60 | }
61 |
62 | inline void safeCudaFree(void* deviceMem) {
63 | CUDA_CHECK(cudaFree(deviceMem));
64 | }
65 |
66 | inline void error(const std::string& message, const int line, const std::string& function, const std::string& file) {
67 | std::cout << message << " at " << line << " in " << function << " in " << file << std::endl;
68 | }
69 |
70 |
71 | // write value to buffer
72 | template
73 | void write(char *&buffer, const T &val)
74 | {
75 | *reinterpret_cast(buffer) = val;
76 | buffer += sizeof(T);
77 | }
78 |
79 | // read value from buffer
80 | template
81 | void read(const char *&buffer, T &val)
82 | {
83 | val = *reinterpret_cast(buffer);
84 | buffer += sizeof(T);
85 | }
86 |
87 |
88 |
89 | // return needed space of a datatype
90 | size_t type2size(nvinfer1::DataType type);
91 |
92 | // copy data to device memory
93 | void* copyToDevice(const void* data, size_t count);
94 |
95 | // copy data to buffer.
96 | void copyToBuffer(char*& buffer, const void* data, size_t count);
97 |
98 | // convert data to datatype and copy it to device
99 | void convertAndCopyToDeivce(void*& deviceWeights, const nvinfer1::Weights &weights,
100 | nvinfer1::DataType datatype);
101 |
102 | // convert data to datatype and copy it to buffer
103 | void convertAndCopyToBuffer(char*& buffer, const nvinfer1::Weights weights,
104 | nvinfer1::DataType datatype);
105 |
106 | // deserialize buffer to device memory.
107 | void deserializeToDevice(const char*& hostBuffer, void*& deviceWeights, size_t size);
108 |
109 | #endif //PLUGIN_UTILS_H
--------------------------------------------------------------------------------
/plugin/cmake/CUDA_utils.cmake:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 |
16 | # List of currently used arch values
17 | set(CUDA_known_archs "60" "61" "70" "75")
18 |
19 | set(CUDA_TARGET_ARCHS ${CUDA_known_archs} CACHE STRING "List of target CUDA architectures")
20 | if ("${CUDA_TARGET_ARCHS}" STREQUAL "")
21 | message("CUDA_TARGET_ARCHS cannot be empty, setting to the default")
22 | set(CUDA_TARGET_ARCHS ${CUDA_known_archs} CACHE STRING "List of target CUDA architectures" FORCE)
23 | endif()
24 |
25 | # Find if passing `flags` to nvcc producess success or failure
26 | # Unix only
27 | #
28 | # Equivalent to dry-running preprocessing on /dev/null as .cu file
29 | # and checking the exit code
30 | # $ nvcc ${flags} --dryrun -E -x cu /dev/null
31 | #
32 | # @param out_status TRUE iff exit code is 0, FALSE otherwise
33 | # @param nvcc_bin nvcc binary to use in shell invocation
34 | # @param flags flags to check
35 | # @return out_status
36 | function(CUDA_check_nvcc_flag out_status nvcc_bin flags)
37 | set(preprocess_empty_cu_file "--dryrun" "-E" "-x" "cu" "/dev/null")
38 | set(nvcc_command ${flags} ${preprocess_empty_cu_file})
39 | # Run nvcc and check the exit status
40 | execute_process(COMMAND ${nvcc_bin} ${nvcc_command}
41 | RESULT_VARIABLE tmp_out_status
42 | OUTPUT_QUIET
43 | ERROR_QUIET)
44 | if (${tmp_out_status} EQUAL 0)
45 | set(${out_status} TRUE PARENT_SCOPE)
46 | else()
47 | set(${out_status} FALSE PARENT_SCOPE)
48 | endif()
49 | endfunction()
50 |
51 | # Given the list of arch values, check which are supported by
52 | # nvcc found in CUDA_TOOLKIT_ROOT_DIR. Requires CUDA to be set up in CMake.
53 | #
54 | # @param out_arch_values_allowed List of arch values supported by nvcc
55 | # @param arch_values_to_check List of values to be checked against nvcc
56 | # for example: 60;61;70;75
57 | # @return out_arch_values_allowed
58 | function(CUDA_find_supported_arch_values out_arch_values_allowed arch_values_to_check)
59 | if (NOT CUDA_FOUND)
60 | message(ERROR "CUDA is needed to check supported architecture values")
61 | endif()
62 | # allow the user to pass the list like a normal variable
63 | set(arch_list ${arch_values_to_check} ${ARGN})
64 | set(nvcc "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc")
65 | foreach(arch IN LISTS arch_list ITEMS)
66 | CUDA_check_nvcc_flag(supported ${nvcc} "-arch=sm_${arch}")
67 | if (supported)
68 | set(out_list ${out_list} ${arch})
69 | endif()
70 | endforeach(arch)
71 | set(${out_arch_values_allowed} ${out_list} PARENT_SCOPE)
72 | endfunction()
73 |
74 | # Generate -gencode arch=compute_XX,code=sm_XX for list of supported arch values
75 | # List should be sorted in increasing order.
76 | # The last arch value will be repeated as -gencode arch=compute_XX,code=compute_XX
77 | # to ensure the generation of PTX for most recent virtual architecture
78 | # and maintain forward compatibility
79 | #
80 | # @param out_args_string output string containing appropriate CUDA_NVCC_FLAGS
81 | # @param arch_values list of arch values to use
82 | # @return out_args_string
83 | function(CUDA_get_gencode_args out_args_string arch_values)
84 | # allow the user to pass the list like a normal variable
85 | set(arch_list ${arch_values} ${ARGN})
86 | set(out "")
87 | foreach(arch IN LISTS arch_list)
88 | set(out "${out} -gencode arch=compute_${arch},code=sm_${arch}")
89 | endforeach(arch)
90 | # Repeat the last one as to ensure the generation of PTX for most
91 | # recent virtual architecture for forward compatibility
92 | list(GET arch_list -1 last_arch)
93 | set(out "${out} -gencode arch=compute_${last_arch},code=compute_${last_arch}")
94 | set(${out_args_string} ${out} PARENT_SCOPE)
95 | endfunction()
96 |
--------------------------------------------------------------------------------
/plugin/pybind11/.appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 1.0.{build}
2 | image:
3 | - Visual Studio 2017
4 | - Visual Studio 2015
5 | test: off
6 | skip_branch_with_pr: true
7 | build:
8 | parallel: true
9 | platform:
10 | - x64
11 | - x86
12 | environment:
13 | matrix:
14 | - PYTHON: 36
15 | CPP: 14
16 | CONFIG: Debug
17 | - PYTHON: 27
18 | CPP: 14
19 | CONFIG: Debug
20 | - CONDA: 36
21 | CPP: latest
22 | CONFIG: Release
23 | matrix:
24 | exclude:
25 | - image: Visual Studio 2015
26 | platform: x86
27 | - image: Visual Studio 2015
28 | CPP: latest
29 | - image: Visual Studio 2017
30 | CPP: latest
31 | platform: x86
32 | install:
33 | - ps: |
34 | if ($env:PLATFORM -eq "x64") { $env:CMAKE_ARCH = "x64" }
35 | if ($env:APPVEYOR_JOB_NAME -like "*Visual Studio 2017*") {
36 | $env:CMAKE_GENERATOR = "Visual Studio 15 2017"
37 | $env:CMAKE_INCLUDE_PATH = "C:\Libraries\boost_1_64_0"
38 | $env:CXXFLAGS = "-permissive-"
39 | } else {
40 | $env:CMAKE_GENERATOR = "Visual Studio 14 2015"
41 | }
42 | if ($env:PYTHON) {
43 | if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
44 | $env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
45 | python -W ignore -m pip install --upgrade pip wheel
46 | python -W ignore -m pip install pytest numpy --no-warn-script-location
47 | } elseif ($env:CONDA) {
48 | if ($env:CONDA -eq "27") { $env:CONDA = "" }
49 | if ($env:PLATFORM -eq "x64") { $env:CONDA = "$env:CONDA-x64" }
50 | $env:PATH = "C:\Miniconda$env:CONDA\;C:\Miniconda$env:CONDA\Scripts\;$env:PATH"
51 | $env:PYTHONHOME = "C:\Miniconda$env:CONDA"
52 | conda --version
53 | conda install -y -q pytest numpy scipy
54 | }
55 | - ps: |
56 | Start-FileDownload 'http://bitbucket.org/eigen/eigen/get/3.3.3.zip'
57 | 7z x 3.3.3.zip -y > $null
58 | $env:CMAKE_INCLUDE_PATH = "eigen-eigen-67e894c6cd8f;$env:CMAKE_INCLUDE_PATH"
59 | build_script:
60 | - cmake -G "%CMAKE_GENERATOR%" -A "%CMAKE_ARCH%"
61 | -DPYBIND11_CPP_STANDARD=/std:c++%CPP%
62 | -DPYBIND11_WERROR=ON
63 | -DDOWNLOAD_CATCH=ON
64 | -DCMAKE_SUPPRESS_REGENERATION=1
65 | .
66 | - set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
67 | - cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger%
68 | - cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger%
69 | - if "%CPP%"=="latest" (cmake --build . --config %CONFIG% --target test_cmake_build -- /m /v:m /logger:%MSBuildLogger%)
70 | on_failure: if exist "tests\test_cmake_build" type tests\test_cmake_build\*.log*
71 |
--------------------------------------------------------------------------------
/plugin/pybind11/.gitignore:
--------------------------------------------------------------------------------
1 | CMakeCache.txt
2 | CMakeFiles
3 | Makefile
4 | cmake_install.cmake
5 | .DS_Store
6 | *.so
7 | *.pyd
8 | *.dll
9 | *.sln
10 | *.sdf
11 | *.opensdf
12 | *.vcxproj
13 | *.filters
14 | example.dir
15 | Win32
16 | x64
17 | Release
18 | Debug
19 | .vs
20 | CTestTestfile.cmake
21 | Testing
22 | autogen
23 | MANIFEST
24 | /.ninja_*
25 | /*.ninja
26 | /docs/.build
27 | *.py[co]
28 | *.egg-info
29 | *~
30 | .*.swp
31 | .DS_Store
32 | /dist
33 | /build
34 | /cmake/
35 | .cache/
36 | sosize-*.txt
37 | pybind11Config*.cmake
38 | pybind11Targets.cmake
39 |
--------------------------------------------------------------------------------
/plugin/pybind11/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "tools/clang"]
2 | path = tools/clang
3 | url = ../../wjakob/clang-cindex-python3
4 |
--------------------------------------------------------------------------------
/plugin/pybind11/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | python:
2 | version: 3
3 | requirements_file: docs/requirements.txt
4 |
--------------------------------------------------------------------------------
/plugin/pybind11/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Thank you for your interest in this project! Please refer to the following
2 | sections on how to contribute code and bug reports.
3 |
4 | ### Reporting bugs
5 |
6 | At the moment, this project is run in the spare time of a single person
7 | ([Wenzel Jakob](http://rgl.epfl.ch/people/wjakob)) with very limited resources
8 | for issue tracker tickets. Thus, before submitting a question or bug report,
9 | please take a moment of your time and ensure that your issue isn't already
10 | discussed in the project documentation provided at
11 | [http://pybind11.readthedocs.org/en/latest](http://pybind11.readthedocs.org/en/latest).
12 |
13 | Assuming that you have identified a previously unknown problem or an important
14 | question, it's essential that you submit a self-contained and minimal piece of
15 | code that reproduces the problem. In other words: no external dependencies,
16 | isolate the function(s) that cause breakage, submit matched and complete C++
17 | and Python snippets that can be easily compiled and run on my end.
18 |
19 | ## Pull requests
20 | Contributions are submitted, reviewed, and accepted using Github pull requests.
21 | Please refer to [this
22 | article](https://help.github.com/articles/using-pull-requests) for details and
23 | adhere to the following rules to make the process as smooth as possible:
24 |
25 | * Make a new branch for every feature you're working on.
26 | * Make small and clean pull requests that are easy to review but make sure they
27 | do add value by themselves.
28 | * Add tests for any new functionality and run the test suite (``make pytest``)
29 | to ensure that no existing features break.
30 | * Please run ``flake8`` and ``tools/check-style.sh`` to check your code matches
31 | the project style. (Note that ``check-style.sh`` requires ``gawk``.)
32 | * This project has a strong focus on providing general solutions using a
33 | minimal amount of code, thus small pull requests are greatly preferred.
34 |
35 | ### Licensing of contributions
36 |
37 | pybind11 is provided under a BSD-style license that can be found in the
38 | ``LICENSE`` file. By using, distributing, or contributing to this project, you
39 | agree to the terms and conditions of this license.
40 |
41 | You are under no obligation whatsoever to provide any bug fixes, patches, or
42 | upgrades to the features, functionality or performance of the source code
43 | ("Enhancements") to anyone; however, if you choose to make your Enhancements
44 | available either publicly, or directly to the author of this software, without
45 | imposing a separate written license agreement for such Enhancements, then you
46 | hereby grant the following license: a non-exclusive, royalty-free perpetual
47 | license to install, use, modify, prepare derivative works, incorporate into
48 | other computer software, distribute, and sublicense such enhancements or
49 | derivative works thereof, in binary and source code form.
50 |
--------------------------------------------------------------------------------
/plugin/pybind11/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Make sure you've completed the following steps before submitting your issue -- thank you!
2 |
3 | 1. Check if your question has already been answered in the [FAQ](http://pybind11.readthedocs.io/en/latest/faq.html) section.
4 | 2. Make sure you've read the [documentation](http://pybind11.readthedocs.io/en/latest/). Your issue may be addressed there.
5 | 3. If those resources didn't help and you only have a short question (not a bug report), consider asking in the [Gitter chat room](https://gitter.im/pybind/Lobby).
6 | 4. If you have a genuine bug report or a more complex question which is not answered in the previous items (or not suitable for chat), please fill in the details below.
7 | 5. Include a self-contained and minimal piece of code that reproduces the problem. If that's not possible, try to make the description as clear as possible.
8 |
9 | *After reading, remove this checklist and the template text in parentheses below.*
10 |
11 | ## Issue description
12 |
13 | (Provide a short description, state the expected behavior and what actually happens.)
14 |
15 | ## Reproducible example code
16 |
17 | (The code should be minimal, have no external dependencies, isolate the function(s) that cause breakage. Submit matched and complete C++ and Python snippets that can be easily compiled and run to diagnose the issue.)
18 |
--------------------------------------------------------------------------------
/plugin/pybind11/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Wenzel Jakob , All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are met:
5 |
6 | 1. Redistributions of source code must retain the above copyright notice, this
7 | list of conditions and the following disclaimer.
8 |
9 | 2. Redistributions in binary form must reproduce the above copyright notice,
10 | this list of conditions and the following disclaimer in the documentation
11 | and/or other materials provided with the distribution.
12 |
13 | 3. Neither the name of the copyright holder nor the names of its contributors
14 | may be used to endorse or promote products derived from this software
15 | without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
28 | Please also refer to the file CONTRIBUTING.md, which clarifies licensing of
29 | external contributions to this project including patches, pull requests, etc.
30 |
--------------------------------------------------------------------------------
/plugin/pybind11/MANIFEST.in:
--------------------------------------------------------------------------------
1 | recursive-include include/pybind11 *.h
2 | include LICENSE README.md CONTRIBUTING.md
3 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/Doxyfile:
--------------------------------------------------------------------------------
1 | PROJECT_NAME = pybind11
2 | INPUT = ../include/pybind11/
3 | RECURSIVE = YES
4 |
5 | GENERATE_HTML = NO
6 | GENERATE_LATEX = NO
7 | GENERATE_XML = YES
8 | XML_OUTPUT = .build/doxygenxml
9 | XML_PROGRAMLISTING = YES
10 |
11 | MACRO_EXPANSION = YES
12 | EXPAND_ONLY_PREDEF = YES
13 | EXPAND_AS_DEFINED = PYBIND11_RUNTIME_EXCEPTION
14 |
15 | ALIASES = "rst=\verbatim embed:rst"
16 | ALIASES += "endrst=\endverbatim"
17 |
18 | QUIET = YES
19 | WARNINGS = YES
20 | WARN_IF_UNDOCUMENTED = NO
21 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/_static/theme_overrides.css:
--------------------------------------------------------------------------------
1 | .wy-table-responsive table td,
2 | .wy-table-responsive table th {
3 | white-space: initial !important;
4 | }
5 | .rst-content table.docutils td {
6 | vertical-align: top !important;
7 | }
8 | div[class^='highlight'] pre {
9 | white-space: pre;
10 | white-space: pre-wrap;
11 | }
12 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/advanced/cast/chrono.rst:
--------------------------------------------------------------------------------
1 | Chrono
2 | ======
3 |
4 | When including the additional header file :file:`pybind11/chrono.h` conversions
5 | from C++11 chrono datatypes to python datetime objects are automatically enabled.
6 | This header also enables conversions of python floats (often from sources such
7 | as ``time.monotonic()``, ``time.perf_counter()`` and ``time.process_time()``)
8 | into durations.
9 |
10 | An overview of clocks in C++11
11 | ------------------------------
12 |
13 | A point of confusion when using these conversions is the differences between
14 | clocks provided in C++11. There are three clock types defined by the C++11
15 | standard and users can define their own if needed. Each of these clocks have
16 | different properties and when converting to and from python will give different
17 | results.
18 |
19 | The first clock defined by the standard is ``std::chrono::system_clock``. This
20 | clock measures the current date and time. However, this clock changes with to
21 | updates to the operating system time. For example, if your time is synchronised
22 | with a time server this clock will change. This makes this clock a poor choice
23 | for timing purposes but good for measuring the wall time.
24 |
25 | The second clock defined in the standard is ``std::chrono::steady_clock``.
26 | This clock ticks at a steady rate and is never adjusted. This makes it excellent
27 | for timing purposes, however the value in this clock does not correspond to the
28 | current date and time. Often this clock will be the amount of time your system
29 | has been on, although it does not have to be. This clock will never be the same
30 | clock as the system clock as the system clock can change but steady clocks
31 | cannot.
32 |
33 | The third clock defined in the standard is ``std::chrono::high_resolution_clock``.
34 | This clock is the clock that has the highest resolution out of the clocks in the
35 | system. It is normally a typedef to either the system clock or the steady clock
36 | but can be its own independent clock. This is important as when using these
37 | conversions as the types you get in python for this clock might be different
38 | depending on the system.
39 | If it is a typedef of the system clock, python will get datetime objects, but if
40 | it is a different clock they will be timedelta objects.
41 |
42 | Provided conversions
43 | --------------------
44 |
45 | .. rubric:: C++ to Python
46 |
47 | - ``std::chrono::system_clock::time_point`` → ``datetime.datetime``
48 | System clock times are converted to python datetime instances. They are
49 | in the local timezone, but do not have any timezone information attached
50 | to them (they are naive datetime objects).
51 |
52 | - ``std::chrono::duration`` → ``datetime.timedelta``
53 | Durations are converted to timedeltas, any precision in the duration
54 | greater than microseconds is lost by rounding towards zero.
55 |
56 | - ``std::chrono::[other_clocks]::time_point`` → ``datetime.timedelta``
57 | Any clock time that is not the system clock is converted to a time delta.
58 | This timedelta measures the time from the clocks epoch to now.
59 |
60 | .. rubric:: Python to C++
61 |
62 | - ``datetime.datetime`` or ``datetime.date`` or ``datetime.time`` → ``std::chrono::system_clock::time_point``
63 | Date/time objects are converted into system clock timepoints. Any
64 | timezone information is ignored and the type is treated as a naive
65 | object.
66 |
67 | - ``datetime.timedelta`` → ``std::chrono::duration``
68 | Time delta are converted into durations with microsecond precision.
69 |
70 | - ``datetime.timedelta`` → ``std::chrono::[other_clocks]::time_point``
71 | Time deltas that are converted into clock timepoints are treated as
72 | the amount of time from the start of the clocks epoch.
73 |
74 | - ``float`` → ``std::chrono::duration``
75 | Floats that are passed to C++ as durations be interpreted as a number of
76 | seconds. These will be converted to the duration using ``duration_cast``
77 | from the float.
78 |
79 | - ``float`` → ``std::chrono::[other_clocks]::time_point``
80 | Floats that are passed to C++ as time points will be interpreted as the
81 | number of seconds from the start of the clocks epoch.
82 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/advanced/cast/custom.rst:
--------------------------------------------------------------------------------
1 | Custom type casters
2 | ===================
3 |
4 | In very rare cases, applications may require custom type casters that cannot be
5 | expressed using the abstractions provided by pybind11, thus requiring raw
6 | Python C API calls. This is fairly advanced usage and should only be pursued by
7 | experts who are familiar with the intricacies of Python reference counting.
8 |
9 | The following snippets demonstrate how this works for a very simple ``inty``
10 | type that that should be convertible from Python types that provide a
11 | ``__int__(self)`` method.
12 |
13 | .. code-block:: cpp
14 |
15 | struct inty { long long_value; };
16 |
17 | void print(inty s) {
18 | std::cout << s.long_value << std::endl;
19 | }
20 |
21 | The following Python snippet demonstrates the intended usage from the Python side:
22 |
23 | .. code-block:: python
24 |
25 | class A:
26 | def __int__(self):
27 | return 123
28 |
29 | from example import print
30 | print(A())
31 |
32 | To register the necessary conversion routines, it is necessary to add
33 | a partial overload to the ``pybind11::detail::type_caster`` template.
34 | Although this is an implementation detail, adding partial overloads to this
35 | type is explicitly allowed.
36 |
37 | .. code-block:: cpp
38 |
39 | namespace pybind11 { namespace detail {
40 | template <> struct type_caster {
41 | public:
42 | /**
43 | * This macro establishes the name 'inty' in
44 | * function signatures and declares a local variable
45 | * 'value' of type inty
46 | */
47 | PYBIND11_TYPE_CASTER(inty, _("inty"));
48 |
49 | /**
50 | * Conversion part 1 (Python->C++): convert a PyObject into a inty
51 | * instance or return false upon failure. The second argument
52 | * indicates whether implicit conversions should be applied.
53 | */
54 | bool load(handle src, bool) {
55 | /* Extract PyObject from handle */
56 | PyObject *source = src.ptr();
57 | /* Try converting into a Python integer value */
58 | PyObject *tmp = PyNumber_Long(source);
59 | if (!tmp)
60 | return false;
61 | /* Now try to convert into a C++ int */
62 | value.long_value = PyLong_AsLong(tmp);
63 | Py_DECREF(tmp);
64 | /* Ensure return code was OK (to avoid out-of-range errors etc) */
65 | return !(value.long_value == -1 && !PyErr_Occurred());
66 | }
67 |
68 | /**
69 | * Conversion part 2 (C++ -> Python): convert an inty instance into
70 | * a Python object. The second and third arguments are used to
71 | * indicate the return value policy and parent object (for
72 | * ``return_value_policy::reference_internal``) and are generally
73 | * ignored by implicit casters.
74 | */
75 | static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) {
76 | return PyLong_FromLong(src.long_value);
77 | }
78 | };
79 | }} // namespace pybind11::detail
80 |
81 | .. note::
82 |
83 | A ``type_caster`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires
84 | that ``T`` is default-constructible (``value`` is first default constructed
85 | and then ``load()`` assigns to it).
86 |
87 | .. warning::
88 |
89 | When using custom type casters, it's important to declare them consistently
90 | in every compilation unit of the Python extension module. Otherwise,
91 | undefined behavior can ensue.
92 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/advanced/cast/functional.rst:
--------------------------------------------------------------------------------
1 | Functional
2 | ##########
3 |
4 | The following features must be enabled by including :file:`pybind11/functional.h`.
5 |
6 |
7 | Callbacks and passing anonymous functions
8 | =========================================
9 |
10 | The C++11 standard brought lambda functions and the generic polymorphic
11 | function wrapper ``std::function<>`` to the C++ programming language, which
12 | enable powerful new ways of working with functions. Lambda functions come in
13 | two flavors: stateless lambda function resemble classic function pointers that
14 | link to an anonymous piece of code, while stateful lambda functions
15 | additionally depend on captured variables that are stored in an anonymous
16 | *lambda closure object*.
17 |
18 | Here is a simple example of a C++ function that takes an arbitrary function
19 | (stateful or stateless) with signature ``int -> int`` as an argument and runs
20 | it with the value 10.
21 |
22 | .. code-block:: cpp
23 |
24 | int func_arg(const std::function &f) {
25 | return f(10);
26 | }
27 |
28 | The example below is more involved: it takes a function of signature ``int -> int``
29 | and returns another function of the same kind. The return value is a stateful
30 | lambda function, which stores the value ``f`` in the capture object and adds 1 to
31 | its return value upon execution.
32 |
33 | .. code-block:: cpp
34 |
35 | std::function func_ret(const std::function &f) {
36 | return [f](int i) {
37 | return f(i) + 1;
38 | };
39 | }
40 |
41 | This example demonstrates using python named parameters in C++ callbacks which
42 | requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
43 | methods of classes:
44 |
45 | .. code-block:: cpp
46 |
47 | py::cpp_function func_cpp() {
48 | return py::cpp_function([](int i) { return i+1; },
49 | py::arg("number"));
50 | }
51 |
52 | After including the extra header file :file:`pybind11/functional.h`, it is almost
53 | trivial to generate binding code for all of these functions.
54 |
55 | .. code-block:: cpp
56 |
57 | #include
58 |
59 | PYBIND11_MODULE(example, m) {
60 | m.def("func_arg", &func_arg);
61 | m.def("func_ret", &func_ret);
62 | m.def("func_cpp", &func_cpp);
63 | }
64 |
65 | The following interactive session shows how to call them from Python.
66 |
67 | .. code-block:: pycon
68 |
69 | $ python
70 | >>> import example
71 | >>> def square(i):
72 | ... return i * i
73 | ...
74 | >>> example.func_arg(square)
75 | 100L
76 | >>> square_plus_1 = example.func_ret(square)
77 | >>> square_plus_1(4)
78 | 17L
79 | >>> plus_1 = func_cpp()
80 | >>> plus_1(number=43)
81 | 44L
82 |
83 | .. warning::
84 |
85 | Keep in mind that passing a function from C++ to Python (or vice versa)
86 | will instantiate a piece of wrapper code that translates function
87 | invocations between the two languages. Naturally, this translation
88 | increases the computational cost of each function call somewhat. A
89 | problematic situation can arise when a function is copied back and forth
90 | between Python and C++ many times in a row, in which case the underlying
91 | wrappers will accumulate correspondingly. The resulting long sequence of
92 | C++ -> Python -> C++ -> ... roundtrips can significantly decrease
93 | performance.
94 |
95 | There is one exception: pybind11 detects case where a stateless function
96 | (i.e. a function pointer or a lambda function without captured variables)
97 | is passed as an argument to another C++ function exposed in Python. In this
98 | case, there is no overhead. Pybind11 will extract the underlying C++
99 | function pointer from the wrapped function to sidestep a potential C++ ->
100 | Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
101 |
102 | .. note::
103 |
104 | This functionality is very useful when generating bindings for callbacks in
105 | C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
106 |
107 | The file :file:`tests/test_callbacks.cpp` contains a complete example
108 | that demonstrates how to work with callbacks and anonymous functions in
109 | more detail.
110 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/advanced/cast/index.rst:
--------------------------------------------------------------------------------
1 | Type conversions
2 | ################
3 |
4 | Apart from enabling cross-language function calls, a fundamental problem
5 | that a binding tool like pybind11 must address is to provide access to
6 | native Python types in C++ and vice versa. There are three fundamentally
7 | different ways to do this—which approach is preferable for a particular type
8 | depends on the situation at hand.
9 |
10 | 1. Use a native C++ type everywhere. In this case, the type must be wrapped
11 | using pybind11-generated bindings so that Python can interact with it.
12 |
13 | 2. Use a native Python type everywhere. It will need to be wrapped so that
14 | C++ functions can interact with it.
15 |
16 | 3. Use a native C++ type on the C++ side and a native Python type on the
17 | Python side. pybind11 refers to this as a *type conversion*.
18 |
19 | Type conversions are the most "natural" option in the sense that native
20 | (non-wrapped) types are used everywhere. The main downside is that a copy
21 | of the data must be made on every Python ↔ C++ transition: this is
22 | needed since the C++ and Python versions of the same type generally won't
23 | have the same memory layout.
24 |
25 | pybind11 can perform many kinds of conversions automatically. An overview
26 | is provided in the table ":ref:`conversion_table`".
27 |
28 | The following subsections discuss the differences between these options in more
29 | detail. The main focus in this section is on type conversions, which represent
30 | the last case of the above list.
31 |
32 | .. toctree::
33 | :maxdepth: 1
34 |
35 | overview
36 | strings
37 | stl
38 | functional
39 | chrono
40 | eigen
41 | custom
42 |
43 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/advanced/pycpp/index.rst:
--------------------------------------------------------------------------------
1 | Python C++ interface
2 | ####################
3 |
4 | pybind11 exposes Python types and functions using thin C++ wrappers, which
5 | makes it possible to conveniently call Python code from C++ without resorting
6 | to Python's C API.
7 |
8 | .. toctree::
9 | :maxdepth: 2
10 |
11 | object
12 | numpy
13 | utilities
14 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/benchmark.py:
--------------------------------------------------------------------------------
1 | import random
2 | import os
3 | import time
4 | import datetime as dt
5 |
6 | nfns = 4 # Functions per class
7 | nargs = 4 # Arguments per function
8 |
9 |
10 | def generate_dummy_code_pybind11(nclasses=10):
11 | decl = ""
12 | bindings = ""
13 |
14 | for cl in range(nclasses):
15 | decl += "class cl%03i;\n" % cl
16 | decl += '\n'
17 |
18 | for cl in range(nclasses):
19 | decl += "class cl%03i {\n" % cl
20 | decl += "public:\n"
21 | bindings += ' py::class_(m, "cl%03i")\n' % (cl, cl)
22 | for fn in range(nfns):
23 | ret = random.randint(0, nclasses - 1)
24 | params = [random.randint(0, nclasses - 1) for i in range(nargs)]
25 | decl += " cl%03i *fn_%03i(" % (ret, fn)
26 | decl += ", ".join("cl%03i *" % p for p in params)
27 | decl += ");\n"
28 | bindings += ' .def("fn_%03i", &cl%03i::fn_%03i)\n' % \
29 | (fn, cl, fn)
30 | decl += "};\n\n"
31 | bindings += ' ;\n'
32 |
33 | result = "#include \n\n"
34 | result += "namespace py = pybind11;\n\n"
35 | result += decl + '\n'
36 | result += "PYBIND11_MODULE(example, m) {\n"
37 | result += bindings
38 | result += "}"
39 | return result
40 |
41 |
42 | def generate_dummy_code_boost(nclasses=10):
43 | decl = ""
44 | bindings = ""
45 |
46 | for cl in range(nclasses):
47 | decl += "class cl%03i;\n" % cl
48 | decl += '\n'
49 |
50 | for cl in range(nclasses):
51 | decl += "class cl%03i {\n" % cl
52 | decl += "public:\n"
53 | bindings += ' py::class_("cl%03i")\n' % (cl, cl)
54 | for fn in range(nfns):
55 | ret = random.randint(0, nclasses - 1)
56 | params = [random.randint(0, nclasses - 1) for i in range(nargs)]
57 | decl += " cl%03i *fn_%03i(" % (ret, fn)
58 | decl += ", ".join("cl%03i *" % p for p in params)
59 | decl += ");\n"
60 | bindings += ' .def("fn_%03i", &cl%03i::fn_%03i, py::return_value_policy())\n' % \
61 | (fn, cl, fn)
62 | decl += "};\n\n"
63 | bindings += ' ;\n'
64 |
65 | result = "#include \n\n"
66 | result += "namespace py = boost::python;\n\n"
67 | result += decl + '\n'
68 | result += "BOOST_PYTHON_MODULE(example) {\n"
69 | result += bindings
70 | result += "}"
71 | return result
72 |
73 |
74 | for codegen in [generate_dummy_code_pybind11, generate_dummy_code_boost]:
75 | print ("{")
76 | for i in range(0, 10):
77 | nclasses = 2 ** i
78 | with open("test.cpp", "w") as f:
79 | f.write(codegen(nclasses))
80 | n1 = dt.datetime.now()
81 | os.system("g++ -Os -shared -rdynamic -undefined dynamic_lookup "
82 | "-fvisibility=hidden -std=c++14 test.cpp -I include "
83 | "-I /System/Library/Frameworks/Python.framework/Headers -o test.so")
84 | n2 = dt.datetime.now()
85 | elapsed = (n2 - n1).total_seconds()
86 | size = os.stat('test.so').st_size
87 | print(" {%i, %f, %i}," % (nclasses * nfns, elapsed, size))
88 | print ("}")
89 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/benchmark.rst:
--------------------------------------------------------------------------------
1 | Benchmark
2 | =========
3 |
4 | The following is the result of a synthetic benchmark comparing both compilation
5 | time and module size of pybind11 against Boost.Python. A detailed report about a
6 | Boost.Python to pybind11 conversion of a real project is available here: [#f1]_.
7 |
8 | .. [#f1] http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf
9 |
10 | Setup
11 | -----
12 |
13 | A python script (see the ``docs/benchmark.py`` file) was used to generate a set
14 | of files with dummy classes whose count increases for each successive benchmark
15 | (between 1 and 2048 classes in powers of two). Each class has four methods with
16 | a randomly generated signature with a return value and four arguments. (There
17 | was no particular reason for this setup other than the desire to generate many
18 | unique function signatures whose count could be controlled in a simple way.)
19 |
20 | Here is an example of the binding code for one class:
21 |
22 | .. code-block:: cpp
23 |
24 | ...
25 | class cl034 {
26 | public:
27 | cl279 *fn_000(cl084 *, cl057 *, cl065 *, cl042 *);
28 | cl025 *fn_001(cl098 *, cl262 *, cl414 *, cl121 *);
29 | cl085 *fn_002(cl445 *, cl297 *, cl145 *, cl421 *);
30 | cl470 *fn_003(cl200 *, cl323 *, cl332 *, cl492 *);
31 | };
32 | ...
33 |
34 | PYBIND11_MODULE(example, m) {
35 | ...
36 | py::class_(m, "cl034")
37 | .def("fn_000", &cl034::fn_000)
38 | .def("fn_001", &cl034::fn_001)
39 | .def("fn_002", &cl034::fn_002)
40 | .def("fn_003", &cl034::fn_003)
41 | ...
42 | }
43 |
44 | The Boost.Python version looks almost identical except that a return value
45 | policy had to be specified as an argument to ``def()``. For both libraries,
46 | compilation was done with
47 |
48 | .. code-block:: bash
49 |
50 | Apple LLVM version 7.0.2 (clang-700.1.81)
51 |
52 | and the following compilation flags
53 |
54 | .. code-block:: bash
55 |
56 | g++ -Os -shared -rdynamic -undefined dynamic_lookup -fvisibility=hidden -std=c++14
57 |
58 | Compilation time
59 | ----------------
60 |
61 | The following log-log plot shows how the compilation time grows for an
62 | increasing number of class and function declarations. pybind11 includes many
63 | fewer headers, which initially leads to shorter compilation times, but the
64 | performance is ultimately fairly similar (pybind11 is 19.8 seconds faster for
65 | the largest largest file with 2048 classes and a total of 8192 methods -- a
66 | modest **1.2x** speedup relative to Boost.Python, which required 116.35
67 | seconds).
68 |
69 | .. only:: not latex
70 |
71 | .. image:: pybind11_vs_boost_python1.svg
72 |
73 | .. only:: latex
74 |
75 | .. image:: pybind11_vs_boost_python1.png
76 |
77 | Module size
78 | -----------
79 |
80 | Differences between the two libraries become much more pronounced when
81 | considering the file size of the generated Python plugin: for the largest file,
82 | the binary generated by Boost.Python required 16.8 MiB, which was **2.17
83 | times** / **9.1 megabytes** larger than the output generated by pybind11. For
84 | very small inputs, Boost.Python has an edge in the plot below -- however, note
85 | that it stores many definitions in an external library, whose size was not
86 | included here, hence the comparison is slightly shifted in Boost.Python's
87 | favor.
88 |
89 | .. only:: not latex
90 |
91 | .. image:: pybind11_vs_boost_python2.svg
92 |
93 | .. only:: latex
94 |
95 | .. image:: pybind11_vs_boost_python2.png
96 |
97 |
98 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. only: not latex
2 |
3 | .. image:: pybind11-logo.png
4 |
5 | pybind11 --- Seamless operability between C++11 and Python
6 | ==========================================================
7 |
8 | .. only: not latex
9 |
10 | Contents:
11 |
12 | .. toctree::
13 | :maxdepth: 1
14 |
15 | intro
16 | changelog
17 | upgrade
18 |
19 | .. toctree::
20 | :caption: The Basics
21 | :maxdepth: 2
22 |
23 | basics
24 | classes
25 | compiling
26 |
27 | .. toctree::
28 | :caption: Advanced Topics
29 | :maxdepth: 2
30 |
31 | advanced/functions
32 | advanced/classes
33 | advanced/exceptions
34 | advanced/smart_ptrs
35 | advanced/cast/index
36 | advanced/pycpp/index
37 | advanced/embedding
38 | advanced/misc
39 |
40 | .. toctree::
41 | :caption: Extra Information
42 | :maxdepth: 1
43 |
44 | faq
45 | benchmark
46 | limitations
47 | reference
48 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/intro.rst:
--------------------------------------------------------------------------------
1 | .. image:: pybind11-logo.png
2 |
3 | About this project
4 | ==================
5 | **pybind11** is a lightweight header-only library that exposes C++ types in Python
6 | and vice versa, mainly to create Python bindings of existing C++ code. Its
7 | goals and syntax are similar to the excellent `Boost.Python`_ library by David
8 | Abrahams: to minimize boilerplate code in traditional extension modules by
9 | inferring type information using compile-time introspection.
10 |
11 | .. _Boost.Python: http://www.boost.org/doc/libs/release/libs/python/doc/index.html
12 |
13 | The main issue with Boost.Python—and the reason for creating such a similar
14 | project—is Boost. Boost is an enormously large and complex suite of utility
15 | libraries that works with almost every C++ compiler in existence. This
16 | compatibility has its cost: arcane template tricks and workarounds are
17 | necessary to support the oldest and buggiest of compiler specimens. Now that
18 | C++11-compatible compilers are widely available, this heavy machinery has
19 | become an excessively large and unnecessary dependency.
20 | Think of this library as a tiny self-contained version of Boost.Python with
21 | everything stripped away that isn't relevant for binding generation. Without
22 | comments, the core header files only require ~4K lines of code and depend on
23 | Python (2.7 or 3.x, or PyPy2.7 >= 5.7) and the C++ standard library. This
24 | compact implementation was possible thanks to some of the new C++11 language
25 | features (specifically: tuples, lambda functions and variadic templates). Since
26 | its creation, this library has grown beyond Boost.Python in many ways, leading
27 | to dramatically simpler binding code in many common situations.
28 |
29 | Core features
30 | *************
31 | The following core C++ features can be mapped to Python
32 |
33 | - Functions accepting and returning custom data structures per value, reference, or pointer
34 | - Instance methods and static methods
35 | - Overloaded functions
36 | - Instance attributes and static attributes
37 | - Arbitrary exception types
38 | - Enumerations
39 | - Callbacks
40 | - Iterators and ranges
41 | - Custom operators
42 | - Single and multiple inheritance
43 | - STL data structures
44 | - Smart pointers with reference counting like ``std::shared_ptr``
45 | - Internal references with correct reference counting
46 | - C++ classes with virtual (and pure virtual) methods can be extended in Python
47 |
48 | Goodies
49 | *******
50 | In addition to the core functionality, pybind11 provides some extra goodies:
51 |
52 | - Python 2.7, 3.x, and PyPy (PyPy2.7 >= 5.7) are supported with an
53 | implementation-agnostic interface.
54 |
55 | - It is possible to bind C++11 lambda functions with captured variables. The
56 | lambda capture data is stored inside the resulting Python function object.
57 |
58 | - pybind11 uses C++11 move constructors and move assignment operators whenever
59 | possible to efficiently transfer custom data types.
60 |
61 | - It's easy to expose the internal storage of custom data types through
62 | Pythons' buffer protocols. This is handy e.g. for fast conversion between
63 | C++ matrix classes like Eigen and NumPy without expensive copy operations.
64 |
65 | - pybind11 can automatically vectorize functions so that they are transparently
66 | applied to all entries of one or more NumPy array arguments.
67 |
68 | - Python's slice-based access and assignment operations can be supported with
69 | just a few lines of code.
70 |
71 | - Everything is contained in just a few header files; there is no need to link
72 | against any additional libraries.
73 |
74 | - Binaries are generally smaller by a factor of at least 2 compared to
75 | equivalent bindings generated by Boost.Python. A recent pybind11 conversion
76 | of `PyRosetta`_, an enormous Boost.Python binding project, reported a binary
77 | size reduction of **5.4x** and compile time reduction by **5.8x**.
78 |
79 | - Function signatures are precomputed at compile time (using ``constexpr``),
80 | leading to smaller binaries.
81 |
82 | - With little extra effort, C++ types can be pickled and unpickled similar to
83 | regular Python objects.
84 |
85 | .. _PyRosetta: http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf
86 |
87 | Supported compilers
88 | *******************
89 |
90 | 1. Clang/LLVM (any non-ancient version with C++11 support)
91 | 2. GCC 4.8 or newer
92 | 3. Microsoft Visual Studio 2015 or newer
93 | 4. Intel C++ compiler v17 or newer (v16 with pybind11 v2.0 and v15 with pybind11 v2.0 and a `workaround `_ )
94 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/limitations.rst:
--------------------------------------------------------------------------------
1 | Limitations
2 | ###########
3 |
4 | pybind11 strives to be a general solution to binding generation, but it also has
5 | certain limitations:
6 |
7 | - pybind11 casts away ``const``-ness in function arguments and return values.
8 | This is in line with the Python language, which has no concept of ``const``
9 | values. This means that some additional care is needed to avoid bugs that
10 | would be caught by the type checker in a traditional C++ program.
11 |
12 | - The NumPy interface ``pybind11::array`` greatly simplifies accessing
13 | numerical data from C++ (and vice versa), but it's not a full-blown array
14 | class like ``Eigen::Array`` or ``boost.multi_array``.
15 |
16 | These features could be implemented but would lead to a significant increase in
17 | complexity. I've decided to draw the line here to keep this project simple and
18 | compact. Users who absolutely require these features are encouraged to fork
19 | pybind11.
20 |
21 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/pybind11-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chinthysl/AdderNetTensorRT/b4164cf9c9fd818430b38344c054ddb49c3a967e/plugin/pybind11/docs/pybind11-logo.png
--------------------------------------------------------------------------------
/plugin/pybind11/docs/pybind11_vs_boost_python1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chinthysl/AdderNetTensorRT/b4164cf9c9fd818430b38344c054ddb49c3a967e/plugin/pybind11/docs/pybind11_vs_boost_python1.png
--------------------------------------------------------------------------------
/plugin/pybind11/docs/pybind11_vs_boost_python2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chinthysl/AdderNetTensorRT/b4164cf9c9fd818430b38344c054ddb49c3a967e/plugin/pybind11/docs/pybind11_vs_boost_python2.png
--------------------------------------------------------------------------------
/plugin/pybind11/docs/reference.rst:
--------------------------------------------------------------------------------
1 | .. _reference:
2 |
3 | .. warning::
4 |
5 | Please be advised that the reference documentation discussing pybind11
6 | internals is currently incomplete. Please refer to the previous sections
7 | and the pybind11 header files for the nitty gritty details.
8 |
9 | Reference
10 | #########
11 |
12 | .. _macros:
13 |
14 | Macros
15 | ======
16 |
17 | .. doxygendefine:: PYBIND11_MODULE
18 |
19 | .. _core_types:
20 |
21 | Convenience classes for arbitrary Python types
22 | ==============================================
23 |
24 | Common member functions
25 | -----------------------
26 |
27 | .. doxygenclass:: object_api
28 | :members:
29 |
30 | Without reference counting
31 | --------------------------
32 |
33 | .. doxygenclass:: handle
34 | :members:
35 |
36 | With reference counting
37 | -----------------------
38 |
39 | .. doxygenclass:: object
40 | :members:
41 |
42 | .. doxygenfunction:: reinterpret_borrow
43 |
44 | .. doxygenfunction:: reinterpret_steal
45 |
46 | Convenience classes for specific Python types
47 | =============================================
48 |
49 | .. doxygenclass:: module
50 | :members:
51 |
52 | .. doxygengroup:: pytypes
53 | :members:
54 |
55 | .. _extras:
56 |
57 | Passing extra arguments to ``def`` or ``class_``
58 | ================================================
59 |
60 | .. doxygengroup:: annotations
61 | :members:
62 |
63 | Embedding the interpreter
64 | =========================
65 |
66 | .. doxygendefine:: PYBIND11_EMBEDDED_MODULE
67 |
68 | .. doxygenfunction:: initialize_interpreter
69 |
70 | .. doxygenfunction:: finalize_interpreter
71 |
72 | .. doxygenclass:: scoped_interpreter
73 |
74 | Redirecting C++ streams
75 | =======================
76 |
77 | .. doxygenclass:: scoped_ostream_redirect
78 |
79 | .. doxygenclass:: scoped_estream_redirect
80 |
81 | .. doxygenfunction:: add_ostream_redirect
82 |
83 | Python built-in functions
84 | =========================
85 |
86 | .. doxygengroup:: python_builtins
87 | :members:
88 |
89 | Inheritance
90 | ===========
91 |
92 | See :doc:`/classes` and :doc:`/advanced/classes` for more detail.
93 |
94 | .. doxygendefine:: PYBIND11_OVERLOAD
95 |
96 | .. doxygendefine:: PYBIND11_OVERLOAD_PURE
97 |
98 | .. doxygendefine:: PYBIND11_OVERLOAD_NAME
99 |
100 | .. doxygendefine:: PYBIND11_OVERLOAD_PURE_NAME
101 |
102 | .. doxygenfunction:: get_overload
103 |
104 | Exceptions
105 | ==========
106 |
107 | .. doxygenclass:: error_already_set
108 | :members:
109 |
110 | .. doxygenclass:: builtin_exception
111 | :members:
112 |
113 |
114 | Literals
115 | ========
116 |
117 | .. doxygennamespace:: literals
118 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/release.rst:
--------------------------------------------------------------------------------
1 | To release a new version of pybind11:
2 |
3 | - Update the version number and push to pypi
4 | - Update ``pybind11/_version.py`` (set release version, remove 'dev').
5 | - Update ``PYBIND11_VERSION_MAJOR`` etc. in ``include/pybind11/detail/common.h``.
6 | - Ensure that all the information in ``setup.py`` is up-to-date.
7 | - Update version in ``docs/conf.py``.
8 | - Tag release date in ``docs/changelog.rst``.
9 | - ``git add`` and ``git commit``.
10 | - if new minor version: ``git checkout -b vX.Y``, ``git push -u origin vX.Y``
11 | - ``git tag -a vX.Y.Z -m 'vX.Y.Z release'``.
12 | - ``git push``
13 | - ``git push --tags``.
14 | - ``python setup.py sdist upload``.
15 | - ``python setup.py bdist_wheel upload``.
16 | - Update conda-forge (https://github.com/conda-forge/pybind11-feedstock) via PR
17 | - download release package from Github: ``wget https://github.com/pybind/pybind11/archive/vX.Y.Z.tar.gz``
18 | - compute checksum: ``shasum -a 256 vX.Y.Z.tar.gz``
19 | - change version number and checksum in ``recipe/meta.yml``
20 | - Get back to work
21 | - Update ``_version.py`` (add 'dev' and increment minor).
22 | - Update version in ``docs/conf.py``
23 | - Update version macros in ``include/pybind11/common.h``
24 | - ``git add`` and ``git commit``.
25 | ``git push``
26 |
--------------------------------------------------------------------------------
/plugin/pybind11/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | breathe == 4.5.0
2 |
--------------------------------------------------------------------------------
/plugin/pybind11/include/pybind11/common.h:
--------------------------------------------------------------------------------
1 | #include "detail/common.h"
2 | #warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'."
3 |
--------------------------------------------------------------------------------
/plugin/pybind11/include/pybind11/complex.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/complex.h: Complex number support
3 |
4 | Copyright (c) 2016 Wenzel Jakob
5 |
6 | All rights reserved. Use of this source code is governed by a
7 | BSD-style license that can be found in the LICENSE file.
8 | */
9 |
10 | #pragma once
11 |
12 | #include "pybind11.h"
13 | #include
14 |
15 | /// glibc defines I as a macro which breaks things, e.g., boost template names
16 | #ifdef I
17 | # undef I
18 | #endif
19 |
20 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
21 |
22 | template struct format_descriptor, detail::enable_if_t::value>> {
23 | static constexpr const char c = format_descriptor::c;
24 | static constexpr const char value[3] = { 'Z', c, '\0' };
25 | static std::string format() { return std::string(value); }
26 | };
27 |
28 | #ifndef PYBIND11_CPP17
29 |
30 | template constexpr const char format_descriptor<
31 | std::complex, detail::enable_if_t::value>>::value[3];
32 |
33 | #endif
34 |
35 | NAMESPACE_BEGIN(detail)
36 |
37 | template struct is_fmt_numeric, detail::enable_if_t::value>> {
38 | static constexpr bool value = true;
39 | static constexpr int index = is_fmt_numeric::index + 3;
40 | };
41 |
42 | template class type_caster> {
43 | public:
44 | bool load(handle src, bool convert) {
45 | if (!src)
46 | return false;
47 | if (!convert && !PyComplex_Check(src.ptr()))
48 | return false;
49 | Py_complex result = PyComplex_AsCComplex(src.ptr());
50 | if (result.real == -1.0 && PyErr_Occurred()) {
51 | PyErr_Clear();
52 | return false;
53 | }
54 | value = std::complex((T) result.real, (T) result.imag);
55 | return true;
56 | }
57 |
58 | static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) {
59 | return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
60 | }
61 |
62 | PYBIND11_TYPE_CASTER(std::complex, _("complex"));
63 | };
64 | NAMESPACE_END(detail)
65 | NAMESPACE_END(PYBIND11_NAMESPACE)
66 |
--------------------------------------------------------------------------------
/plugin/pybind11/include/pybind11/detail/descr.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time
3 |
4 | Copyright (c) 2016 Wenzel Jakob
5 |
6 | All rights reserved. Use of this source code is governed by a
7 | BSD-style license that can be found in the LICENSE file.
8 | */
9 |
10 | #pragma once
11 |
12 | #include "common.h"
13 |
14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
15 | NAMESPACE_BEGIN(detail)
16 |
17 | #if !defined(_MSC_VER)
18 | # define PYBIND11_DESCR_CONSTEXPR static constexpr
19 | #else
20 | # define PYBIND11_DESCR_CONSTEXPR const
21 | #endif
22 |
23 | /* Concatenate type signatures at compile time */
24 | template
25 | struct descr {
26 | char text[N + 1];
27 |
28 | constexpr descr() : text{'\0'} { }
29 | constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence()) { }
30 |
31 | template
32 | constexpr descr(char const (&s)[N+1], index_sequence) : text{s[Is]..., '\0'} { }
33 |
34 | template
35 | constexpr descr(char c, Chars... cs) : text{c, static_cast(cs)..., '\0'} { }
36 |
37 | static constexpr std::array types() {
38 | return {{&typeid(Ts)..., nullptr}};
39 | }
40 | };
41 |
42 | template
43 | constexpr descr plus_impl(const descr &a, const descr &b,
44 | index_sequence, index_sequence) {
45 | return {a.text[Is1]..., b.text[Is2]...};
46 | }
47 |
48 | template
49 | constexpr descr operator+(const descr &a, const descr &b) {
50 | return plus_impl(a, b, make_index_sequence(), make_index_sequence());
51 | }
52 |
53 | template
54 | constexpr descr _(char const(&text)[N]) { return descr(text); }
55 | constexpr descr<0> _(char const(&)[1]) { return {}; }
56 |
57 | template struct int_to_str : int_to_str { };
58 | template struct int_to_str<0, Digits...> {
59 | static constexpr auto digits = descr(('0' + Digits)...);
60 | };
61 |
62 | // Ternary description (like std::conditional)
63 | template
64 | constexpr enable_if_t> _(char const(&text1)[N1], char const(&)[N2]) {
65 | return _(text1);
66 | }
67 | template
68 | constexpr enable_if_t> _(char const(&)[N1], char const(&text2)[N2]) {
69 | return _(text2);
70 | }
71 |
72 | template
73 | constexpr enable_if_t _(const T1 &d, const T2 &) { return d; }
74 | template
75 | constexpr enable_if_t _(const T1 &, const T2 &d) { return d; }
76 |
77 | template auto constexpr _() -> decltype(int_to_str::digits) {
78 | return int_to_str::digits;
79 | }
80 |
81 | template constexpr descr<1, Type> _() { return {'%'}; }
82 |
83 | constexpr descr<0> concat() { return {}; }
84 |
85 | template
86 | constexpr descr concat(const descr &descr) { return descr; }
87 |
88 | template
89 | constexpr auto concat(const descr &d, const Args &...args)
90 | -> decltype(std::declval>() + concat(args...)) {
91 | return d + _(", ") + concat(args...);
92 | }
93 |
94 | template
95 | constexpr descr type_descr(const descr &descr) {
96 | return _("{") + descr + _("}");
97 | }
98 |
99 | NAMESPACE_END(detail)
100 | NAMESPACE_END(PYBIND11_NAMESPACE)
101 |
--------------------------------------------------------------------------------
/plugin/pybind11/include/pybind11/detail/typeid.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/detail/typeid.h: Compiler-independent access to type identifiers
3 |
4 | Copyright (c) 2016 Wenzel Jakob
5 |
6 | All rights reserved. Use of this source code is governed by a
7 | BSD-style license that can be found in the LICENSE file.
8 | */
9 |
10 | #pragma once
11 |
12 | #include
13 | #include
14 |
15 | #if defined(__GNUG__)
16 | #include
17 | #endif
18 |
19 | #include "common.h"
20 |
21 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
22 | NAMESPACE_BEGIN(detail)
23 | /// Erase all occurrences of a substring
24 | inline void erase_all(std::string &string, const std::string &search) {
25 | for (size_t pos = 0;;) {
26 | pos = string.find(search, pos);
27 | if (pos == std::string::npos) break;
28 | string.erase(pos, search.length());
29 | }
30 | }
31 |
32 | PYBIND11_NOINLINE inline void clean_type_id(std::string &name) {
33 | #if defined(__GNUG__)
34 | int status = 0;
35 | std::unique_ptr res {
36 | abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free };
37 | if (status == 0)
38 | name = res.get();
39 | #else
40 | detail::erase_all(name, "class ");
41 | detail::erase_all(name, "struct ");
42 | detail::erase_all(name, "enum ");
43 | #endif
44 | detail::erase_all(name, "pybind11::");
45 | }
46 | NAMESPACE_END(detail)
47 |
48 | /// Return a string representation of a C++ type
49 | template static std::string type_id() {
50 | std::string name(typeid(T).name());
51 | detail::clean_type_id(name);
52 | return name;
53 | }
54 |
55 | NAMESPACE_END(PYBIND11_NAMESPACE)
56 |
--------------------------------------------------------------------------------
/plugin/pybind11/include/pybind11/eval.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/exec.h: Support for evaluating Python expressions and statements
3 | from strings and files
4 |
5 | Copyright (c) 2016 Klemens Morgenstern and
6 | Wenzel Jakob
7 |
8 | All rights reserved. Use of this source code is governed by a
9 | BSD-style license that can be found in the LICENSE file.
10 | */
11 |
12 | #pragma once
13 |
14 | #include "pybind11.h"
15 |
16 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
17 |
18 | enum eval_mode {
19 | /// Evaluate a string containing an isolated expression
20 | eval_expr,
21 |
22 | /// Evaluate a string containing a single statement. Returns \c none
23 | eval_single_statement,
24 |
25 | /// Evaluate a string containing a sequence of statement. Returns \c none
26 | eval_statements
27 | };
28 |
29 | template
30 | object eval(str expr, object global = globals(), object local = object()) {
31 | if (!local)
32 | local = global;
33 |
34 | /* PyRun_String does not accept a PyObject / encoding specifier,
35 | this seems to be the only alternative */
36 | std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
37 |
38 | int start;
39 | switch (mode) {
40 | case eval_expr: start = Py_eval_input; break;
41 | case eval_single_statement: start = Py_single_input; break;
42 | case eval_statements: start = Py_file_input; break;
43 | default: pybind11_fail("invalid evaluation mode");
44 | }
45 |
46 | PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
47 | if (!result)
48 | throw error_already_set();
49 | return reinterpret_steal