From 4de22df9306b74cc19ebcf002e4589fccdfc783d Mon Sep 17 00:00:00 2001 From: Philippe Tillet Date: Thu, 15 Aug 2019 20:50:10 -0700 Subject: [PATCH] [python] added skeleton for python interface --- CMakeLists.txt | 27 +- examples/CMakeLists.txt | 1 - examples/python/CMakeLists.txt | 2 - examples/python/pytorch/CMakeLists.txt | 10 - examples/python/pytorch/batchnorm.cpp | 90 - examples/python/pytorch/conv.cpp | 148 -- examples/python/pytorch/run.py | 183 -- examples/python/pytorch/shift.cpp | 165 -- examples/python/pytorch/test.py | 30 - examples/python/pytorch/triton.py | 221 -- examples/python/tensorflow/CMakeLists.txt | 13 - examples/python/tensorflow/batchnorm.cpp | 157 -- examples/python/tensorflow/blocksparse.cpp | 304 --- examples/python/tensorflow/conv.cpp | 82 - examples/python/tensorflow/dot.cpp | 64 - examples/python/tensorflow/run.py | 136 -- examples/python/tensorflow/shift.cpp | 167 -- include/triton/runtime/arg.h | 4 +- lib/runtime/function.cpp | 170 +- python/dist/triton-0.1-py3.6-linux-x86_64.egg | Bin 0 -> 709047 bytes python/examples/dot.py | 42 + python/setup.py | 76 + python/src/pybind11/attr.h | 493 ++++ python/src/pybind11/buffer_info.h | 108 + python/src/pybind11/cast.h | 2128 ++++++++++++++++ python/src/pybind11/chrono.h | 162 ++ python/src/pybind11/common.h | 2 + python/src/pybind11/complex.h | 65 + python/src/pybind11/detail/class.h | 623 +++++ python/src/pybind11/detail/common.h | 807 ++++++ python/src/pybind11/detail/descr.h | 100 + python/src/pybind11/detail/init.h | 335 +++ python/src/pybind11/detail/internals.h | 291 +++ python/src/pybind11/detail/typeid.h | 55 + python/src/pybind11/eigen.h | 607 +++++ python/src/pybind11/embed.h | 200 ++ python/src/pybind11/eval.h | 117 + python/src/pybind11/functional.h | 94 + python/src/pybind11/iostream.h | 207 ++ python/src/pybind11/numpy.h | 1610 ++++++++++++ python/src/pybind11/operators.h | 168 ++ python/src/pybind11/options.h | 65 + python/src/pybind11/pybind11.h | 2162 +++++++++++++++++ python/src/pybind11/pytypes.h | 1471 +++++++++++ python/src/pybind11/stl.h | 386 +++ python/src/pybind11/stl_bind.h | 630 +++++ python/src/tensorflow.cpp | 224 ++ 47 files changed, 13251 insertions(+), 1951 deletions(-) delete mode 100644 examples/python/CMakeLists.txt delete mode 100644 examples/python/pytorch/CMakeLists.txt delete mode 100644 examples/python/pytorch/batchnorm.cpp delete mode 100644 examples/python/pytorch/conv.cpp delete mode 100644 examples/python/pytorch/run.py delete mode 100644 examples/python/pytorch/shift.cpp delete mode 100644 examples/python/pytorch/test.py delete mode 100644 examples/python/pytorch/triton.py delete mode 100644 examples/python/tensorflow/CMakeLists.txt delete mode 100644 examples/python/tensorflow/batchnorm.cpp delete mode 100644 examples/python/tensorflow/blocksparse.cpp delete mode 100644 examples/python/tensorflow/conv.cpp delete mode 100644 examples/python/tensorflow/dot.cpp delete mode 100644 examples/python/tensorflow/run.py delete mode 100644 examples/python/tensorflow/shift.cpp create mode 100644 python/dist/triton-0.1-py3.6-linux-x86_64.egg create mode 100644 python/examples/dot.py create mode 100644 python/setup.py create mode 100644 python/src/pybind11/attr.h create mode 100644 python/src/pybind11/buffer_info.h create mode 100644 python/src/pybind11/cast.h create mode 100644 python/src/pybind11/chrono.h create mode 100644 python/src/pybind11/common.h create mode 100644 python/src/pybind11/complex.h create mode 100644 python/src/pybind11/detail/class.h create mode 100644 python/src/pybind11/detail/common.h create mode 100644 python/src/pybind11/detail/descr.h create mode 100644 python/src/pybind11/detail/init.h create mode 100644 python/src/pybind11/detail/internals.h create mode 100644 python/src/pybind11/detail/typeid.h create mode 100644 python/src/pybind11/eigen.h create mode 100644 python/src/pybind11/embed.h create mode 100644 python/src/pybind11/eval.h create mode 100644 python/src/pybind11/functional.h create mode 100644 python/src/pybind11/iostream.h create mode 100644 python/src/pybind11/numpy.h create mode 100644 python/src/pybind11/operators.h create mode 100644 python/src/pybind11/options.h create mode 100644 python/src/pybind11/pybind11.h create mode 100644 python/src/pybind11/pytypes.h create mode 100644 python/src/pybind11/stl.h create mode 100644 python/src/pybind11/stl_bind.h create mode 100644 python/src/tensorflow.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bece7b6f..5b252c520 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,10 @@ project(triton) include(CTest) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +# Options +option(BUILD_EXAMPLES "Build C++ Triton examples" ON) +option(BUILD_PYTHON_MODULE "Build Python Triton bindings" OFF) + # FLEX/YACC find_package(BISON) find_package(FLEX) @@ -35,15 +39,24 @@ add_custom_target( ALL SOURCES ${ALL_SRC} ) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_CXXFLAGS} -std=c++11") +# Examples +if(BUILD_EXAMPLES) + message(STATUS "Adding C++ examples") + add_subdirectory(examples) +endif() + +# Python module +if(BUILD_PYTHON_MODULE) + message(STATUS "Adding Python module") + file(GLOB_RECURSE PYTHON_SRC python/src/*.cpp) + include_directories(python/src/ ${PYTHON_INCLUDE_DIRS}) + set(PYTHON_LIBS ) +endif() + + # Triton file(GLOB_RECURSE LIBTRITON_SRC lib/*.cpp) -add_library(triton SHARED ${LIBTRITON_SRC} ${BISON_Parser_OUTPUTS} ${FLEX_Lexer_OUTPUTS}) +add_library(triton SHARED ${LIBTRITON_SRC} ${PYTHON_SRC} ${BISON_Parser_OUTPUTS} ${FLEX_Lexer_OUTPUTS}) target_link_libraries(triton LLVM) -# Examples -add_subdirectory(examples) - - - - diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 8277f0611..2322a85f7 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,2 +1 @@ add_subdirectory(cpp) -add_subdirectory(python) diff --git a/examples/python/CMakeLists.txt b/examples/python/CMakeLists.txt deleted file mode 100644 index a73011f48..000000000 --- a/examples/python/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(tensorflow) -add_subdirectory(pytorch) diff --git a/examples/python/pytorch/CMakeLists.txt b/examples/python/pytorch/CMakeLists.txt deleted file mode 100644 index f4b4df758..000000000 --- a/examples/python/pytorch/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -find_package(Torch) -if(${TORCH_FOUND}) - set(CUDA_HOME "/usr/local/cuda") - include_directories(${TORCH_INCLUDE_DIRS}) - include_directories("${CUDA_HOME}/include") - link_directories(${TORCH_LIBRARY_DIRS}) - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) - add_library(torch_triton SHARED conv.cpp shift.cpp batchnorm.cpp) - target_link_libraries(torch_triton torch triton) -endif() diff --git a/examples/python/pytorch/batchnorm.cpp b/examples/python/pytorch/batchnorm.cpp deleted file mode 100644 index 64559e197..000000000 --- a/examples/python/pytorch/batchnorm.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include "ATen/cuda/CUDAContext.h" -#include "triton/driver/stream.h" -#include "triton/dnn/batchnorm.h" - -#define CHECK_CUDA(x) AT_CHECK(x.type().is_cuda(), #x " must be a CUDA tensor") -#define CHECK_CONTIGUOUS(x) AT_CHECK(x.is_contiguous(), #x " must be contiguous") -#define CHECK_INPUT(x) CHECK_CUDA(x); CHECK_CONTIGUOUS(x) - -std::vector - batchnorm_ymv(const torch::Tensor fw_x, - const torch::Tensor fw_g, - const torch::Tensor fw_b, - double eps) { - CHECK_INPUT(fw_x); - CHECK_INPUT(fw_g); - CHECK_INPUT(fw_b); - // Wrap CUDA handles - c10::DeviceIndex device = fw_x.storage().device().index(); - CUstream custream = (CUstream)at::cuda::getCurrentCUDAStream(device).stream(); - triton::driver::cu_stream stream(custream, false); - triton::driver::context* ctx = stream.context(); - // get sizes - int C = fw_x.size(0); - int H = fw_x.size(1); - int W = fw_x.size(2); - int B = fw_x.size(3); - // allocate outputs - torch::Tensor fw_y = torch::empty(fw_x.sizes()).cuda(); - torch::Tensor fw_m = torch::empty(fw_g.sizes()).cuda(); - torch::Tensor fw_v = torch::empty(fw_g.sizes()).cuda(); - triton::driver::cu_buffer x(ctx, (CUdeviceptr)fw_x.storage().data(), false); - triton::driver::cu_buffer g(ctx, (CUdeviceptr)fw_g.storage().data(), false); - triton::driver::cu_buffer b(ctx, (CUdeviceptr)fw_b.storage().data(), false); - triton::driver::cu_buffer y(ctx, (CUdeviceptr)fw_y.storage().data(), false); - triton::driver::cu_buffer m(ctx, (CUdeviceptr)fw_m.storage().data(), false); - triton::driver::cu_buffer v(ctx, (CUdeviceptr)fw_v.storage().data(), false); - // create template - triton::dnn::batchnorm_forward batchnorm(C, 1, H, W, B, "float"); - batchnorm.enqueue(&stream, {&y, &m, &v, &x, &g, &b}); - stream.synchronize(); - return {fw_y, fw_m, fw_v}; -} - -std::vector - batchnorm_dxdgdb(const torch::Tensor fw_dy, - const torch::Tensor fw_x, - const torch::Tensor fw_g, - const torch::Tensor fw_m, - const torch::Tensor fw_v, - double eps) { - CHECK_INPUT(fw_dy); - CHECK_INPUT(fw_x); - CHECK_INPUT(fw_g); - CHECK_INPUT(fw_m); - CHECK_INPUT(fw_v); - // Wrap CUDA handles - c10::DeviceIndex device = fw_x.storage().device().index(); - CUstream custream = (CUstream)at::cuda::getCurrentCUDAStream(device).stream(); - triton::driver::cu_stream stream(custream, false); - triton::driver::context* ctx = stream.context(); - // get sizes - int C = fw_x.size(0); - int H = fw_x.size(1); - int W = fw_x.size(2); - int B = fw_x.size(3); - // allocate outputs - torch::Tensor fw_dx = torch::empty(fw_x.sizes()).cuda(); - torch::Tensor fw_dg = torch::empty(fw_g.sizes()).cuda(); - torch::Tensor fw_db = torch::empty(fw_g.sizes()).cuda(); - // triton handles - triton::driver::cu_buffer dy(ctx, (CUdeviceptr)fw_dy.storage().data(), false); - triton::driver::cu_buffer x(ctx, (CUdeviceptr) fw_x.storage().data(), false); - triton::driver::cu_buffer g(ctx, (CUdeviceptr) fw_g.storage().data(), false); - triton::driver::cu_buffer m(ctx, (CUdeviceptr) fw_m.storage().data(), false); - triton::driver::cu_buffer v(ctx, (CUdeviceptr) fw_v.storage().data(), false); - triton::driver::cu_buffer dx(ctx, (CUdeviceptr)fw_dx.storage().data(), false); - triton::driver::cu_buffer dg(ctx, (CUdeviceptr)fw_dg.storage().data(), false); - triton::driver::cu_buffer db(ctx, (CUdeviceptr)fw_db.storage().data(), false); - // create config - triton::dnn::batchnorm_backward batchnorm(C, 1, H, W, B, "float", eps); - batchnorm.enqueue(&stream, {&dx, &dg, &db, &dy, &x, &g, &m, &v}); - stream.synchronize(); - return {fw_dx, fw_dg, fw_db}; -} - -static auto registry = - torch::jit::RegisterOperators("triton::batchnorm_ymv", &batchnorm_ymv) - .op("triton::batchnorm_dxdgdb", &batchnorm_dxdgdb); diff --git a/examples/python/pytorch/conv.cpp b/examples/python/pytorch/conv.cpp deleted file mode 100644 index 91cef5441..000000000 --- a/examples/python/pytorch/conv.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include -#include -#include "ATen/cuda/CUDAContext.h" -#include "triton/driver/stream.h" -#include "triton/dnn/conv.h" - -#define CHECK_CUDA(x) AT_CHECK(x.type().is_cuda(), #x " must be a CUDA tensor") -#define CHECK_CONTIGUOUS(x) AT_CHECK(x.is_contiguous(), #x " must be contiguous") -#define CHECK_INPUT(x) CHECK_CUDA(x); CHECK_CONTIGUOUS(x) - -torch::Tensor conv_common( - int32_t B, int32_t C, int32_t D, int32_t H, int32_t W, - int32_t T, int32_t R, int32_t S, int32_t NF, - int32_t stride_d, int32_t stride_h, int32_t stride_w, - int32_t pad_d, int32_t pad_h, int32_t pad_w, - triton::dnn::conv::type ty, - torch::Tensor torcha, torch::Tensor torchb, torch::Tensor torchbias, - bool autotune = false - ) { - // Wrap CUDA handles - c10::DeviceIndex device = torcha.storage().device().index(); - // Get stream - CUstream custream = (CUstream)at::cuda::getCurrentCUDAStream(device).stream(); - triton::driver::cu_stream stream(custream, false); - triton::driver::context* ctx = stream.context(); - // Get template - bool has_bias = torchbias.storage().size() > 0; - triton::dnn::conv conv(B, C, D, H, W, T, R, S, NF, - stride_d, stride_h, stride_w, - pad_d, pad_h, pad_w, - 1, 1, 1, - "float", "float", ty, has_bias); - // Bind memory - triton::driver::cu_buffer a(ctx, (CUdeviceptr)torcha.storage().data(), false); - triton::driver::cu_buffer b(ctx, (CUdeviceptr)torchb.storage().data(), false); - triton::driver::cu_buffer cubias(ctx, (CUdeviceptr)torchbias.storage().data(), false); - triton::driver::buffer* bias = has_bias ? &cubias : nullptr; - // Allocate output - std::vector c_shapes = conv.c_shapes(); - torch::Tensor torchc; - if(ty == triton::dnn::conv::WGRAD) - torchc = torch::empty({c_shapes[0], c_shapes[2], c_shapes[3], c_shapes[4]}, torch::kFloat).cuda(); - else - torchc = torch::empty({c_shapes[0], c_shapes[1], c_shapes[3], c_shapes[4]}, torch::kFloat).cuda(); - triton::driver::cu_buffer c(ctx, (CUdeviceptr)torchc.storage().data(), false); - // Enqueue - conv.enqueue(&stream, {&a, &b, &c, bias}); - return torchc; -} - -torch::Tensor conv_fprop( - const torch::Tensor data, - const torch::Tensor weight, - const torch::Tensor bias, - int64_t stride_h, int64_t stride_w, - int64_t pad_h, int64_t pad_w) { - // Check - CHECK_INPUT(data); - CHECK_INPUT(weight); - // Unpack data shapes - const int32_t B = data.size(0); - const int32_t Ci = data.size(1); - const int32_t D = 1; - const int32_t H = data.size(2); - const int32_t W = data.size(3); - // Unpack weight shapes - const int32_t Cf = weight.size(0); - const int32_t T = 1; - const int32_t R = weight.size(1); - const int32_t S = weight.size(2); - const int32_t NF = weight.size(3); - // Configuration - const int32_t stride_d = 1; - const int32_t pad_d = 0; - // Check - AT_CHECK(Ci == Cf, "Number of channels in data and weights must match"); - return conv_common(B, Ci, D, H, W, T, R, S, NF, stride_d, stride_h, stride_w, pad_d, pad_h, pad_w, triton::dnn::conv::FPROP, data, weight, bias); -} - -torch::Tensor conv_bprop( - const torch::Tensor derror, - const torch::Tensor weight, - const torch::Tensor bias, - int64_t H, int64_t W, - int64_t stride_h, int64_t stride_w, - int64_t pad_h, int64_t pad_w){ - // Check - CHECK_INPUT(derror); - CHECK_INPUT(weight); - // Unpack data shapes - const int32_t B = derror.size(0); - const int32_t Ki = derror.size(1); - const int32_t M = 1; - const int32_t P = derror.size(2); - const int32_t Q = derror.size(3); - // Unpack weight shapes - const int32_t C = weight.size(0); - const int32_t T = 1; - const int32_t R = weight.size(1); - const int32_t S = weight.size(2); - const int32_t Kw = weight.size(3); - // Compute M, P, Q - const int32_t stride_d = 1; - int32_t pad_d = 0; - int32_t D = 1; - // Check - AT_CHECK(Ki == Kw, "Number of channels in error and weights must match"); - return conv_common(B, C, D, H, W, T, R, S, Kw, stride_d, stride_h, stride_w, pad_d, pad_h, pad_w, triton::dnn::conv::BPROP, derror, weight, bias); -} - -torch::Tensor conv_wgrad( - const torch::Tensor data, - const torch::Tensor derror, - const torch::Tensor bias, - int64_t R, int64_t S, - int64_t stride_h, int64_t stride_w, - int64_t pad_h, int64_t pad_w - ){ - // Check - CHECK_INPUT(data); - CHECK_INPUT(derror); - // Unpack data shapes - const int32_t Ba = data.size(0); - const int32_t C = data.size(1); - const int32_t D = 1; - const int32_t H = data.size(2); - const int32_t W = data.size(3); - // Unpack error shapes - const int32_t Bb = derror.size(0); - const int32_t K = derror.size(1); - const int32_t M = 1; - const int32_t P = derror.size(2); - const int32_t Q = derror.size(3); - // Compute M, P, Q - const int32_t upsample_d = 1, upsample_h = 1, upsample_w = 1; - const int32_t stride_d = 1; - const int32_t pad_d = 0; - const int32_t T = 1; - // Check - AT_CHECK(Ba == Bb, "Number of channels in error and weights must match"); - return conv_common(Ba, C, D, H, W, T, R, S, K, stride_d, stride_h, stride_w, pad_d, pad_h, pad_w, triton::dnn::conv::WGRAD, data, derror, bias); -} - -static auto registry = - torch::jit::RegisterOperators("triton::conv_fprop", &conv_fprop) - .op("triton::conv_bprop", &conv_bprop) - .op("triton::conv_wgrad", &conv_wgrad); diff --git a/examples/python/pytorch/run.py b/examples/python/pytorch/run.py deleted file mode 100644 index e7c10112c..000000000 --- a/examples/python/pytorch/run.py +++ /dev/null @@ -1,183 +0,0 @@ -from __future__ import print_function -import argparse -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.optim as optim -from torchvision import datasets, transforms -import triton -from torch.utils.cpp_extension import load -from torch.distributions import categorical - -shift_cuda = load( - 'shift_cuda', ['/home/philippe/development/shiftnet/kernels/shift_cuda.cpp', - '/home/philippe/development/shiftnet/kernels/shift_cuda_kernel.cu'], extra_cflags=['-O3']) - -class shift(torch.autograd.Function): - @staticmethod - def forward(ctx, x, shift): - ctx.save_for_backward(shift) - return shift_cuda.forward(x, shift) - - @staticmethod - def backward(ctx, grad_output): - shift, = ctx.saved_tensors - grad_output = shift_cuda.backward(grad_output, shift) - - return grad_output, None - - -class Shift(nn.Module): - def __init__(self, in_channels, kernel_size): - super(Shift, self).__init__() - self.channels = in_channels - self.kernel_size = kernel_size - if kernel_size == 3: - p = torch.Tensor([0.3, 0.4, 0.3]) - elif kernel_size == 5: - p = torch.Tensor([0.1, 0.25, 0.3, 0.25, 0.1]) - elif kernel_size == 7: - p = torch.Tensor([0.075, 0.1, 0.175, 0.3, 0.175, 0.1, 0.075]) - elif kernel_size == 9: - p = torch.Tensor([0.05, 0.075, 0.1, 0.175, 0.2, 0.175, 0.1, 0.075, 0.05]) - else: - raise RuntimeError('Unsupported kernel size') - shift_t = categorical.Categorical(p).sample((in_channels, 2)) - (kernel_size // 2) - self.register_buffer('shift_t', shift_t.int()) - - def forward(self, x): - if x.is_cuda: - return shift.apply(x, self.shift_t) - else: - print('Shift only supports GPU for now..') - assert False - - def extra_repr(self): - s = ('{channels}, kernel_size={kernel_size}') - return s.format(**self.__dict__) - - -def ShiftConv2d(in_planes, out_planes, kernel_size=3, stride=1, groups=1, dilation=1): - return nn.Sequential( - Shift(in_planes, kernel_size), - nn.Conv2d(in_planes, out_planes, kernel_size=1, stride=stride, - padding=0, groups=groups, bias=False) - ) - - -class Net(nn.Module): - def __init__(self): - super(Net, self).__init__() - self.conv1 = ShiftConv2d(1, 32, 3, 1) - self.conv2 = ShiftConv2d(32, 128, 3, 1) - self.conv3 = ShiftConv2d(128, 128, 3, 2) - self.bn1 = nn.BatchNorm2d(128) - self.conv4 = ShiftConv2d(128, 256, 3, 2) - self.bn2 = nn.BatchNorm2d(256) - self.fc1 = nn.Linear(256*7*7, 500) - self.fc2 = nn.Linear(500, 10) - - def forward(self, x): - x = self.conv1(x) - x = self.conv2(x) - x = self.conv3(x) - x = self.bn1(x) - x = F.relu(x) - x = self.conv4(x) - x = self.bn2(x) - x = F.relu(x) - x = x.view(-1, 256*7*7) - x = F.relu(self.fc1(x)) - x = self.fc2(x) - return F.log_softmax(x, dim=1) - -Net = Net() - -def train(args, model, device, train_loader, optimizer, epoch): - model.train() - for batch_idx, (data, target) in enumerate(train_loader): - data, target = data.to(device), target.to(device) - optimizer.zero_grad() - output = model(data) - loss = F.nll_loss(output, target) - loss.backward() - optimizer.step() - if batch_idx % args.log_interval == 0: - print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( - epoch, batch_idx * len(data), len(train_loader.dataset), - 100. * batch_idx / len(train_loader), loss.item())) - -def test(args, model, device, test_loader): - model.eval() - test_loss = 0 - correct = 0 - with torch.no_grad(): - for data, target in test_loader: - data, target = data.to(device), target.to(device) - output = model(data) - test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss - pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability - correct += pred.eq(target.view_as(pred)).sum().item() - - test_loss /= len(test_loader.dataset) - - print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format( - test_loss, correct, len(test_loader.dataset), - 100. * correct / len(test_loader.dataset))) - -def main(): - # Training settings - parser = argparse.ArgumentParser(description='PyTorch MNIST Example') - parser.add_argument('--batch-size', type=int, default=64, metavar='N', - help='input batch size for training (default: 64)') - parser.add_argument('--test-batch-size', type=int, default=1000, metavar='N', - help='input batch size for testing (default: 1000)') - parser.add_argument('--epochs', type=int, default=10, metavar='N', - help='number of epochs to train (default: 10)') - parser.add_argument('--lr', type=float, default=0.01, metavar='LR', - help='learning rate (default: 0.01)') - parser.add_argument('--momentum', type=float, default=0.5, metavar='M', - help='SGD momentum (default: 0.5)') - parser.add_argument('--no-cuda', action='store_true', default=False, - help='disables CUDA training') - parser.add_argument('--seed', type=int, default=1, metavar='S', - help='random seed (default: 1)') - parser.add_argument('--log-interval', type=int, default=10, metavar='N', - help='how many batches to wait before logging training status') - - parser.add_argument('--save-model', action='store_true', default=False, - help='For Saving the current Model') - args = parser.parse_args() - use_cuda = not args.no_cuda and torch.cuda.is_available() - - torch.manual_seed(args.seed) - - device = torch.device("cuda" if use_cuda else "cpu") - - kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {} - train_loader = torch.utils.data.DataLoader( - datasets.MNIST('../data', train=True, download=True, - transform=transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize((0.1307,), (0.3081,)) - ])), - batch_size=args.batch_size, shuffle=True, **kwargs) - test_loader = torch.utils.data.DataLoader( - datasets.MNIST('../data', train=False, transform=transforms.Compose([ - transforms.ToTensor(), - transforms.Normalize((0.1307,), (0.3081,)) - ])), - batch_size=args.test_batch_size, shuffle=True, **kwargs) - - - model = Net.to(device) - optimizer = optim.SGD(model.parameters(), lr=args.lr, momentum=args.momentum) - - for epoch in range(1, args.epochs + 1): - train(args, model, device, train_loader, optimizer, epoch) - test(args, model, device, test_loader) - - if (args.save_model): - torch.save(model.state_dict(),"mnist_cnn.pt") - -main() diff --git a/examples/python/pytorch/shift.cpp b/examples/python/pytorch/shift.cpp deleted file mode 100644 index bd80d73d9..000000000 --- a/examples/python/pytorch/shift.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include -#include -#include -#include "ATen/cuda/CUDAContext.h" -#include "triton/driver/stream.h" -#include "triton/dnn/shift.h" - -#define CHECK_CUDA(x) AT_CHECK(x.type().is_cuda(), #x " must be a CUDA tensor") -#define CHECK_CONTIGUOUS(x) AT_CHECK(x.is_contiguous(), #x " must be contiguous") -#define CHECK_INPUT(x) CHECK_CUDA(x); CHECK_CONTIGUOUS(x) - -void extract_shapes(const torch::Tensor &x, - int64_t &C, int64_t &H, int64_t &W, int64_t &B, - triton::dnn::layout_t layout) { - if(layout == triton::dnn::CHWN){ - C = x.size(0); - H = x.size(1); - W = x.size(2); - B = x.size(3); - } - else if(layout == triton::dnn::NCHW){ - B = x.size(0); - C = x.size(1); - H = x.size(2); - W = x.size(3); - } - else{ - throw std::runtime_error("unsupported layout"); - } -} - -static const triton::dnn::layout_t layout = triton::dnn::NCHW; - -torch::Tensor shift_common( - int32_t B, int32_t C, int32_t D, int32_t H, int32_t W, - int32_t T, int32_t R, int32_t S, int32_t F, - int32_t stride_h, int32_t stride_w, - int32_t* shift_h, int32_t* shift_w, - triton::dnn::op_t op, triton::dnn::layout_t layout, - torch::Tensor torcha, torch::Tensor torchb, torch::Tensor torchbias, - bool autotune = false - ) { - // Wrap CUDA handles - c10::DeviceIndex device = torcha.storage().device().index(); - CUstream custream = (CUstream)at::cuda::getCurrentCUDAStream(device).stream(); - triton::driver::cu_stream stream(custream, false); - triton::driver::context* ctx = stream.context(); - // Data-type - std::string dtype; - at::ScalarType type = torcha.scalar_type(); - switch(type){ - case at::ScalarType::Double: dtype = "double"; break; - case at::ScalarType::Float: dtype = "float"; break; - case at::ScalarType::Half: dtype = "half"; break; - default: AT_ERROR("unknown data-type for shift-conv"); - } - // Get configuration - bool has_bias = torchbias.storage().size() > 0; - triton::dnn::shift shift(B, C, D, H, W, T, R, S, F, - stride_h, stride_w, - shift_h, shift_w, dtype, dtype, - op, has_bias, layout); - // Bind memory - triton::driver::cu_buffer a(ctx, (CUdeviceptr)torcha.storage().data(), false); - triton::driver::cu_buffer b(ctx, (CUdeviceptr)torchb.storage().data(), false); - triton::driver::cu_buffer cubias(ctx, (CUdeviceptr)torchbias.storage().data(), false); - triton::driver::buffer* bias = has_bias ? &cubias : nullptr; - // Allocate output - std::vector _c_shapes = shift.c_shapes(); - std::vector c_shapes; - for(auto x: _c_shapes) - c_shapes.push_back(x); - torch::Tensor torchc = torch::empty(c_shapes, type).cuda(); - - - triton::driver::cu_buffer c(ctx, (CUdeviceptr)torchc.storage().data(), false); - std::cout << B << ", " << C << ", " << H << ", " << W << ", " << T << ", " << R << ", " << S << ", " << F << ", " << stride_h << ", " << stride_w << ", " << op << ", " << layout << std::endl; - // Enqueue - shift.enqueue(&stream, {&a, &b, &c}, triton::dnn::NO_TUNING); - return torchc; -} - -torch::Tensor shift_y( - const torch::Tensor x, - const torch::Tensor w, - const torch::Tensor bias, - int64_t R, int64_t S, - int64_t stride_h, int64_t stride_w, - const torch::Tensor shift_h, const torch::Tensor shift_w) { - CHECK_INPUT(x); - CHECK_INPUT(w); - // shapes for a - int64_t Ca, H, W, B; - extract_shapes(x, Ca, H, W, B, layout); - // shapes for b - int64_t Cb = w.size(0); - int64_t F = w.size(1); - AT_CHECK(Ca == Cb, "operands must have the same number of channels"); - int64_t C = Ca; - // run - return shift_common(B, C, 1, H, W, 1, R, S, F, stride_h, stride_w, - (int32_t*)shift_h.storage().data(), (int32_t*)shift_w.storage().data(), - triton::dnn::FPROP, layout, x, w, bias); -} - -torch::Tensor shift_dx( - const torch::Tensor dy, - const torch::Tensor w, - const torch::Tensor bias, - int64_t R, int64_t S, - int64_t stride_h, int64_t stride_w, - const torch::Tensor shift_h, const torch::Tensor shift_w) { - CHECK_INPUT(dy); - CHECK_INPUT(w); - // shapes for a - int64_t Ca, H, W, B; - extract_shapes(dy, Ca, H, W, B, layout); - H *= stride_h; - W *= stride_w; - // shapes for b - int64_t Cb = w.size(0); - int64_t F = w.size(1); - std::swap(Cb, F); - // checks - AT_CHECK(Ca == Cb, "operands must have the same number of channels"); - int64_t C = Ca; - std::swap(C, F); - // run - return shift_common(B, C, 1, H, W, 1, R, S, F, stride_h, stride_w, - (int32_t*)shift_h.storage().data(), (int32_t*)shift_w.storage().data(), - triton::dnn::BPROP, layout, dy, w, bias); -} - -torch::Tensor shift_dw( - const torch::Tensor dy, - const torch::Tensor x, - const torch::Tensor bias, - int64_t R, int64_t S, - int64_t stride_h, int64_t stride_w, - const torch::Tensor shift_h, const torch::Tensor shift_w) { - CHECK_INPUT(dy); - CHECK_INPUT(x); - // shapes for a - int64_t F, Ha, Wa, Ba; - extract_shapes(dy, F, Ha, Wa, Ba, layout); - // shapes for b - int64_t C, Hb, Wb, Bb; - extract_shapes(x, C, Hb, Wb, Bb, layout); - // check - AT_CHECK(Ha*stride_h == Hb, "operands must have the same image height"); - AT_CHECK(Wa*stride_w == Wb, "operands must have the same image width"); - AT_CHECK(Ba == Bb, "operands must have the same batch size"); - int64_t H = Hb; - int64_t W = Wb; - int64_t B = Bb; - // run - return shift_common(B, C, 1, H, W, 1, R, S, F, stride_h, stride_w, - (int32_t*)shift_h.storage().data(), (int32_t*)shift_w.storage().data(), - triton::dnn::WGRAD, layout, dy, x, bias); -} - -static auto registry = - torch::jit::RegisterOperators("triton::shift_conv_y", &shift_y) - .op("triton::shift_conv_dx", &shift_dx) - .op("triton::shift_conv_dw", &shift_dw); diff --git a/examples/python/pytorch/test.py b/examples/python/pytorch/test.py deleted file mode 100644 index 4c80fd187..000000000 --- a/examples/python/pytorch/test.py +++ /dev/null @@ -1,30 +0,0 @@ -import torch -import triton - -torch.manual_seed(0) -torch.set_printoptions(precision=4) - -x = torch.autograd.Variable(torch.randn(64, 3, 8, 8).cuda(), requires_grad=True) -bias = torch.autograd.Variable(torch.randn(6).cuda(), requires_grad=True) -w = torch.autograd.Variable(torch.randn(3, 3, 3, 6).cuda(), requires_grad=True) -cuw = torch.autograd.Variable(w.permute(3,0,1,2).cuda(), requires_grad=True) -y_target = torch.autograd.Variable(torch.randn(64, 6, 8, 8).cuda(), requires_grad=True) - -def run(x, w, conv): - y = conv(x, w) - loss = (y - y_target).norm(2) - loss.backward() - return loss, y.clone(), x.grad.clone(), w.grad.clone(), bias.grad.clone() - -ttyloss, tty, ttdx, ttdw, ttbias = run(x, w, lambda x, w: triton.ConvFunction.apply(x, w, bias, (1,1), (1,1))) -x.grad.zero_() -w.grad.zero_() -bias.grad.zero_() -culoss, cuy, cudx, cudw, cubias = run(x, cuw, lambda x, w: torch.nn.functional.conv2d(x, w, bias=bias, stride=1, padding=1)) - -print(ttdx[0,0,:,:]) -print(cudx[0,0,:,:]) -print((tty - cuy).norm(2)) -print((ttdx - cudx).norm(2)) -print((ttdw.permute(3,0,1,2) - cudw).norm(2)) -print((ttbias - cubias).norm(2)) diff --git a/examples/python/pytorch/triton.py b/examples/python/pytorch/triton.py deleted file mode 100644 index 2d78e58f7..000000000 --- a/examples/python/pytorch/triton.py +++ /dev/null @@ -1,221 +0,0 @@ -import torch -import math -import numpy as np -from torch.nn.modules.utils import _single, _pair, _triple -from torch.distributions import categorical - -torch.ops.load_library("/home/philippe/development/triton/build/examples/python/pytorch/libtorch_triton.so") - -################################# -####### Convolutions ########## -################################# - -class ConvFunction(torch.autograd.Function): - - @staticmethod - def forward(ctx, input, weight, bias, stride, padding): - if bias is None: - bias = torch.empty(0) - ctx.save_for_backward(input, weight, bias) - ctx.stride = stride - ctx.padding = padding - output = torch.ops.triton.conv_fprop(input, weight, bias, stride[0], stride[1], padding[0], padding[1]) - return output - - @staticmethod - def backward(ctx, grad_output): - input, weight, bias = ctx.saved_tensors - stride = ctx.stride - padding = ctx.padding - grad_input = grad_weight = grad_bias = None - if ctx.needs_input_grad[0]: - grad_input = torch.ops.triton.conv_bprop(grad_output, weight, bias, input.shape[2], input.shape[3], stride[0], stride[1], padding[0], padding[1]) - if ctx.needs_input_grad[1]: - grad_weight = torch.ops.triton.conv_wgrad(input, grad_output, bias, weight.shape[1], weight.shape[2], stride[0], stride[1], padding[0], padding[1]) - if ctx.needs_input_grad[2]: - grad_bias = torch.sum(grad_output, (0, 2, 3)) - return grad_input, grad_weight, grad_bias, None, None - - -class _ConvNd(torch.nn.Module): - - def __init__(self, in_channels, out_channels, kernel_size, stride, - padding, dilation, transposed, output_padding, groups, bias): - super(_ConvNd, self).__init__() - # not everything is supported by Triton - assert all(x==1 or x==2 for x in stride) - assert all(x==1 for x in dilation) - assert transposed == False - assert all(x==0 for x in output_padding) - assert groups == 1 - # initialize - self.in_channels = in_channels - self.out_channels = out_channels - self.kernel_size = kernel_size - self.stride = stride - self.padding = padding - self.weight = torch.nn.Parameter(torch.Tensor( - in_channels, kernel_size[0], kernel_size[1], out_channels)) - if bias: - self.bias = torch.nn.Parameter(torch.Tensor(out_channels)) - else: - self.register_parameter('bias', None) - self.reset_parameters() - - def forward(self, input): - return ConvFunction.apply(input, self.weight, self.bias, self.stride, self.padding) - - def reset_parameters(self): - n = self.in_channels - for k in self.kernel_size: - n *= k - stdv = 1. / math.sqrt(n) - self.weight.data.uniform_(-stdv, stdv) - if self.bias is not None: - self.bias.data.uniform_(-stdv, stdv) - - - -class Conv2d(_ConvNd): - - def __init__(self, in_channels, out_channels, kernel_size, stride=1, - padding=0, dilation=1, groups=1, bias=True): - kernel_size = _pair(kernel_size) - stride = _pair(stride) - padding = _pair(padding) - dilation = _pair(dilation) - super(Conv2d, self).__init__( - in_channels, out_channels, kernel_size, stride, padding, dilation, - False, _pair(0), groups, bias) - -################################# -#### Shift-Convolutions ####### -################################# - -class ShiftConvFunction(torch.autograd.Function): - - @staticmethod - def forward(ctx, input, weight, bias, stride, width, shift_h, shift_w): - if bias is None: - bias = torch.empty(0) - ctx.save_for_backward(input, weight, bias) - ctx.stride = stride - ctx.width = width - ctx.shift_h = shift_h - ctx.shift_w = shift_w - output = torch.ops.triton.shift_conv_y(input, weight, bias, - width[0], width[1], - stride[0], stride[1], - shift_h, shift_w) - return output - - @staticmethod - def backward(ctx, dy): - input, weight, bias = ctx.saved_tensors - stride = ctx.stride - width = ctx.width - shift_h = ctx.shift_h - shift_w = ctx.shift_w - dx = dw = dbias = None - if ctx.needs_input_grad[0]: - dx = torch.ops.triton.shift_conv_dx(dy.contiguous(), weight, bias, width[0], width[1], stride[0], stride[1], shift_h, shift_w) - if ctx.needs_input_grad[1]: - dw = torch.ops.triton.shift_conv_dw(dy.contiguous(), input, bias, width[0], width[1], stride[0], stride[1], shift_h, shift_w) - if ctx.needs_input_grad[2]: - dbias = torch.sum(dy, (1, 2, 3)) - return dx, dw, dbias, None, None, None, None - - -class _ShiftConvNd(torch.nn.Module): - - def __init__(self, in_channels, out_channels, kernel_size, stride, bias): - super(_ShiftConvNd, self).__init__() - # initialize - self.in_channels = in_channels - self.out_channels = out_channels - self.kernel_size = kernel_size - self.stride = stride - self.weight = torch.nn.Parameter(torch.Tensor(in_channels, out_channels)) - if bias: - self.bias = torch.nn.Parameter(torch.Tensor(out_channels)) - else: - self.register_parameter('bias', None) - self.shift_h = self.make_shift(kernel_size[0]) - self.shift_w = self.make_shift(kernel_size[1]) - self.reset_parameters() - - def forward(self, input): - return ShiftConvFunction.apply(input, self.weight, self.bias, self.stride, - self.kernel_size, self.shift_h, self.shift_w) - - def make_shift(self, kernel_size): - if kernel_size == 3: - p = torch.Tensor([0.3, 0.4, 0.3]) - elif kernel_size == 5: - p = torch.Tensor([0.1, 0.25, 0.3, 0.25, 0.1]) - elif kernel_size == 7: - p = torch.Tensor([0.075, 0.1, 0.175, 0.3, 0.175, 0.1, 0.075]) - elif kernel_size == 9: - p = torch.Tensor([0.05, 0.075, 0.1, 0.175, 0.2, 0.175, 0.1, 0.075, 0.05]) - else: - raise RuntimeError('Unsupported kernel size') - return categorical.Categorical(p).sample((self.in_channels,)) - (kernel_size // 2) - - def reset_parameters(self): - n = self.in_channels - for k in self.kernel_size: - n *= k - stdv = 1. / math.sqrt(n) - self.weight.data.uniform_(-stdv, stdv) - if self.bias is not None: - self.bias.data.uniform_(-stdv, stdv) - -class ShiftConv2d(_ShiftConvNd): - - def __init__(self, in_channels, out_channels, kernel_size, stride=1, bias=False): - kernel_size = _pair(kernel_size) - stride = _pair(stride) - super(ShiftConv2d, self).__init__( - in_channels, out_channels, kernel_size, stride, bias) - -################################# -######### BatchNorm ########### -################################# - -class BatchNormFunction(torch.autograd.Function): - - @staticmethod - def forward(ctx, x, gamma, beta, eps): - ctx.eps = eps - y, mean, var = torch.ops.triton.batchnorm_ymv(x, gamma, beta, eps) - ctx.save_for_backward(x, gamma, beta, mean, var) - return y - - @staticmethod - def backward(ctx, dy): - eps = ctx.eps - x, gamma, beta, mean, var = ctx.saved_tensors - dx, dg, db = torch.ops.triton.batchnorm_dxdgdb(dy.contiguous(), x, gamma, mean, var, eps) - return dx, dg, db, None - - -class _BatchNorm(torch.nn.Module): - - def __init__(self, num_features, eps=1e-5): - super(_BatchNorm, self).__init__() - self.num_features = num_features - self.eps = eps - self.weight = torch.nn.Parameter(torch.Tensor(num_features)) - self.bias = torch.nn.Parameter(torch.Tensor(num_features)) - self.reset_parameters() - - def reset_parameters(self): - torch.nn.init.uniform_(self.weight) - torch.nn.init.zeros_(self.bias) - - def forward(self, input): - return BatchNormFunction.apply(input, self.weight, self.bias, self.eps) - -class BatchNorm2d(_BatchNorm): - - pass diff --git a/examples/python/tensorflow/CMakeLists.txt b/examples/python/tensorflow/CMakeLists.txt deleted file mode 100644 index 0dad37f19..000000000 --- a/examples/python/tensorflow/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -find_package(TensorFlow) -if(${TensorFlow_FOUND}) - set(CUDA_HOME "/usr/local/cuda") - include_directories("${TF_INC}/tensorflow/include") - include_directories("${CUDA_HOME}/include") - link_directories(${TF_LIB}) - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=${TF_ABI}) - add_library(tf_blocksparse SHARED blocksparse.cpp dot.cpp conv.cpp shift.cpp batchnorm.cpp) - target_link_libraries(tf_blocksparse tensorflow_framework triton) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run.py - ${CMAKE_CURRENT_BINARY_DIR}/run.py - COPYONLY) -endif() diff --git a/examples/python/tensorflow/batchnorm.cpp b/examples/python/tensorflow/batchnorm.cpp deleted file mode 100644 index 956ecef24..000000000 --- a/examples/python/tensorflow/batchnorm.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include - -#include "triton/driver/buffer.h" -#include "triton/driver/backend.h" -#include "triton/driver/stream.h" -#include "triton/runtime/jit.h" -#include "triton/tools/bench.hpp" -#include "triton/dnn/batchnorm.h" - -#define EIGEN_USE_GPU -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/util/cuda_kernel_helper.h" -#include "tensorflow/core/util/padding.h" -#include "tensorflow/core/util/tensor_format.h" -#include "tensorflow/core/framework/common_shape_fns.h" - -using namespace tensorflow; -using shape_inference::DimensionHandle; -using shape_inference::InferenceContext; -using shape_inference::ShapeHandle; -using GPUDevice = Eigen::GpuDevice; - -class BatchnormForwardOp : public OpKernel { -public: - explicit BatchnormForwardOp(OpKernelConstruction* context): OpKernel(context) { - context->GetAttr("eps", &eps_); - } - - void Compute(OpKernelContext* context){ - // get device/stream - GPUDevice device = context->eigen_device(); - triton::driver::cu_stream sstream(device.stream(), false); - triton::driver::context* ctx = sstream.context(); - triton::driver::stream* stream = &sstream; - // get inputs - const Tensor& fw_x = context->input(0); - const Tensor& fw_g = context->input(1); - const Tensor& fw_b = context->input(2); - // get sizes - int C = fw_x.dim_size(0); - int H = fw_x.dim_size(1); - int W = fw_x.dim_size(2); - int B = fw_x.dim_size(3); - // allocate outputs - Tensor* fw_y = nullptr; - Tensor* fw_m = nullptr; - Tensor* fw_v = nullptr; - OP_REQUIRES_OK(context, context->allocate_output(0, fw_x.shape(), &fw_y)); - OP_REQUIRES_OK(context, context->allocate_output(1, fw_g.shape(), &fw_m)); - OP_REQUIRES_OK(context, context->allocate_output(2, fw_g.shape(), &fw_v)); - // triton handles - triton::driver::cu_buffer x(ctx, fw_x.tensor_data().size(), (CUdeviceptr)fw_x.tensor_data().data(), false); - triton::driver::cu_buffer g(ctx, fw_g.tensor_data().size(), (CUdeviceptr)fw_g.tensor_data().data(), false); - triton::driver::cu_buffer b(ctx, fw_b.tensor_data().size(), (CUdeviceptr)fw_b.tensor_data().data(), false); - triton::driver::cu_buffer y(ctx, fw_y->tensor_data().size(), (CUdeviceptr)fw_y->tensor_data().data(), false); - triton::driver::cu_buffer m(ctx, fw_m->tensor_data().size(), (CUdeviceptr)fw_m->tensor_data().data(), false); - triton::driver::cu_buffer v(ctx, fw_v->tensor_data().size(), (CUdeviceptr)fw_v->tensor_data().data(), false); - // create config - triton::dnn::batchnorm_forward batchnorm(C, 1, H, W, B, "float", triton::dnn::FULL_TUNING); - batchnorm.enqueue(stream, {&y, &m, &v, &x, &g, &b}); - } - -private: - float eps_; -}; - - -REGISTER_KERNEL_BUILDER(Name("BatchnormForward").Device(DEVICE_GPU), BatchnormForwardOp); -REGISTER_OP("BatchnormForward") - .Input("x: T") - .Input("g: float") - .Input("b: float") - .Output("y: T") - .Output("m: float") - .Output("v: float") - .Attr("T: {float}") - .Attr("eps: float") - .SetShapeFn([](InferenceContext* ctx) { - ctx->set_output(0, ctx->input(0)); - ctx->set_output(1, ctx->input(1)); - ctx->set_output(2, ctx->input(1)); - return Status::OK(); - }) -; - - -class BatchnormBackwardOp : public OpKernel { -public: - explicit BatchnormBackwardOp(OpKernelConstruction* context): OpKernel(context) { - context->GetAttr("eps", &eps_); - } - - void Compute(OpKernelContext* context){ - // get device/stream - GPUDevice device = context->eigen_device(); - triton::driver::cu_stream sstream(device.stream(), false); - triton::driver::context* ctx = sstream.context(); - triton::driver::stream* stream = &sstream; - // get inputs - const Tensor& fw_dy = context->input(0); - const Tensor& fw_x = context->input(1); - const Tensor& fw_g = context->input(2); - const Tensor& fw_m = context->input(3); - const Tensor& fw_v = context->input(4); - // get sizes - int C = fw_x.dim_size(0); - int H = fw_x.dim_size(1); - int W = fw_x.dim_size(2); - int B = fw_x.dim_size(3); - // allocate outputs - Tensor* fw_dx = nullptr; - Tensor* fw_dg = nullptr; - Tensor* fw_db = nullptr; - OP_REQUIRES_OK(context, context->allocate_output(0, fw_x.shape(), &fw_dx)); - OP_REQUIRES_OK(context, context->allocate_output(1, fw_g.shape(), &fw_dg)); - OP_REQUIRES_OK(context, context->allocate_output(2, fw_g.shape(), &fw_db)); - // triton handles - triton::driver::cu_buffer dy(ctx, fw_dy.tensor_data().size(), (CUdeviceptr)fw_dy.tensor_data().data(), false); - triton::driver::cu_buffer x(ctx, fw_x.tensor_data().size(), (CUdeviceptr)fw_x.tensor_data().data(), false); - triton::driver::cu_buffer g(ctx, fw_g.tensor_data().size(), (CUdeviceptr)fw_g.tensor_data().data(), false); - triton::driver::cu_buffer m(ctx, fw_m.tensor_data().size(), (CUdeviceptr)fw_m.tensor_data().data(), false); - triton::driver::cu_buffer v(ctx, fw_v.tensor_data().size(), (CUdeviceptr)fw_v.tensor_data().data(), false); - triton::driver::cu_buffer dx(ctx, fw_dx->tensor_data().size(), (CUdeviceptr)fw_dx->tensor_data().data(), false); - triton::driver::cu_buffer dg(ctx, fw_dg->tensor_data().size(), (CUdeviceptr)fw_dg->tensor_data().data(), false); - triton::driver::cu_buffer db(ctx, fw_db->tensor_data().size(), (CUdeviceptr)fw_db->tensor_data().data(), false); - // create config - triton::dnn::batchnorm_backward batchnorm(C, 1, H, W, B, "float", triton::dnn::FULL_TUNING); - batchnorm.enqueue(stream, {&dx, &dg, &db, &dy, &x, &g, &m, &v}); - } - -private: - float eps_; -}; - - -REGISTER_KERNEL_BUILDER(Name("BatchnormBackward").Device(DEVICE_GPU), BatchnormBackwardOp); -REGISTER_OP("BatchnormBackward") - .Input("dy: TY") - .Input("x: TX") - .Input("g: float") - .Input("m: float") - .Input("v: float") - .Output("dx: TY") - .Output("dg: float") - .Output("db: float") - .Attr("TX: {float}") - .Attr("TY: {float}") - .Attr("eps: float") - .SetShapeFn([](InferenceContext* ctx) { - ctx->set_output(0, ctx->input(1)); - ctx->set_output(1, ctx->input(2)); - ctx->set_output(2, ctx->input(2)); - return Status::OK(); - }) -; diff --git a/examples/python/tensorflow/blocksparse.cpp b/examples/python/tensorflow/blocksparse.cpp deleted file mode 100644 index 1ff5e9f6f..000000000 --- a/examples/python/tensorflow/blocksparse.cpp +++ /dev/null @@ -1,304 +0,0 @@ -#include - -#include "triton/driver/buffer.h" -#include "triton/driver/backend.h" -#include "triton/driver/stream.h" -#include "triton/runtime/jit.h" -#include "triton/dnn/blocksparse/dot.h" - -#define EIGEN_USE_GPU -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/util/cuda_kernel_helper.h" -#include "tensorflow/core/util/padding.h" -#include "tensorflow/core/util/tensor_format.h" -#include "tensorflow/core/framework/common_shape_fns.h" -#include "tensorflow/core/framework/allocation_description.pb.h" - -using namespace tensorflow; -using shape_inference::DimensionHandle; -using shape_inference::InferenceContext; -using shape_inference::ShapeHandle; -using GPUDevice = Eigen::GpuDevice; - - -Status XpropShape(InferenceContext* ctx) -{ - int K; TF_RETURN_IF_ERROR(ctx->GetAttr( "K", &K)); - int axis; TF_RETURN_IF_ERROR(ctx->GetAttr("axis", &axis)); - - // C ==> K - ShapeHandle x = ctx->input(0); - int rank = ctx->Rank(x); - //printf("XpropShape: %d\n", rank); - if (rank > 0) - { - std::vector shape; - shape.reserve(rank); - for (int i = 0; i < rank; i++) - shape.push_back(i == axis ? ctx->MakeDim(K) : ctx->Dim(x, i)); - ctx->set_output(0, ctx->MakeShape(shape)); - } - else - ctx->set_output(0, ctx->UnknownShape()); - ctx->set_output(1, ctx->UnknownShape()); - return Status::OK(); -} - -Status UpdatShape(InferenceContext* ctx) -{ - //printf("UpdatShape: %d\n", ctx->Rank(ctx->input(0))); - - int blocks, bsize; - TF_RETURN_IF_ERROR(ctx->GetAttr("blocks", &blocks)); - TF_RETURN_IF_ERROR(ctx->GetAttr("bsize", &bsize)); - - // (blocks, block_size, block_size) - DimensionHandle bsize_dim = ctx->MakeDim(bsize); - ctx->set_output(0, ctx->MakeShape({ ctx->MakeDim(blocks), bsize_dim, bsize_dim })); - return Status::OK(); -} - -typedef struct bsmm_params -{ - const int* Lut; - const float* Gate; - int* Lock; - int blocks; - int bsize; - int segments; - int locks; - int C; - int K; - int N; - int shared; - int pcount; - uint blk_a; - uint blk_A; - uint blk_b; - uint blk_B; - float alpha; - float beta; - CUstream stream; -} bsmm_params; - -template -class BlocksparseMatmulOp : public OpKernel { -private: - void ComputeDw(OpKernelContext* context){ - // get device/stream - GPUDevice device = context->eigen_device(); - triton::driver::cu_stream sstream(device.stream(), false); - triton::driver::context* ctx = sstream.context(); - triton::driver::stream* stream = &sstream; - // extract input - OpInputList x, dy, gate; - context->input_list( "x", &x); - context->input_list( "dy", &dy); - context->input_list("gate", &gate); - // sanity checks - params_.pcount = x.size(); - if (params_.pcount > 1) - errors::Internal("No more than 1 input allowed."); - if (params_.beta != 0.0f || params_.alpha != 1.0f) - errors::Internal("Not supported yet"); - // N - int N = 1; - int rank = x[0].dims(); - for (int i = 0; i < rank; i++) - if (i != axis_) - N *= x[0].dim_size(i); - // allocate output - Tensor* C; - TensorShape shapeC({ params_.blocks, params_.bsize, params_.bsize }); - OP_REQUIRES_OK(context, context->allocate_output(0, shapeC, &C)); - // wrap tensorflow handles - triton::driver::cu_buffer da(ctx, x[0].tensor_data().size(), (CUdeviceptr)x[0].tensor_data().data(), false); - triton::driver::cu_buffer db(ctx, dy[0].tensor_data().size(), (CUdeviceptr)dy[0].tensor_data().data(), false); - triton::driver::cu_buffer dc(ctx, C->tensor_data().size(), (CUdeviceptr)C->tensor_data().data(), false); - triton::driver::cu_buffer dlut(ctx, context->input(params_.pcount*2).tensor_data().size(), (CUdeviceptr)context->input(params_.pcount*2).tensor_data().data(), false); - // create profile - triton::dnn::blocksparse::dot dot(N, params_.K, params_.segments, params_.C, "half", params_.bsize, params_.locks, params_.blocks, OP); - // enqueue - dot.enqueue(stream, {&da, &db, &dc, &dlut}, triton::dnn::FULL_TUNING); - } - - void ComputeYDx(OpKernelContext* context){ - // get device/stream - GPUDevice device = context->eigen_device(); - triton::driver::cu_stream sstream(device.stream(), false); - triton::driver::context* ctx = sstream.context(); - triton::driver::stream* stream = &sstream; - // get inputs - const Tensor& a = context->input(0); - const Tensor& b = context->input(1); - const Tensor& lut = context->input(2); - // allocate c - TensorShape shape_c; - int N = 1; - int rank_a = a.dims(); - for (int i = 0; i < rank_a; i++) - if (i != axis_) { - shape_c.AddDim(a.dim_size(i)); - N *= a.dim_size(i); - } - else - shape_c.AddDim(params_.K); - Tensor* c = nullptr; - OP_REQUIRES_OK(context, context->allocate_output(0, shape_c, &c)); - // wrap tensorflow handles - triton::driver::cu_buffer da(ctx, a.tensor_data().size(), (CUdeviceptr)a.tensor_data().data(), false); - triton::driver::cu_buffer db(ctx, b.tensor_data().size(), (CUdeviceptr)b.tensor_data().data(), false); - triton::driver::cu_buffer dc(ctx, c->tensor_data().size(), (CUdeviceptr)c->tensor_data().data(), false); - triton::driver::cu_buffer dlut(ctx, lut.tensor_data().size(), (CUdeviceptr)lut.tensor_data().data(), false); - // create profile - triton::dnn::blocksparse::dot dot(N, params_.K, params_.segments, params_.C, "half", params_.bsize, params_.locks, params_.blocks, OP); - // enqueue - triton::dnn::base* op = dot.enqueue(stream, {&da, &db, &dc, &dlut}, triton::dnn::NO_TUNING); - triton::driver::buffer* locks_buffer = ((triton::dnn::blocksparse::dot*)op)->get_locks(); - Tensor *tmp = nullptr; - TensorShape tmp_shapes; - tmp_shapes.AddDim(locks_buffer->size() / 4); - OP_REQUIRES_OK(context, context->allocate_output(1, tmp_shapes, &tmp)); - } - -public: - - explicit BlocksparseMatmulOp(OpKernelConstruction* ctx) : OpKernel(ctx) { - OP_REQUIRES_OK(ctx, ctx->GetAttr("segments", ¶ms_.segments)); - OP_REQUIRES_OK(ctx, ctx->GetAttr("locks", ¶ms_.locks )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("blocks", ¶ms_.blocks )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("bsize", ¶ms_.bsize )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("C", ¶ms_.C )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("K", ¶ms_.K )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("shared", ¶ms_.shared )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("alpha", ¶ms_.alpha )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("beta", ¶ms_.beta )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("gated_dw", &gated_dw_ )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("axis", &axis_ )); - OP_REQUIRES_OK(ctx, ctx->GetAttr("bench", &bench_)); - OP_REQUIRES(ctx, params_.K < params_.bsize*65536, errors::InvalidArgument("K < bsize*65536")); - OP_REQUIRES(ctx, params_.C < params_.bsize*65536, errors::InvalidArgument("C < bsize*65536")); - params_.pcount = 1; - params_.blk_A = 0; - is_gpu_ = ctx->device_type() == DEVICE_GPU; - if (bench_) { - repeat_ = bench_; - flops_ = (float)(params_.blocks * params_.bsize*params_.bsize); - const char* op = "FPROP"; - sprintf(bench_string_, "%s %02d-%d C:%05d K:%05d blks:%d", op, params_.bsize, axis_, params_.C, params_.K, params_.blocks); - } - } - - void Compute(OpKernelContext* context) override{ - if(OP == triton::dnn::blocksparse::WGRAD) - ComputeDw(context); - else - ComputeYDx(context); - } - -private: - bsmm_params params_; - int axis_, bench_, repeat_, SMs_, major_, grid_n_; - float flops_; - bool gated_dw_, is_gpu_; - char bench_string_[256]; -}; - -REGISTER_OP("TritonBlocksparseMatmul") -.Input("x: T") -.Input("w: T") -.Input("lut: int64") -.Input("lut_dx: int64") -.Input("lut_dw: int64") -.Input("gate: ngate * float") -.Output("y: T") -.Output("temp: int32") -.Attr("T: {half, float, bfloat16}") -.Attr("blocks: int >=0") -.Attr("bsize: int") -.Attr("segments: int = 0") -.Attr("segments_dx: int = 0") -.Attr("locks: int = 0") -.Attr("locks_dx: int = 0") -.Attr("axis: int = 1") -.Attr("C: int >=0") -.Attr("K: int >=0") -.Attr("shared: int = 0") -.Attr("shared_dx: int = 0") -.Attr("alpha: float = 1.0") -.Attr("beta: float = 0.0") -.Attr("gated_dw: bool = false") -.Attr("gate_grad: bool = false") -.Attr("bench: int = 0") -.Attr("ngate: int >= 0") -.SetShapeFn(XpropShape) -.Doc(R"doc( - Multiply the matrix "a" by the blocksparse matrix "b". - )doc"); - -REGISTER_KERNEL_BUILDER(Name("TritonBlocksparseMatmul").Device(DEVICE_GPU).TypeConstraint("T"), BlocksparseMatmulOp); -REGISTER_KERNEL_BUILDER(Name("TritonBlocksparseMatmul").Device(DEVICE_GPU).TypeConstraint("T"), BlocksparseMatmulOp); - - -REGISTER_OP("TritonBlocksparseMatmulDX") - .Input("dy: T") - .Input("w: T") - .Input("lut: int64") - .Input("gate: ngate * float") - .Output("dx: T") - .Output("temp: int32") - .Attr("T: {half, float, bfloat16}") - .Attr("blocks: int >=0") - .Attr("bsize: int") - .Attr("segments: int = 0") - .Attr("locks: int = 0") - .Attr("axis: int = 1") - .Attr("C: int >=0") - .Attr("K: int >=0") - .Attr("shared: int = 0") - .Attr("alpha: float = 1.0") - .Attr("beta: float = 0.0") - .Attr("gated_dw: bool = false") - .Attr("gate_grad: bool = false") - .Attr("bench: int = 0") - .Attr("ngate: int >= 0") - .SetShapeFn(XpropShape) - .Doc(R"doc( -Multiply the matrix "a" by the blocksparse matrix "b". -)doc"); - -REGISTER_KERNEL_BUILDER(Name("TritonBlocksparseMatmulDX").Device(DEVICE_GPU).TypeConstraint("T"),BlocksparseMatmulOp); -REGISTER_KERNEL_BUILDER(Name("TritonBlocksparseMatmulDX").Device(DEVICE_GPU).TypeConstraint("T"),BlocksparseMatmulOp); - - -REGISTER_OP("TritonBlocksparseMatmulDW") - .Input("x: params * T") - .Input("dy: params * T") - .Input("lut: int64") - .Input("gate: ngate * float") - .Output("dw: T") - .Attr("T: {half, float, bfloat16}") - .Attr("params: int") - .Attr("blocks: int >=0") - .Attr("bsize: int") - .Attr("segments: int = 0") - .Attr("locks: int = 0") - .Attr("axis: int = 1") - .Attr("C: int >=0") - .Attr("K: int >=0") - .Attr("shared: int = 0") - .Attr("alpha: float = 1.0") - .Attr("beta: float = 0.0") - .Attr("gated_dw: bool = false") - .Attr("gate_grad: bool = false") - .Attr("bench: int = 0") - .Attr("ngate: int >= 0") - .SetShapeFn(UpdatShape) - .Doc(R"doc( -Multiply the matrix "a" by the blocksparse matrix "b". -)doc"); - -REGISTER_KERNEL_BUILDER(Name("TritonBlocksparseMatmulDW").Device(DEVICE_GPU).TypeConstraint("T"),BlocksparseMatmulOp); -REGISTER_KERNEL_BUILDER(Name("TritonBlocksparseMatmulDW").Device(DEVICE_GPU).TypeConstraint("T"),BlocksparseMatmulOp); diff --git a/examples/python/tensorflow/conv.cpp b/examples/python/tensorflow/conv.cpp deleted file mode 100644 index 00bf05473..000000000 --- a/examples/python/tensorflow/conv.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include - -#include "triton/driver/buffer.h" -#include "triton/driver/backend.h" -#include "triton/driver/stream.h" -#include "triton/runtime/jit.h" -#include "triton/tools/bench.hpp" -#include "triton/dnn/conv.h" - -#define EIGEN_USE_GPU -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/util/cuda_kernel_helper.h" -#include "tensorflow/core/util/padding.h" -#include "tensorflow/core/util/tensor_format.h" -#include "tensorflow/core/framework/common_shape_fns.h" - -using namespace tensorflow; -using GPUDevice = Eigen::GpuDevice; - -class Conv2dOp : public OpKernel { -public: - explicit Conv2dOp(OpKernelConstruction* context) : OpKernel(context) { - } - - void Compute(OpKernelContext* context){ - // get device/stream - GPUDevice device = context->eigen_device(); - triton::driver::cu_stream sstream(device.stream(), false); - triton::driver::context* ctx = sstream.context(); - triton::driver::stream* stream = &sstream; - // get inputs - const Tensor& tfa = context->input(0); - const Tensor& tfb = context->input(1); - // get shapes - int32_t B = tfa.dim_size(0); - int32_t Ca = tfa.dim_size(1); - int32_t D = 1; - int32_t H = tfa.dim_size(2); - int32_t W = tfa.dim_size(3); - int32_t Cb = tfb.dim_size(0); - int32_t T = 1; - int32_t R = tfb.dim_size(1); - int32_t S = tfb.dim_size(2); - int32_t NF = tfb.dim_size(3); - assert(Ca == Cb); - int32_t C = Ca; - int32_t stride_d = 1, stride_h = 1, stride_w = 1; - int32_t pad_d = 0, pad_h = 0, pad_w = 0; - bool has_bias = false; - // wrap buffers - triton::driver::cu_buffer a(ctx, tfa.tensor_data().size(), (CUdeviceptr)tfa.tensor_data().data(), false); - triton::driver::cu_buffer b(ctx, tfb.tensor_data().size(), (CUdeviceptr)tfb.tensor_data().data(), false); - triton::driver::buffer* bias = nullptr; - // template - triton::dnn::conv conv(B, C, - D, H, W, - T, R, S, - NF, - stride_d, stride_h, stride_w, - pad_d, pad_h, pad_w, - 1, 1, 1, - "half", "half", - triton::dnn::conv::FPROP, has_bias); - // allocate output - auto c_shapes = conv.c_shapes(); - Tensor* tfc = nullptr; - TensorShape out_shape({c_shapes[0], c_shapes[1], c_shapes[2], c_shapes[3]}); - OP_REQUIRES_OK(context, context->allocate_output(0, out_shape, &tfc)); - triton::driver::cu_buffer c(ctx, tfc->tensor_data().size(), (CUdeviceptr)tfc->tensor_data().data(), false); - // enqueue - conv.enqueue(stream, {&a, &b, &c, bias}); - } -}; - -REGISTER_KERNEL_BUILDER(Name("Conv2d").Device(DEVICE_GPU), Conv2dOp); -REGISTER_OP("Conv2d") - .Input("a: float16") - .Input("b: float16") - .Output("c: float32") -; diff --git a/examples/python/tensorflow/dot.cpp b/examples/python/tensorflow/dot.cpp deleted file mode 100644 index 453bb87cb..000000000 --- a/examples/python/tensorflow/dot.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include - -#include "triton/driver/buffer.h" -#include "triton/driver/backend.h" -#include "triton/driver/stream.h" -#include "triton/runtime/jit.h" -#include "triton/tools/bench.hpp" -#include "triton/dnn/dot.h" - -#define EIGEN_USE_GPU -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/util/cuda_kernel_helper.h" -#include "tensorflow/core/util/padding.h" -#include "tensorflow/core/util/tensor_format.h" -#include "tensorflow/core/framework/common_shape_fns.h" - -using namespace tensorflow; -using GPUDevice = Eigen::GpuDevice; - -class DotOp : public OpKernel { - public: - explicit DotOp(OpKernelConstruction* context) : OpKernel(context) { - } - - void Compute(OpKernelContext* context){ - // get device/stream - GPUDevice device = context->eigen_device(); - triton::driver::cu_stream sstream(device.stream(), false); - triton::driver::context* ctx = sstream.context(); - triton::driver::stream* stream = &sstream; - // get inputs - const Tensor& a = context->input(0); - const Tensor& b = context->input(1); - // get shapes - const int32_t M = a.dim_size(0); - const int32_t N = b.dim_size(0); - const int32_t K = a.dim_size(1); - // allocate output - Tensor* c = nullptr; - TensorShape out_shape({(int64)M, (int64)N}); - OP_REQUIRES_OK(context, context->allocate_output(0, out_shape, &c)); - // return early if possible - if (out_shape.num_elements() == 0) - return; - // matrix multiplication parameters - triton::driver::cu_buffer da(ctx, a.tensor_data().size(), (CUdeviceptr)a.tensor_data().data(), false); - triton::driver::cu_buffer db(ctx, b.tensor_data().size(), (CUdeviceptr)b.tensor_data().data(), false); - triton::driver::cu_buffer dc(ctx, c->tensor_data().size(), (CUdeviceptr)c->tensor_data().data(), false); - // template - triton::dnn::dot dot(M, N, K, false, false, "half", "half", "float", 8, 8, 8); - dot.enqueue(stream, {&da, &db, &dc}, triton::dnn::autotuning_t::NO_TUNING); - } - -private: -}; - -REGISTER_KERNEL_BUILDER(Name("Dot").Device(DEVICE_GPU), DotOp); -REGISTER_OP("Dot") - .Input("a: float16") - .Input("b: float16") - .Output("c: float32") -; diff --git a/examples/python/tensorflow/run.py b/examples/python/tensorflow/run.py deleted file mode 100644 index ffdde3f76..000000000 --- a/examples/python/tensorflow/run.py +++ /dev/null @@ -1,136 +0,0 @@ -import os -import tensorflow as tf -from tensorflow.python.framework import ops -import numpy as np -from time import time - -data_files_path = tf.resource_loader.get_data_files_path() -library_dir = os.path.dirname(os.path.realpath(__file__)) -module = tf.load_op_library(os.path.join(library_dir, 'libtf_blocksparse.so')) - -def run_dot(): - M, N, K = 128, 128, 128 - a = tf.placeholder(tf.float16, shape=[M, K]) - b = tf.placeholder(tf.float16, shape=[N, K]) - # c = tf.matmul(a, b, transpose_a=True) - c = module.dot(a, b) - # Reference - ha = np.random.rand(M, K).astype(np.float16) - hb = np.random.rand(N, K).astype(np.float16) - # Run - sess = tf.InteractiveSession() - sess.run(tf.global_variables_initializer()) - result = sess.run([c], feed_dict = {a: ha, - b: hb})[0] - # Test - hresult = np.dot(ha.T, hb.T).T - dif = np.abs(result - hresult) - np.savetxt('dif.dat', dif, '%2.4f') - print(hresult) - print(result) - print("dif: %f" % np.max(dif)) - -def run_conv(): - B, C, H, W = 16, 32, 32, 32 - R, S, NF = 3, 3, 32 - a = tf.placeholder(tf.float32, shape=[B, C, H, W]) - b = tf.placeholder(tf.float32, shape=[C, R, S, NF]) - c = module.conv2d(a, b) - # Reference - ha = np.random.rand(B, C, H, W) - hb = np.random.rand(C, R, S, NF) - # Run - sess = tf.InteractiveSession() - sess.run(tf.global_variables_initializer()) - result = sess.run([c], feed_dict = {a: ha, - b: hb})[0] - - -@ops.RegisterGradient('ShiftConv') -def blocksparse_matmul_grad(op, dy): - shift_h = op.get_attr('shift_h') - shift_w = op.get_attr('shift_w') - stride_h = op.get_attr('stride_h') - stride_w = op.get_attr('stride_w') - x = op.inputs[0] - w = op.inputs[1] - dx = module.shift_conv_dx(dy, w, stride_h=stride_h, stride_w=stride_w, shift_h=shift_h, shift_w=shift_w) - dw = module.shift_conv_dw(dy, x, stride_h=stride_h, stride_w=stride_w, shift_h=shift_h, shift_w=shift_w) - return (dx, dw) - -def run_shift(): - B, C, H, W = 2, 16, 4, 4 - R, S, F = 3, 3, 16 - stride_h, stride_w = 1, 1 - np.random.seed(2) - a = tf.placeholder(tf.float16, shape=[B, C, H, W]) - b = tf.placeholder(tf.float16, shape=[C, F]) - hshift_h = np.random.randint(- (R//2), R//2 + 1, size=C, dtype=np.int32) - hshift_w = np.random.randint(- (S//2), R//2 + 1, size=C, dtype=np.int32) - c = module.shift_conv(a, b, stride_h=stride_h, stride_w=stride_w, shift_h=tf.make_tensor_proto(hshift_h), shift_w=tf.make_tensor_proto(hshift_w)) - # feed values - ha = np.random.rand(B, C, H, W)*0.1 - hb = np.random.rand(C, F)*0.1 - sess = tf.InteractiveSession() - # check gradients - grads = tf.test.compute_gradient([a, b], [(B, C, H, W), (C, F)], c, (B, F, H//stride_h, W//stride_w), - extra_feed_dict = {a: ha, b: hb}, delta=1e-2) - dw_t, dw_n = grads[1] - dx_t, dx_n = grads[0] - #import sys - #np.set_printoptions(threshold=sys.maxsize) - print(dw_t) - print(dw_n) - print(np.max(np.abs(dw_t - dw_n))) - print(np.max(np.abs(dx_t - dx_n))) - # Run - sess.run(tf.global_variables_initializer()) - result = sess.run([c], feed_dict = {a: ha, - b: hb})[0] - #print(result) - - -def batch_norm(x, g, b, epsilon=1e-6): - shape = x.shape - C = int(shape[1]) - assert g.get_shape().num_elements() == C - assert b.get_shape().num_elements() == C - return module.batchnorm_forward(x, g, b, eps=epsilon) - -@ops.RegisterGradient("BatchnormForward") -def batch_norm_grad(op, dy, mean, var): - eps = op.get_attr("eps") - return module.batchnorm_backward(dy, op.inputs[0], op.inputs[1], - op.outputs[1], op.outputs[2], eps=eps) - - -def run_batchnorm(): - C, H, W, B = 8, 4, 4, 32 - np.random.seed(0) - # Placeholders - x = tf.placeholder(tf.float32, shape=[C, H, W, B]) - g = tf.placeholder(tf.float32, shape=[C]) - b = tf.placeholder(tf.float32, shape=[C]) - # Feed values - hx = np.random.rand(C, H, W, B) - hg = np.random.rand(C) - hb = np.random.rand(C) - # batchnorm - y, m, v = module.batchnorm_forward(x, g, b, eps=1e-5) - loss = np.sum(y) - # Run - sess = tf.InteractiveSession() - sess.run(tf.global_variables_initializer()) - result = sess.run([y, m, v], feed_dict = {x: hx, g: hg, b: hb}) - grads = tf.test.compute_gradient([x, g, b], [(C, H, W, B), (C, ), (C, )], y, (C, H, W, B), - extra_feed_dict = {x: hx, g: hg, b: hb}) - dx_t, dx_n = grads[0] - dg_t, dg_n = grads[1] - db_t, db_n = grads[2] - print(np.max(np.abs(dx_t - dx_n))) - print(np.max(np.abs(dg_t - dg_n))) - print(np.max(np.abs(db_t - db_n))) - -run_dot() -#run_shift() -#run_batchnorm() diff --git a/examples/python/tensorflow/shift.cpp b/examples/python/tensorflow/shift.cpp deleted file mode 100644 index cb28ce281..000000000 --- a/examples/python/tensorflow/shift.cpp +++ /dev/null @@ -1,167 +0,0 @@ -#include - -#include "triton/driver/buffer.h" -#include "triton/driver/backend.h" -#include "triton/driver/stream.h" -#include "triton/runtime/jit.h" -#include "triton/tools/bench.hpp" -#include "triton/dnn/shift.h" - -#define EIGEN_USE_GPU -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/util/cuda_kernel_helper.h" -#include "tensorflow/core/util/padding.h" -#include "tensorflow/core/util/tensor_format.h" -#include "tensorflow/core/framework/common_shape_fns.h" - -using namespace tensorflow; -using GPUDevice = Eigen::GpuDevice; - -template -class ShiftConvOp : public OpKernel { -public: - explicit ShiftConvOp(OpKernelConstruction* context) : OpKernel(context), layout_(triton::dnn::NCHW) { - context->GetAttr("shift_h", &h_shift_h_); - context->GetAttr("shift_w", &h_shift_w_); - context->GetAttr("stride_h", &stride_h_); - context->GetAttr("stride_w", &stride_w_); - R_ = 3; - S_ = 3; - } - - void ExtractShapes(const Tensor &x, int64_t &C, int64_t &H, int64_t &W, int64_t &B) { - if(layout_ == triton::dnn::CHWN){ - C = x.dim_size(0); - H = x.dim_size(1); - W = x.dim_size(2); - B = x.dim_size(3); - } - else if(layout_ == triton::dnn::NCHW){ - B = x.dim_size(0); - C = x.dim_size(1); - H = x.dim_size(2); - W = x.dim_size(3); - } - else{ - throw std::runtime_error("unsupported layout"); - } - } - - void FillShapes(OpKernelContext* context, - int64_t &C, int64_t &H, int64_t &W, int64_t &B, int64_t &F, - const Tensor& tf_a, const Tensor& tf_b) { - if(OP == triton::dnn::WGRAD) { - int64_t Ha, Wa, Ba; - int64_t Hb, Wb, Bb; - ExtractShapes(tf_a, F, Ha, Wa, Ba); - ExtractShapes(tf_b, C, Hb, Wb, Bb); - OP_REQUIRES(context, Ha*stride_h_ == Hb, tensorflow::errors::InvalidArgument("operands must have the same image height")); - OP_REQUIRES(context, Wa*stride_w_ == Wb, tensorflow::errors::InvalidArgument("operands must have the same image width")); - OP_REQUIRES(context, Ba == Bb, tensorflow::errors::InvalidArgument("operands must have the same batch size")); - H = Hb; - W = Wb; - B = Bb; - } - else { - // shapes for a - int64_t Ca; - ExtractShapes(tf_a, Ca, H, W, B); - if(OP == triton::dnn::BPROP){ - H *= stride_h_; - W *= stride_w_; - } - // shapes for b - int64_t Cb = tf_b.dim_size(0); - F = tf_b.dim_size(1); - if(OP == triton::dnn::BPROP) - std::swap(Cb, F); - // checks - OP_REQUIRES(context, Ca == Cb, tensorflow::errors::InvalidArgument("operands must have the same number of channels")); - C = Ca; - if(OP == triton::dnn::BPROP) - std::swap(C, F); - } - } - - void Compute(OpKernelContext* context){ - // get device/stream - GPUDevice device = context->eigen_device(); - triton::driver::cu_stream sstream(device.stream(), false); - triton::driver::context* ctx = sstream.context(); - triton::driver::stream* stream = &sstream; - // get inputs - const Tensor& tf_a = context->input(0); - const Tensor& tf_b = context->input(1); - // shapes - int64_t C, H, W, B, F; - FillShapes(context, C, H, W, B, F, tf_a, tf_b); - int64_t D = 1, T = 1; - bool has_bias = false; - // shift offsets - int32_t* shift_h_data = h_shift_h_.flat().data(); - int32_t* shift_w_data = h_shift_w_.flat().data(); - // create configuration - triton::dnn::shift shift(B, C, D, H, W, T, R_, S_, F, - stride_h_, stride_w_, - shift_h_data, shift_w_data, - "half", "half", OP, has_bias, layout_); - - // shapes for c - std::vector c_shapes; - for(int32_t x: shift.c_shapes()) - c_shapes.push_back(x); - TensorShape out_shapes(c_shapes); - Tensor* tf_c = nullptr; - OP_REQUIRES_OK(context, context->allocate_output(0, out_shapes, &tf_c)); - // return early if possible - if (out_shapes.num_elements() == 0) - return; - // matrix multiplication parameters - triton::driver::cu_buffer da(ctx, tf_a.tensor_data().size(), (CUdeviceptr)tf_a.tensor_data().data(), false); - triton::driver::cu_buffer db(ctx, tf_b.tensor_data().size(), (CUdeviceptr)tf_b.tensor_data().data(), false); - triton::driver::cu_buffer dc(ctx, tf_c->tensor_data().size(), (CUdeviceptr)tf_c->tensor_data().data(), false); - shift.enqueue(stream, {&da, &db, &dc}, triton::dnn::PARTIAL_TUNING); - } - -private: - Tensor h_shift_h_; - Tensor h_shift_w_; - int stride_h_; - int stride_w_; - int R_; - int S_; - triton::dnn::layout_t layout_; -}; - -REGISTER_KERNEL_BUILDER(Name("ShiftConv").Device(DEVICE_GPU), ShiftConvOp); -REGISTER_OP("ShiftConv") - .Input("a: float16") - .Input("b: float16") - .Attr("shift_h: tensor") - .Attr("shift_w: tensor") - .Attr("stride_h: int") - .Attr("stride_w: int") - .Output("c: float16"); - -REGISTER_KERNEL_BUILDER(Name("ShiftConvDx").Device(DEVICE_GPU), ShiftConvOp); -REGISTER_OP("ShiftConvDx") - .Input("a: float16") - .Input("b: float16") - .Attr("shift_h: tensor") - .Attr("shift_w: tensor") - .Attr("stride_h: int") - .Attr("stride_w: int") - .Output("c: float16"); - -REGISTER_KERNEL_BUILDER(Name("ShiftConvDw").Device(DEVICE_GPU), ShiftConvOp); -REGISTER_OP("ShiftConvDw") - .Input("a: float16") - .Input("b: float16") - .Attr("shift_h: tensor") - .Attr("shift_w: tensor") - .Attr("stride_h: int") - .Attr("stride_w: int") - .Output("c: float16"); - diff --git a/include/triton/runtime/arg.h b/include/triton/runtime/arg.h index 3f7131fbc..af55f4014 100644 --- a/include/triton/runtime/arg.h +++ b/include/triton/runtime/arg.h @@ -24,7 +24,7 @@ enum arg_type { BUFFER_T }; -size_t size_of(arg_type ty){ +inline size_t size_of(arg_type ty){ switch(ty){ case INT1_T: return 1; case INT8_T: return 1; @@ -39,7 +39,7 @@ size_t size_of(arg_type ty){ } } -bool is_int_type(arg_type ty){ +inline bool is_int_type(arg_type ty){ return ty == INT1_T || ty == INT8_T || ty == INT16_T || ty == INT32_T || ty == INT64_T; } diff --git a/lib/runtime/function.cpp b/lib/runtime/function.cpp index 24e66397b..034738c93 100644 --- a/lib/runtime/function.cpp +++ b/lib/runtime/function.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "triton/codegen/selection/selection.h" #include "triton/runtime/function.h" #include "triton/lang/lang.h" @@ -260,174 +261,5 @@ void function::operator()(const std::vector& args, const grid_t& grid, driv return this->operator()(args, [&grid](const params_t&){ return grid; }, stream); } -std::string to_tf_ty(ir::type *ty) { - if(ty->is_integer_ty(1)) - return "bool"; - if(ty->is_integer_ty(8)) - return "int8"; - if(ty->is_integer_ty(16)) - return "int16"; - if(ty->is_integer_ty(32)) - return "int32"; - if(ty->is_integer_ty(64)) - return "int64"; - if(ty->is_half_ty()) - return "float16"; - if(ty->is_float_ty()) - return "float32"; - if(ty->is_double_ty()) - return "float64"; - if(ty->is_pointer_ty()) - return "Tensor"; - throw std::runtime_error("unknown type"); -} - -std::string ref_to_tf_ty(ir::type *ty) { - std::string res = to_tf_ty(ty); - if(ty->is_pointer_ty()) - res = "const " + res + "&"; - return res; -} - - -std::string function::make_tensorflow_src(const std::vector& outputs, const std::string& macro) { - std::unique_ptr ir = make_ir(ast_); - // extract function signature - ir::function* fn = ir->get_function_list().front(); - ir::function_type* fn_ty = fn->get_fn_type(); - // numberof arguments - size_t n_args = fn_ty->get_num_params(); - size_t n_outputs = outputs.size(); - // extract function name - std::string name = fn->get_name(); - std::string classname = name + "Op"; - // extract argument name - std::vector arg_names; - for(ir::argument *arg: fn->args()) - arg_names.push_back(arg->get_name()); - // cached int to str - std::vector str_i; - for(size_t i = 0; i < fn_ty->get_num_params(); i++) - str_i.push_back(std::to_string(i)); - // index of tensors - std::vector ptr_idx; - for(unsigned i = 0; i < fn_ty->get_num_params(); i++) - if(fn_ty->get_param_ty(i)->is_pointer_ty()) - ptr_idx.push_back(i); - // extract tensorflow types - std::vector tf_tys; - std::transform(fn_ty->params_begin(), fn_ty->params_end(), std::back_inserter(tf_tys), to_tf_ty); - std::vector tf_cref_tys; - std::transform(fn_ty->params_begin(), fn_ty->params_end(), std::back_inserter(tf_cref_tys), ref_to_tf_ty); - - std::ostringstream oss; - - std::string result = R"( -#include "triton/driver/buffer.h" -#include "triton/driver/backend.h" -#include "triton/driver/stream.h" -#include "triton/runtime/function.h" - -#define EIGEN_USE_GPU -#include "tensorflow/core/framework/op.h" -#include "tensorflow/core/framework/shape_inference.h" -#include "tensorflow/core/framework/op_kernel.h" -#include "tensorflow/core/util/cuda_kernel_helper.h" -#include "tensorflow/core/util/padding.h" -#include "tensorflow/core/util/tensor_format.h" -#include "tensorflow/core/framework/common_shape_fns.h" - -using namespace tensorflow; -using GPUDevice = Eigen::GpuDevice; -namespace rt = triton::runtime; -namespace drv = triton::driver; - -std::string src = R"TTKERNSRC( )" + src_ + ")TTKERNSRC\";" + R"( - -class )" + classname + R"(: public OpKernel { - public: - explicit )" + classname + R"((OpKernelConstruction* context) - : OpKernel(context), fn_(src) { } - - void Compute(OpKernelContext* context){ - - // get device/stream - GPUDevice device = context->eigen_device(); - drv::cu_stream sstream(device.stream(), false); - drv::context* ctx = sstream.context(); - drv::stream* stream = &sstream; - - // extract inputs)"; -for(unsigned i = 0; i < n_args; i++){ - std::string suffix = ""; - std::string ty = tf_cref_tys[i]; - if(!fn_ty->get_param_ty(i)->is_pointer_ty()) - suffix = ".scalar<" + ty + ">()()"; - result += R"( - )" + ty + " " + arg_names[i] + " = context->input(" + str_i[i] + ")" + suffix + ";"; -} - -result += R"( - - // extract outputs)"; -for(unsigned i = 0; i < n_outputs; i++) - result += R"( - context->set_output()" + str_i[i] + ", " + arg_names[outputs[i]] + ");"; - -result += R"( - - // wrap tensors)"; -for(size_t i: ptr_idx) -result += R"( - drv::cu_buffer cu_)" + arg_names[i] + "(ctx, " + arg_names[i] + ".tensor_data().size(), (CUdeviceptr)" + arg_names[i] + R"(.tensor_data().data(), false);)"; - - -std::regex regex("#([a-zA-Z]([a-zA-Z]|[0-9])*)"); -std::string grid_str = std::regex_replace(macro, regex, "x.at(\"$1\")"); - -result += R"( - - // create launch grid; - auto grid = [&](const rt::params_t& x) { return rt::grid_t{)" + grid_str + R"(}; };)"; - -result += R"( - - // execute function - fn_({ - )"; -for(unsigned i = 0; i < n_args; i++){ - std::string arg = arg_names[i]; - if(fn_ty->get_param_ty(i)->is_pointer_ty()) - arg = "&cu_" + arg; - if(i > 0) - result += ", "; - result += arg; -} -result += R"( - }, grid, stream); - - } - -private: - rt::function fn_; -}; - -REGISTER_KERNEL_BUILDER(Name(")" + name + "\").Device(DEVICE_GPU), " + classname + R"(); - -REGISTER_OP(")" + name + "\")\n"; -for(size_t i = 0; i < tf_tys.size(); i++){ - bool is_output = std::find(outputs.begin(), outputs.end(), i) != outputs.end(); - std::string mode = is_output ? "Output" : "Input" ; - result += " ." + mode + "(\"" + arg_names[i] + ": " + tf_tys[i] + "\")\n"; -} -result += ";\n"; - - - return result; -} - - - - } } diff --git a/python/dist/triton-0.1-py3.6-linux-x86_64.egg b/python/dist/triton-0.1-py3.6-linux-x86_64.egg new file mode 100644 index 0000000000000000000000000000000000000000..87a0f96634233209f5f9fbc5ec0380012688b069 GIT binary patch literal 709047 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 z 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

>uWK5dXTlo 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%0AY$119ub2S+pkj+qhO{k7)yxPj6w$ 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

|Aeimwj1YDWS&kOxv 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

+(MfPDRdK$O=gK3)( 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�jeNK(sg3xep-gpy9e*cl9;n7Vf>d-A`1pb3t$~EM6#pL_bOm zZ1ya0l@5UJX1^Ak=YqA z^)6eqkM=Dd=xeUVhzEOW85crz*%hAYI3(G=2|(E%>hR1Q`%5~Ui_NAU_#956F^@jbl%8gcPt+^9 z?32vHs}6gVEu+i_Yo&u%sdr`vrE7*BF~5{>g5EZNJ)SV|>vxivFTNGT{NfLhIoFNP z!ygiJx=t6ve%Nnz``kwoFH50=)A7C^D&(s#j zhTuUTiofDuvBNigGPZ(#oVT4OrF}HDf>Y7|0p(vCW3t~r^#fVGe*Ib-&Dg zV3^0=sd1tXJh0I{nCG$YJRL4PYrzEAJ`Ec$o>#po6s(E zI4f`l_nQ1Jcjf`C^8#*6%=>U;ux}$(_%ok@N=|;TP$+r%?-y{~XC!!r68uS2F%FKN z`84G7jt`pjqj%~c9ouz)mWQvYwj4@6R?WO>hrvpE`D$j6HRHxqeF0r;!`I#bpBJ$; zMx4)M*VD842qp>>^^5rPfv)qbaDoDTV_lPDF07%L0ipAo>Bk3seoPMnIDE%+ji zGN)s#FBZ$1_%gy@2KNmc{{J|A46{0F%+=$SRb z7QONYWPW^%W>4no7rA)O^%<0oyj>>+i=|b#`aO5BO{|J8bVJezb0ff?If4?a`pI z1E=ihSl-oNA#9l>+{Dg(oML6UCi)iW7UA2NMaZE5`Z^Ac7*AhIM7Sne0buvxvjLC! zih@TkG3xlaO5Jx;i=)$(e4X|6uB+&jP^fz>wtwnR-h2KupSyHiw1{ef?oxqDc*1q{ z^Dt=IFx~s-MQ&OxZ{~Q&RJbNCo5wId8p&nEEHGh?^0SWat{++iQsBDldyd3xoX3ed zy;>%Qsg3Eg#QAHFdfsrzbL!!V$2_jyd+?;L-S^=Nt?FA16i&7j*ebyyYIXc@<_Qf~ zEO#qa{dkAdgRZN(=bQNO0I)z2%;?C!4cGj6zsH8Rxj$aZ=kXbgYvR-@T82~gB-ysy zU)Hgm3HpKAEC%)3BG2xIs_ehg@&R70*DS!GUFFX0+Fw8vz)EJvBt!l!Z?I$cwMUg^ zH*#6AS*UTDXE>&#ef?nhq+c1=m^pEN%-buG;_qy6y}zS3~1isj(fToeXu`LDmk&)aZ6nSV@P zzq#j+^N`N^OW17E2u*L_$HqXece2$Y(xFS4=Ji$m5i({QGj3u+3w?lZ>Q(~9UlM3M z$^s7~yw`Qrt+f1g@7bPv_AT(t)cl6k{+@h;C*X^^U# zpCtkVlBw@`4(|27;jg|^_jo5;>%FeN@6mx5)!9ebJPuyojBwe9`k^tN#7|f1Ku?3* z;f>7Atz#OG)&V9E((_KPmpi1X>xrf*MhK=tCgyKEEbMIuxqkbLVtv#;eg&^boOEOg z`||ohG}QmkS3xqqdRSghM7hB643L8NAW$}6VQ0V3jH$VIj_l_hNPdq5CsbNNJ1#fS z!_0um6RKH%4}JXP+dw_srm}CmS;>lmBL<&3q~5v9=$$>%=Rwf}Py7`B{aXLK9%Ku* za#n~ve(Q7ZL1(Lj2>1j~gX5?zxd#TZO0LyYV~tEta4Ef(y`-`LaMa^0I;M`KI+}(Jp>LxPKpO_7}Wi>=g~8BLWKZ z=|gONQ|R9g(!c$HPk!u>p+CXia9#ZoTzzD%W8x1l6$(OdNm_Fc(}?*@?CrkG`yO^v z!ckSesk`~X;Kj4wR;Jx}Y#BpLXPW1B#Org4A_ga~rTx(>Cz(2n=pxxp^@DHY0ve#Iwt})(zsb z7~B~HzI9vh`yQ6&Vs>&1tN#3alBBVbT+LsYl5U_Sa_BLqzL(qcbfNG9-q&`qa2%qy z)K-t{y?eyiokqz&UC64R28TGSc;7#mw=nvBGy|D&GA)sV&6 zhwIsK|M}nioegiG#dV#3Tdix-4dAy`d1l%Izr`ju|BMe;v7V9Kns2Xv9?Nv~J&&s9 ztTYG4J%Q{r_z?dR!htiGAgHSuu( zU41a!w&re}T{?Eta%fI9_1uT^&)rjd+w4x?v!$A~c}DJYxu3q*j+|3$F?@qPk$>&m&v`wat)rp9C6v?T0q*}qO&ege6Y+}X zDXqRXH_)}ezz)`!Ier1+_w8h%;C}2o{P_Reaqma|cOB(hJwYhDuKdvg)?=6v9i_6f zcph$U;icpuviDkckJl{iOyi@UyO;;)Dc7;M-|<~*&8+V!^t$f4`26nOPgdog!h$=W zK)FJ-!`2|Vqtetn_v^c)@4->hZlxMsimyoXIikytQ#ikoWQ5Os_40x(-!Ix_$M^s2 zWnV9L=nDA?6XMXP;OdF7ui6}CI&uP6sj6~E17+UM`&_%vVf$Kt6J@;k$ryCEb&8IWis<&=@ed~a<>J86(a`QlYqf&K4>yps7MfmZGEcAE zrr661gV{J!|7Z8F_8qH_Ysl)F9{%+r)7A069AuvHq{HcKy_4&+d-Ina5YDJG*Rx6? z`w!PCF9H=!XQzs3DA&Z7X)J{6gAeB3+|H}^z3{PX;#tiFV)s?vJTDxj*7_;_+CRF# zAP?oJXSN$Rd8C08I=y>m&aL&%j4l!k$_=F$8Ede&d2o+VKxBH%uqyG*EbfGI*%4V& zm$N!K#9!+0g`BPNsAV!#r*7xBX5P(=2%Aa!udo!Ly6zpbZ}HoA+O_zvcCoM5Io6=l zWtqGhB^KniB#HEirg_X7K$`JpfJ4xVUR0>pW=x%UOiZO`u}&U~uu6DHxjV1Ne7?d#J91A%3`P2<`I5}r zsk~ax!ExRY7P%%<iXPIl9%|=&w{?Y4>HbIJxkruyTVjvHIp26{XzX%)Gks}RmwMNNZxrL`a8Dn z{FN2#B->hF=e116a1MwrOmJOwES1<@O-cJZ?{QuA@FAggL{GZ=u0y#0@nL@H_mX>% zvM&tpFMOwg(|&3r^MFy=9!7RE_>xC+Q^Q3P?3#E#kx>)KNz)`FGF} ziN6-e^DB0yX-sW*_iL_!I!m+q%x^zj;C^}}fm5@&OJG=+AAX)r6)2j>oLqevT|DDT zzU45P6ia08-gSkzTmt6^fi3x;k*@`*30%2kjV6C+mPtOnklWSt{1?BBCRp1W!F0zO zg^I5Y0oiT)3c3La(Rk`Us)4(=6$Me@aw8GxrnvM8%tR&dDh@f zRj#W(NBXvHC6xKizjC(z26@4@2lA^)iq>suKCv6p}C)mz2(&7&^Ok&CTJt^ z4Db4Yf zM-z9z(qwgx%6|@|xgV8R&eu+ecNcz!S$)UHvbqa?b5}q!$LZk<@&(#5){W)R^x8Iv z$&X<(zNm%hJ?kn^lfS=&90cjeJjZDa&H_4u-OF}Nczw(%^7jpF8*pc2zhMT@0d%Ix z3Sm+PH!zkj^f9n%#Q8^QT!pW%&%0i!GjhoN@BLD@beVASH9G%a5+09>W%?iR6J{QTD%tmQ+vYdgp*LK8 z&ge`XVLD$=wmxNg7*XfVC9B(#aRk3_Z zYuJ2pYjV+3I1m2^Y1)!yV9W2@92(8tG-r}Kqup4PVJkAbR-SHxc)Bc-z zALA*4p4~6jWEZ1SXj%-7W# z6s1>L`uwL^i+r?0KcsOT^kj5R7jI+j_?}_q=eNJ)(7o(!)1}lrqwuvhX+}X@FgFVQ zcJ5OUlaC!{ggwCBoA1rP>#(^9uP7qkhB)rCWCjt#ZADWsV2J?(bE~k3s+Z*=Ea!de zXO=X0rWbgoZ==pd-xA`ZJAI(1oVjRGH*>?ShSAjYMT>kht@nC6f2+NlJc?0@>hK0K z8fi?g&V3rsC8UcdwH2UZ!LadM?CE?|JKc--opiQ%X4cka|7BmF@TUcwQ_pMdo=z}X zzL)(AULFFuXTQS4V=I>g&vaL_*>SEw=cuEvQ(+V2+l$wqJO~CYuG?$;%=W@w?j1dh zb{kD|RFnRoGF+4BdbIDObiTUDC(olhjhau|YU|uz(C-5k9%PVxvbM;J?3-WIy~ys* z-7$py*Jg_o*+>Z|vK%>)^_hIgo>L4TvSs2P2{>~v;v3yXf0A_#9hj8TJtQDCcMn&7%QTZOG}IdTOUBx& z@W7v^tGfKMga7|Bh{xr7b==bjh z=Bf41MYlex9>GJr^rn4I69pv1ovo#vzLfVzt=#2iof(=BKuw|x<9 zWe|JZGcpB&f5Izw)GN8eE9CR3+y@FDW0u#wsNc^7#XvPM^$T<|Hl1Iz-g17?DY?JU zO4Dob{G!dx%mC}hU&r%{3SY80zX!(*=N3yc-S?T=TS9yMs?vMQvc^lH=qghR` zZG)gGuKT>CDRyuCM`((fqYX{5l9>%#mj^%0pttiQxo4JR z2NbTa?Q=iN_J!ciC$=vHCtKJA5)PVs7HRW*(+%Bt-A^-4qTo2lJA;E;Y0l3#bvt<| z?9K1~eN}e8mkoZo_rf%kIo-1euQg&jXgut`laKKY|2HelQ}e?5Mf(rs@t6(~a1(h43ArU3a~!`M|v}*!l{*?AbSO_aCb!e#MT3>ORm5CZ22J>1sC1 zM1B-Fze3J`j8b%AxskH*G<&DpY3WK3Gx2ctEuQJ)AMi|X!V8&xO6stRp#f>}Vhfs9 zo?Up3R?8ko|!+Eppv;a`oPQ4E2dVbfR7N zIcle4FaqO;%AK1+@tv-LCifE(0LBfVWFtt1yk34bbJnNljkI5ewa%ZoCNYVp^GB$K zTz&3`v2FD0htEMGU*|7flfSPb@$pVQtTp5xuhP$zvn0EhC38*U^ko0^8$fB0cB4)R zx7O5V-?*>yIy`C42QrK2$*u5#oOV8(-3K!DDP%tp?V2F8X4X8s6Zijx_&#y;e>jZ( zRJ`f-&zy<0d-2w;d-ffz&)-iS_D*-A+WET=Z&JN*0S=`1K%?ddwj<@JbB=io(CDA4 z%00alr@_8JC(Lypm_$6PU6Vhi@mU|9>o`bb@dH|oclUxS@ALq>vt(x7BEIzoBBs|Z z^30sMmyS8OyuL#V@J(MGx!9xJXnGJ&p%+He_qAoR(X=Rkg5ayLo7g#2+;)1}vm3Ij zWfNi`M;+N)y}Osw#N9gF;{|FDMFmH*T*@a;66d+<4TE{N-BfLOx49<&h6APo-mf$D zFtM_3!&sew)4eyQ-oXo%zP1rpSBj=N0ox5`-a|u5g<&HMT@N-p7o6ZrT zI@e_8DAw#yH%gYlJveKB#eJwoWxqK?esS|H5Pd&+WivOU+{(`)#`j{2ASYz#c&0DI z2Ei^moUZw~cj_@}6`y6T!pF8VLer?%_mQ)9FpYCd2gzcu<`>oI>!OnUyCz(8hYq!YKZ789rpKA7PI~cTws#$E zUg%v1YCRxv9*{gPb*{-vNNcw4rA=*G{UB&T<|*8fJMiN|foIcIBzHRiEg^SzC`EGj z3B@dTD#@LSayOX$3`b`HD@sgoEP!5y26yYA7e;Z+pTp(PtS26GP5uh^<|6xClY7x0 zglURj&{PcBVQfL{HpN&F+a%w|L0*__T+l#n^K6PO_x4*!CZG=_ned=YWK!OP&$A2v zrfYsCWP*8w&?zq-+E!Rk<+6Q+Z=pzeUm@VUfSTe#)MsvY0iAe4KBy6~Ws&H*BZCh|A|`J=iyM{9YWdZSmsF(>?o+G3*^WZxfOKJKZdO=6r?hxs$zAF_=Loz@b+# zxg8v{*EfBfZ|V)WQLj1o*lq9d4i}mDMi=J$*Wu$pj5qo zaZTKUhX+F+gWc22N6GL7Ltr94U%$G~H+@uo7tZ;!j?Iv7-oH_!6ZHzlNHunIHP>1D zH(w3w-%i%c$NFq$^{M)(KCzp_`c!kT)U*0jMSbQcg?}}+2Hvhb$gDB80Xp}Cn{lS$ z0X)*yIL-;8al9~!2ito1!Kti?F=OOGdgoifp{49wV$j!4PE!9t&jU>F(n+mgkFay3 z4&(ma1?~cpHPAmjNbO}Wq#--wEOcz>eAEXW>XN*Bp4bQAn?BE+?#(QnYqD;h+^*J1 ziusiMXtjW6=iIWUMyD-7y?8qhW$~yicB|bOj6#pQ4F%#4xsUz@I>-;Af4dmR*5h7y z*gyLCtgpRdzxA)NzP5p7pIn5Eh2K=^5x0mxxSqx{`)au#>jT&t z@%&$J=YHSxO4r1r+`c-&OFE5Zu7O$C3MSf0-&A{U{b^{T-GRg0s_{_sbKcHpw57hO zKa$>F%}tMaMWzQ`SKIlU?5}9d`@Vzh{L~ju-CxM359<3SYZfEEuA`aG1@mX(O|)=k zQoe`bQ~td#;@TbX=@D{7ko6}RUoYyeTgU9h<~s8cz1gE*ulK=f*6dyRPqF*^ywJgj z(~`ycTE3Z+_liT4AJ{h^^v%>Op6RprdC8#do>JHt_N^XXKAmyw(vM`DYTb)sJat^| zUr*g{tb*^pjWze>FJsXUf<|*qK8MENTe;qY9x1?@(`Kz&Zrk>yT2&nt~n@Fucl<%Yo;pb@+Eoh;< zmjJ$sSmhH1eBMpKr_%E@J-59g`4&uFgWvW|=N7z)rlze%InH4Gs-8KBr)a_AC^j&# zS<0WrlYNTgZx<6px8SPr)VqqcB&CP5^JZbDlW@nq@!RFP^A<#uMY5I{a@{jlgei>(XSad;;+tUn^$WG@s z?oV5a^M`DDhR^jvJkIeldl(vi5B0;-$KHvvUY!qVD~t&ioZo)|OrEKq;&gWIZESsI zP#sV7WpD`YZow@CcOLG+CAhmg!5)N%LvRQd+})jrySoH;cZbLF``7M%*xD~s)6+dw zcc!Q2p4)xyJzx3zpQr^Z4aQDt{T9xJe8F7RzSDS(V$nS1S%Ev-&Mq)F8hauVQZeH{ z)i>AI6u@`ix#sKmas`%tjsp&jg3`Uyo)@FjqefV`nd_OaW{pQMp3q!v0MdQbWma?`jA-c57L-TK(=IXfn>QRqrpm?6E zHf#0$*#D)BrIK&l&2R}rz`N55%;BWbU-!~ayP2wQ6gtmlz;gi+*Ki;ij8uCN-DmvX zx2VEq({T_OwxH0ou;VLxs9d@CW8Z;NKkMGYkEhmQ^4mH@ z@L~6(hV5U58UQi%42X5Rt}{93`{TJ^3umWir{3ocrkGUZ&I(5f!k(Ac^Rf;tHpq71 zT&V`scObdd;*1JQs#SQQfY`8v6f$+aFhd8TN4CTttw_1m`7ht7hgfb>sxrYcqv5NSD$a0z0!>E2EHA%bTp>kzc=O zOjBvTX()*V&mN0f&6Bp&Xp;oqP;w6()5Ko>q41rW%bgP=GDLoJ7Hdq(RELu?fg*)m z(MEDE^;jB)oqeAg4-!&G*}Y-+g%k-S1>OClj}pwy68~Eo8;ZqR{VxNUA`zd64VQkf z2?o8#-}Os^uNgKsL&noA{2wFzP-wzI9qxHY`qY)9#dye=%qN+HZ$~nMd_*ccnC8wu zmeW?C<}EARMHq2qK}oRlr`ybc(QJ=Sb<9u3Y@d0=Gd6Z zSjrVTeP9++RLf^>RO>So_lwQ0Sn}o>c-24Ax2SOK;%5+Hg=%QG_y?g&?)-*px{@$)AE-xl=4`&+CivN55rTYKIny3M#=p34(yJq;6eJ63X4tFP zp9+2%#YoK%8YQ)IWk!{$#FE-uGUnRIx)b=r2^Y*DyZ`LOzC^Gl0Ho7Jd3`^|Io~WXoCXT1iNW1eKy%I52h4-g+8g)lJ)}rfWLf`DW$DPY1{O(=6_HG^-4ldGE2Ksvlr?i>?p~1~(ql%*Rw{j)L06A-gQ&mvH!E`c~wQAqV9&bH0%js1BH#04H;NQ?A0zGdSupqnyV0532w zOB#-TmNK0FqZq4W)Ayi5*B<|@PkEd&rql6j+~eFfeJWywE=^SRg|qy2k=x$<$kz1s zsP}WG)QQYagS;ipZOuO;C)=qapm%2HyY=&!hluRk%Ge=?Qskk;iegH8GX0%av7r^w z*c9tb`I2pP8sBk>rql)^3W;$>Ng2MW$tCc&@KF8og#)@Yhp#WmLWRxa`TiG)tdMp{ z&K=|-aW||g_xa6G5zx3Rclw|}9~&n5fsEg;0;a6`pQ<`@6oIn8QAh&)y6-%(lx4x1 zsW5g%?~{S}!a?{nM~2o!8~t6oQw>IKw^t42$nTyrmbcU9`%PiOsnrvUw4%SMGTv!! zmz63p{BRNJ4R8Npj?3h^{k*yZ#?A$z?lE!ToDlOPXkbV*Jw8SK@gvom5jK?Hoz#ez zpKkh+Nz)#ieecDd5q)$Ma`txGVD@vZygj!-qEk==IPm_+<{{M1 z;VRo|6}ZudP8h6sUGzb-?pChL~ZYqJd8=M;VZaEBPp?-su29V#9bYy`L*RO_6U` z0X@2y*HHh=JB~jPe(T`%E#cA!8>DpQ+1`Fjjp$fne8EFrMV}RNnYy$55`Ovi9m8o9 zfxn0z0udP@M=|>{W-qf@_a#H7e%lhcU-dno&bcWs`&X<3%>~h>V9DOS6F)zZY?Jt% z1oV|~!n(~>6GEMC(=Rm1{st@@{M0&@!1Cm|+HfnAbVE}=WchZXctr`5*dZ`hVm@B9 zv{5zI5PQ?_ieWdwF3rl~vZE{XJ7Y%kIh_ zI@;fk*!t|xsd?hjMBlBBoxrV99b;=VHMVy>!Fj`0KTzT8r(~enZ^bJGppTq-HK)F( zt$6t-jAT9E6}hJ4mF|PxV0Bexf)JFgh9&HZWZKNptQRLK&sK8lWqwp0vzs)b>b3!yQbN{z#V3NNM z9~X^!GGAaL^GuXqW&5P{<|>FKGt^QvuxX8)FBfAxBh{D1E?Y=ky-QC6%HjyWoWG^~ zEF1cgq9>)-g%a><{`S{$ufQ9##*;K76_=FAqj`$NPm!6HVc+E~)=HlOnU5OgCbcvNn}_>gjK z&l0jk&7W#cD%WJ$5d`N`f9Qa6n}Dds5jTnpJzU^3-_cExdlf!N93(n3L*MjE;k9!I z<`l#JSx-_w{;Ii*>2B1|H`^~(`V~0kp`CN^SKy^W*v!J zSXoZepvIZ3kT|VOQ;#l1)8sHN!5P*hlM$r4eVkL1vw_u3q+#0Il6*n0NZV3mL8qJo z_pe-ROT77URPjET3x8RS|=Dw%QO@cK=pDS?!YS9-Z^-(dEUX+O(I`2~wTQ@h$b z+5Y#i`cGWdmlIM8`vC>z%U3wXk6YvlTT7>5Qm;)v49$xX3u}5-m5nQsw|`0LO_3n* zelfc6u450KM4W9~n6ghqi`a4$^+qOhZV-_)jY1s*R1tYS#|2oZ0)OBZuiuSq9@Trv zDe?SL*wP@VcZ2s1hfaXc_9pC(^iA!tEKNd07q}JiXkh*m{H~)>IlL}?GTTu*WK`z$ zAxuo#|2fV4n}4H>BTM&Zw)PxZQZnTbQEOC3We>_uZlPZIQ^G_OpYNi0g@e%e^z_85 zTPbXTOqH8(%-s_dN&({$Wk1?1TEsT9qf4?Od>CR}go-w(Bi1&E z$LMT>5*XcB4AC`CA~ke@{5;ao2)uzd5mbxgyMkRD0|dWkbntqw7)8TpKz~@KuR@!- z9w$|I>#uNiEg6S884F@Pn|Ml?bkgST7ig32W@u!VB`Y%Twh4Drzk{V5a!}9jX-c7C zJ#>#7IYshTOl4z&VP4W7#gzp?b~C8TW_d)THvKi1e1t21jW3bBE%fOxB=Y8Z6xPgd zuv(m97HN*GxFxV?+`NM3pd4d&e*Jcirt12Ic%K#UZ7#8(41UXsYgp){nwXe(NmXMr z^op1ur_iejhg@!;_6o$;DH$OhBGJ45h^s2dEnT=8rWQ>vBtH*t>@viVqwhjiGXxdB zixXdZOzm1qG>?Z}Fr~9Z{z9ZcYue6LO+*pG{Yh?$1BJQ8NFyOF>=ZFdk^}$h^A72d zhfJd}*K0=b8)BzDLc=NE-2^g<9bK&&N`Xb5wXxY0&Jp()BtXmeUi96$Fq;ZYNlitD zCMV9?JGWnag5tKT1FDO~?M@SU`l^{A#>xbYD(tTaKWY;_0*dAjIOY~3c@b^j) zDK3la89ZcT;iTO;P2=C6I>ykY%!!D9%6)(2P2p?^ZfxuA&uRN3Xo)!t0-ZubY(Bvf zesWx14N_!TEuV6)qm{AvKK0GkEJ;W?zc!RdhF`aK35BULaSz{(d0sIkc_HhbsII-! z4A)#GRZJfBfhXd(h|O!fA0WSF4FW00Bg~U^uX4kxrEty7gJ8Vq(C3}@zcNzEPPK1i|4puuU zO9R?vZfDzm7%&s|LIO-;8JyybcTKxlVc(6`DbKb-HmsRMXyCvDZ2(bYxrD|iTxXQl zd^Yz=1-g(azE;I;R=n0V(rB=G*#xupgH>O(3PkLCLxAj%h3gaMOHGLO-el`Ry*%4! z%ov!60lnxs<>|N&tok_W+t3IQfM}m6EyQ?SQ{8lh16?*23YJEH|BKN%s#5!%;SXgP z0a3k{KPwqA0Im#IVz+OKmo%Cp#B2-}Y`E0we(oGq?bPtdyd>9(@=%U|==A@6-;pzK zoh*5+#JWw{0mt&i#U#D&ZAzwBNO&$!vz~xm>?cbg62<@1a;m$o!h(!8yDxWXiGfSo z`61!WR9jhAH;T8DaGfM?im&*W9=D4>HqQ>L68sNF0Lu>a<}l&+_KWYMmj!kd0$!r{ z{>+vzr4bzve0Qx8c$~-8E5ij**8;;$Kqbz@jix|0&O7XcqRS~P>yF+CyjzdqrCvzN zljWWt&EDv1!d-FcN79vcDF0EQ4T6_#YQZxm-7}m6G=cyG>AB)Q9fj4Z=2|HkAn+nR z#R?E;AQyO33rGDi0*N!;9{~^+CZZlnfU|29N6N}z+Y?@s>!30Zo0v9!L*#C=N)syu ziXggO0?Wz;w@tX6iRa7(?}IOgy>n z-3+pFRh9UveU{g9Jz4rbV81EfK&}l;s?Cv~X6>C!@+Sn+5!Y72zQ*o5JfIi6)>9KA zP5#8}-ObuXn_)C$jGd6s-1OHT0e_zW6y%5tAz*!d_}A2VZIX59d~Z45Vc}8HD9@=Z z`(^(f1Z=!I*^o>X$=H54NzZ+?o8}-1w{AY9vA5_!?3~cd5I$suQ^_FXAv7nsF>H>l zfNYDpp$?=~b)qoy7IVWZFf}U5&JScWkUof_Ec>BI!4S@R?rH!N>Q&1f=p!!ftN)ze zMC2}97dP~)2nm)J@!Dh;9jY;tT+*f84#r*)aFa<#4U%&6!J<}Y8*-4%4ww#j{c}hV zAL^onMYy~43CGnJ*EeWFU9;YU85aV^r5i0|hx*4tgLQn-FPos-^js%M zC?r6QG-M5p7B1$JtL&UBHLU+hsoj>FY;6Rqw@9bFHt*omhKdXt>|?4AhH{S)haurt zMP8@4UFXcsxv$YLxgmH|;T64sb!||#7($vCaGFhH?qN;hS9~P>sGo`FI7C_we@buP z+Oxff=!DxZ+kVQJ?0ckz%?CR5^JAr~4LOGk`&m=c=?k}K5Y~y zywu@O&|lA~I@ny1A%ZFg1D+$1Fx3!5MwY!;Hka&YiWueIBo>kIf0~P*M810zZ{Gbu z%e6&%UA5w58_>3rU=|I*GK+#0koZNaIvyOXU_8%k@x?T(K~Wte{4;y*FKchbS=W%i z9Q-OnhQ|V`-V?ct+9M;gHCATV4AmA@Sgoz?5m8ecBm^Qf4k^}%hn%oxL}QN<*g4;n z=ytHD)IPUsJE*cFO*$E!A0nXK!ffY(6sU}8zf_OnVkzhld=8VwMzx;v8JE9g`4-}M zS-$|28i)3$ndiguDl(H|C7noi6sVS`{ zRtl-$$mA`}NkO#-gcXq}w@dZC<>B*$qR94qZZIh0ufpPT;8#j%gO`!jN)_kvi9rX7f76~i8Z}})Z?p8Qh&!a zoM~(qEvs7)mN$Ux*F#uRMheBpnp)Juz`Owq3aO|*dy_AU*F&7vdq{VjZbw_7d5RY(&n$!%q7JOEh zxo!Eg4aJT03dJNWn{lk03H2A2nnHFj?*!hzm1-AJC{x^EvX3C z{?ta%ad}IRYUBO1F%?cs*QKt#YFYpk{R`1A^D*qj@JT%`gkI*^vbFV?-p_NZOc@hi z5^CL`Wz9&TB}(2cc7RIEY$EM;*MuJRPP{tP` zL6>7fhN`P)kGQ-J4h^JL4*FdBgN8(1L@|-pno+FXDN?CDzQE|uTKQWb(yxJQG|6N8 z3FSM{&r6H6d5ZIf!Q(YXP2Dz;u_RGniH(We^B(P^pzR7J#*9~_f512sW}$E zr;q&_mpVX-5k2?L$gQN8Y^1ysZa>Lgi({zu`Z?k>_02RA(&wv_qIxRNI5`{nllMx` z9HvU=x-{t;<0fK(kH10ekw{)x^Hl@sVFjyN^Ywd?C7klXO)*oq@}5OlMv1Ykg3hk;f!Qf_g*709a)VqMiE<025t50r6~puW>zyJ zm*tl;aUiac6wT`BSQ`;NVAWnhS~v;%9(^aKUbbGW%~N3`ApjVX1V2E?LodIqYhHr4 ziY^x$y|;2EPQPBD(Jmm`mCoJuJ9yvB;m~7dLitKYa>CQ0QD(ZbSRWaepSX##8U%n% zq3?Yg`KD;gz~1}?KSv~JKG*7)riq*01gkOJzQNp-x+WbR6zT@~A+pgNx(3b0F=QSz zPRa?D5CPBoEUY(5`wt5!28@<()i|`yVck2hL3pgxLaNf)G;fyM#037dm(durRdNAt zgTMhPS5+EgekR|MUi(+t4qeTD(0K)3G=p4|Oa=^-);}Oy8&2Lkj;#s1uRfudN{Aki z-M0ef!!7?fQ92Jg`~Tv&oqBNY2QbRg@EGYXi=YH(LPp(>)PXy4)=wo#*R??xsv{qg zjJ5(^8oyHZ41GNr$#<$nerB#t03>$J4>mqn{02$CwCpzrlV&=9vbWDea4u`Jdi5@= z5;ijrQ+7^YS79d#USTpuE>xo$rE4`bP7PJ;15@7Bk=wf@Lz+h7K0LF*epW^(_PZ_h zqbdZhHU>oM%K%B*1~bCh5OcrQJqP?aO4<5Acq4`ls(Qd3tl#YKHu-`X#~a5!#)JQZ z;@qz%tDmcX9I+mxYgOz0dIbiQ~^*_|Bxvr(!IR?;<`49IcyB8;r6?+6UC2N65R?T4?la%P* ztP3_i0Nt}vi?0B2YsMS>N=6cdvHxGET+)WQIJm1r^-+~uq~Nk(r842|%SgYn+yh?{ zYf;>jB^{vPHYNd8djgX1Wcx9d*Om=2AF#3vLfjO{I`41xrZE!oRT7K>(0Vq1&9ob8 z#k#zHX4+5{1>&9pF^WQxH(*u16f7atOd00|Z5Z$LNScUpb6~CMKnPlM@0MIXE!@q^ zH4>?BlC!c(x-(Dnz`~|yn0W9GMDY%QM(_#UnAs11m`&9T8PQ0FkVK;J;Sstpvzsx* zGg_Ph{2oG&#zaqkHD4`Vqw5fZ=ZF@!s~sFXiHxpFTh_D#q&qDfTzyT{?Wnr@)ndHi z1)i0CB@eP14yLsvJ*raH&S{FwTzYXUE4+4%yIP&}%Q;kO9UXxI6-OpI#0=~iHN7r1 z4kb&~%RF*VgPZnRSPOye$k}mR=35+Q69#}9%z`eo5gB3H(&R=ybr4vWF`EF$B)nT( zt_F2&p~U>GO*kx4UT%dD{=>ENSv28K6=?t;km~6^8_rVNny^}CbRxU19z|xxB;i-< z7o^DQ`8-Ne>UW;UCY8NAIWh}@p@ZMYRJ>x7E`IGqQrT3VD$zzQiU-b`hqqrc`$|S( z_`z`(>F0cvrN%+Vv`S94b&L!t{M2V;=I5=NIn4diYvkg;nm&h}mzWMFnlxq3@bjq4 z9kBZ^Kb}x%;AYgHzJo6^^2Q2;Fk3}f8_>Yv$2k1dTmin!&bM!v%8URajb*l;-{aCn zq|eLFP(YgiUiX^P&3nva2Z`X#2ac!wH5o+HD zA#E$Ax!gxAl}M+{-ZzCP7SLOtTOIqEzmcXvG6+q;y$Bi;=R{(>WkH(($mgsc`?od&E`uOBJZR(FmA zrcVFFldRAbp`$;-Kr#%A_)OS?pZiNpvZv^z8KVhbOhD!$)&MnnilaVf7LUE;D>N~T z`sw+svYqd9VsIM{mT<7098LQF-WUQ=?x^D_ymd{OX{t3#sgwgv1O+MyOkLS5@OJc{ zT2`PsPc(YU@Vp2svAp`;-QW3O-WT5v_BA2ReN^3m7D(`E`#Hc8y-Mz~_BHZCanFJ+zC;bK-`_+PNt1aHg(WZsk? ze;;vO^0+K`)QWg7#VNL5x}4;fcKjIAbUn!koR@Qci@DyNlPlr7v^pwl%0}u~;rz#@r~UWB9UIP|&=ZGf zhoHymG&wr8I5)c@dZiJ3R=pVNo_oRvyYsVw@>?0MG$XkF+-^6D4z=%a^_Va~e|48o zkvyeg+D5u~0jykte#j*B#!QCXfX6_>(VPtDu97snvI+h68ej7adBoFB++&w=-A0EA zb?Wr%sk#MtfiA1#)XA+*t$mfneBKg!BLn18pul{UnNvN*Cj&a-rtA-=J!7i}U& zhDMtCVoHQNE7yO?y5Pe6RJA+&OtQVk;$q>){R$s4@)KuXYo-eg`xap!_sULhK3<2S z@LZ;_iFGwu(L&9J*4x@FsdP{pd+X4OGlNAjQM-VDh!zr^zY#$#IYPhKlE4bWabhs*RMAN@O!ESd^ zy)SnEyzgdeCmZQCHSW_P1{iN?e<+Kx!aR8I)eXoArSmD@M#lC#T&}gF;5rY^C0fhd zo}x0sd@UQU?CoQ+W&9)7NC?a$!H74u3M!a78!a!;{EEO|F>1h+V2j+on>Xv?A0$Wg zqR`cEnj+|Udcb>HiKhiS0c4t*>73-FYbDE-i~^dkSeE#Y-w@mC$QeK7Jrfsz7uaO5 zJ@Om|Klv8tMc+`TCGY($OW8vvNZnb80qVXVx9oeA@T%nI?;N4~qu@){AM!Z+J}S@ea*5+hAoXA?E*M1@eo7s41b&?oQA zZr6cfN)d1BOa&3~DX=W=;0>2wV0_zfS^7GBf=X;>J)Ay0dFQwMyT!kD{G^n-TYfVB zq0Ahy?Ll5c+X!{3n12IsK^yT5vvm0bs^9#HYTxF9{6x^*C#gH(rKedxO7^620^#q> z`#>hPb<;n*V)ehFS4Fi6DG>Mg7;eYgQ41lY-Yeh zJlRlgClr;);PX-OWa}X7=pYQlPO_sI-eEZ;47;gq7GAiS1{@M%A_dGYSTUz94S+c` zT@@xHZK!PXkg9*>%Y93#XUK)iMe0WR9j)SgVxryc0GX!$tC4i~CU{uCV47v#BVA?k z#I^JNhor=T2PUDo*(UqS52I+bg4`pOnRi<2yH5xv zaSZ|p;wm#*OCpb1acIO+jBxyb0DcPb?M#(wPrZWsg4y9)_QP`NoYU&h@6bHoRfd_p zk*_LeNs?r?&(Q)smq-YI52-}(u}dbA%9d?e!TW?(tF<>E7P$oyI3NdB>LX_}slpw_ zmn7oufxf++rK&N0B|^7z4cl%^D8^SKA}h+n-EN&uq$iUp(KS{!lH^Huia^Sr4b0^I z696lz9#MO`9RMS0V{xci?jUb|CJK`yUpwu_R!z&^Fk>xI5{M!`nM}U##;`EFlphHa z6A`}kwpLE37l}yX3enPGCPGjv<(h53kggt%kt3F99+`oUJ-T|W_6^Pd|TnV3ft@qW3G;vP*$Yf!M z5!_Yg2G~Y&o^Gu1MG=UVWY;LhX$a4H_zbe1YDN*@v@S6B5|iE9t!LpCjxWMz?D)3> zveb~7Mp9^EVTXjliQjgzp&MyOXW@QA*_UM6V8L5{%dHzw8;s~s5zNl{(WPY7M@z28 z?`priO(?O7UnAM3a1e*fw+>#BNM)fV_EnGyDm_z>w7Z(>Pt@%%xN#0ytUw9%B0{(v zmSy>jd-?}Gb)MM|$yXL*7j1=-bb&QN_Qm@fp>i%nm?4w3jf3J0 zXS_TU>rz26o`F46ex98CQ)0Llm1&%^=B#dz>GK&Uvoba>n~G?wlNnR$aJG^>t=kw~ z>;N9|?-L9U_SqmV-H zlQAKvCn@xEj94?A7+#MzqGL$)MTB^;qxd5Q=o1JRV_*F7=`pA0fI<&GhrEXY;~spW zyk&sMBl5VmTZX<$k)?+tYxxWa#7aFVnW_1OT-X~H^^qxV$! zGpHp6tcr5?W@3}$`1O*dg1;Sx61Ug&Wo5F6+5k@QyM{XaMykwn1rvemwqaQ;d66Dt z65u#HM#LYs-Ce(|=UJCBc^vlTF)?EH`A@^EMfKCGos-dIH~S?ECzINjP?y`;-7rAf zRo&0nmc}ei(IyzL<$DBywBm2JYQv1>mb$Xi6%VKulnk`9^_EjD|CBoO)SIuMrlVpwTE! zKze+_4U;%9osdj`qK=(m5pvri07!33H+`9X8nk%WmjhZNO=zGf{qh05X%T0cT;G)B z@I8>*iSH->1vqZ0WwgG0PTwy7@y?0NdkA$`GKmFYm3(7OC%Bu%*~PpCSLm=G4a%wmzUNMK zye0S`*8O#d5Z@Gq|)54AHFOOEOT zU^FyV>p;0PKo3|v3;3|}+J=fhvKe!`vpqu>0-2T#zFj@bY?h#%_Mo z7#!0n_k7AdUX7QVv}&S4=$9#!?rbUn2g`p=_ZNkn4H$8FvdsLi{+;c%yGdDrNA7L< z5_2?69J0TrQzZtSxvRU9f2S1dm<-_IhY&thnLWx&U127hWPz7heh8}}yr!|iELejX zubC1qxGmO^oipUAD(QivQr#`e>MD>0(qFFhMreEuP@ed~$i z2~&4@B;`|3vln+EN+mHV2@6#>?m0OZKZ@FF&Rd@3QqoG5Eh+udg(s)#^0{Xsd(HBN z6{FaxC(bLXv+MW`KSA4SLga)M3KQMgC<+%q{oChg2Bc=RrLqnR#RvSsxm6g zr|%au&MHQ8&y#;^U?fMku4=WcrbJg-X*cAWYeTPZmUL)b8arDg9fz`W*z}?qy&*oE zuy%5`Nqq1cq;gZuEps#$KDe=Ew^OfFH|_e;u0utoox6=1j6))vIRV45>m{%-*5=xB z#I}x_)PmC8I^PSmDy|=PJ`BEgx%h<&*@`- z?EV%n8}%hmH{~k2JSX>>66R-ZIj^uLyMJ&A6GK{-^LEv+QRB&98pRXu+A6QNs!Yk` zovOIfFd!S40ht)GGSDPJ=}7A;`cH-STWr(%)X$T+8g-phMw2}L4}^~`lb!Anc0X7G z#T6IbukI`?)S5Oci_H7}lX1^h7Ck&6TqfixcgBH+;cacXH#j&i6dAk^R=VD>tz+K2 zsnEu|d?I}8$Or|CHlz3KU_=~_)AqzwOt`i!+-5%id>I1C3c#zdC@9swj(CQNnbeXNZ*Tq zj<1fWkMT9ci4-J+@pte7o%Ab;7(u8L9q5ECfETeQ6dnIV^92_X9CC>TdcGk4dMkz~ z{wKhR3G_lCh?KLB5Q_XA!xzH@GiT3d4HL>fhhV^8A>%mCIUOQjDa_TT_ZvZz7 zbU-D3;_X~8*uLDyAKdT?282i4RQ9VM{xj$;iBXfh{Y}QEp|IJsw>X7fQ2}0s*bzHg zuzBBXs!L#Bo^7lLB)uA;FA$Rn?m|6jp`B0Hs@GUG)laf&b>PnMCpPCvMzANrA6auf zWQabL|B#F`Lh16I(rPh{0&tE|pL6<09M*f6W2=%x$xJZ&sQdHKQaMr5{L?6^|ClO@jmR%go!ExvUwGb~r zih{^RWXgCsKtmOkkn8WbmCZL3w=yXn>P7^{#E`wtS(z}` z&bhKL7A2pGJve7Lu-7T1ae!K zI*l)x_<*ncz>)75f3^hfY)Uv0uze$STQy2+NtiFO-lUSp0FA%Q6_Uke|TCLr|+f0e!EhZ4-E5;iG)jj;$z23piYH zRMDgMOsMjLHzY#}_&Q<6pzLkk#uh$R1OP~z(aI#Tr4ct~zO2FOXp>ny;?@djtH4`4 zdPD~52qVkCz{(C*qI!crYa110b$`G@Drqq=Jvsk26~jhH{J5Zof#1UOfkmM!{Qhml zRegyIwY;pau-R3HLO8$6(?q!fiDr%CEQtGRKbu{T(1LJtN z7&$+IIwKMHB~y#!MMj|Z`?1^vC0Nt1Pd>V_8M6GE2!O{EdORG*h^H?`NHazO>YydBp@g3B z=mP<0S%9Sj^275BwTZREGYxJZgpjpcM+6^-qAXmN+u8Nfa$=Cu3H(-XtEksqrP{Nv zxZg-?bl-;YMc2OYo?s0A65o`k!2{j}M&C<&koe`45DGQ=3j+7U3j&Y59=N0}Yn{g( z{S#gG>3Xy>*Tp|j)WzDr*#q*Ge^n^rr?E2|9g;^6(5Zf%!o`2ix1!(H$$&}^v0kUE zGdq}*U3kR=8&Wa>4Z(LuM`WjJ>(h^Dd!+ax&4^;yAb3Q1it=Ah{GbAiWKl0xkQ!wM zlrbBKgE9kdYYpRTs1rAc3*&20HFD3fC;eS>Iz<74RVmRz$rm(qMCsXGdt%sm3`A@H z-X1fIdN_k(+_%7XRh-@x^$1j4Nju3{VRI9&2u==V}=85Pi z)z1hbQj4_csmlT7|-PwJGv(ZOp=m`IOAm!$C3L2P$<1S%H+&Q0-&CYZ>_qF{CB&SH?L=@|MeoScapU7`ZlA|F=_&@ z)pHCFg6!`p`bZ73rSv`3#1np*UhdK08N=fiDGs`vJ+Va23fK&-Cf!b>6nt7={s;}J zDar$!tQPII$}nayCW5D+wEJcj@$G+2Dl z`=1OJSjr6Otwrp*;23dU{GMry`%`#5%8z-x99iyJr2GfF<%?)b;d>vk-19hP>V*$dqj)`DS?(FfprvpV_cAAX{IunVF#*aJdpvrfR6?{A z_Ywf@1VTaq?7Gb`Vi-N?6l4BgjUV0^5tKk7c%8G{^B(vOdaDAXl;WQ|=_PuP6e1JF zt}w6eBPEE5LV_X#b}I?}6Uj$@i7kb?xR(?BF40cUnSo|Z2?G0CG+q*bzJ^tWI#GfWDpOf}p}a0$2 zcdKw&>~jx0A_oR}u#;e-JNnQZIRMHXmJ%%ouBSU@67M|32@d3r@jImYVPLsOi{c;R zNANBlaPmS)Kd-S5ws~|UgMBP2ENrxZ{7QpE#+zH{0X!nT4-&*Rw-Wt57*E%tfgFIJ zfj4{YNd9C&`Rt{ow)^DnbHDQT#ksjK;FgV(Z%Pj|w5~uJ7(tWsXz=I#P_u^L2tEh* z#0@RjuS(_agCC|g?$2s|2>#6mQ@<9drgRzdXHJ;06G6=DmZzsl1qKE@&f9NiM!&ZG zdt7Ze>A3LOcznct^xR8o^Hfq$P*gNcz>InUF_Ky8$%Gj>_#{6Tnk;= z2nD#j-SPO|=G}h~?1~tRx-X98Qf4Z~)H?IZLx8|+z0!6anb(wiy(7|zCrQMKF^mj*QuG)3rHL+WE}_?Odxl9ojI$#RpHfvP)EY0V z4AsxoJM(?D2ls487Ly$5H`F@|{#E!A7kA1%wYxAU3V(V(3#=7JB6v>3hDyOs;^}^Q zNJ71YQ0)zNrPCpn`9IeN@`CsPqUITWE!W(8IGdlZ@6XgV!F%AFB*_uSBu}Wbw@({Y z|MHmO$vVZYm6PeCM^p=BwF{ZGCX~}~o37vEJXtTDqn~yLvt~mkq%>4eRHfi%<(TYe ziL6!ZdlKuTX$k6Q>SYBezkf+RRFBL(&6Z#O8dNL!t$4nn!GghNo@nlPr8el?L1j#J zcflfF;rSJ?!I5A)8@YD(vJt;HEO2oBFUxhpbwY1~eu0koKy4%_8rnUKZHjk}cZ~NR zff>Yy*Ol)8!b|80OVopVqHA)9eSPfQmd#DfV{7QT! ztiy&O+Er@SuGSlZNmYd&uVnVGfysYl4H=bvMxNv?CJbp=<%?Mn&Meft(E&b_Eelr} zqscELKLtA(3N!gGQrFjAD;suwm42?hXLxS781ls&6gFi%jD7F+-(w*&Jn*#?lJk8x z5W0_YEwq^&S5j;3=wI#}Pc*RI0nf@qEPaMLT{_;~m!4+p`uTzP2ERDwz*?a%TE9w; zi&z6+UmxVBeEzKYgdNA%tv@R*W_3Koc2umXjj279Ii9oZuLCRDV+N&NXWYfln_bBp~6kGI% zDmwJx>gc zbe8Mb%{1`3G4C(Q=rqqrnR-2Sk^@`h5p|?|^1G#?JuYixw>-9kF#?f-Z2NI>0 zejo2@zVG|)f1iAF{$HOUPsd)nr32oD*2MOeJH%}vukYbv-gJ_8(0zBmh+%Dg+wT49 zPUrbuinZjK{G9S-| zA+}Np@1)}0?QPiyeR*|7s9z9Bepd@Py1&nBNMajJKUO;ScMtd0ZE0o)EBIA>Id-|} z1nJF>s|MRNrsYMb*QAy0Gc+-(OcpcEyO*kKl%33@>cy-VJE-!M6&&M90nAJF)CrJd63?V$*V8jw%$|{+v%2)#~|g%&{KP>Q^~VRd^E$JsJGh`1k0p`z=DSF;dW4~r!#zH>v< zHvXFTEfd4|ySoOw?m7mL{>o7cy&Oh=(f2T5*25+a(NH_K1w?_QYz}j92q@2QQd<(G z&9hx`+=s2Iq&gz(_9wUhspV*2_qV`P;`(*bGxgo9K5%0;-3{CUp`CW|i{I7S7d{mT zSpTO49Dk=Pdw6P70nStP@#rx{a=buF92wvB7Y>N$KV+CT;QYXgcmqiXwN-;J=Sfj3 za?5#|(`qkA_|Lav-JTYDp0!_db#G}#Mv99yCvzSEl|+1bK51ej(|)FR1z zJ_`R|JiT{VQ_T}LtPct*O++9_iHHc&i%KUTB~k*U&G3W``XMe@?)>^_AHP{cqH|cj(dgUO z508_b1(H+011CrL%}>*HvNM<8Lh`nmO3^yf;;9nD?*?q{p`IjcJ3XQ`WcGsgV0k8~ zOIIWm2YjU`@05C%3T1?mohrg|oUcy~>!j*L>a^%MN+rI%H#7y`h8#cfpFS|;+HI6< zP?{+3u)$|M?#4ctEJT@|rs||iT6SKlHYaRbkbqr?qEaIdJG{^&Ff(ir5w|T`>XP9g zX)lpG;0rL6vT2e;_Fy?m*|}SIu``E<_NytRj8+CfSnzhoRfs$;1=`yce*Kw}kcs`D@HJx`z zBC1kWH}~PW@J-p6mE`74z;6S26Np_i#aA(M51X5Zv#Y1jB=k7bJN1 zlNa^?Z$E*W)5J#`PIjMh?-%b^2YY7-4m~w|-6|0&ls~sAl-{!G(kN@ektps^*E1Mv z;${78cCqhJoEJ=Qzob(g>uyj6Xt7}LZx}c5lO)66Eq*&#lb&uirMDR{;{UN>8pbG< zCOMbTMS*AQZ>0Xbu<5V83`nqfnk1QL1il9bL~}&niw007geQ`OWtU>eatZGqMSD?q zfTV;qK77@9?cpdW{M^M?Pyk)aGN~ckvJ7F@u&beDphi?y*~&;o19C|6H8jb zOH~K2JN_PH7^)rJ*WX`mS=w;w$Wwx6YH5_02;`PY%l93%YERu)U>|2cnb}^dX0rpz z9@aPOQ1W3OEFaln)kru+rg}GY;JL|)BbUJn5{QmF@YZM(#QH*0hg{BYCEk=T^DV5R;GC(>s1#CPv<1`|omKbgf4pl6ej)S|rjt$?BLz(Bs)R9GJKD zqjHm5{&^y~vgm$qza=BBYJ>dVtVPFibY9AN`#K`d#L7ncQLTx#Fm1_8=9*KzBDhXL zlY;Akhji`A^1J2LbfR!ORJVX8Q8EPE0GoSmaM?}wcmehfsx7^7$~s4Sa^|Lg_KT?- zl+$obig{w!AeZVaNbm_EE2I%cdI0a~p6&HMu9TgViRJr#8Bi$EE%TA=wwV{4;Du=E z;O_tG6}u9Pg z9{g{1ugkjJZ4U*n7;W7jwDHj+eGbLd?1YOFPBeUAVe++l9dm9qVW~t27pftB3izkZ z`frve^vr#(9{8k&pJ-t+Ktgsdb{$Hd|I@Spt`w$?wa$9)2}_^b&P8u|`ilIGkvANE z#a2N(eSNRX)HSz1jm*DS5WEaRO}xro$aN?A?ST`#iw`b6pkZxg-Vjud9caeRTubaYs*uB*jw%Hfc_rh5OS~R|vGr3rJ|k}L%Ci%^%7-#s zbk+f{yX#^vhhNnh*TQ3c5){@I?7n(sWjVcLFPeVGi+Z8I#qM~|@w;nU&LC5;Any+^ z*U+fAvh~idYFX0k*K^7|B;}xv;zo6F>ynLjNQh~ettIz1>vtcV$JOBAD2d;I;TO)$ zU)+nm-o13J`q>B(EV>^QdMZ<-HkbH%Q+NGFuq3x*j#K+{NC^0SlMicP3UA^iC}zDn zas7Q9u6&0lYB85{Xj~>T&=4U1*iRg6^}Uwr4HN*LQ_VnVNy56T=%NC?hYcM*Y~+{O zZ1k*5WlEOpy8OiyNaJpDETTHBlgR02E_-~S)-xqg)8eB>TD)w_ZRzk)Gv3Tua}p*) zyS?y-oG|hT6V5QH>-a?ae zB};~aaYyiqOouEoOIFRu(!0xKsljxvn#^u7;QUJCJc)azjWXRs{Pg>vs-U(xd@sG!abpLHp;m7qZXne_V1(%N+S!{{7wfJAByOTmyxy z`mN~hPM_9hjx4?a5twTt9*iVKURp(@OATbXwR`(LUjM*wN9j z?&qY5%04V@>HOcDh2~0Q^L+g|JE$mAGBf*K`vc(`7oE2XfegHzu|v5w?f25$bti8I z@T_;aYD8^$@3FhPgTfe{u`7p*IsG{3!=hK3&UcHZBoed(R(3WbsD?U>Pihi8&RN>J z|M*$;jvbL1o{_n`e0`flbhQGTaRG1BpYlsS16JcR$iOypEwID{_sE;j+fc^s#z#Gu z*;5jrliJ=bA`ukr|)RSHo9DQ}`!AnF) z2vpevI50;hWb<;hL9b!Jp-RLAD<$%Yof0TmLk!M>msmv!dkzNd_}*MtKdD{<1t1o- zY|vBx)`+6yAA_YVGix^OHUw*GgwvsQ&iTx$7WNQl9!E zc(I>93kVhxY^0Axd7E9vck9Nl7;>(1*KLX1+OjaRFh(@JT(ef6*=0?gwm%*#nVbh* zEQNf1JtV3O4quPx+Xfm;60s1L9*{=En9j0e-0=0Bx%)5*<(bX4pe4Y`IS1EYL@1nT>mQ@cIs$K`hfp z>g!+SRgEEk?k^)UGh-X~Tid@KXNhujx1pLhHU#zb9ULxIHyg_bWL+gG8xz|@AhI6# zhi!>I8C8W4f9HPA1wBn47x(1Ot%k&|K*_8CVa~r!n6^cEUys5+T>*gu0y@B)2jX^zm z-G&{^$YqOh(@^#OhCkf?7p6T1@YtGMu9aG}=~==0(2v)q4i2bu++6wE{Q3gy#gOI* zt#(CRTjX|M2}=7@><8XE@onlr>!(9$FV=My`eUn5es>e@AFHffxZLGhQGN1Y{3hDv z^PVcWyTejy*a7aVuK;Dq8z?}!vX$|UYWY1(z9{|GO?9wklyV`<0!MKu2? zA{%aA(q`|FRrAk?B~Z69sAO6&UU53re)Hbk&tG=!$&@2K8~wL?xK_H~iKc54Sp!K%*AAor>)#Bw`Fzj_}CyVkn`Aa;|)$8 zl5)wFUGT?<);{yG_Dj<|j~U3NYWwkOsq-|qncmB^XRjv(r^b>fr#WPH`YxNxUnYLb zGJIq9M%HSaW?z-%>GHVA@Jv(15=6a)-OK3bvRq@e;Mv{o*+0``UbzLVuUU;BGDybW z-_KPznr9&5sHO&}6`+(J`fYqJ*lG1@ z-0l6I%tyKAT_b!}6e6tkClA%rbc$Af__YE-Q9rK)<6cj0%^#%@G%SDTMWubc$joYi-z zEsrU$3%uCVVlQ}@^_lxXH>DP}Bg>cSQ@%B*U8>dYQdFlklJl}6`rp=bSovqw`10!fxYVX^@2pTXzr}Vg)%?~@(OMb-Rtx{#>oy)Dne*7igu3#> zWK*Q7_i9qn$BNbJJ-lbUq|S0#KE6iTgXeRn>{Bm3Ojnte&O4f&8kfEt^(9-EPQx2^ zh8N6E{Y(9HgfgCmjhE9%xZ!ewN_*g_CUX>GuYP1!8vUP{QfpTCyKTSAU{k_vBDVWS z(YiT`)BE7x>vWcEyA{RI@c7Ezqy3+gVtpsR-IBOP1-(m&(d4bIAz-dsHJ4(?58LA@ zh0*Qnn*sGnoU-M+=dyZv$y@BQ20PzBY-lMMC2#eaw2t(TjO4+$`adUuWJjID0-n{g zMDnF3i@mj4j$wj@xn2&I@DIvA)$lPBZ~9sMp}|nB`P-AjwNL#fbsJinw3{goTZx=T zKgzTtZOBj~J=nmU3+{W1qQsxXW6>ls*dZS1-SRPCIIakWuQY+i<5% zUf&2Y_yOXI}jTHdxG1c^Fd#B8uW6urS>eo4O=zpY5a8J{YWoo z!<$7stKXkx0}W4xTYi=b8rTS-9!Wj96TQKG`mn5Hm1~7bIF)b3%gR{EdOkF4Z46Yq zrJ=r2gXGK^6&$X4UX@2lPi6k>M81mo@!1Uz693A+9+9v0zSL3|41L`_B3AS?S&Nq`?*)-UcPTuHvRK#v4>bPVYi>FGWrAj14974%i7ykeI zsdXwD_o!)^VBkS)YpRkv7djzKL12|dQ<7HeamCG3KlLYDK7F}8%UOBCp<>vJzS^V+7FCZcyB32_H zVE0$ZvEHRMukwYDcbEzxQ;RcM#?DVx!rD$W2M7W)y;WKmhQV3e(xC8BJ!dGT>YHIZ zGK{R)B9hOl7|B<{ew`E427f+m_il?_s;wvo^ayA<36QP(n^PBQxWUxalNzii2o}^;sNBmvkSPcn;tQ}@;|e$^M3b0 zvgHSls9B8JR~M4|dP0(yCLuMzf4TUgx%eSr(dC6>r2=0?t1uz!A~eoL?$!xZlLU6? zroHd>y7@qeo!G@5cdfsSN-am{@k46U`sk_rT$W}aDMj8vcj%o4Y*LE zHN=-Z{NOBaa_JDB&|cT=6BUB(UZkn>5zFAU8;jQpsOkQs7zMd%Kx^98>dMQl!3()gZcRt!U5zCg7M4kjbd)$?fm*l>jwObVt z%t6+kt^6BkEdyiW#=rZ?dqD208N%;o6-+Wmuk^PW^&A9W;9Qe=*c~lH&Oc8Mv&T9L zrjF)@xQD42tB1*Dzsq2(?9bBx50q!5r7xk~UBn2p9ie^fllz~Ok)wEmN2y|C@ciBj zP_+~o-#cuH@$xxvfhMe8el5p&i;g0CYT$0Pw<=tZ9GyHJQut>c{?|9#HBx={r+Ekl zeVaH4ZQ&c^{$hbo*Hrc=%$4+HUVE{K+QY9tYYD%tCmWk#4wo*z-beQ9&u- z^|i+o;`B*vCT`v-vux*DHZtQ=MomY`Ya=5z#-&3~OKTQ)@_kz|oMgaslB(S&e!jQr=CE5Po61Ua4*>u_(88#-3+tM!}m50pFH(4BJs{$flHx z6-z~wh0^wv;qbjLTZjyzmYjL<#y_|_1N zitX;VjSU}#%zmzE#{+{YD?<3Zyvf7%{-1IAv5u|-A649E&*C+w9+jy0@zje`TMrJITo2;ypG zEKthUNAHV{QNUSUclb}a<#--iW~68yjJV@?eRDF8Rx^3|)vGammHnma^1oT*4xqWv z4!GePeLnC&64%O54PCR`e~$B;zI$gz(>|MbO^k-C(z07};r-H##W>lZ#)>$$yfK1T zp<;nM&5w~T^`F9-nP2ND|FHY}RSBLz`WH{$C7P0WQX1--3nzpTxWt`fMqb>-+j`}8 za%gp-yQ!eqIse&Hf;g+!e}HFu<=2l_#@;;p$Vl zfzvle!RdAV3)HvJLr(QDPW*Z!@F{|bD?!J)j>+*EIRuCZiE%7@32I_vc(mwaft|PH z^`thX^ka<~-fyZhK{#u^ryjWNr#{Ot)E_?*zzhvl`%LHsJNIx0IUla+~c8)?4-m3H794)I=>z^ zmN$OEZKG5%7VXREaBh*@F@hnCf z4;q^NuOhDEb-I4iSBGtXGvmfp$GO+uA$!0>smy0AD-u%Z)z9z8 z{TxN*3XbJiI&Q_U@Hig^?6)B;&#+GxVwiZNCI+>&nI-1tQR4OQh?PlQt{(dauOA$W zX>;btG4}Dg;@rPKd}jXk?4bKrJ#~48$iZG~X8%4;OLyeKbR>G(0C{ZnlHqN=+_JQM zJF;50;y5MA6aIA9bpbITs$BxnibqyzY9Cn4FW1xZy)c^{UP?t%0uP|??1M5nAdt18 zQ7}mxZQ|3Q%MAyc6F4*ngoYK%izb`kIQcwyy0egw)mV$+3pP=q6}zp(rn(*3jkkTa z8p24~j=G1WP9NJ$Y{^cY=n= zr_eN?sjY--nVN@fWP#o zlYp4}uPd$AyrC9#d06tR3Jz=jP@N@Zd^1jD0yPov0%!sp1FPHPzJ#Wr(PqdzfBK)D zXNKQKPaEc=l`JBe=mw5wT}~hQy4}zHE==Y>!MJ>z*2RB3X_ngu$5-hx+6Fnj$kol% z2rZp)ZVJ@O)gA4z@so>dH=J{qJL%fRUPBbmZr{Tul~1y>)n8)eknCKUe)C>8cll?w z#m(w>5irtbd!4S(95=_fnU+G(hFw^$Rn!;BMzFSeE;n2cSN({STG3DL{6U(@?6!d~ zWY_n$Dy^v=id zF@nlPx*vpkuuCXrOR{sxr0m4>u)RaK=J{Z_AEeE-<15|Z^FKe?jovUj-jSyhO##z9;C4G%Evm2t|sp^*mEBNU)LDU)$mg7oElH~ zFjUSu7qfLgKyVw^%=TTbo2rajvsWwkFk1I zdpyV%$zb=e!OG))=;7m2$n9-#)buWUF_7J=CbZZCs9$4JNITo-MJ@gIb{C*$A0ty` zRdHwSw+i3H=#C!)-s`cP#>}oCpi{#)u~5O}D@geHtkcAophb$I+&CB9l%Tb=+c~w( zL^Vi)(tPc?4Yf;v$sP%R;|yeVr*{(pJr9$LmZf%11L+FPlPWTcqiq&H=<7W0@|rS{ zJq6`m7M%=1kZL)vYQmjB(U*31tp4VA6vX~PHfMc+j6MSuDZApvJ^zO8pYkT4}{-(dVCDuZVXTvx?7z_xJ;{UWOLhi*8$k72J1- zkWNc=+?c+W0-!ne4EYh#mWfw6H#kllG2dwjy?I2+@$Vel$ASD z@{4LA=k-K`8PJ=W^dcX=qx^N7c{JOMH&-6PG0*T3OWap9>IQQPn-aSog)7<(??S_m-v(wLq!mx+b$a}f#_pp^L-O)m0p+VtEG1uuK z3R_Ur8g;HZD9Hi^@m(Ct50`|Qk2e*oc%+2Iw_v3Q6T4wbbos-mf9j&3J#_zpZ6I8qK5eSRM93j3H!F9#>>gk*$_ zTZh9aRb!Rr^NCn6lpd$HyG{?GB97qH!nt2`(5?$&73cDcFwm^aB^~_es}4Y5qYA2f z<&_>5^~+~UnkbGaRq-eQHHR(aiv;vFM;&Xnk*ie}oID8g)Vbj^E6GaKp7{uJd^i6- zhwGUCy!1bs9X2j8ebMY zLSBZAor|1)_+mCd{D3vbGvn%}YAueV&Bv2m9zvV1<^nX>9QtIQ%;$44_Fbf$g(~;v zV$BiVeKfmE<@z2fjs``#)|v`5&vr^MyR+X^86{Ra^u>bTj6_#DD(otzoC4UVzDW=G zgP*+@TDYF{ekxwV)oqIT&$72p(Q@3G9fzODLNvAX&ZW^1eEu61=2u8>&zWW-WJypq zN%}qQ$@rcIlEftIF1=GssSD>_WcBGFM*~S8o^cE~(&JH}_U7<=Pd|8auYt|dV3G9@$~U|w{lFznxCxa`=sRi}|#n{`=ppNoBE_OqU^q6%e++&vXJ zQe67xsK7^r2l?92@m6R?Uv!S@dpP0Tin#TDj&E_CdLKn7MZsN1RZLeI zxLE}BX$h;1xaY@Y<~8VH4|*#*D|Hay1i~U`zeyLY6E(PcFxL0{MhmA z!#b|{#F@-Wl=5$eT(!&U2Wve7c>86fDvYeSZPlPk7<&qhW+*E0j@IP^UKLhvbBxv{ zQxSKwxF9!M*$&3C#ao@C8@-k`JHn!ulk{JU4IV+GN0iB2@>m1JrERoT_(!xn!jB90 zzlP@gs8ue=fB3Kl)vcm+t43>n6q>7*x(JZ6&;4N8EQM?S|lS7|}Y_3!|$@ zGGezrm`Xd9)Ls1UVwHZfuFIu1n2`&S*N}+Zo&5DD7ZPbvCg;CHzjl#3kEdQ8S^Uob zR@|k`DtyMgpJul9_reQkcutxB4*IJYqW$q{yym{KlS#e>c?;okBVqr#u8PqYrRbyKM{r=sr$7| z;Z8TdaF<4GK;D&&sBbMqfKgXp$_bif`Hn24Y>hqIS0(7bgh;hky_Cy6OjHMy(o3%A+i9Jgijf5_&0MZDQq?_)>cba6PQ zI}xKngS(OBJYoJ2l=R3gJtSwmIQ>O?FEa?|mA6zZB>sUXK{ubX7??FxZ0R)me!`~T z#6P)_nEG$4P7&`VA~)(Xp_y$8GxoK+7v&j+dDwx;)oFi6#Jz-!MW?V$j)$rwH-;#O zWW@30e9+JNc$V{MpQzk>-p#wPdXH{h1EK3Y!DI^4{3=EVRSWWzj}m*--l5N!{z?zy zGtP}^Px0;YUUZ&#Y$H4JWLuc7khTazKj;9GSn4Q}lLI}9^TwdG#M@m>Ux42kE%;Bvv&X#UkBV4|fP+C45k7!2VDp(nFu=meuo5bFm*#=})CK320#v6+Rb z%a|s8hu1D4U$)+$MAerZy+IM{SMZl9=RU_lpwnn3?AyOrk55_>Dq?B&h5E^Cm0(6Z zun?4gXtU$Tu?v0KE*_^uS8WSbo#maPH3Qlc(}ls(tw2hxzM2A%-L)#~eq!3AeKi6z zf;US1Un(cf90S+YMnV=|g&zX9l}9KI``2;u)?KnU#{UR;x?lqcWol7+XpOm~$93MA zC-)q0^|8s#-e%O0__Vt6_0Z!RZ0jaDF=5v3y>SuIG}cA8hDs-g4ncdHdEpAWTT=`trFX!vjugE8b<`n~pqh z^8NGcH>1x$cdF9@$0C=dUocj2+<>Vh|xUE{aFdH(&=%-)RsX zs){x@_UVP8>8DOhFWSdHW-~~J4)5x}qTwL*$61aRcn*pKCoWwWbSLtkTOWWRPvITHRd`c78 zw!3B4zHyOgJoH??b?jparkfAb$%5&<0`cO)dots_IH<+%r4q6bP^s-A`mT(ROun{v z9rMvb^T4X+yZab0O|=GpHJHs^Lt0}jUIM%Ni**9^nl7IzJR_VZC(;J{_F5>QC)Ej; zbp{r4SC)?&|F|$7Tb_#by4^aSWW@QUQ*1UV(^5C?)*W zLWJo3@0s^kC4^VK+9JTX(#R_eoww&DKCPn(OVE5uPt-ALVy#~6c+b=bRKp!^)jQlx zFD}gHtvl_$ssthmIVQ)VnZ-Zg0MDg0JSEI_oS+E1#0XS=1S*kor&geA%0H)V)j%B; zZN+_<|Il;(*0IDAOcx*E7Ym^CLj=n24yDc-rKc}D?Ou1Ze<%{7;?2{qDKlKEJy{!Lgo!$XBqyDL885$*|p4G?PEKqr(R zrdzzVR=;!oS6Bq<30(m*@0*A;hk2U)<~z9nHEDMZ;EYz_o(GQtWo}HJoNdU;@}e62 z`0+%S@#t*v4-0$>W?>qEI_la&MCN@Ns$7h^bhR?D`u7$0?%Ns<6&~?1D``;LB!T}o z0o>SCZ@Rzl>1=NBQU=~s3*}a$%n-laSRxM7b&Kw=B%RF_-sY&x}t>I$)54 z%@s>Pw*lSi9lG^f32(0yH8Y54>LYJfHPi0{)M?H@3E1%{(II7Nx$$_Zv1k?y#q219 zsJ)&>c`8PENok0G(oZNrUzy+Xq%1x}5fxWPxNc6QC^nxX6w{N6>3WJm(F1;oQ+vrr zy`p~*${E3gu)B*YLjU?UqAtW*z=g#8vd45AVLBTyy|*D=wD=#a#0=kS+eIwl8Br7? zYcqtp(JB!aKRyAYEaRDcu5iq+L`-)ThT>`$p0!-ds zqXP8!In|DloO;}xPy%v4$oj>wXTCPnt>dv)IUkiOl|iCCSMU-s6%rA<5((K7pO_MC z=|n(9#HwQ0cPB87oH$Lc46P+bMH)XAFEk$QG6v%ir>OKb|C?|fdCr$IIUml#zXkaI z_4c);ZxxSWN+>J=p+QlXMa*3?RJ?CK>RZIMhikG?0W{99;OA;L822$p(&)M*dC0zEh)Z#I_?-bpi&)Q6Fz5U;ea_Ul+D((K8 zI0lPPJQgsf#e|P45ul_%2^Lk%FY(QM!i_Up?5ZGwTQd-`?%@0OS}q{jQ-%~c5ZQu} zkHf3}-;s_xmt0~r?0J`qZo(Lb)cIKpXpw;5_sx=QpucaM>E5^0`F*3*?r!~9fbh2M z6(UBLX9d#}Q;7oLz5d>w0P0Y>{Q$uUZW)hru~&>5`)Dp6@tFUsXsO-bz#We8=4-0W z|8)VBn-YD;qa}Rvltar5l!jEKN1ls8#N)0a7z&moKA4NgGypn_lVgBY7`ZQjWAXK4 zU$vCR;)KSMuKNC!qqD7wKouuzk{{x)LdHK*nuA6<@BdHT(XDGG{JnP*Dv4sb8Lf}V zd)}_gW2vJ`qpQrnX-ARwT`EAG&t)?DPYe^{k16aihGQTs_G+avO8iXh{}+(^qQFU) zCRAXx_JvLvmxOp09=!Wzf?Y%55Bc@Zu5VH>K%)kekDUAllZtVa*_E2B5&v+NZcUDE z^^q4RG4R@|XIdcZwhe}J=ln?{{6&Wjf4lHNVv>(6=yN+W+aTf0Q?|918VTsW;@*2> z4!myYvgdk`fAog@Dg~@x8xpAhCx1%p_5)eSoAb}WIM&>?xx}YR2kN) z+v`>+p!XjiV#VngU8pqnG}+VcPkR=LZ@K&ISgEVcsit=7)MIb=&)aI$RkB0&CcmZpZ1 z>AFj<0jb!_cI}@|bA3TKivV4H!3cBKQ@rCmmFnT7JBC2J_1*P2Tr?q{rV99q!FTOF z*7gQfGkw>$5x(4xuX?`uR7)AKu*zSzMZ5kwB%K2;K0_2>r$Bvc41weH)78Z|9@p+0 zW;xx!M_~v%IXMa1CCqbRn(dYJw>M1Q{!Q?6lSvqI((%>+k@2kF*&F)l?6)T~ zI_J^()jr@ZQe@-s`9!R~7~6o~)9rjVvPyls%XH}BD<1=~i-Qq;0^xJE8n3sH91KTpOzM|<~ z>h*a~ReR}&DS-=x2GeMYJqzlPJ9Avl(`XrsTpy2a`G3|C!Qe5ICiDjM=`!Er;c4R8 z_%K91O7h$2e-prk%JjmX@k(iyK3pEU{smk7*wdslHEHVcc&aUNC@Ze_c6H~kYdhM@ zCQ#k_M%D>22{u*c?_1Ah$%dmCdD!u&Lrc9WVcbuNSQLZx$vSOq*?(wq!UnquiKcjcM@sTIq_-m8OA^o2MIHxG8D8r>ur}M71RT zx7!8CtLzc<}@dd)$9(q&bh26o$3C+l6WS7#1Xbg3&pJVpIPZKelOpEXA~tEe+q{6^0JB3rl5MBm``QHX_a<9* z*u-JHy@FN;So;4!i--z|xZUvs{;*gYUQ8E&+Uu_cd)b|iy)wpEaDbU+M;V!h`vDhL zap;I~siV|#4k%oa0R~2m<8K`OfL?gsoCg+lE zmb2vd6VO!r^DP&IyxfeBLUR<>y3D%Z6o#P4V!7Db?(QVpXA(7DF>0k4WQ)7qE6%WEZLRGj^o}UKngwzx=8C9AiDZ2EQ4dbgrqlsHQZIXB%jW@%8F_ zz&@)F2V4s6e;^HGX|Q2^M}87VA!;BnYUKq@mCbRq{_ENPzy(xE=)slQTbx@I|v)5f-G|3*pEySbKc^MAjgp? z$n4WfloPE&wf^eMoq#1vrBx3oK9G-%Xc-GPqRR_6u4{$qh{Po*D?pGmiZEF(ydQPBY6 zu~iWABla+PmR+WLnZJhlm0s9d&lBHotcrtTHOvSn#@4Z|bi$5^obZXJ2;?u(d!)0j-tlWnc8j!ku40yL+s;+IW(z2&71+ zNu8!YdUC0-sgO9pnu`Y zbW3F*UdgwJ67{>1Zg<;7JVJ#+lqLK%POvTN-gO>N;}@VQ&F7jN|7dFK7jN}ZlrG=L zCO&CE;SBl}qC#;gX(@Pm#>E_AowmNik5-s3oV5cOQZ;9gKF#d*@#CvK#?A8{kg~s( zmBq5NQ>l-fOl*Je36Th4wTA7OP`8Z{Ax2xE$BQi`i1x#fs|M}Y#S zo8oF<-FKL|&c{S4z6jtKV(SkBzXJc3_0EZ`?C6A8UNS*3g^}3Im3uw`ocXNOI$rzr zj1~GaC`?cNj4 zuch1EH7T%HB#4~C)UR9r%BZ!PC@;afhKto+$=tLne^z*IXU(n6LyJr?p8RfPMZSDpHQ!-n)#N(8Fgv&lsgfi6 z1u2#q&BjC{cCgX{v#V9DcahE4LYx010)Abo?z-=OXVhbwiu?j1!_CEpcrOj{x=!t- zXy#+)_d0Dog1$Q(hso$X!*usxI?>0tcanlN zO?|NVuEa;E={U#AR9&Y9D4=G4lIgZWV+@?x4^j8-1Z3q?ESK zx*aNr;@=@04%Ou6Hhn!%O|j!x0BOp$KZK7qyl0H^H=|v~V|i{yn=hw&ap6+;C7gK|LRA#=nJ1qO1j77#uTUJfCBW|< zKo9zkJI5)^pRQ0fuZZ{P?@XekRk7t*BJ2EI{Nuy^P+5EfLf*j!5I=_J+ZSC}l`~CB zJJ)11TuvthRL#fQVDr%~J3y{xmB#p2*4Z&+^JAoDlHnddpmSJ~%(dU5nWX0`w!fmR z=$>{C)~_BuCh_gu2Ru@cg$#L6N0F_-3TFFF5UOb}338>OO9$6tC zXM@dUolL~MfNcw(!S7f95j^ke8+A;v)6uC>n|(8(9^jzE7OG1^^unUxbG6)CBinSrgXs-Hsu~I-~QCP?H&rq3UvMy}s9}J!SD_DBl~%APKIX z8*=TBi17j-h*;9L8^wc<;RI^3h0E|hIIr)6svVg0V0&W{VBcZTFYrNU#)P+DWWq0F zrD7Smu5TQ2to`Ohu=ZkYu_KQx=|&4UF#@)29-2)VSn&_sbgSM8f8YC##BXN|wb{+L z3BR3X5aR_yqP+=ywV@~Xr3T1Yc&ZSGth)y=AB|Lt$OE*qunhMuIlO3 zkga;V5G&`Bq!Q4jvQq7Tq46<{`_iwhk~~P+&SKc*=N%PAVU(BLy(Dk@^17LNQ10F^jW^)#$$;fg@;w3FSO;%s++zuPJ>MwQ3wu8 z(5piyxBRd~rGYs$vdaHQ*;j@&;e~xmD+s7aNQ#JbcaD%25D*w3-L0g=7>EjrNVk-< z#E1b>1EfoOz=$c`qhn*+yZ`&XU!M=pmwniMU1!(s^ZVWBu5%w-fpbJzf}iI}G!Et+ zs)UY!ms*1?BHrZGs3Hr!TNw_b7Xw0#IX0AP^xMQli}fLdGO4t6@AXJ7ytMg(Yx$oy z!h@4_^M~j2oIl&+K|9`v7~!h!qe1EA*z~W`2Z|rw4M2COnPfZk$K_M6#1{kL_Pzen z$80NFWDSS_zSeQi>2$8xtz>B>5;hI*Q0h-&U(=_gbAz7lF*fdSZ@-3@s;`fKw0fEk zjI((mUrW1%m(C@ez*>7E+KdO=Y82@|=rRgu&9!CkYRkTkxxe(mXz5eB!eYRy)gIhT z9Gmxc@7(}LLQ<8O>(}e1wz!kQAc6ttDKXC9*4kS34lNp8lfGND;hKudlRoGg6j_8a zMqk#mg zd3-pRhN|#i-)&&P%4OI)t^<+*4(Ywo!e>7y2qlDb+X?VQUHr-Ye3qVVbTS%{eE=)P zO)?kS{$R!E+#yd5{AX*0lHrXIkXY!X*doq%kSlWvs;3 zkOaGr9QQ8zX0RvR9}zz2Ryh&wU?{={@07ng5oCM`~^(Zy#HFE5?g&m@A3tTO{0G4#p(p{0HF z0BdGr*sEPGphcw?PGq-+qGpN@iv&xg@R{E}@R+l%ug_`Xc4}NIwOY=0+5B@`?BA1T zAMWMMKA3)>cAK-(y3T?V+Uw$6mgTOgew*{d#9>n@Ab6MN0M?1}U%6aaxm>zjTCDa2 z=bvBqo`e3Je)rEi{l2BR)xJe*S~bCJd58L43N)g#>+zxrK5cDkjDq=Ydd|IH zdmCFvTg_7lA4#PzcO^)~Q%7t*i4UyE2}_{_+$vwB36he7C(<_T>g72rHxAzJ*c7SI z`q#6<{Z4(qhW_Y6L<6W0Jqn`2V{U=jMJ8I3-*#RsJIEF3i@Z-{Q5lR6x;1{MtKs9X z&$lf?gIMqk|{Fe zAv<8Ej6D3Eb+(HLUIiO(HtFoVDN_UKh7Kq&=+wO^gYh9)liXUS+*C z9MFy`;iEm;Uv}q~fy8Oca`?`LY`qv^UU}w#IA^hMM;bYEHlkiS{_nVk1 zL^MzFmym0U>4w(X(TC=py0ltm!X?WRpZZI{KWr^)SZ;6Z!GV?Wo0S@D#yeVP{k~{U zx~YsOfaD4fyx*yr$-PC9n5x!)Z+99els|jza4(Z<=$Y?6sQ;lucyA;i9sD|!zO`2I zrpc0m#yW>hCfl%Xd-pN2Ec)qj zs(3Lba&{V4iVCI0M7-V92d5wJ{_@L#xr1y}>l%7E6d=|<`hITN;{m&V44PYG)K*@s z=TADn*uK!7Cbs|t&LDjyxi&OMN=B-WvnavjvmC90O5thBq^Dr%^y7dMM&dPs` z_(kQM)i@V{)i|za#h{DZ?gK4wpQ4ZnK~Zsyfwe^Q3^7jYN39%?58oj4XG+fm97RR} z;73`&5{CL!gRd`I$RCe{oPB^AJ8A98<&1>K!!Y9x*eP;HAy3Nv3@67&1?R3<-$kaK zk$M?4PXIui!`8y*+pLTj&vXV={V@C88FOabu!`q+USf?a+X{!{x~2DRj@1SrX%Zc% z4&{1SD&#kcte08Vk>*Uha>RXa$wdBkh;W6jnxm7N9tW$n_V8lTUfsm+>j$UmYn#(0 zu8lJuI9ZM+fFOnCD}7H zvD$yamh;HwZ&>+_HD4{e-6TKQoNRPLnX{VO`}842K44|GBMuJOWzcJFw@=d)&LP91wHy0ZP-_ScREe%rs zv0CSg#x`2}Dp?A)z;FOpu4dsf!XO3I>1^U#ejXPHk0`qS@>rfbt1od!(NQh*QY$e; z&$s;DqXQ@D&W2{Ymqs_PdqlMmgVFAXcpdLKvMLPXGb%thjntZ!6Pb`cfi}>_u1~#o z(4DzYpKo>FFxX71-!Mqs%=)}HSUTegNBUi*GT-ls7aIF+EkEYAZG-(+>|x7(i^;7e zd(y%Z5Lc47KG21SX%9TnvKrrP^}2J8hCiHHS#pGVv!ng9lo=lOO=$LPT-w<}479h< zdpTUpjBfg<5LHR9R?TKE$1b-!5=;`-!biXpnFM2~p_)Mo4soK?qJNX!_CU`y5Rb)BKoVEa9(oo?u5ynX<1myXWd|DKF9% zWK`2l<@TBvj5j|)x88z1IWqO47J>7?LXXZruDA8#rw8V!V7)fn{fsARR}u1{@J}2L z;WR_RHY#${|E&S@I~o&?gwTh7^Zs{A9S!jz3O}Z>XJ<@OxZj_LI+%<<)iCdx$g9wN$jP;M07wd`VY!Qd>*phu#(Yk<#me zo=#ZsM-Lk9Q%9;*=#%0D87AV*Z$}5E{uvDwI;G?0Q^CgpNAJ3NE=X&|gmQ+{d>gCl z`Wb8MMe}zxTQk|{rf7L{dzh_me}_M;EX4n|3aVEkPN#ZH+Y?F3ebz50TvBynbXzRWS{E`nxyUAXynP_gJQ-*bfUuv)0ekU)X8Ip>cnC7F$}FX>y@L5b_JJMI*X zb5xK~ft5e^g#KDPRZDGJ?Zpe<$k6d|=6m@vgh;}qIF&R*A)y+`3pdk$YBgWK;HD=A zjeN&#@lati$~>C+vCF&4ZE~N_0nA&TDgqxBkv31K?73NblQzo% zdL}iLFvhF_+-b<_6;KZC$(yIgXe36sf*;YfDj%S{qqG}D&$2F|;Wag{K(RrJb#UnK_)#G%)?J{LL%`$QH836q0GZn|AOn&WI= zVeavudvZN!)ugRr&Pvpo@VuQ;BINT`bbp4=U~sq35Q^}c1cJX2i{gn27f7;DaNV1! zY51#$f2U?Ss+OFjqpRnNm2-;CMbrTY`YPF#*d^-5Z+VczKbM~t;S+WSJ4QB?@T=w8Nb zzbxFN(R>=*!}I4YHpRdGbu*q}cXZEJbo`rP0PF4m7riJYu&*vcxw8Xc7<+-M#dao2 zh5uc3PNEJj64Hy14ggOn9@jr0xMW z;m!`EI2sx70YR%>Gv`J9gXE;=(d|@)foH|ElHKa~ZGOXdD{+#}{N@xhZrF}`YUi^@$SW!boRG)Q5Qry*y!d8>Fv zE3oNf>JVi}IqXH5p$qGoO~+jE*`e{^nKFyz=C7gfC|vL}JR%C?cGjuB$;RWwaPCam zxA<6qzR8bj;bW+7w3 z$;#s}X^v9gotDW>V3Dt5?DX!+ul@d#Ks}#^B_CMyZ@Q`A-*wwXF(2VFeb&O;ZN%;n z?y%R_FSZ+ug-wbM7pmy}tYn^`(tFB^`IJ$wrV9YRK%YD3_#$_Xp5in5>)wismv7aG zP9k13TSye?`*hpfx?p3)|3re5`;e`5G6yei#NP<(ob!>Px)k@OKU@T}7tHYNwN;J_ z;+*kA4{h_kW|x4?%IgCAZuy_Cboin#7CKJ?+-#%f_kq~>XgOv4^sTJfJ1NFu*F&v| z;^rwY{%z`OZ1Ot6*(CW)6Gs~)#i;^DJ`WwgN&NN2ONk_OPw}0xe54cmSwQ)Pg=1jW zCBx_9cRy%OJZN)MS1UR)l&bUQoY9N#U6jFVh$mV;amq&-xOc_~4G^lQOzm6=&Okx& zh^qWW)0!wdYfWm!Rz>ab^BbR|u&!~qC`xC}TIO}ASlg@FInsa~Tn(FFfe&P2SS{R_y&t>Lx-2s za)^lM5$LMO2F7(vil6CAq61jryPkw~vd3A&GKz~Lldub&9l%VJ4D=BeQ-eLd%d`0i zGQr9PK!m@)PxlS?kh@ew@&4M|i(+WPgXt6iZ%n(aosJW@#M=RUWL5yM$JliF4rQhO zhy@f0{k5tfiJIVEl6m1#X`fnhtM$~wQSxw9t~8_c8Pv3?sX8_A?>gPK(7w)&*D&UQ z=Y2R5=opxD3D4SeZ2%R}Cr;-o@KI0VX0`HfAC&Fsds(HfB?;=-!Q0n|UB4slJ!s5ONH_&wz@&hx(;W;ZK*stra zINVt%JKL`E5z|Du@O(wSWi`wR9LEQxWtN^|3Q=28OGSaI{ATTE8D28#ZeIh0LBr|v2bN{@4%L&NbCuD>pm7+eCGH?N(QH+ z#ojM}>Syxhz`VCvyj78VHqAj)&e(WvI#Vk+S=Rp^r0In&M~pH=O{l@Z#&%?G*F|cP zoh26X6{gELPFD(0XB>3r}gDTW5L^u6$IBoVCL9IC4e-a zDPLVw5QibZwW27aA@Au*0M!44gQr9j0RY08Jq{`IJA1!3X1uFTa)PV6Y%ug%I)Qlr z?7Ex$CtGr8*wYdGGK)A}v!Sk)yX~=kDCjApG-$`hX+myt^YaE@1Y*l}lyB*K9}qjpmP& zz3~UMLt2VK=u|KV-6Ed4>T3^wWZF;BsSu%B$}6*TWt}Dzqw`PV2!*tY0;#`NBto@3 zEVF4tF38N7ZkeMLz8%X|g(rz3wBZzQ!kuJ}C#=*?QeV9|<@c;KSTcl3{UJ3B6;X5- z#_0Y_1j#qHVYf`C80y!Yl~+u|gvU%kbK4~c?+v@cT!xV{55uY{P%7EK_pTj*?Vu1S ztn?^?ncer{nQ~bBZ%k{#T*U@RD}Rn?1x-i4()nS)ih8BDif_ky)tmk(qIi6f03Ozl zmw89;I-C-&DN)q_j!O%B`fAMHiBKmrv$nH&(zo&B*4hugp!G)h&$di9(NqUz`=szU zW`E@zgK#-h`E^$)6Q2{ptGt(gve5>ppB1X?MXo{-B4llNQX*sGfLRUX8yc_|yDRF2 z%c=44fcmX@wy(8ocU6v89FC0v2Y`a`9De9|V-BfO@^6j{1&ne#ww!_5CN$Z5N z2WC`C513ongys}~a9oa^=E=C=ugozeCR3Uh)IRLaUNYGN=Of$rXWvQLzFB{2kvgAN zClznOt^=sW$GO4AZy)r3m~O;<*l(qI$A2a^jzJtw&h}9rgS=mHi0qnN-oLhamL9O71nV`u z`5lTaZ^W%t0EPo1wG-A3V~IwW^QoxR3Y?p-l=Wf+G0Z?yrvz%?EMfw0{w z#%op)uL|n$;QGu)xmVz4VZ#zT7iEeU2U8J0yC>J#vyqU*&U;6?UrHw~Ow9dCmsz&m8U;8tMd3%44l)W2Po8 zJ==!b9kbqn(&F(NM`4Q$otG)q;KJ~gxzb{mia&EoRkp6@?B*HQ;YMi-SV&nR%=ZP> z5b4<4513D`_SZ#+-Q5k?Lv3y>Dt~53Fx|(MO^e}jpZ>z%k(|Te7ek90MMgreP_$+9 za)1{0-wO2Gd5^kn$k+2LtVHpvPhuFa<~r@b9krcwKY07!@dmWb=8U#I&)DHRkdBp4 ztD5dKhm%w2G-Pl&7FO}e z%569<=#4s&)!uGYRe3^Lz&I+IX)JhBFr<2fik;%bwj9}%5|Oke^{@?gQ4m@^TG6^V z*!RqPiTsH?iFwGU?|`=Fxu7ln*9M2lf2gOw7arej)mq|OR#}ViiG7O%W!3mkFE6@; z8vY`Ry2$I#a~JIm7w4AR-cD|sth~%KRzM^v_pDo-Ef?(L)CZZH-aQeweWZ!G5Ioji zn^9h%9rYA``OryNWzB#Y(c3Y~bx?ZU2c!MK>{$UT`O)C*Vo6S~lcd&e#EZk7EJW@p8y5V@hc~s4o0nC$9C4vOMCVtHW;} z$8*Febg9j?|DvJb#V*#t=h&FS3Lo7*3@I&+yZF(vjrHFX-VOZa()2!^-di5P4L`f> zA1#QZ@LiN#b)UL!yNp4@YqK}&Y(GtebXy#it?=zce9_8Q9}bxOzMJz{jOiNH-yoL9 zxQ#*4OiXodO@`}jlco3Dt9Kd8d9eb;V=VrtUQa5I&{w4n->M>;H!0j=+kZ1qq3KyB zMlo5^Lm0*waYMc8%LHsQI(w@-)JYx^uNhX1HNBQ0KE0(!t#k?05IcxW8kw_a>qGuZ zGBYut-!fDdA(!7-n&!f$1>9dQ$K|PE0;IOi%iG5;65gdf9L{DZN%I9iw)>OkBD6luUt2nmFX3j@=!QY%azTvj483My38# z5~_2qd_?k81O=Nw;wFNZIN^exoDH%x7uw?0rzzJ|lTlL9iX0rgg%}=^PGme$GYXX? zU5*%g!@lW@@x-XJ)~*0N>YmyWYM4g$kGjxNS*Dp(Kn~IK%bEuod9+-M<)1o=Ig!mn z(h)%rg!J~ae}D?_o^O%|+WE2a*r+K~h;O125Nh%4=qvq(+$TRtuJML6;xF)f_=~hy>&v2qSj5isz)((Z;-;#vT%|H&4 zHar7O@Vy-_F&UBfd2v=sCs}R2lllJ7F;4Yq4QHFPKRgA>y~cR0rt?KL z@!v8wL@0Zyi0HsvX*6S3f)Y!XwEm|RW(7rK@iY`HY}Pxwh>Mnv#=oOnp&r8_^8Dr^ z+zA0?ssChS`8sDx-g8FdXaIbCGl%plI2D!}RA9qmZs`p+Sw=UZb-_wgkGy}e1QG z5_>MJC;c%NwVZQT4e5`Xoos)*(SdjivHm8s_2cORIeE89?E;q&iQV;a$LVJa{vV{K z1xgi7dSZa>%Ma~gx#+k5`eKPz&IV6a${zcUDQjaf4&obWqg^hxT;l-wm!$}zgtN%E z2H=ja)s=JY%Zge~yD`+5{X>?oBzh6Zp4Gv~`M-x)vIOk&Y{b?7+lbrEJa>m8 zM@S~7YTfI&{oIUh5LUck!p_)NdYH#=bMieHts%s=p~lr}@F_>+Ru4;&QX~9PJ2!^)T3x z_QxM#j58sDQ>IezI5FRBmMxR@nhF@|moN%|lI<`fSHf1p01 z8y+gGk0o~)gcUFQAW%a5BON0q4*GjWsp&=Q*2qm0chAKfzR|f7bGsWk=ec0!hE%=- zn?SU%yRYSVyMbtaHp?1(vUyM`gL8M#T!XCzu3CFH$1KW&{~iqxddLvQz3FSd18L)q zc6q0-;Ik0LZ41+rHm~W$P)8=y|zy(Vj6t= z#aF}DQ%^CJWw^4QDl&gesQO{ zS`AOFtVIC;-!i)(u%nE!J_+}C9hChz)}5@jH1JO?=hZ9Tx;4*BA^D)jxEW>obAsDatrShiL#)Sfmq?1$J)W>Y%x zhrNu78#zt;oA~T)hIH1K=NOkJFqU@1yEhOH}{oAhDXK8+*ln|SK#KumkowCD*A5NKDzG$q& zciR}D^i%)1qfGf>Qb^cMW1^J&R#=5E4~f5TW_pB+C==Ab&L0GO*#s^Y(2zfGPBylq z=l|M)C-Y)z{pD=q>9d(13;$dpa%n!PjCJ2JI_Us_fNZpK3)Y$Z<2oT>Nx>u8eOqIP z-R(3uGVI~q>du*cdr5k?W$tRBS5YEC2hes3jj)yT7x?WTOW2t&P;PC^Vi$DdCb*Y# z-gD}DdW!$cqi^Wkh^38>R*bCc%=+bD&_JXaxXmJCT}5ir{J8U4;6`` zO6pT@_1q>T;srx~W)?M@EhYq2tA@}#?L_~HF1(yd%~56qDY#zZRUjYB4E63jMMaF^ zYFd;$&d6{jT?!`^iidkU?OV_Qg?M}C_b273T7DV4F%%n%XbI%%7ukMOhx9K$P)sxp z?UM`(ds2|=zlHd=9BmveTk*~^R9&Z%z4AM*?e2?QM4|3CWL&ouxE~r2`5>W+JPL#- zI(&|cTi)th>4@^Cf1EH~k-N$<(Z*Pk9QG};PuC{3aCOxE+M83_7TEY5PBU({au6F+ z;3Oiv4W*C;0qPY)I$<3X+(ONM7xiip9EA*iR-b}(H-_Z| z8Wsl;ac)8d^w!m1+YI>kOe5 zQagxKBw=643iC&@Z9JVJiFnI*A0y**SCzaY-u_XG$V_IPJTQyb#{+ifRN;*NyuFYF z*h=YmOnai=ruGdh#DX%pjDEdK;rw&wZrJ6WP$5;cFE6$w`^*dH|9~{%Gn1D z@**XMBfmawqoGeGbOYS>F&u8W=K7v13Kfu&zz%o5EI5h5y(&773+L=nZ*UbHmvdlTQRmOp3cx#^JGMHz*iN77RA%2*YGpFP_PW!m|Yf7x{dX4|I=V6OZeba2w*>$>CCCOt7Pe~x?aJCBgzMbYh~ z-k1rk(=UmR!8Zl-m#b}Dt@JTcH~uWnx$Sg21Bp0)-A?_Ki0bfX#yXJp7;)W=W!bS6 z{YFK9nM>;9C-~;>rEQ00q;l?4`gk0IeU^Qsn8i^62Zu;_)!>$a_!?H$4z5N3wq$$&a-jiAb zJ9mHabdy`@C0AM$+a)q&2&&1Y=8@~Y$)75F6bDWpH?682P_S@!+7>$I-f&hgktsFG-#LB!ln~mayiv zkzBu=x*i1m6+?1z8RsVb)B5WfqVL z3Ka<1@Q9 zGpf(Vjf){+23fQnVOAooGs+0n z=Y*#lGL$$A+X&R`$59dX1KW%D$;h}s``Lu6xGuov8iXppGwB5N>T3KaRVAz!pnZ+G zO1PVle?||cJpmil#c&6z9z>xt{x20cQgM}5>iO7uMvL6oFKqB1uPeh!8YLGk^IRJt zQ%WsWy@TF^MJL=P)Tj>Hmf2E@sCvQ{1_f+JuO5V6ZbHd`~q z&7_qYI`VEY3S_~D)c=>3a8=3M*~x!X7Gv8fJdB6vV!!?3E~aHyN1vG!8e={hHtsOnQ^w@oP&2AR}EyE3P+&&591Wi8U#%?uoj>vpE z>&STs@~xp>v`OKJ?6}~)iT_8ax6tBN*!z@)e^Ngpku-|PDJyB?!~X0#)6mYZ9DPzA z4$?-pSR~~?5w=YVzl5k`#geZa3kHjYC_6dBal}V5=qqF^pJ2qvT;SgXguGDa0>W=v zu|H8D5Zj1aTDh0zT3K(+oWu1!OjLhbxYM5h6&IB?vP3(~8GDegOxgDL)aJ8&!NGpsaR)eSbDXzMtt@&lcmu2x&G%Bwo8N_q zjqxH`zO+jberl!jV>?3TA$FhcHJ}R5)p1E(f)A74#f&R@?rJPu)f@AHIj#gSX(ztR zzuZ7iZ`e1EhuWNvPlg{uPR86X^75TcwL{3v7&WKPq*`;7wQa2v8PC(jS9*Q!u8Pd5 zJ61|AwgK^FC+#KBaaWlSXN*H&75rrh>P{|oaCO;-3_3AO;4N>YkJ@hf|WJtm1?FsOPB18wpcOhZLHnoCIgiU7P*8cA3fE%_Z51}pr(8V`A7n%_Kc?E{(|vdzuf`2iyz8oluEE0wbjJ6)7=Rkt$ZdX~B< zWvhrYQ+hn21F2#Hi99!JBkc59 zrHQMOdfK~~Wd%2Nw)1) zVP!7~3L`b^wf|qLOA;*=(?_JYTKm-QGiy50XurL%-5pjlV!^x~{;0mUK(<<--R`Ax zHhqXkl{#NO^B%~u2Exn|Y6;J0W&vCJ&`P_cf1P{OC_!bjD1#gQtZT8<+*W zGB7dB0^S*z9Og=o3=D+1(l-Me#q8;xfsJF{^UA=cG4FY1U$W;*o`C?}OgYh%FSyng=VW@g&q?F(M<5~t9783X$`%g6U_X*nF+aPF{ zgrHroOad7D31H03AZXVj$fNH6qcMtrMs5NcYb9w|h+Vd7-`bI}x?D@31!DS01pd`J z5jNfBKOlVU@{p@~2qcLy{SQE)cHXRT;;NJ$`Ka?ZK#tl78WwWtUVC=CB36cT#Wys1 z@A4k@6A&ZDx_OIX++Kq~h^o6l{uon|k-r4)8qj!>nGM=ocP+8PX$ch6j5PJjWCT*j z^tIo@{zqLp0(CwAqb?1By72#~izZNa{xN~NEdL19T_aG}%k1MMbMLL%^3U!=nzt6C z-z9@V4y;fnBB4?`aWd%BiB(cb3b$k8Y!)afQ8lGxP9*%c<&Q`>(SLCdtz~_rG`Z!^ zNQUz#2vZe3QXy-VhUj$80{Und#tD8^|J!cV1#)E2pb1J+sPe>XVnRglkq{AZpP3Vl zkz3Y9rW0jbsR$5PKUb-|RsBk(lA`*BiYH0+Yn45+YBd!WqH1Fmi5s#Y-U9AOGogZ# zXfv(?`uAo61!>V{JO#5+W+DZR@8ORN&LiQx1=P{-rv+p0;erKy!S;miw<#4*dV)vV zc*o7TppnY0u^{j^A<7G+bXzV6yyK=`5J=@_GZ9J({gq*FNNmaP1|qg3a>Ei^^0|=^ zTT;746I)8SsS{f=y7dqv9=mZ7XH!6ph=eX6M=8XX;%;li*>sW#k!Hl%<|>usgpkMc zM_dEXxqEJb1u2wh;s+`8?Sum;6ePT;)HyWa9BFVByIE`ggB%C5! zPlbi7`lU)k`_*DexCw5f@=q3;<0*n)(s+IR9G*v1e zPTU1Yvr)R;DKMpS+bNj6?e?)?meOsbVD^q%V8JYvTXlidZ8xO?DN47V0;xN04FytE zZpS&Ihqv9_3mPfigeMTBQ1OW+>uF=pud2#>$(`YcH!^N{EAADaA8c7Vj=%i#YeFuP zVM5-Dc)TRYJNaPTUDWMQU+p#inT0J(=34s?Q|)GYSJ<(TQaz}AyrA!L@S?asIm`(& zy#$`)TCCi}?y)bxq)@h(gILv5TwucM2q`lp*QJaUe2VMRPzt`lb?GVvpX0g&OGz(r zVW^}wcajKZC=MZr;gU+PwYaeL5DaYCN6ln9HtciE0w-MvV>;^U$LjH>jiau(wj8c zZD%w6;}qE|>m2OJX#|i@5-vTeT;fz!h z1VM4XOY`7y3Uk~t|A3W;;M+>p{EE7>YCpxYe#)ld<9ud+-?TLiDYH7$Zz7j3?HjE& z-o1*K@=jYbmx9AgzXi_%$IaxF%^af%0?YV#g1}eGWjk#xP>NwrVBpe2u);i#w!H4E zO$e@_|8>VnxO#lr+3+cyl-Yv7xa$ni8ls3davUQFbm9XE0s$%bqQLmT%=}A;BG|-n zjUX_Lw`dwVRhMGu)Xy{gIo|)wH)Si|V-%*J2l-j|+xz6k%pbof9im*-g7?l*1e-aY zFRouVF?%jN8y}wqZV@Dqel%eP!j81-+lah$%=11$zb9;oFhr}o?!&?ine=z5eNsrpsfwpB>)8~00hCk~92u9uP7QqKt0-c1G zZQ_FMI{3d{IL#I*g+|VXq6G|RY!2-27Bu{f03R@Boy>#frVf|Dhv?J7( zDOWo9YMfl*hkhj%zxLGy3y#@G3I6osK_y~ynH&E5)G%fA2tEm}628o353*(s8eGe0 z6+VCrt#MY4w3Nk|W+busg_j982gk4?E9x@mHm(e;Gm4evV2*(cA(r!jZ`EDqikpN@ zXK*RH);K>)V4!FyJ}m`2VL2v zn}-{VZmq8(=H%v>`*vwVziL@EQQ8@?nqkNfKzTj;SDp*1AM;#%#Vl=jDeK2m4)0O6 zC&XTZ2Zb)&&H+>{C0(I9hk+XQJAg)xo7W3$UG1!9q@!z-yPd?|;)h0O9M%t;aEp(p zVS1H#A3L(PUNi@Jhi68U7rR|9;Rt)S`o$V?@=T5Jj7jQ=jlakIhR~-MJy5gDG$-2W zF9%zB%;|@Vk0BA3R);=zfvnQEs)8)7GTyFRNmS2l9GLvB(VMbLRH&W>k=OonuRDxW z4IXnFAsqRUgd<#ue(-y%gD?**?ehyR?h zRC6mE#sHsV{teLKdhLi6Rn|wF>T0M;>0;&la3D{Nvp{sB%EOLu_y# zuW6OR>jAd4_L1kSYISO-!rYiy`7qWx&IgS!ED; z;C<6t!|R2sTAz1NV7||$D-aQ!f)ZlAyjgh3tx)}J(_O#G*4jN|lB~1_M609;W}H7z zPP)DIu8Pe}XX6GtnajUg3;D$2-^Ry`v>kt*AUz48uqO#J4aoLRq}A~r4uiC`wIZ!L zLOR%5-3g^N&yy$kTJXD7aRQEv!}Hg^C0_@|AzzCU9j_CbzBY6@;JJhye`9K=@ox@j ztG@KGcJbqjgo;>NtFID_`?p@7@;kDv2lzXCk;55_zb+TJYA;>U5}Yy3sFJtyg0-*Q zEl&OvCp==d6_=2d-E?lWVVIb@8?tRT$adL-BtPE$it1{X{ym4 zLd!uvx3}&2kFSo&Q|5-2bV0WI*u?eGtC5jIJozSRlLa3t9OF)Z^{Kl|*k7rZlg5)s zy8O3zY7ob*{@vr=-P*l>A4i|Bebq#Xsh4wzCat8X`bv9@xKO}*32qv*DHAB4mkfSO z@BykfSjDW>`BUzt@vK!C6776qdW{QZe69ffk~m(Yp-LN=*tZgZ{KbFPp}(;icZPER z6JLrUj~i4@AJZ0kiYhflUt$^*QrO@wMJsWZ*ZW^>B-Ww(VqCfEer6uS+^vAnl5Gp8 z3+yS^{D=^GYf6x#2+t~8gvF6mQOx_%r{Aq&$#lWe0W&Bak@(0!;x*I)7mENzHLYYv z8|e_ko~mJNUJ}jI)*j|PVuMTTrlK*rs0O*c5;D!KjJ&h9prG`8UHVSO{}y5qWG2MUNdF|6 zrSp(kZq5<;E%K+Wkk_@(jC^nOF?kERH@b@a-)HFW(A)dus=_J56_d^LgN65Ia;TKRc_ zKAP?S0q z|KUs7eh#KWvGKidIo&8iN+v%W4~NqL`mI_&o2?n|&fw~-6Jt_+%g|npDBI_BH|QU; zL&b9W^oC`1kh?)E$^O5R%m3egubg~o+9>8{uuZQ&md^>|%glR=p5`)T>gMibrOFM! z={hQQr*{|HE+s{9 zCI0uC+5CT$?sMNMu1P>eka-nKJmq?@Q;JenOae$oZ)Yq<9s$o_56 zjpZz5+`TrCZ$9HLsg=r523bWLX5_a@i#4*?UEVHqr7O8Iknd>$UqASIX{^Vp1ck0T`n?$h=$!mZ-_r-F*vTW4IbNJp}WzqEXCw{&N328ik-G zm22m4EdE7%qyo24d%m7EXUEwa&8EjvY%7;$9E-gqOd)bV9ui}%w^f_|+Rdea{ zmGlEh-;DGZQTki6wD-WIQcO2D2BazNK8*B*RGy2nbow{F$M8%_>NzQfs};*4f1W}5 zyJAM_Ccd>rv~bi-T#XG1}hXj>{=024=nzHtkUZQ@z1~L z-8n)0^EJJfp-)Q!t>rpF`~zCAfaV5mOhBswEw(z4#@0W^=)IU3_GXx6uN9&16sk7T z;}5z)JINa-c~>g(1~V5e&kjAdT&2WWzZb|0BhIRaJkM21oV6h{tT>C-Ui-oC_|=T` z5b+RC5Oh8JgDk4op*@5 z;7hn>Mt%?EGCOxy)coHANuMwnN-6{AEi`r(f>!yP8R

^ycXFc*QB)9NkH=qeBxr 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 O=;?s!w;h@(CiXuAPatUk literal 0 HcmV?d00001 diff --git a/python/examples/dot.py b/python/examples/dot.py new file mode 100644 index 000000000..e7c7b1664 --- /dev/null +++ b/python/examples/dot.py @@ -0,0 +1,42 @@ +import libtriton + +src = """ +const tunable int TM = {128}; +const tunable int TN = {128}; +const tunable int TK = {32}; + +void matmul(restrict read_only align(16) half *A, + restrict read_only align(16) half *B, + restrict read_only align(16) half *C, + int M, int N, int K, + multiple_of(8) int lda, multiple_of(8)" int ldb, int ldc) { + int ridx = get_range_id(0); + int ridy = get_range_id(1); + int rxa[TM] = ridx * TM + (0 ... TM); + int ryb[TN] = ridy * TN + (0 ... TN); + int rka[TK] = 0 ... TK; + int rkb[TK] = 0 ... TK; + float xc[TM, TN] = 0; + half* pa[TM, TK] = A + rka[newaxis, :]*lda + rxa[:, newaxis]; + half* pb[TN, TK] = B + rkb[newaxis, :]*ldb + ryb[:, newaxis]; + half a[TM, TK] = *pa; + half b[TN, TK] = *pb; + for(int k = K; k > 0; k = k - TK){ + xc = dot(a, trans(b), xc); + pa = pa + TK*lda; + pb = pb + TK*ldb; + a = *pa; + b = *pb; + } + int rxc[TM] = ridx * TM + (0 ... TM); + int ryc[TN] = ridy * TN + (0 ... TN); + half* pc[TM, TN] = C + ryc[newaxis, :]*ldc + rxc[:, newaxis]; + half c[TM, TN] = xc; + bool checkc0[TM] = rxc < M; + bool checkc1[TN] = ryc < N; + bool checkc[TM, TN] = checkc0[:, newaxis] && checkc1[newaxis, :]; + @checkc *pc = c; +} +""" + +print(libtriton.make_tensorflow_src(src, [2], '(M + #TM - 1)/#TM, (N + #TN - 1)/#TN, 1')) \ No newline at end of file diff --git a/python/setup.py b/python/setup.py new file mode 100644 index 000000000..057362b0f --- /dev/null +++ b/python/setup.py @@ -0,0 +1,76 @@ +import os +import re +import sys +import sysconfig +import platform +import subprocess +import distutils + +from distutils.version import LooseVersion +from setuptools import setup, Extension, find_packages +from setuptools.command.build_ext import build_ext +from setuptools.command.test import test as TestCommand + +class CMakeExtension(Extension): + def __init__(self, name, sourcedir=''): + Extension.__init__(self, name, sources=[]) + self.sourcedir = os.path.abspath(sourcedir) + + +class CMakeBuild(build_ext): + def run(self): + try: + out = subprocess.check_output(['cmake', '--version']) + except OSError: + raise RuntimeError("CMake must be installed to build the following extensions: " + + ", ".join(e.name for e in self.extensions)) + + if platform.system() == "Windows": + cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1)) + if cmake_version < '3.1.0': + raise RuntimeError("CMake >= 3.1.0 is required on Windows") + + for ext in self.extensions: + self.build_extension(ext) + + def build_extension(self, ext): + extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) + python_include_dirs = distutils.sysconfig.get_python_inc() + python_lib_dirs = distutils.sysconfig.get_config_var('LIBDIR') + cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, + '-DBUILD_EXAMPLES=OFF', + '-DBUILD_PYTHON_MODULE=ON', + '-DPYTHON_INCLUDE_DIRS=' + python_include_dirs] + + cfg = 'Debug' if self.debug else 'Release' + build_args = ['--config', cfg] + + if platform.system() == "Windows": + cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)] + if sys.maxsize > 2**32: + cmake_args += ['-A', 'x64'] + build_args += ['--', '/m'] + else: + cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] + build_args += ['--', '-j4'] + + env = os.environ.copy() + env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(env.get('CXXFLAGS', ''), + self.distribution.get_version()) + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + sourcedir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) + subprocess.check_call(['cmake', sourcedir] + cmake_args, cwd=self.build_temp, env=env) + subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=self.build_temp) + +setup( + name='triton', + version='0.1', + author='Philippe Tillet', + author_email='ptillet@g.harvard.edu', + description='A language and compiler for custom Deep Learning operations', + long_description='', + ext_modules=[CMakeExtension('triton')], + cmdclass=dict(build_ext=CMakeBuild), + zip_safe=False, +) diff --git a/python/src/pybind11/attr.h b/python/src/pybind11/attr.h new file mode 100644 index 000000000..6962d6fc5 --- /dev/null +++ b/python/src/pybind11/attr.h @@ -0,0 +1,493 @@ +/* + pybind11/attr.h: Infrastructure for processing custom + type and function attributes + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "cast.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +/// \addtogroup annotations +/// @{ + +/// Annotation for methods +struct is_method { handle class_; is_method(const handle &c) : class_(c) { } }; + +/// Annotation for operators +struct is_operator { }; + +/// Annotation for parent scope +struct scope { handle value; scope(const handle &s) : value(s) { } }; + +/// Annotation for documentation +struct doc { const char *value; doc(const char *value) : value(value) { } }; + +/// Annotation for function names +struct name { const char *value; name(const char *value) : value(value) { } }; + +/// Annotation indicating that a function is an overload associated with a given "sibling" +struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } }; + +/// Annotation indicating that a class derives from another given type +template struct base { + PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") + base() { } +}; + +/// Keep patient alive while nurse lives +template struct keep_alive { }; + +/// Annotation indicating that a class is involved in a multiple inheritance relationship +struct multiple_inheritance { }; + +/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class +struct dynamic_attr { }; + +/// Annotation which enables the buffer protocol for a type +struct buffer_protocol { }; + +/// Annotation which requests that a special metaclass is created for a type +struct metaclass { + handle value; + + PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.") + metaclass() {} + + /// Override pybind11's default metaclass + explicit metaclass(handle value) : value(value) { } +}; + +/// Annotation that marks a class as local to the module: +struct module_local { const bool value; constexpr module_local(bool v = true) : value(v) { } }; + +/// Annotation to mark enums as an arithmetic type +struct arithmetic { }; + +/** \rst + A call policy which places one or more guard variables (``Ts...``) around the function call. + + For example, this definition: + + .. code-block:: cpp + + m.def("foo", foo, py::call_guard()); + + is equivalent to the following pseudocode: + + .. code-block:: cpp + + m.def("foo", [](args...) { + T scope_guard; + return foo(args...); // forwarded arguments + }); + \endrst */ +template struct call_guard; + +template <> struct call_guard<> { using type = detail::void_type; }; + +template +struct call_guard { + static_assert(std::is_default_constructible::value, + "The guard type must be default constructible"); + + using type = T; +}; + +template +struct call_guard { + struct type { + T guard{}; // Compose multiple guard types with left-to-right default-constructor order + typename call_guard::type next{}; + }; +}; + +/// @} annotations + +NAMESPACE_BEGIN(detail) +/* Forward declarations */ +enum op_id : int; +enum op_type : int; +struct undefined_t; +template struct op_; +inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); + +/// Internal data structure which holds metadata about a keyword argument +struct argument_record { + const char *name; ///< Argument name + const char *descr; ///< Human-readable version of the argument value + handle value; ///< Associated Python object + bool convert : 1; ///< True if the argument is allowed to convert when loading + bool none : 1; ///< True if None is allowed when loading + + argument_record(const char *name, const char *descr, handle value, bool convert, bool none) + : name(name), descr(descr), value(value), convert(convert), none(none) { } +}; + +/// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) +struct function_record { + function_record() + : is_constructor(false), is_new_style_constructor(false), is_stateless(false), + is_operator(false), has_args(false), has_kwargs(false), is_method(false) { } + + /// Function name + char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ + + // User-specified documentation string + char *doc = nullptr; + + /// Human-readable version of the function signature + char *signature = nullptr; + + /// List of registered keyword arguments + std::vector args; + + /// Pointer to lambda function which converts arguments and performs the actual call + handle (*impl) (function_call &) = nullptr; + + /// Storage for the wrapped function pointer and captured data, if any + void *data[3] = { }; + + /// Pointer to custom destructor for 'data' (if needed) + void (*free_data) (function_record *ptr) = nullptr; + + /// Return value policy associated with this function + return_value_policy policy = return_value_policy::automatic; + + /// True if name == '__init__' + bool is_constructor : 1; + + /// True if this is a new-style `__init__` defined in `detail/init.h` + bool is_new_style_constructor : 1; + + /// True if this is a stateless function pointer + bool is_stateless : 1; + + /// True if this is an operator (__add__), etc. + bool is_operator : 1; + + /// True if the function has a '*args' argument + bool has_args : 1; + + /// True if the function has a '**kwargs' argument + bool has_kwargs : 1; + + /// True if this is a method + bool is_method : 1; + + /// Number of arguments (including py::args and/or py::kwargs, if present) + std::uint16_t nargs; + + /// Python method object + PyMethodDef *def = nullptr; + + /// Python handle to the parent scope (a class or a module) + handle scope; + + /// Python handle to the sibling function representing an overload chain + handle sibling; + + /// Pointer to next overload + function_record *next = nullptr; +}; + +/// Special data structure which (temporarily) holds metadata about a bound class +struct type_record { + PYBIND11_NOINLINE type_record() + : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), + default_holder(true), module_local(false) { } + + /// Handle to the parent scope + handle scope; + + /// Name of the class + const char *name = nullptr; + + // Pointer to RTTI type_info data structure + const std::type_info *type = nullptr; + + /// How large is the underlying C++ type? + size_t type_size = 0; + + /// What is the alignment of the underlying C++ type? + size_t type_align = 0; + + /// How large is the type's holder? + size_t holder_size = 0; + + /// The global operator new can be overridden with a class-specific variant + void *(*operator_new)(size_t) = nullptr; + + /// Function pointer to class_<..>::init_instance + void (*init_instance)(instance *, const void *) = nullptr; + + /// Function pointer to class_<..>::dealloc + void (*dealloc)(detail::value_and_holder &) = nullptr; + + /// List of base classes of the newly created type + list bases; + + /// Optional docstring + const char *doc = nullptr; + + /// Custom metaclass (optional) + handle metaclass; + + /// Multiple inheritance marker + bool multiple_inheritance : 1; + + /// Does the class manage a __dict__? + bool dynamic_attr : 1; + + /// Does the class implement the buffer protocol? + bool buffer_protocol : 1; + + /// Is the default (unique_ptr) holder type used? + bool default_holder : 1; + + /// Is the class definition local to the module shared object? + bool module_local : 1; + + PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { + auto base_info = detail::get_type_info(base, false); + if (!base_info) { + std::string tname(base.name()); + detail::clean_type_id(tname); + pybind11_fail("generic_type: type \"" + std::string(name) + + "\" referenced unknown base type \"" + tname + "\""); + } + + if (default_holder != base_info->default_holder) { + std::string tname(base.name()); + detail::clean_type_id(tname); + pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + + (default_holder ? "does not have" : "has") + + " a non-default holder type while its base \"" + tname + "\" " + + (base_info->default_holder ? "does not" : "does")); + } + + bases.append((PyObject *) base_info->type); + + if (base_info->type->tp_dictoffset != 0) + dynamic_attr = true; + + if (caster) + base_info->implicit_casts.emplace_back(type, caster); + } +}; + +inline function_call::function_call(const function_record &f, handle p) : + func(f), parent(p) { + args.reserve(f.nargs); + args_convert.reserve(f.nargs); +} + +/// Tag for a new-style `__init__` defined in `detail/init.h` +struct is_new_style_constructor { }; + +/** + * Partial template specializations to process custom attributes provided to + * cpp_function_ and class_. These are either used to initialize the respective + * fields in the type_record and function_record data structures or executed at + * runtime to deal with custom call policies (e.g. keep_alive). + */ +template struct process_attribute; + +template struct process_attribute_default { + /// Default implementation: do nothing + static void init(const T &, function_record *) { } + static void init(const T &, type_record *) { } + static void precall(function_call &) { } + static void postcall(function_call &, handle) { } +}; + +/// Process an attribute specifying the function's name +template <> struct process_attribute : process_attribute_default { + static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } +}; + +/// Process an attribute specifying the function's docstring +template <> struct process_attribute : process_attribute_default { + static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } +}; + +/// Process an attribute specifying the function's docstring (provided as a C-style string) +template <> struct process_attribute : process_attribute_default { + static void init(const char *d, function_record *r) { r->doc = const_cast(d); } + static void init(const char *d, type_record *r) { r->doc = const_cast(d); } +}; +template <> struct process_attribute : process_attribute { }; + +/// Process an attribute indicating the function's return value policy +template <> struct process_attribute : process_attribute_default { + static void init(const return_value_policy &p, function_record *r) { r->policy = p; } +}; + +/// Process an attribute which indicates that this is an overloaded function associated with a given sibling +template <> struct process_attribute : process_attribute_default { + static void init(const sibling &s, function_record *r) { r->sibling = s.value; } +}; + +/// Process an attribute which indicates that this function is a method +template <> struct process_attribute : process_attribute_default { + static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } +}; + +/// Process an attribute which indicates the parent scope of a method +template <> struct process_attribute : process_attribute_default { + static void init(const scope &s, function_record *r) { r->scope = s.value; } +}; + +/// Process an attribute which indicates that this function is an operator +template <> struct process_attribute : process_attribute_default { + static void init(const is_operator &, function_record *r) { r->is_operator = true; } +}; + +template <> struct process_attribute : process_attribute_default { + static void init(const is_new_style_constructor &, function_record *r) { r->is_new_style_constructor = true; } +}; + +/// Process a keyword argument attribute (*without* a default value) +template <> struct process_attribute : process_attribute_default { + static void init(const arg &a, function_record *r) { + if (r->is_method && r->args.empty()) + r->args.emplace_back("self", nullptr, handle(), true /*convert*/, false /*none not allowed*/); + r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); + } +}; + +/// Process a keyword argument attribute (*with* a default value) +template <> struct process_attribute : process_attribute_default { + static void init(const arg_v &a, function_record *r) { + if (r->is_method && r->args.empty()) + r->args.emplace_back("self", nullptr /*descr*/, handle() /*parent*/, true /*convert*/, false /*none not allowed*/); + + if (!a.value) { +#if !defined(NDEBUG) + std::string descr("'"); + if (a.name) descr += std::string(a.name) + ": "; + descr += a.type + "'"; + if (r->is_method) { + if (r->name) + descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; + else + descr += " in method of '" + (std::string) str(r->scope) + "'"; + } else if (r->name) { + descr += " in function '" + (std::string) r->name + "'"; + } + pybind11_fail("arg(): could not convert default argument " + + descr + " into a Python object (type not registered yet?)"); +#else + pybind11_fail("arg(): could not convert default argument " + "into a Python object (type not registered yet?). " + "Compile in debug mode for more information."); +#endif + } + r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none); + } +}; + +/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that) +template +struct process_attribute::value>> : process_attribute_default { + static void init(const handle &h, type_record *r) { r->bases.append(h); } +}; + +/// Process a parent class attribute (deprecated, does not support multiple inheritance) +template +struct process_attribute> : process_attribute_default> { + static void init(const base &, type_record *r) { r->add_base(typeid(T), nullptr); } +}; + +/// Process a multiple inheritance attribute +template <> +struct process_attribute : process_attribute_default { + static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; } +}; + +template <> +struct process_attribute : process_attribute_default { + static void init(const module_local &l, type_record *r) { r->module_local = l.value; } +}; + +/// Process an 'arithmetic' attribute for enums (does nothing here) +template <> +struct process_attribute : process_attribute_default {}; + +template +struct process_attribute> : process_attribute_default> { }; + +/** + * Process a keep_alive call policy -- invokes keep_alive_impl during the + * pre-call handler if both Nurse, Patient != 0 and use the post-call handler + * otherwise + */ +template struct process_attribute> : public process_attribute_default> { + template = 0> + static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); } + template = 0> + static void postcall(function_call &, handle) { } + template = 0> + static void precall(function_call &) { } + template = 0> + static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); } +}; + +/// Recursively iterate over variadic template arguments +template struct process_attributes { + static void init(const Args&... args, function_record *r) { + int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; + ignore_unused(unused); + } + static void init(const Args&... args, type_record *r) { + int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; + ignore_unused(unused); + } + static void precall(function_call &call) { + int unused[] = { 0, (process_attribute::type>::precall(call), 0) ... }; + ignore_unused(unused); + } + static void postcall(function_call &call, handle fn_ret) { + int unused[] = { 0, (process_attribute::type>::postcall(call, fn_ret), 0) ... }; + ignore_unused(unused); + } +}; + +template +using is_call_guard = is_instantiation; + +/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found) +template +using extract_guard_t = typename exactly_one_t, Extra...>::type; + +/// Check the number of named arguments at compile time +template ::value...), + size_t self = constexpr_sum(std::is_same::value...)> +constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { + return named == 0 || (self + named + has_args + has_kwargs) == nargs; +} + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/buffer_info.h b/python/src/pybind11/buffer_info.h new file mode 100644 index 000000000..9f072fa73 --- /dev/null +++ b/python/src/pybind11/buffer_info.h @@ -0,0 +1,108 @@ +/* + pybind11/buffer_info.h: Python buffer object interface + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "detail/common.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +/// Information record describing a Python buffer object +struct buffer_info { + void *ptr = nullptr; // Pointer to the underlying storage + ssize_t itemsize = 0; // Size of individual items in bytes + ssize_t size = 0; // Total number of entries + std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() + ssize_t ndim = 0; // Number of dimensions + std::vector shape; // Shape of the tensor (1 entry per dimension) + std::vector strides; // Number of entries between adjacent entries (for each per dimension) + + buffer_info() { } + + buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, + detail::any_container shape_in, detail::any_container strides_in) + : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), + shape(std::move(shape_in)), strides(std::move(strides_in)) { + if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) + pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); + for (size_t i = 0; i < (size_t) ndim; ++i) + size *= shape[i]; + } + + template + buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in) + : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in)) { } + + buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size) + : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}) { } + + template + buffer_info(T *ptr, ssize_t size) + : buffer_info(ptr, sizeof(T), format_descriptor::format(), size) { } + + explicit buffer_info(Py_buffer *view, bool ownview = true) + : buffer_info(view->buf, view->itemsize, view->format, view->ndim, + {view->shape, view->shape + view->ndim}, {view->strides, view->strides + view->ndim}) { + this->view = view; + this->ownview = ownview; + } + + buffer_info(const buffer_info &) = delete; + buffer_info& operator=(const buffer_info &) = delete; + + buffer_info(buffer_info &&other) { + (*this) = std::move(other); + } + + buffer_info& operator=(buffer_info &&rhs) { + ptr = rhs.ptr; + itemsize = rhs.itemsize; + size = rhs.size; + format = std::move(rhs.format); + ndim = rhs.ndim; + shape = std::move(rhs.shape); + strides = std::move(rhs.strides); + std::swap(view, rhs.view); + std::swap(ownview, rhs.ownview); + return *this; + } + + ~buffer_info() { + if (view && ownview) { PyBuffer_Release(view); delete view; } + } + +private: + struct private_ctr_tag { }; + + buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, + detail::any_container &&shape_in, detail::any_container &&strides_in) + : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in)) { } + + Py_buffer *view = nullptr; + bool ownview = false; +}; + +NAMESPACE_BEGIN(detail) + +template struct compare_buffer_info { + static bool compare(const buffer_info& b) { + return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); + } +}; + +template struct compare_buffer_info::value>> { + static bool compare(const buffer_info& b) { + return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || + ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || + ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); + } +}; + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/cast.h b/python/src/pybind11/cast.h new file mode 100644 index 000000000..8d0fd5d90 --- /dev/null +++ b/python/src/pybind11/cast.h @@ -0,0 +1,2128 @@ +/* + pybind11/cast.h: Partial template specializations to cast between + C++ and Python types + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pytypes.h" +#include "detail/typeid.h" +#include "detail/descr.h" +#include "detail/internals.h" +#include +#include +#include +#include + +#if defined(PYBIND11_CPP17) +# if defined(__has_include) +# if __has_include() +# define PYBIND11_HAS_STRING_VIEW +# endif +# elif defined(_MSC_VER) +# define PYBIND11_HAS_STRING_VIEW +# endif +#endif +#ifdef PYBIND11_HAS_STRING_VIEW +#include +#endif + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +/// A life support system for temporary objects created by `type_caster::load()`. +/// Adding a patient will keep it alive up until the enclosing function returns. +class loader_life_support { +public: + /// A new patient frame is created when a function is entered + loader_life_support() { + get_internals().loader_patient_stack.push_back(nullptr); + } + + /// ... and destroyed after it returns + ~loader_life_support() { + auto &stack = get_internals().loader_patient_stack; + if (stack.empty()) + pybind11_fail("loader_life_support: internal error"); + + auto ptr = stack.back(); + stack.pop_back(); + Py_CLEAR(ptr); + + // A heuristic to reduce the stack's capacity (e.g. after long recursive calls) + if (stack.capacity() > 16 && stack.size() != 0 && stack.capacity() / stack.size() > 2) + stack.shrink_to_fit(); + } + + /// This can only be used inside a pybind11-bound function, either by `argument_loader` + /// at argument preparation time or by `py::cast()` at execution time. + PYBIND11_NOINLINE static void add_patient(handle h) { + auto &stack = get_internals().loader_patient_stack; + if (stack.empty()) + throw cast_error("When called outside a bound function, py::cast() cannot " + "do Python -> C++ conversions which require the creation " + "of temporary values"); + + auto &list_ptr = stack.back(); + if (list_ptr == nullptr) { + list_ptr = PyList_New(1); + if (!list_ptr) + pybind11_fail("loader_life_support: error allocating list"); + PyList_SET_ITEM(list_ptr, 0, h.inc_ref().ptr()); + } else { + auto result = PyList_Append(list_ptr, h.ptr()); + if (result == -1) + pybind11_fail("loader_life_support: error adding patient"); + } + } +}; + +// Gets the cache entry for the given type, creating it if necessary. The return value is the pair +// returned by emplace, i.e. an iterator for the entry and a bool set to `true` if the entry was +// just created. +inline std::pair all_type_info_get_cache(PyTypeObject *type); + +// Populates a just-created cache entry. +PYBIND11_NOINLINE inline void all_type_info_populate(PyTypeObject *t, std::vector &bases) { + std::vector check; + for (handle parent : reinterpret_borrow(t->tp_bases)) + check.push_back((PyTypeObject *) parent.ptr()); + + auto const &type_dict = get_internals().registered_types_py; + for (size_t i = 0; i < check.size(); i++) { + auto type = check[i]; + // Ignore Python2 old-style class super type: + if (!PyType_Check((PyObject *) type)) continue; + + // Check `type` in the current set of registered python types: + auto it = type_dict.find(type); + if (it != type_dict.end()) { + // We found a cache entry for it, so it's either pybind-registered or has pre-computed + // pybind bases, but we have to make sure we haven't already seen the type(s) before: we + // want to follow Python/virtual C++ rules that there should only be one instance of a + // common base. + for (auto *tinfo : it->second) { + // NB: Could use a second set here, rather than doing a linear search, but since + // having a large number of immediate pybind11-registered types seems fairly + // unlikely, that probably isn't worthwhile. + bool found = false; + for (auto *known : bases) { + if (known == tinfo) { found = true; break; } + } + if (!found) bases.push_back(tinfo); + } + } + else if (type->tp_bases) { + // It's some python type, so keep follow its bases classes to look for one or more + // registered types + if (i + 1 == check.size()) { + // When we're at the end, we can pop off the current element to avoid growing + // `check` when adding just one base (which is typical--i.e. when there is no + // multiple inheritance) + check.pop_back(); + i--; + } + for (handle parent : reinterpret_borrow(type->tp_bases)) + check.push_back((PyTypeObject *) parent.ptr()); + } + } +} + +/** + * Extracts vector of type_info pointers of pybind-registered roots of the given Python type. Will + * be just 1 pybind type for the Python type of a pybind-registered class, or for any Python-side + * derived class that uses single inheritance. Will contain as many types as required for a Python + * class that uses multiple inheritance to inherit (directly or indirectly) from multiple + * pybind-registered classes. Will be empty if neither the type nor any base classes are + * pybind-registered. + * + * The value is cached for the lifetime of the Python type. + */ +inline const std::vector &all_type_info(PyTypeObject *type) { + auto ins = all_type_info_get_cache(type); + if (ins.second) + // New cache entry: populate it + all_type_info_populate(type, ins.first->second); + + return ins.first->second; +} + +/** + * Gets a single pybind11 type info for a python type. Returns nullptr if neither the type nor any + * ancestors are pybind11-registered. Throws an exception if there are multiple bases--use + * `all_type_info` instead if you want to support multiple bases. + */ +PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) { + auto &bases = all_type_info(type); + if (bases.size() == 0) + return nullptr; + if (bases.size() > 1) + pybind11_fail("pybind11::detail::get_type_info: type has multiple pybind11-registered bases"); + return bases.front(); +} + +inline detail::type_info *get_local_type_info(const std::type_index &tp) { + auto &locals = registered_local_types_cpp(); + auto it = locals.find(tp); + if (it != locals.end()) + return it->second; + return nullptr; +} + +inline detail::type_info *get_global_type_info(const std::type_index &tp) { + auto &types = get_internals().registered_types_cpp; + auto it = types.find(tp); + if (it != types.end()) + return it->second; + return nullptr; +} + +/// Return the type info for a given C++ type; on lookup failure can either throw or return nullptr. +PYBIND11_NOINLINE inline detail::type_info *get_type_info(const std::type_index &tp, + bool throw_if_missing = false) { + if (auto ltype = get_local_type_info(tp)) + return ltype; + if (auto gtype = get_global_type_info(tp)) + return gtype; + + if (throw_if_missing) { + std::string tname = tp.name(); + detail::clean_type_id(tname); + pybind11_fail("pybind11::detail::get_type_info: unable to find type info for \"" + tname + "\""); + } + return nullptr; +} + +PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp, bool throw_if_missing) { + detail::type_info *type_info = get_type_info(tp, throw_if_missing); + return handle(type_info ? ((PyObject *) type_info->type) : nullptr); +} + +struct value_and_holder { + instance *inst = nullptr; + size_t index = 0u; + const detail::type_info *type = nullptr; + void **vh = nullptr; + + // Main constructor for a found value/holder: + value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index) : + inst{i}, index{index}, type{type}, + vh{inst->simple_layout ? inst->simple_value_holder : &inst->nonsimple.values_and_holders[vpos]} + {} + + // Default constructor (used to signal a value-and-holder not found by get_value_and_holder()) + value_and_holder() {} + + // Used for past-the-end iterator + value_and_holder(size_t index) : index{index} {} + + template V *&value_ptr() const { + return reinterpret_cast(vh[0]); + } + // True if this `value_and_holder` has a non-null value pointer + explicit operator bool() const { return value_ptr(); } + + template H &holder() const { + return reinterpret_cast(vh[1]); + } + bool holder_constructed() const { + return inst->simple_layout + ? inst->simple_holder_constructed + : inst->nonsimple.status[index] & instance::status_holder_constructed; + } + void set_holder_constructed(bool v = true) { + if (inst->simple_layout) + inst->simple_holder_constructed = v; + else if (v) + inst->nonsimple.status[index] |= instance::status_holder_constructed; + else + inst->nonsimple.status[index] &= (uint8_t) ~instance::status_holder_constructed; + } + bool instance_registered() const { + return inst->simple_layout + ? inst->simple_instance_registered + : inst->nonsimple.status[index] & instance::status_instance_registered; + } + void set_instance_registered(bool v = true) { + if (inst->simple_layout) + inst->simple_instance_registered = v; + else if (v) + inst->nonsimple.status[index] |= instance::status_instance_registered; + else + inst->nonsimple.status[index] &= (uint8_t) ~instance::status_instance_registered; + } +}; + +// Container for accessing and iterating over an instance's values/holders +struct values_and_holders { +private: + instance *inst; + using type_vec = std::vector; + const type_vec &tinfo; + +public: + values_and_holders(instance *inst) : inst{inst}, tinfo(all_type_info(Py_TYPE(inst))) {} + + struct iterator { + private: + instance *inst = nullptr; + const type_vec *types = nullptr; + value_and_holder curr; + friend struct values_and_holders; + iterator(instance *inst, const type_vec *tinfo) + : inst{inst}, types{tinfo}, + curr(inst /* instance */, + types->empty() ? nullptr : (*types)[0] /* type info */, + 0, /* vpos: (non-simple types only): the first vptr comes first */ + 0 /* index */) + {} + // Past-the-end iterator: + iterator(size_t end) : curr(end) {} + public: + bool operator==(const iterator &other) { return curr.index == other.curr.index; } + bool operator!=(const iterator &other) { return curr.index != other.curr.index; } + iterator &operator++() { + if (!inst->simple_layout) + curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs; + ++curr.index; + curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr; + return *this; + } + value_and_holder &operator*() { return curr; } + value_and_holder *operator->() { return &curr; } + }; + + iterator begin() { return iterator(inst, &tinfo); } + iterator end() { return iterator(tinfo.size()); } + + iterator find(const type_info *find_type) { + auto it = begin(), endit = end(); + while (it != endit && it->type != find_type) ++it; + return it; + } + + size_t size() { return tinfo.size(); } +}; + +/** + * Extracts C++ value and holder pointer references from an instance (which may contain multiple + * values/holders for python-side multiple inheritance) that match the given type. Throws an error + * if the given type (or ValueType, if omitted) is not a pybind11 base of the given instance. If + * `find_type` is omitted (or explicitly specified as nullptr) the first value/holder are returned, + * regardless of type (and the resulting .type will be nullptr). + * + * The returned object should be short-lived: in particular, it must not outlive the called-upon + * instance. + */ +PYBIND11_NOINLINE inline value_and_holder instance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/, bool throw_if_missing /*= true in common.h*/) { + // Optimize common case: + if (!find_type || Py_TYPE(this) == find_type->type) + return value_and_holder(this, find_type, 0, 0); + + detail::values_and_holders vhs(this); + auto it = vhs.find(find_type); + if (it != vhs.end()) + return *it; + + if (!throw_if_missing) + return value_and_holder(); + +#if defined(NDEBUG) + pybind11_fail("pybind11::detail::instance::get_value_and_holder: " + "type is not a pybind11 base of the given instance " + "(compile in debug mode for type details)"); +#else + pybind11_fail("pybind11::detail::instance::get_value_and_holder: `" + + std::string(find_type->type->tp_name) + "' is not a pybind11 base of the given `" + + std::string(Py_TYPE(this)->tp_name) + "' instance"); +#endif +} + +PYBIND11_NOINLINE inline void instance::allocate_layout() { + auto &tinfo = all_type_info(Py_TYPE(this)); + + const size_t n_types = tinfo.size(); + + if (n_types == 0) + pybind11_fail("instance allocation failed: new instance has no pybind11-registered base types"); + + simple_layout = + n_types == 1 && tinfo.front()->holder_size_in_ptrs <= instance_simple_holder_in_ptrs(); + + // Simple path: no python-side multiple inheritance, and a small-enough holder + if (simple_layout) { + simple_value_holder[0] = nullptr; + simple_holder_constructed = false; + simple_instance_registered = false; + } + else { // multiple base types or a too-large holder + // Allocate space to hold: [v1*][h1][v2*][h2]...[bb...] where [vN*] is a value pointer, + // [hN] is the (uninitialized) holder instance for value N, and [bb...] is a set of bool + // values that tracks whether each associated holder has been initialized. Each [block] is + // padded, if necessary, to an integer multiple of sizeof(void *). + size_t space = 0; + for (auto t : tinfo) { + space += 1; // value pointer + space += t->holder_size_in_ptrs; // holder instance + } + size_t flags_at = space; + space += size_in_ptrs(n_types); // status bytes (holder_constructed and instance_registered) + + // Allocate space for flags, values, and holders, and initialize it to 0 (flags and values, + // in particular, need to be 0). Use Python's memory allocation functions: in Python 3.6 + // they default to using pymalloc, which is designed to be efficient for small allocations + // like the one we're doing here; in earlier versions (and for larger allocations) they are + // just wrappers around malloc. +#if PY_VERSION_HEX >= 0x03050000 + nonsimple.values_and_holders = (void **) PyMem_Calloc(space, sizeof(void *)); + if (!nonsimple.values_and_holders) throw std::bad_alloc(); +#else + nonsimple.values_and_holders = (void **) PyMem_New(void *, space); + if (!nonsimple.values_and_holders) throw std::bad_alloc(); + std::memset(nonsimple.values_and_holders, 0, space * sizeof(void *)); +#endif + nonsimple.status = reinterpret_cast(&nonsimple.values_and_holders[flags_at]); + } + owned = true; +} + +PYBIND11_NOINLINE inline void instance::deallocate_layout() { + if (!simple_layout) + PyMem_Free(nonsimple.values_and_holders); +} + +PYBIND11_NOINLINE inline bool isinstance_generic(handle obj, const std::type_info &tp) { + handle type = detail::get_type_handle(tp, false); + if (!type) + return false; + return isinstance(obj, type); +} + +PYBIND11_NOINLINE inline std::string error_string() { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred"); + return "Unknown internal error occurred"; + } + + error_scope scope; // Preserve error state + + std::string errorString; + if (scope.type) { + errorString += handle(scope.type).attr("__name__").cast(); + errorString += ": "; + } + if (scope.value) + errorString += (std::string) str(scope.value); + + PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace); + +#if PY_MAJOR_VERSION >= 3 + if (scope.trace != nullptr) + PyException_SetTraceback(scope.value, scope.trace); +#endif + +#if !defined(PYPY_VERSION) + if (scope.trace) { + PyTracebackObject *trace = (PyTracebackObject *) scope.trace; + + /* Get the deepest trace possible */ + while (trace->tb_next) + trace = trace->tb_next; + + PyFrameObject *frame = trace->tb_frame; + errorString += "\n\nAt:\n"; + while (frame) { + int lineno = PyFrame_GetLineNumber(frame); + errorString += + " " + handle(frame->f_code->co_filename).cast() + + "(" + std::to_string(lineno) + "): " + + handle(frame->f_code->co_name).cast() + "\n"; + frame = frame->f_back; + } + } +#endif + + return errorString; +} + +PYBIND11_NOINLINE inline handle get_object_handle(const void *ptr, const detail::type_info *type ) { + auto &instances = get_internals().registered_instances; + auto range = instances.equal_range(ptr); + for (auto it = range.first; it != range.second; ++it) { + for (auto vh : values_and_holders(it->second)) { + if (vh.type == type) + return handle((PyObject *) it->second); + } + } + return handle(); +} + +inline PyThreadState *get_thread_state_unchecked() { +#if defined(PYPY_VERSION) + return PyThreadState_GET(); +#elif PY_VERSION_HEX < 0x03000000 + return _PyThreadState_Current; +#elif PY_VERSION_HEX < 0x03050000 + return (PyThreadState*) _Py_atomic_load_relaxed(&_PyThreadState_Current); +#elif PY_VERSION_HEX < 0x03050200 + return (PyThreadState*) _PyThreadState_Current.value; +#else + return _PyThreadState_UncheckedGet(); +#endif +} + +// Forward declarations +inline void keep_alive_impl(handle nurse, handle patient); +inline PyObject *make_new_instance(PyTypeObject *type); + +class type_caster_generic { +public: + PYBIND11_NOINLINE type_caster_generic(const std::type_info &type_info) + : typeinfo(get_type_info(type_info)), cpptype(&type_info) { } + + type_caster_generic(const type_info *typeinfo) + : typeinfo(typeinfo), cpptype(typeinfo ? typeinfo->cpptype : nullptr) { } + + bool load(handle src, bool convert) { + return load_impl(src, convert); + } + + PYBIND11_NOINLINE static handle cast(const void *_src, return_value_policy policy, handle parent, + const detail::type_info *tinfo, + void *(*copy_constructor)(const void *), + void *(*move_constructor)(const void *), + const void *existing_holder = nullptr) { + if (!tinfo) // no type info: error will be set already + return handle(); + + void *src = const_cast(_src); + if (src == nullptr) + return none().release(); + + auto it_instances = get_internals().registered_instances.equal_range(src); + for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { + for (auto instance_type : detail::all_type_info(Py_TYPE(it_i->second))) { + if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) + return handle((PyObject *) it_i->second).inc_ref(); + } + } + + auto inst = reinterpret_steal(make_new_instance(tinfo->type)); + auto wrapper = reinterpret_cast(inst.ptr()); + wrapper->owned = false; + void *&valueptr = values_and_holders(wrapper).begin()->value_ptr(); + + switch (policy) { + case return_value_policy::automatic: + case return_value_policy::take_ownership: + valueptr = src; + wrapper->owned = true; + break; + + case return_value_policy::automatic_reference: + case return_value_policy::reference: + valueptr = src; + wrapper->owned = false; + break; + + case return_value_policy::copy: + if (copy_constructor) + valueptr = copy_constructor(src); + else + throw cast_error("return_value_policy = copy, but the " + "object is non-copyable!"); + wrapper->owned = true; + break; + + case return_value_policy::move: + if (move_constructor) + valueptr = move_constructor(src); + else if (copy_constructor) + valueptr = copy_constructor(src); + else + throw cast_error("return_value_policy = move, but the " + "object is neither movable nor copyable!"); + wrapper->owned = true; + break; + + case return_value_policy::reference_internal: + valueptr = src; + wrapper->owned = false; + keep_alive_impl(inst, parent); + break; + + default: + throw cast_error("unhandled return_value_policy: should not happen!"); + } + + tinfo->init_instance(wrapper, existing_holder); + + return inst.release(); + } + + // Base methods for generic caster; there are overridden in copyable_holder_caster + void load_value(value_and_holder &&v_h) { + auto *&vptr = v_h.value_ptr(); + // Lazy allocation for unallocated values: + if (vptr == nullptr) { + auto *type = v_h.type ? v_h.type : typeinfo; + if (type->operator_new) { + vptr = type->operator_new(type->type_size); + } else { + #if defined(PYBIND11_CPP17) + if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) + vptr = ::operator new(type->type_size, + (std::align_val_t) type->type_align); + else + #endif + vptr = ::operator new(type->type_size); + } + } + value = vptr; + } + bool try_implicit_casts(handle src, bool convert) { + for (auto &cast : typeinfo->implicit_casts) { + type_caster_generic sub_caster(*cast.first); + if (sub_caster.load(src, convert)) { + value = cast.second(sub_caster.value); + return true; + } + } + return false; + } + bool try_direct_conversions(handle src) { + for (auto &converter : *typeinfo->direct_conversions) { + if (converter(src.ptr(), value)) + return true; + } + return false; + } + void check_holder_compat() {} + + PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) { + auto caster = type_caster_generic(ti); + if (caster.load(src, false)) + return caster.value; + return nullptr; + } + + /// Try to load with foreign typeinfo, if available. Used when there is no + /// native typeinfo, or when the native one wasn't able to produce a value. + PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) { + constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID; + const auto pytype = src.get_type(); + if (!hasattr(pytype, local_key)) + return false; + + type_info *foreign_typeinfo = reinterpret_borrow(getattr(pytype, local_key)); + // Only consider this foreign loader if actually foreign and is a loader of the correct cpp type + if (foreign_typeinfo->module_local_load == &local_load + || (cpptype && !same_type(*cpptype, *foreign_typeinfo->cpptype))) + return false; + + if (auto result = foreign_typeinfo->module_local_load(src.ptr(), foreign_typeinfo)) { + value = result; + return true; + } + return false; + } + + // Implementation of `load`; this takes the type of `this` so that it can dispatch the relevant + // bits of code between here and copyable_holder_caster where the two classes need different + // logic (without having to resort to virtual inheritance). + template + PYBIND11_NOINLINE bool load_impl(handle src, bool convert) { + if (!src) return false; + if (!typeinfo) return try_load_foreign_module_local(src); + if (src.is_none()) { + // Defer accepting None to other overloads (if we aren't in convert mode): + if (!convert) return false; + value = nullptr; + return true; + } + + auto &this_ = static_cast(*this); + this_.check_holder_compat(); + + PyTypeObject *srctype = Py_TYPE(src.ptr()); + + // Case 1: If src is an exact type match for the target type then we can reinterpret_cast + // the instance's value pointer to the target type: + if (srctype == typeinfo->type) { + this_.load_value(reinterpret_cast(src.ptr())->get_value_and_holder()); + return true; + } + // Case 2: We have a derived class + else if (PyType_IsSubtype(srctype, typeinfo->type)) { + auto &bases = all_type_info(srctype); + bool no_cpp_mi = typeinfo->simple_type; + + // Case 2a: the python type is a Python-inherited derived class that inherits from just + // one simple (no MI) pybind11 class, or is an exact match, so the C++ instance is of + // the right type and we can use reinterpret_cast. + // (This is essentially the same as case 2b, but because not using multiple inheritance + // is extremely common, we handle it specially to avoid the loop iterator and type + // pointer lookup overhead) + if (bases.size() == 1 && (no_cpp_mi || bases.front()->type == typeinfo->type)) { + this_.load_value(reinterpret_cast(src.ptr())->get_value_and_holder()); + return true; + } + // Case 2b: the python type inherits from multiple C++ bases. Check the bases to see if + // we can find an exact match (or, for a simple C++ type, an inherited match); if so, we + // can safely reinterpret_cast to the relevant pointer. + else if (bases.size() > 1) { + for (auto base : bases) { + if (no_cpp_mi ? PyType_IsSubtype(base->type, typeinfo->type) : base->type == typeinfo->type) { + this_.load_value(reinterpret_cast(src.ptr())->get_value_and_holder(base)); + return true; + } + } + } + + // Case 2c: C++ multiple inheritance is involved and we couldn't find an exact type match + // in the registered bases, above, so try implicit casting (needed for proper C++ casting + // when MI is involved). + if (this_.try_implicit_casts(src, convert)) + return true; + } + + // Perform an implicit conversion + if (convert) { + for (auto &converter : typeinfo->implicit_conversions) { + auto temp = reinterpret_steal(converter(src.ptr(), typeinfo->type)); + if (load_impl(temp, false)) { + loader_life_support::add_patient(temp); + return true; + } + } + if (this_.try_direct_conversions(src)) + return true; + } + + // Failed to match local typeinfo. Try again with global. + if (typeinfo->module_local) { + if (auto gtype = get_global_type_info(*typeinfo->cpptype)) { + typeinfo = gtype; + return load(src, false); + } + } + + // Global typeinfo has precedence over foreign module_local + return try_load_foreign_module_local(src); + } + + + // Called to do type lookup and wrap the pointer and type in a pair when a dynamic_cast + // isn't needed or can't be used. If the type is unknown, sets the error and returns a pair + // with .second = nullptr. (p.first = nullptr is not an error: it becomes None). + PYBIND11_NOINLINE static std::pair src_and_type( + const void *src, const std::type_info &cast_type, const std::type_info *rtti_type = nullptr) { + if (auto *tpi = get_type_info(cast_type)) + return {src, const_cast(tpi)}; + + // Not found, set error: + std::string tname = rtti_type ? rtti_type->name() : cast_type.name(); + detail::clean_type_id(tname); + std::string msg = "Unregistered type : " + tname; + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return {nullptr, nullptr}; + } + + const type_info *typeinfo = nullptr; + const std::type_info *cpptype = nullptr; + void *value = nullptr; +}; + +/** + * Determine suitable casting operator for pointer-or-lvalue-casting type casters. The type caster + * needs to provide `operator T*()` and `operator T&()` operators. + * + * If the type supports moving the value away via an `operator T&&() &&` method, it should use + * `movable_cast_op_type` instead. + */ +template +using cast_op_type = + conditional_t>::value, + typename std::add_pointer>::type, + typename std::add_lvalue_reference>::type>; + +/** + * Determine suitable casting operator for a type caster with a movable value. Such a type caster + * needs to provide `operator T*()`, `operator T&()`, and `operator T&&() &&`. The latter will be + * called in appropriate contexts where the value can be moved rather than copied. + * + * These operator are automatically provided when using the PYBIND11_TYPE_CASTER macro. + */ +template +using movable_cast_op_type = + conditional_t::type>::value, + typename std::add_pointer>::type, + conditional_t::value, + typename std::add_rvalue_reference>::type, + typename std::add_lvalue_reference>::type>>; + +// std::is_copy_constructible isn't quite enough: it lets std::vector (and similar) through when +// T is non-copyable, but code containing such a copy constructor fails to actually compile. +template struct is_copy_constructible : std::is_copy_constructible {}; + +// Specialization for types that appear to be copy constructible but also look like stl containers +// (we specifically check for: has `value_type` and `reference` with `reference = value_type&`): if +// so, copy constructability depends on whether the value_type is copy constructible. +template struct is_copy_constructible, + std::is_same + >::value>> : is_copy_constructible {}; + +#if !defined(PYBIND11_CPP17) +// Likewise for std::pair before C++17 (which mandates that the copy constructor not exist when the +// two types aren't themselves copy constructible). +template struct is_copy_constructible> + : all_of, is_copy_constructible> {}; +#endif + +NAMESPACE_END(detail) + +// polymorphic_type_hook::get(src, tinfo) determines whether the object pointed +// to by `src` actually is an instance of some class derived from `itype`. +// If so, it sets `tinfo` to point to the std::type_info representing that derived +// type, and returns a pointer to the start of the most-derived object of that type +// (in which `src` is a subobject; this will be the same address as `src` in most +// single inheritance cases). If not, or if `src` is nullptr, it simply returns `src` +// and leaves `tinfo` at its default value of nullptr. +// +// The default polymorphic_type_hook just returns src. A specialization for polymorphic +// types determines the runtime type of the passed object and adjusts the this-pointer +// appropriately via dynamic_cast. This is what enables a C++ Animal* to appear +// to Python as a Dog (if Dog inherits from Animal, Animal is polymorphic, Dog is +// registered with pybind11, and this Animal is in fact a Dog). +// +// You may specialize polymorphic_type_hook yourself for types that want to appear +// polymorphic to Python but do not use C++ RTTI. (This is a not uncommon pattern +// in performance-sensitive applications, used most notably in LLVM.) +template +struct polymorphic_type_hook +{ + static const void *get(const itype *src, const std::type_info*&) { return src; } +}; +template +struct polymorphic_type_hook::value>> +{ + static const void *get(const itype *src, const std::type_info*& type) { + type = src ? &typeid(*src) : nullptr; + return dynamic_cast(src); + } +}; + +NAMESPACE_BEGIN(detail) + +/// Generic type caster for objects stored on the heap +template class type_caster_base : public type_caster_generic { + using itype = intrinsic_t; + +public: + static constexpr auto name = _(); + + type_caster_base() : type_caster_base(typeid(type)) { } + explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) { } + + static handle cast(const itype &src, return_value_policy policy, handle parent) { + if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) + policy = return_value_policy::copy; + return cast(&src, policy, parent); + } + + static handle cast(itype &&src, return_value_policy, handle parent) { + return cast(&src, return_value_policy::move, parent); + } + + // Returns a (pointer, type_info) pair taking care of necessary type lookup for a + // polymorphic type (using RTTI by default, but can be overridden by specializing + // polymorphic_type_hook). If the instance isn't derived, returns the base version. + static std::pair src_and_type(const itype *src) { + auto &cast_type = typeid(itype); + const std::type_info *instance_type = nullptr; + const void *vsrc = polymorphic_type_hook::get(src, instance_type); + if (instance_type && !same_type(cast_type, *instance_type)) { + // This is a base pointer to a derived type. If the derived type is registered + // with pybind11, we want to make the full derived object available. + // In the typical case where itype is polymorphic, we get the correct + // derived pointer (which may be != base pointer) by a dynamic_cast to + // most derived type. If itype is not polymorphic, we won't get here + // except via a user-provided specialization of polymorphic_type_hook, + // and the user has promised that no this-pointer adjustment is + // required in that case, so it's OK to use static_cast. + if (const auto *tpi = get_type_info(*instance_type)) + return {vsrc, tpi}; + } + // Otherwise we have either a nullptr, an `itype` pointer, or an unknown derived pointer, so + // don't do a cast + return type_caster_generic::src_and_type(src, cast_type, instance_type); + } + + static handle cast(const itype *src, return_value_policy policy, handle parent) { + auto st = src_and_type(src); + return type_caster_generic::cast( + st.first, policy, parent, st.second, + make_copy_constructor(src), make_move_constructor(src)); + } + + static handle cast_holder(const itype *src, const void *holder) { + auto st = src_and_type(src); + return type_caster_generic::cast( + st.first, return_value_policy::take_ownership, {}, st.second, + nullptr, nullptr, holder); + } + + template using cast_op_type = detail::cast_op_type; + + operator itype*() { return (type *) value; } + operator itype&() { if (!value) throw reference_cast_error(); return *((itype *) value); } + +protected: + using Constructor = void *(*)(const void *); + + /* Only enabled when the types are {copy,move}-constructible *and* when the type + does not have a private operator new implementation. */ + template ::value>> + static auto make_copy_constructor(const T *x) -> decltype(new T(*x), Constructor{}) { + return [](const void *arg) -> void * { + return new T(*reinterpret_cast(arg)); + }; + } + + template ::value>> + static auto make_move_constructor(const T *x) -> decltype(new T(std::move(*const_cast(x))), Constructor{}) { + return [](const void *arg) -> void * { + return new T(std::move(*const_cast(reinterpret_cast(arg)))); + }; + } + + static Constructor make_copy_constructor(...) { return nullptr; } + static Constructor make_move_constructor(...) { return nullptr; } +}; + +template class type_caster : public type_caster_base { }; +template using make_caster = type_caster>; + +// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T +template typename make_caster::template cast_op_type cast_op(make_caster &caster) { + return caster.operator typename make_caster::template cast_op_type(); +} +template typename make_caster::template cast_op_type::type> +cast_op(make_caster &&caster) { + return std::move(caster).operator + typename make_caster::template cast_op_type::type>(); +} + +template class type_caster> { +private: + using caster_t = make_caster; + caster_t subcaster; + using subcaster_cast_op_type = typename caster_t::template cast_op_type; + static_assert(std::is_same::type &, subcaster_cast_op_type>::value, + "std::reference_wrapper caster requires T to have a caster with an `T &` operator"); +public: + bool load(handle src, bool convert) { return subcaster.load(src, convert); } + static constexpr auto name = caster_t::name; + static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { + // It is definitely wrong to take ownership of this pointer, so mask that rvp + if (policy == return_value_policy::take_ownership || policy == return_value_policy::automatic) + policy = return_value_policy::automatic_reference; + return caster_t::cast(&src.get(), policy, parent); + } + template using cast_op_type = std::reference_wrapper; + operator std::reference_wrapper() { return subcaster.operator subcaster_cast_op_type&(); } +}; + +#define PYBIND11_TYPE_CASTER(type, py_name) \ + protected: \ + type value; \ + public: \ + static constexpr auto name = py_name; \ + template >::value, int> = 0> \ + static handle cast(T_ *src, return_value_policy policy, handle parent) { \ + if (!src) return none().release(); \ + if (policy == return_value_policy::take_ownership) { \ + auto h = cast(std::move(*src), policy, parent); delete src; return h; \ + } else { \ + return cast(*src, policy, parent); \ + } \ + } \ + operator type*() { return &value; } \ + operator type&() { return value; } \ + operator type&&() && { return std::move(value); } \ + template using cast_op_type = pybind11::detail::movable_cast_op_type + + +template using is_std_char_type = any_of< + std::is_same, /* std::string */ + std::is_same, /* std::u16string */ + std::is_same, /* std::u32string */ + std::is_same /* std::wstring */ +>; + +template +struct type_caster::value && !is_std_char_type::value>> { + using _py_type_0 = conditional_t; + using _py_type_1 = conditional_t::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>; + using py_type = conditional_t::value, double, _py_type_1>; +public: + + bool load(handle src, bool convert) { + py_type py_value; + + if (!src) + return false; + + if (std::is_floating_point::value) { + if (convert || PyFloat_Check(src.ptr())) + py_value = (py_type) PyFloat_AsDouble(src.ptr()); + else + return false; + } else if (PyFloat_Check(src.ptr())) { + return false; + } else if (std::is_unsigned::value) { + py_value = as_unsigned(src.ptr()); + } else { // signed integer: + py_value = sizeof(T) <= sizeof(long) + ? (py_type) PyLong_AsLong(src.ptr()) + : (py_type) PYBIND11_LONG_AS_LONGLONG(src.ptr()); + } + + bool py_err = py_value == (py_type) -1 && PyErr_Occurred(); + if (py_err || (std::is_integral::value && sizeof(py_type) != sizeof(T) && + (py_value < (py_type) std::numeric_limits::min() || + py_value > (py_type) std::numeric_limits::max()))) { + bool type_error = py_err && PyErr_ExceptionMatches( +#if PY_VERSION_HEX < 0x03000000 && !defined(PYPY_VERSION) + PyExc_SystemError +#else + PyExc_TypeError +#endif + ); + PyErr_Clear(); + if (type_error && convert && PyNumber_Check(src.ptr())) { + auto tmp = reinterpret_steal(std::is_floating_point::value + ? PyNumber_Float(src.ptr()) + : PyNumber_Long(src.ptr())); + PyErr_Clear(); + return load(tmp, false); + } + return false; + } + + value = (T) py_value; + return true; + } + + template + static typename std::enable_if::value, handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PyFloat_FromDouble((double) src); + } + + template + static typename std::enable_if::value && std::is_signed::value && (sizeof(U) <= sizeof(long)), handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PYBIND11_LONG_FROM_SIGNED((long) src); + } + + template + static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) <= sizeof(unsigned long)), handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src); + } + + template + static typename std::enable_if::value && std::is_signed::value && (sizeof(U) > sizeof(long)), handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PyLong_FromLongLong((long long) src); + } + + template + static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) > sizeof(unsigned long)), handle>::type + cast(U src, return_value_policy /* policy */, handle /* parent */) { + return PyLong_FromUnsignedLongLong((unsigned long long) src); + } + + PYBIND11_TYPE_CASTER(T, _::value>("int", "float")); +}; + +template struct void_caster { +public: + bool load(handle src, bool) { + if (src && src.is_none()) + return true; + return false; + } + static handle cast(T, return_value_policy /* policy */, handle /* parent */) { + return none().inc_ref(); + } + PYBIND11_TYPE_CASTER(T, _("None")); +}; + +template <> class type_caster : public void_caster {}; + +template <> class type_caster : public type_caster { +public: + using type_caster::cast; + + bool load(handle h, bool) { + if (!h) { + return false; + } else if (h.is_none()) { + value = nullptr; + return true; + } + + /* Check if this is a capsule */ + if (isinstance(h)) { + value = reinterpret_borrow(h); + return true; + } + + /* Check if this is a C++ type */ + auto &bases = all_type_info((PyTypeObject *) h.get_type().ptr()); + if (bases.size() == 1) { // Only allowing loading from a single-value type + value = values_and_holders(reinterpret_cast(h.ptr())).begin()->value_ptr(); + return true; + } + + /* Fail */ + return false; + } + + static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) { + if (ptr) + return capsule(ptr).release(); + else + return none().inc_ref(); + } + + template using cast_op_type = void*&; + operator void *&() { return value; } + static constexpr auto name = _("capsule"); +private: + void *value = nullptr; +}; + +template <> class type_caster : public void_caster { }; + +template <> class type_caster { +public: + bool load(handle src, bool convert) { + if (!src) return false; + else if (src.ptr() == Py_True) { value = true; return true; } + else if (src.ptr() == Py_False) { value = false; return true; } + else if (convert || !strcmp("numpy.bool_", Py_TYPE(src.ptr())->tp_name)) { + // (allow non-implicit conversion for numpy booleans) + + Py_ssize_t res = -1; + if (src.is_none()) { + res = 0; // None is implicitly converted to False + } + #if defined(PYPY_VERSION) + // On PyPy, check that "__bool__" (or "__nonzero__" on Python 2.7) attr exists + else if (hasattr(src, PYBIND11_BOOL_ATTR)) { + res = PyObject_IsTrue(src.ptr()); + } + #else + // Alternate approach for CPython: this does the same as the above, but optimized + // using the CPython API so as to avoid an unneeded attribute lookup. + else if (auto tp_as_number = src.ptr()->ob_type->tp_as_number) { + if (PYBIND11_NB_BOOL(tp_as_number)) { + res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr()); + } + } + #endif + if (res == 0 || res == 1) { + value = (bool) res; + return true; + } + } + return false; + } + static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) { + return handle(src ? Py_True : Py_False).inc_ref(); + } + PYBIND11_TYPE_CASTER(bool, _("bool")); +}; + +// Helper class for UTF-{8,16,32} C++ stl strings: +template struct string_caster { + using CharT = typename StringType::value_type; + + // Simplify life by being able to assume standard char sizes (the standard only guarantees + // minimums, but Python requires exact sizes) + static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char size != 1"); + static_assert(!std::is_same::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2"); + static_assert(!std::is_same::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4"); + // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) + static_assert(!std::is_same::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, + "Unsupported wchar_t size != 2/4"); + static constexpr size_t UTF_N = 8 * sizeof(CharT); + + bool load(handle src, bool) { +#if PY_MAJOR_VERSION < 3 + object temp; +#endif + handle load_src = src; + if (!src) { + return false; + } else if (!PyUnicode_Check(load_src.ptr())) { +#if PY_MAJOR_VERSION >= 3 + return load_bytes(load_src); +#else + if (sizeof(CharT) == 1) { + return load_bytes(load_src); + } + + // The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false + if (!PYBIND11_BYTES_CHECK(load_src.ptr())) + return false; + + temp = reinterpret_steal(PyUnicode_FromObject(load_src.ptr())); + if (!temp) { PyErr_Clear(); return false; } + load_src = temp; +#endif + } + + object utfNbytes = reinterpret_steal(PyUnicode_AsEncodedString( + load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); + if (!utfNbytes) { PyErr_Clear(); return false; } + + const CharT *buffer = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); + size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); + if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32 + value = StringType(buffer, length); + + // If we're loading a string_view we need to keep the encoded Python object alive: + if (IsView) + loader_life_support::add_patient(utfNbytes); + + return true; + } + + static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { + const char *buffer = reinterpret_cast(src.data()); + ssize_t nbytes = ssize_t(src.size() * sizeof(CharT)); + handle s = decode_utfN(buffer, nbytes); + if (!s) throw error_already_set(); + return s; + } + + PYBIND11_TYPE_CASTER(StringType, _(PYBIND11_STRING_NAME)); + +private: + static handle decode_utfN(const char *buffer, ssize_t nbytes) { +#if !defined(PYPY_VERSION) + return + UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) : + UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) : + PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); +#else + // PyPy seems to have multiple problems related to PyUnicode_UTF*: the UTF8 version + // sometimes segfaults for unknown reasons, while the UTF16 and 32 versions require a + // non-const char * arguments, which is also a nuisance, so bypass the whole thing by just + // passing the encoding as a string value, which works properly: + return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr); +#endif + } + + // When loading into a std::string or char*, accept a bytes object as-is (i.e. + // without any encoding/decoding attempt). For other C++ char sizes this is a no-op. + // which supports loading a unicode from a str, doesn't take this path. + template + bool load_bytes(enable_if_t src) { + if (PYBIND11_BYTES_CHECK(src.ptr())) { + // We were passed a Python 3 raw bytes; accept it into a std::string or char* + // without any encoding attempt. + const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr()); + if (bytes) { + value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr())); + return true; + } + } + + return false; + } + + template + bool load_bytes(enable_if_t) { return false; } +}; + +template +struct type_caster, enable_if_t::value>> + : string_caster> {}; + +#ifdef PYBIND11_HAS_STRING_VIEW +template +struct type_caster, enable_if_t::value>> + : string_caster, true> {}; +#endif + +// Type caster for C-style strings. We basically use a std::string type caster, but also add the +// ability to use None as a nullptr char* (which the string caster doesn't allow). +template struct type_caster::value>> { + using StringType = std::basic_string; + using StringCaster = type_caster; + StringCaster str_caster; + bool none = false; + CharT one_char = 0; +public: + bool load(handle src, bool convert) { + if (!src) return false; + if (src.is_none()) { + // Defer accepting None to other overloads (if we aren't in convert mode): + if (!convert) return false; + none = true; + return true; + } + return str_caster.load(src, convert); + } + + static handle cast(const CharT *src, return_value_policy policy, handle parent) { + if (src == nullptr) return pybind11::none().inc_ref(); + return StringCaster::cast(StringType(src), policy, parent); + } + + static handle cast(CharT src, return_value_policy policy, handle parent) { + if (std::is_same::value) { + handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr); + if (!s) throw error_already_set(); + return s; + } + return StringCaster::cast(StringType(1, src), policy, parent); + } + + operator CharT*() { return none ? nullptr : const_cast(static_cast(str_caster).c_str()); } + operator CharT&() { + if (none) + throw value_error("Cannot convert None to a character"); + + auto &value = static_cast(str_caster); + size_t str_len = value.size(); + if (str_len == 0) + throw value_error("Cannot convert empty string to a character"); + + // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that + // is too high, and one for multiple unicode characters (caught later), so we need to figure + // out how long the first encoded character is in bytes to distinguish between these two + // errors. We also allow want to allow unicode characters U+0080 through U+00FF, as those + // can fit into a single char value. + if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) { + unsigned char v0 = static_cast(value[0]); + size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127 + (v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence + (v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence + 4; // 0b11110xxx - start of 4-byte sequence + + if (char0_bytes == str_len) { + // If we have a 128-255 value, we can decode it into a single char: + if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx + one_char = static_cast(((v0 & 3) << 6) + (static_cast(value[1]) & 0x3F)); + return one_char; + } + // Otherwise we have a single character, but it's > U+00FF + throw value_error("Character code point not in range(0x100)"); + } + } + + // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a + // surrogate pair with total length 2 instantly indicates a range error (but not a "your + // string was too long" error). + else if (StringCaster::UTF_N == 16 && str_len == 2) { + one_char = static_cast(value[0]); + if (one_char >= 0xD800 && one_char < 0xE000) + throw value_error("Character code point not in range(0x10000)"); + } + + if (str_len != 1) + throw value_error("Expected a character, but multi-character string found"); + + one_char = value[0]; + return one_char; + } + + static constexpr auto name = _(PYBIND11_STRING_NAME); + template using cast_op_type = pybind11::detail::cast_op_type<_T>; +}; + +// Base implementation for std::tuple and std::pair +template class Tuple, typename... Ts> class tuple_caster { + using type = Tuple; + static constexpr auto size = sizeof...(Ts); + using indices = make_index_sequence; +public: + + bool load(handle src, bool convert) { + if (!isinstance(src)) + return false; + const auto seq = reinterpret_borrow(src); + if (seq.size() != size) + return false; + return load_impl(seq, convert, indices{}); + } + + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + return cast_impl(std::forward(src), policy, parent, indices{}); + } + + static constexpr auto name = _("Tuple[") + concat(make_caster::name...) + _("]"); + + template using cast_op_type = type; + + operator type() & { return implicit_cast(indices{}); } + operator type() && { return std::move(*this).implicit_cast(indices{}); } + +protected: + template + type implicit_cast(index_sequence) & { return type(cast_op(std::get(subcasters))...); } + template + type implicit_cast(index_sequence) && { return type(cast_op(std::move(std::get(subcasters)))...); } + + static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; } + + template + bool load_impl(const sequence &seq, bool convert, index_sequence) { + for (bool r : {std::get(subcasters).load(seq[Is], convert)...}) + if (!r) + return false; + return true; + } + + /* Implementation: Convert a C++ tuple into a Python tuple */ + template + static handle cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence) { + std::array entries{{ + reinterpret_steal(make_caster::cast(std::get(std::forward(src)), policy, parent))... + }}; + for (const auto &entry: entries) + if (!entry) + return handle(); + tuple result(size); + int counter = 0; + for (auto & entry: entries) + PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr()); + return result.release(); + } + + Tuple...> subcasters; +}; + +template class type_caster> + : public tuple_caster {}; + +template class type_caster> + : public tuple_caster {}; + +/// Helper class which abstracts away certain actions. Users can provide specializations for +/// custom holders, but it's only necessary if the type has a non-standard interface. +template +struct holder_helper { + static auto get(const T &p) -> decltype(p.get()) { return p.get(); } +}; + +/// Type caster for holder types like std::shared_ptr, etc. +template +struct copyable_holder_caster : public type_caster_base { +public: + using base = type_caster_base; + static_assert(std::is_base_of>::value, + "Holder classes are only supported for custom types"); + using base::base; + using base::cast; + using base::typeinfo; + using base::value; + + bool load(handle src, bool convert) { + return base::template load_impl>(src, convert); + } + + explicit operator type*() { return this->value; } + explicit operator type&() { return *(this->value); } + explicit operator holder_type*() { return std::addressof(holder); } + + // Workaround for Intel compiler bug + // see pybind11 issue 94 + #if defined(__ICC) || defined(__INTEL_COMPILER) + operator holder_type&() { return holder; } + #else + explicit operator holder_type&() { return holder; } + #endif + + static handle cast(const holder_type &src, return_value_policy, handle) { + const auto *ptr = holder_helper::get(src); + return type_caster_base::cast_holder(ptr, &src); + } + +protected: + friend class type_caster_generic; + void check_holder_compat() { + if (typeinfo->default_holder) + throw cast_error("Unable to load a custom holder type from a default-holder instance"); + } + + bool load_value(value_and_holder &&v_h) { + if (v_h.holder_constructed()) { + value = v_h.value_ptr(); + holder = v_h.template holder(); + return true; + } else { + throw cast_error("Unable to cast from non-held to held instance (T& to Holder) " +#if defined(NDEBUG) + "(compile in debug mode for type information)"); +#else + "of type '" + type_id() + "''"); +#endif + } + } + + template ::value, int> = 0> + bool try_implicit_casts(handle, bool) { return false; } + + template ::value, int> = 0> + bool try_implicit_casts(handle src, bool convert) { + for (auto &cast : typeinfo->implicit_casts) { + copyable_holder_caster sub_caster(*cast.first); + if (sub_caster.load(src, convert)) { + value = cast.second(sub_caster.value); + holder = holder_type(sub_caster.holder, (type *) value); + return true; + } + } + return false; + } + + static bool try_direct_conversions(handle) { return false; } + + + holder_type holder; +}; + +/// Specialize for the common std::shared_ptr, so users don't need to +template +class type_caster> : public copyable_holder_caster> { }; + +template +struct move_only_holder_caster { + static_assert(std::is_base_of, type_caster>::value, + "Holder classes are only supported for custom types"); + + static handle cast(holder_type &&src, return_value_policy, handle) { + auto *ptr = holder_helper::get(src); + return type_caster_base::cast_holder(ptr, std::addressof(src)); + } + static constexpr auto name = type_caster_base::name; +}; + +template +class type_caster> + : public move_only_holder_caster> { }; + +template +using type_caster_holder = conditional_t::value, + copyable_holder_caster, + move_only_holder_caster>; + +template struct always_construct_holder { static constexpr bool value = Value; }; + +/// Create a specialization for custom holder types (silently ignores std::shared_ptr) +#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...) \ + namespace pybind11 { namespace detail { \ + template \ + struct always_construct_holder : always_construct_holder { }; \ + template \ + class type_caster::value>> \ + : public type_caster_holder { }; \ + }} + +// PYBIND11_DECLARE_HOLDER_TYPE holder types: +template struct is_holder_type : + std::is_base_of, detail::type_caster> {}; +// Specialization for always-supported unique_ptr holders: +template struct is_holder_type> : + std::true_type {}; + +template struct handle_type_name { static constexpr auto name = _(); }; +template <> struct handle_type_name { static constexpr auto name = _(PYBIND11_BYTES_NAME); }; +template <> struct handle_type_name { static constexpr auto name = _("*args"); }; +template <> struct handle_type_name { static constexpr auto name = _("**kwargs"); }; + +template +struct pyobject_caster { + template ::value, int> = 0> + bool load(handle src, bool /* convert */) { value = src; return static_cast(value); } + + template ::value, int> = 0> + bool load(handle src, bool /* convert */) { + if (!isinstance(src)) + return false; + value = reinterpret_borrow(src); + return true; + } + + static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) { + return src.inc_ref(); + } + PYBIND11_TYPE_CASTER(type, handle_type_name::name); +}; + +template +class type_caster::value>> : public pyobject_caster { }; + +// Our conditions for enabling moving are quite restrictive: +// At compile time: +// - T needs to be a non-const, non-pointer, non-reference type +// - type_caster::operator T&() must exist +// - the type must be move constructible (obviously) +// At run-time: +// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it +// must have ref_count() == 1)h +// If any of the above are not satisfied, we fall back to copying. +template using move_is_plain_type = satisfies_none_of; +template struct move_always : std::false_type {}; +template struct move_always, + negation>, + std::is_move_constructible, + std::is_same>().operator T&()), T&> +>::value>> : std::true_type {}; +template struct move_if_unreferenced : std::false_type {}; +template struct move_if_unreferenced, + negation>, + std::is_move_constructible, + std::is_same>().operator T&()), T&> +>::value>> : std::true_type {}; +template using move_never = none_of, move_if_unreferenced>; + +// Detect whether returning a `type` from a cast on type's type_caster is going to result in a +// reference or pointer to a local variable of the type_caster. Basically, only +// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe; +// everything else returns a reference/pointer to a local variable. +template using cast_is_temporary_value_reference = bool_constant< + (std::is_reference::value || std::is_pointer::value) && + !std::is_base_of>::value && + !std::is_same, void>::value +>; + +// When a value returned from a C++ function is being cast back to Python, we almost always want to +// force `policy = move`, regardless of the return value policy the function/method was declared +// with. +template struct return_value_policy_override { + static return_value_policy policy(return_value_policy p) { return p; } +}; + +template struct return_value_policy_override>::value, void>> { + static return_value_policy policy(return_value_policy p) { + return !std::is_lvalue_reference::value && + !std::is_pointer::value + ? return_value_policy::move : p; + } +}; + +// Basic python -> C++ casting; throws if casting fails +template type_caster &load_type(type_caster &conv, const handle &handle) { + if (!conv.load(handle, true)) { +#if defined(NDEBUG) + throw cast_error("Unable to cast Python instance to C++ type (compile in debug mode for details)"); +#else + throw cast_error("Unable to cast Python instance of type " + + (std::string) str(handle.get_type()) + " to C++ type '" + type_id() + "'"); +#endif + } + return conv; +} +// Wrapper around the above that also constructs and returns a type_caster +template make_caster load_type(const handle &handle) { + make_caster conv; + load_type(conv, handle); + return conv; +} + +NAMESPACE_END(detail) + +// pytype -> C++ type +template ::value, int> = 0> +T cast(const handle &handle) { + using namespace detail; + static_assert(!cast_is_temporary_value_reference::value, + "Unable to cast type to reference: value is local to type caster"); + return cast_op(load_type(handle)); +} + +// pytype -> pytype (calls converting constructor) +template ::value, int> = 0> +T cast(const handle &handle) { return T(reinterpret_borrow(handle)); } + +// C++ type -> py::object +template ::value, int> = 0> +object cast(const T &value, return_value_policy policy = return_value_policy::automatic_reference, + handle parent = handle()) { + if (policy == return_value_policy::automatic) + policy = std::is_pointer::value ? return_value_policy::take_ownership : return_value_policy::copy; + else if (policy == return_value_policy::automatic_reference) + policy = std::is_pointer::value ? return_value_policy::reference : return_value_policy::copy; + return reinterpret_steal(detail::make_caster::cast(value, policy, parent)); +} + +template T handle::cast() const { return pybind11::cast(*this); } +template <> inline void handle::cast() const { return; } + +template +detail::enable_if_t::value, T> move(object &&obj) { + if (obj.ref_count() > 1) +#if defined(NDEBUG) + throw cast_error("Unable to cast Python instance to C++ rvalue: instance has multiple references" + " (compile in debug mode for details)"); +#else + throw cast_error("Unable to move from Python " + (std::string) str(obj.get_type()) + + " instance to C++ " + type_id() + " instance: instance has multiple references"); +#endif + + // Move into a temporary and return that, because the reference may be a local value of `conv` + T ret = std::move(detail::load_type(obj).operator T&()); + return ret; +} + +// Calling cast() on an rvalue calls pybind::cast with the object rvalue, which does: +// - If we have to move (because T has no copy constructor), do it. This will fail if the moved +// object has multiple references, but trying to copy will fail to compile. +// - If both movable and copyable, check ref count: if 1, move; otherwise copy +// - Otherwise (not movable), copy. +template detail::enable_if_t::value, T> cast(object &&object) { + return move(std::move(object)); +} +template detail::enable_if_t::value, T> cast(object &&object) { + if (object.ref_count() > 1) + return cast(object); + else + return move(std::move(object)); +} +template detail::enable_if_t::value, T> cast(object &&object) { + return cast(object); +} + +template T object::cast() const & { return pybind11::cast(*this); } +template T object::cast() && { return pybind11::cast(std::move(*this)); } +template <> inline void object::cast() const & { return; } +template <> inline void object::cast() && { return; } + +NAMESPACE_BEGIN(detail) + +// Declared in pytypes.h: +template ::value, int>> +object object_or_cast(T &&o) { return pybind11::cast(std::forward(o)); } + +struct overload_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the OVERLOAD_INT macro +template using overload_caster_t = conditional_t< + cast_is_temporary_value_reference::value, make_caster, overload_unused>; + +// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then +// store the result in the given variable. For other types, this is a no-op. +template enable_if_t::value, T> cast_ref(object &&o, make_caster &caster) { + return cast_op(load_type(caster, o)); +} +template enable_if_t::value, T> cast_ref(object &&, overload_unused &) { + pybind11_fail("Internal error: cast_ref fallback invoked"); } + +// Trampoline use: Having a pybind11::cast with an invalid reference type is going to static_assert, even +// though if it's in dead code, so we provide a "trampoline" to pybind11::cast that only does anything in +// cases where pybind11::cast is valid. +template enable_if_t::value, T> cast_safe(object &&o) { + return pybind11::cast(std::move(o)); } +template enable_if_t::value, T> cast_safe(object &&) { + pybind11_fail("Internal error: cast_safe fallback invoked"); } +template <> inline void cast_safe(object &&) {} + +NAMESPACE_END(detail) + +template +tuple make_tuple() { return tuple(0); } + +template tuple make_tuple(Args&&... args_) { + constexpr size_t size = sizeof...(Args); + std::array args { + { reinterpret_steal(detail::make_caster::cast( + std::forward(args_), policy, nullptr))... } + }; + for (size_t i = 0; i < args.size(); i++) { + if (!args[i]) { +#if defined(NDEBUG) + throw cast_error("make_tuple(): unable to convert arguments to Python object (compile in debug mode for details)"); +#else + std::array argtypes { {type_id()...} }; + throw cast_error("make_tuple(): unable to convert argument of type '" + + argtypes[i] + "' to Python object"); +#endif + } + } + tuple result(size); + int counter = 0; + for (auto &arg_value : args) + PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr()); + return result; +} + +/// \ingroup annotations +/// Annotation for arguments +struct arg { + /// Constructs an argument with the name of the argument; if null or omitted, this is a positional argument. + constexpr explicit arg(const char *name = nullptr) : name(name), flag_noconvert(false), flag_none(true) { } + /// Assign a value to this argument + template arg_v operator=(T &&value) const; + /// Indicate that the type should not be converted in the type caster + arg &noconvert(bool flag = true) { flag_noconvert = flag; return *this; } + /// Indicates that the argument should/shouldn't allow None (e.g. for nullable pointer args) + arg &none(bool flag = true) { flag_none = flag; return *this; } + + const char *name; ///< If non-null, this is a named kwargs argument + bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type caster!) + bool flag_none : 1; ///< If set (the default), allow None to be passed to this argument +}; + +/// \ingroup annotations +/// Annotation for arguments with values +struct arg_v : arg { +private: + template + arg_v(arg &&base, T &&x, const char *descr = nullptr) + : arg(base), + value(reinterpret_steal( + detail::make_caster::cast(x, return_value_policy::automatic, {}) + )), + descr(descr) +#if !defined(NDEBUG) + , type(type_id()) +#endif + { } + +public: + /// Direct construction with name, default, and description + template + arg_v(const char *name, T &&x, const char *descr = nullptr) + : arg_v(arg(name), std::forward(x), descr) { } + + /// Called internally when invoking `py::arg("a") = value` + template + arg_v(const arg &base, T &&x, const char *descr = nullptr) + : arg_v(arg(base), std::forward(x), descr) { } + + /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg& + arg_v &noconvert(bool flag = true) { arg::noconvert(flag); return *this; } + + /// Same as `arg::nonone()`, but returns *this as arg_v&, not arg& + arg_v &none(bool flag = true) { arg::none(flag); return *this; } + + /// The default value + object value; + /// The (optional) description of the default value + const char *descr; +#if !defined(NDEBUG) + /// The C++ type name of the default value (only available when compiled in debug mode) + std::string type; +#endif +}; + +template +arg_v arg::operator=(T &&value) const { return {std::move(*this), std::forward(value)}; } + +/// Alias for backward compatibility -- to be removed in version 2.0 +template using arg_t = arg_v; + +inline namespace literals { +/** \rst + String literal version of `arg` + \endrst */ +constexpr arg operator"" _a(const char *name, size_t) { return arg(name); } +} + +NAMESPACE_BEGIN(detail) + +// forward declaration (definition in attr.h) +struct function_record; + +/// Internal data associated with a single function call +struct function_call { + function_call(const function_record &f, handle p); // Implementation in attr.h + + /// The function data: + const function_record &func; + + /// Arguments passed to the function: + std::vector args; + + /// The `convert` value the arguments should be loaded with + std::vector args_convert; + + /// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if + /// present, are also in `args` but without a reference). + object args_ref, kwargs_ref; + + /// The parent, if any + handle parent; + + /// If this is a call to an initializer, this argument contains `self` + handle init_self; +}; + + +/// Helper class which loads arguments for C++ functions called from Python +template +class argument_loader { + using indices = make_index_sequence; + + template using argument_is_args = std::is_same, args>; + template using argument_is_kwargs = std::is_same, kwargs>; + // Get args/kwargs argument positions relative to the end of the argument list: + static constexpr auto args_pos = constexpr_first() - (int) sizeof...(Args), + kwargs_pos = constexpr_first() - (int) sizeof...(Args); + + static constexpr bool args_kwargs_are_last = kwargs_pos >= - 1 && args_pos >= kwargs_pos - 1; + + static_assert(args_kwargs_are_last, "py::args/py::kwargs are only permitted as the last argument(s) of a function"); + +public: + static constexpr bool has_kwargs = kwargs_pos < 0; + static constexpr bool has_args = args_pos < 0; + + static constexpr auto arg_names = concat(type_descr(make_caster::name)...); + + bool load_args(function_call &call) { + return load_impl_sequence(call, indices{}); + } + + template + enable_if_t::value, Return> call(Func &&f) && { + return std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); + } + + template + enable_if_t::value, void_type> call(Func &&f) && { + std::move(*this).template call_impl(std::forward(f), indices{}, Guard{}); + return void_type(); + } + +private: + + static bool load_impl_sequence(function_call &, index_sequence<>) { return true; } + + template + bool load_impl_sequence(function_call &call, index_sequence) { + for (bool r : {std::get(argcasters).load(call.args[Is], call.args_convert[Is])...}) + if (!r) + return false; + return true; + } + + template + Return call_impl(Func &&f, index_sequence, Guard &&) { + return std::forward(f)(cast_op(std::move(std::get(argcasters)))...); + } + + std::tuple...> argcasters; +}; + +/// Helper class which collects only positional arguments for a Python function call. +/// A fancier version below can collect any argument, but this one is optimal for simple calls. +template +class simple_collector { +public: + template + explicit simple_collector(Ts &&...values) + : m_args(pybind11::make_tuple(std::forward(values)...)) { } + + const tuple &args() const & { return m_args; } + dict kwargs() const { return {}; } + + tuple args() && { return std::move(m_args); } + + /// Call a Python function and pass the collected arguments + object call(PyObject *ptr) const { + PyObject *result = PyObject_CallObject(ptr, m_args.ptr()); + if (!result) + throw error_already_set(); + return reinterpret_steal(result); + } + +private: + tuple m_args; +}; + +/// Helper class which collects positional, keyword, * and ** arguments for a Python function call +template +class unpacking_collector { +public: + template + explicit unpacking_collector(Ts &&...values) { + // Tuples aren't (easily) resizable so a list is needed for collection, + // but the actual function call strictly requires a tuple. + auto args_list = list(); + int _[] = { 0, (process(args_list, std::forward(values)), 0)... }; + ignore_unused(_); + + m_args = std::move(args_list); + } + + const tuple &args() const & { return m_args; } + const dict &kwargs() const & { return m_kwargs; } + + tuple args() && { return std::move(m_args); } + dict kwargs() && { return std::move(m_kwargs); } + + /// Call a Python function and pass the collected arguments + object call(PyObject *ptr) const { + PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr()); + if (!result) + throw error_already_set(); + return reinterpret_steal(result); + } + +private: + template + void process(list &args_list, T &&x) { + auto o = reinterpret_steal(detail::make_caster::cast(std::forward(x), policy, {})); + if (!o) { +#if defined(NDEBUG) + argument_cast_error(); +#else + argument_cast_error(std::to_string(args_list.size()), type_id()); +#endif + } + args_list.append(o); + } + + void process(list &args_list, detail::args_proxy ap) { + for (const auto &a : ap) + args_list.append(a); + } + + void process(list &/*args_list*/, arg_v a) { + if (!a.name) +#if defined(NDEBUG) + nameless_argument_error(); +#else + nameless_argument_error(a.type); +#endif + + if (m_kwargs.contains(a.name)) { +#if defined(NDEBUG) + multiple_values_error(); +#else + multiple_values_error(a.name); +#endif + } + if (!a.value) { +#if defined(NDEBUG) + argument_cast_error(); +#else + argument_cast_error(a.name, a.type); +#endif + } + m_kwargs[a.name] = a.value; + } + + void process(list &/*args_list*/, detail::kwargs_proxy kp) { + if (!kp) + return; + for (const auto &k : reinterpret_borrow(kp)) { + if (m_kwargs.contains(k.first)) { +#if defined(NDEBUG) + multiple_values_error(); +#else + multiple_values_error(str(k.first)); +#endif + } + m_kwargs[k.first] = k.second; + } + } + + [[noreturn]] static void nameless_argument_error() { + throw type_error("Got kwargs without a name; only named arguments " + "may be passed via py::arg() to a python function call. " + "(compile in debug mode for details)"); + } + [[noreturn]] static void nameless_argument_error(std::string type) { + throw type_error("Got kwargs without a name of type '" + type + "'; only named " + "arguments may be passed via py::arg() to a python function call. "); + } + [[noreturn]] static void multiple_values_error() { + throw type_error("Got multiple values for keyword argument " + "(compile in debug mode for details)"); + } + + [[noreturn]] static void multiple_values_error(std::string name) { + throw type_error("Got multiple values for keyword argument '" + name + "'"); + } + + [[noreturn]] static void argument_cast_error() { + throw cast_error("Unable to convert call argument to Python object " + "(compile in debug mode for details)"); + } + + [[noreturn]] static void argument_cast_error(std::string name, std::string type) { + throw cast_error("Unable to convert call argument '" + name + + "' of type '" + type + "' to Python object"); + } + +private: + tuple m_args; + dict m_kwargs; +}; + +/// Collect only positional arguments for a Python function call +template ...>::value>> +simple_collector collect_arguments(Args &&...args) { + return simple_collector(std::forward(args)...); +} + +/// Collect all arguments, including keywords and unpacking (only instantiated when needed) +template ...>::value>> +unpacking_collector collect_arguments(Args &&...args) { + // Following argument order rules for generalized unpacking according to PEP 448 + static_assert( + constexpr_last() < constexpr_first() + && constexpr_last() < constexpr_first(), + "Invalid function call: positional args must precede keywords and ** unpacking; " + "* unpacking must precede ** unpacking" + ); + return unpacking_collector(std::forward(args)...); +} + +template +template +object object_api::operator()(Args &&...args) const { + return detail::collect_arguments(std::forward(args)...).call(derived().ptr()); +} + +template +template +object object_api::call(Args &&...args) const { + return operator()(std::forward(args)...); +} + +NAMESPACE_END(detail) + +#define PYBIND11_MAKE_OPAQUE(...) \ + namespace pybind11 { namespace detail { \ + template<> class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> { }; \ + }} + +/// Lets you pass a type containing a `,` through a macro parameter without needing a separate +/// typedef, e.g.: `PYBIND11_OVERLOAD(PYBIND11_TYPE(ReturnType), PYBIND11_TYPE(Parent), f, arg)` +#define PYBIND11_TYPE(...) __VA_ARGS__ + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/chrono.h b/python/src/pybind11/chrono.h new file mode 100644 index 000000000..95ada76e0 --- /dev/null +++ b/python/src/pybind11/chrono.h @@ -0,0 +1,162 @@ +/* + pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime + + Copyright (c) 2016 Trent Houliston and + Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" +#include +#include +#include +#include + +// Backport the PyDateTime_DELTA functions from Python3.3 if required +#ifndef PyDateTime_DELTA_GET_DAYS +#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) +#endif +#ifndef PyDateTime_DELTA_GET_SECONDS +#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) +#endif +#ifndef PyDateTime_DELTA_GET_MICROSECONDS +#define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) +#endif + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +template class duration_caster { +public: + typedef typename type::rep rep; + typedef typename type::period period; + + typedef std::chrono::duration> days; + + bool load(handle src, bool) { + using namespace std::chrono; + + // Lazy initialise the PyDateTime import + if (!PyDateTimeAPI) { PyDateTime_IMPORT; } + + if (!src) return false; + // If invoked with datetime.delta object + if (PyDelta_Check(src.ptr())) { + value = type(duration_cast>( + days(PyDateTime_DELTA_GET_DAYS(src.ptr())) + + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) + + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr())))); + return true; + } + // If invoked with a float we assume it is seconds and convert + else if (PyFloat_Check(src.ptr())) { + value = type(duration_cast>(duration(PyFloat_AsDouble(src.ptr())))); + return true; + } + else return false; + } + + // If this is a duration just return it back + static const std::chrono::duration& get_duration(const std::chrono::duration &src) { + return src; + } + + // If this is a time_point get the time_since_epoch + template static std::chrono::duration get_duration(const std::chrono::time_point> &src) { + return src.time_since_epoch(); + } + + static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) { + using namespace std::chrono; + + // Use overloaded function to get our duration from our source + // Works out if it is a duration or time_point and get the duration + auto d = get_duration(src); + + // Lazy initialise the PyDateTime import + if (!PyDateTimeAPI) { PyDateTime_IMPORT; } + + // Declare these special duration types so the conversions happen with the correct primitive types (int) + using dd_t = duration>; + using ss_t = duration>; + using us_t = duration; + + auto dd = duration_cast(d); + auto subd = d - dd; + auto ss = duration_cast(subd); + auto us = duration_cast(subd - ss); + return PyDelta_FromDSU(dd.count(), ss.count(), us.count()); + } + + PYBIND11_TYPE_CASTER(type, _("datetime.timedelta")); +}; + +// This is for casting times on the system clock into datetime.datetime instances +template class type_caster> { +public: + typedef std::chrono::time_point type; + bool load(handle src, bool) { + using namespace std::chrono; + + // Lazy initialise the PyDateTime import + if (!PyDateTimeAPI) { PyDateTime_IMPORT; } + + if (!src) return false; + if (PyDateTime_Check(src.ptr())) { + std::tm cal; + cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr()); + cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr()); + cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr()); + cal.tm_mday = PyDateTime_GET_DAY(src.ptr()); + cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1; + cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900; + cal.tm_isdst = -1; + + value = system_clock::from_time_t(std::mktime(&cal)) + microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr())); + return true; + } + else return false; + } + + static handle cast(const std::chrono::time_point &src, return_value_policy /* policy */, handle /* parent */) { + using namespace std::chrono; + + // Lazy initialise the PyDateTime import + if (!PyDateTimeAPI) { PyDateTime_IMPORT; } + + std::time_t tt = system_clock::to_time_t(src); + // this function uses static memory so it's best to copy it out asap just in case + // otherwise other code that is using localtime may break this (not just python code) + std::tm localtime = *std::localtime(&tt); + + // Declare these special duration types so the conversions happen with the correct primitive types (int) + using us_t = duration; + + return PyDateTime_FromDateAndTime(localtime.tm_year + 1900, + localtime.tm_mon + 1, + localtime.tm_mday, + localtime.tm_hour, + localtime.tm_min, + localtime.tm_sec, + (duration_cast(src.time_since_epoch() % seconds(1))).count()); + } + PYBIND11_TYPE_CASTER(type, _("datetime.datetime")); +}; + +// Other clocks that are not the system clock are not measured as datetime.datetime objects +// since they are not measured on calendar time. So instead we just make them timedeltas +// Or if they have passed us a time as a float we convert that +template class type_caster> +: public duration_caster> { +}; + +template class type_caster> +: public duration_caster> { +}; + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/common.h b/python/src/pybind11/common.h new file mode 100644 index 000000000..6c8a4f1e8 --- /dev/null +++ b/python/src/pybind11/common.h @@ -0,0 +1,2 @@ +#include "detail/common.h" +#warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'." diff --git a/python/src/pybind11/complex.h b/python/src/pybind11/complex.h new file mode 100644 index 000000000..3f8963857 --- /dev/null +++ b/python/src/pybind11/complex.h @@ -0,0 +1,65 @@ +/* + pybind11/complex.h: Complex number support + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" +#include + +/// glibc defines I as a macro which breaks things, e.g., boost template names +#ifdef I +# undef I +#endif + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +template struct format_descriptor, detail::enable_if_t::value>> { + static constexpr const char c = format_descriptor::c; + static constexpr const char value[3] = { 'Z', c, '\0' }; + static std::string format() { return std::string(value); } +}; + +#ifndef PYBIND11_CPP17 + +template constexpr const char format_descriptor< + std::complex, detail::enable_if_t::value>>::value[3]; + +#endif + +NAMESPACE_BEGIN(detail) + +template struct is_fmt_numeric, detail::enable_if_t::value>> { + static constexpr bool value = true; + static constexpr int index = is_fmt_numeric::index + 3; +}; + +template class type_caster> { +public: + bool load(handle src, bool convert) { + if (!src) + return false; + if (!convert && !PyComplex_Check(src.ptr())) + return false; + Py_complex result = PyComplex_AsCComplex(src.ptr()); + if (result.real == -1.0 && PyErr_Occurred()) { + PyErr_Clear(); + return false; + } + value = std::complex((T) result.real, (T) result.imag); + return true; + } + + static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) { + return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); + } + + PYBIND11_TYPE_CASTER(std::complex, _("complex")); +}; +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/detail/class.h b/python/src/pybind11/detail/class.h new file mode 100644 index 000000000..b1916fcd0 --- /dev/null +++ b/python/src/pybind11/detail/class.h @@ -0,0 +1,623 @@ +/* + pybind11/detail/class.h: Python C API implementation details for py::class_ + + Copyright (c) 2017 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "../attr.h" +#include "../options.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +#if PY_VERSION_HEX >= 0x03030000 +# define PYBIND11_BUILTIN_QUALNAME +# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) +#else +// In pre-3.3 Python, we still set __qualname__ so that we can produce reliable function type +// signatures; in 3.3+ this macro expands to nothing: +# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) setattr((PyObject *) obj, "__qualname__", nameobj) +#endif + +inline PyTypeObject *type_incref(PyTypeObject *type) { + Py_INCREF(type); + return type; +} + +#if !defined(PYPY_VERSION) + +/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance. +extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) { + return PyProperty_Type.tp_descr_get(self, cls, cls); +} + +/// `pybind11_static_property.__set__()`: Just like the above `__get__()`. +extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) { + PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj); + return PyProperty_Type.tp_descr_set(self, cls, value); +} + +/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()` + methods are modified to always use the object type instead of a concrete instance. + Return value: New reference. */ +inline PyTypeObject *make_static_property_type() { + constexpr auto *name = "pybind11_static_property"; + auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); + + /* Danger zone: from now (and until PyType_Ready), make sure to + issue no Python C API calls which could potentially invoke the + garbage collector (the GC will call type_traverse(), which will in + turn find the newly constructed type in an invalid state) */ + auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); + if (!heap_type) + pybind11_fail("make_static_property_type(): error allocating type!"); + + heap_type->ht_name = name_obj.inc_ref().ptr(); +#ifdef PYBIND11_BUILTIN_QUALNAME + heap_type->ht_qualname = name_obj.inc_ref().ptr(); +#endif + + auto type = &heap_type->ht_type; + type->tp_name = name; + type->tp_base = type_incref(&PyProperty_Type); + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; + type->tp_descr_get = pybind11_static_get; + type->tp_descr_set = pybind11_static_set; + + if (PyType_Ready(type) < 0) + pybind11_fail("make_static_property_type(): failure in PyType_Ready()!"); + + setattr((PyObject *) type, "__module__", str("pybind11_builtins")); + PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); + + return type; +} + +#else // PYPY + +/** PyPy has some issues with the above C API, so we evaluate Python code instead. + This function will only be called once so performance isn't really a concern. + Return value: New reference. */ +inline PyTypeObject *make_static_property_type() { + auto d = dict(); + PyObject *result = PyRun_String(R"(\ + class pybind11_static_property(property): + def __get__(self, obj, cls): + return property.__get__(self, cls, cls) + + def __set__(self, obj, value): + cls = obj if isinstance(obj, type) else type(obj) + property.__set__(self, cls, value) + )", Py_file_input, d.ptr(), d.ptr() + ); + if (result == nullptr) + throw error_already_set(); + Py_DECREF(result); + return (PyTypeObject *) d["pybind11_static_property"].cast().release().ptr(); +} + +#endif // PYPY + +/** Types with static properties need to handle `Type.static_prop = x` in a specific way. + By default, Python replaces the `static_property` itself, but for wrapped C++ types + we need to call `static_property.__set__()` in order to propagate the new value to + the underlying C++ data structure. */ +extern "C" inline int pybind11_meta_setattro(PyObject* obj, PyObject* name, PyObject* value) { + // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw + // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`). + PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); + + // The following assignment combinations are possible: + // 1. `Type.static_prop = value` --> descr_set: `Type.static_prop.__set__(value)` + // 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop` + // 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment + const auto static_prop = (PyObject *) get_internals().static_property_type; + const auto call_descr_set = descr && PyObject_IsInstance(descr, static_prop) + && !PyObject_IsInstance(value, static_prop); + if (call_descr_set) { + // Call `static_property.__set__()` instead of replacing the `static_property`. +#if !defined(PYPY_VERSION) + return Py_TYPE(descr)->tp_descr_set(descr, obj, value); +#else + if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) { + Py_DECREF(result); + return 0; + } else { + return -1; + } +#endif + } else { + // Replace existing attribute. + return PyType_Type.tp_setattro(obj, name, value); + } +} + +#if PY_MAJOR_VERSION >= 3 +/** + * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing + * methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function, + * when called on a class, or a PyMethod, when called on an instance. Override that behaviour here + * to do a special case bypass for PyInstanceMethod_Types. + */ +extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) { + PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); + if (descr && PyInstanceMethod_Check(descr)) { + Py_INCREF(descr); + return descr; + } + else { + return PyType_Type.tp_getattro(obj, name); + } +} +#endif + +/** This metaclass is assigned by default to all pybind11 types and is required in order + for static properties to function correctly. Users may override this using `py::metaclass`. + Return value: New reference. */ +inline PyTypeObject* make_default_metaclass() { + constexpr auto *name = "pybind11_type"; + auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); + + /* Danger zone: from now (and until PyType_Ready), make sure to + issue no Python C API calls which could potentially invoke the + garbage collector (the GC will call type_traverse(), which will in + turn find the newly constructed type in an invalid state) */ + auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); + if (!heap_type) + pybind11_fail("make_default_metaclass(): error allocating metaclass!"); + + heap_type->ht_name = name_obj.inc_ref().ptr(); +#ifdef PYBIND11_BUILTIN_QUALNAME + heap_type->ht_qualname = name_obj.inc_ref().ptr(); +#endif + + auto type = &heap_type->ht_type; + type->tp_name = name; + type->tp_base = type_incref(&PyType_Type); + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; + + type->tp_setattro = pybind11_meta_setattro; +#if PY_MAJOR_VERSION >= 3 + type->tp_getattro = pybind11_meta_getattro; +#endif + + if (PyType_Ready(type) < 0) + pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!"); + + setattr((PyObject *) type, "__module__", str("pybind11_builtins")); + PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); + + return type; +} + +/// For multiple inheritance types we need to recursively register/deregister base pointers for any +/// base classes with pointers that are difference from the instance value pointer so that we can +/// correctly recognize an offset base class pointer. This calls a function with any offset base ptrs. +inline void traverse_offset_bases(void *valueptr, const detail::type_info *tinfo, instance *self, + bool (*f)(void * /*parentptr*/, instance * /*self*/)) { + for (handle h : reinterpret_borrow(tinfo->type->tp_bases)) { + if (auto parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) { + for (auto &c : parent_tinfo->implicit_casts) { + if (c.first == tinfo->cpptype) { + auto *parentptr = c.second(valueptr); + if (parentptr != valueptr) + f(parentptr, self); + traverse_offset_bases(parentptr, parent_tinfo, self, f); + break; + } + } + } + } +} + +inline bool register_instance_impl(void *ptr, instance *self) { + get_internals().registered_instances.emplace(ptr, self); + return true; // unused, but gives the same signature as the deregister func +} +inline bool deregister_instance_impl(void *ptr, instance *self) { + auto ®istered_instances = get_internals().registered_instances; + auto range = registered_instances.equal_range(ptr); + for (auto it = range.first; it != range.second; ++it) { + if (Py_TYPE(self) == Py_TYPE(it->second)) { + registered_instances.erase(it); + return true; + } + } + return false; +} + +inline void register_instance(instance *self, void *valptr, const type_info *tinfo) { + register_instance_impl(valptr, self); + if (!tinfo->simple_ancestors) + traverse_offset_bases(valptr, tinfo, self, register_instance_impl); +} + +inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) { + bool ret = deregister_instance_impl(valptr, self); + if (!tinfo->simple_ancestors) + traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl); + return ret; +} + +/// Instance creation function for all pybind11 types. It allocates the internal instance layout for +/// holding C++ objects and holders. Allocation is done lazily (the first time the instance is cast +/// to a reference or pointer), and initialization is done by an `__init__` function. +inline PyObject *make_new_instance(PyTypeObject *type) { +#if defined(PYPY_VERSION) + // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first inherited + // object is a a plain Python type (i.e. not derived from an extension type). Fix it. + ssize_t instance_size = static_cast(sizeof(instance)); + if (type->tp_basicsize < instance_size) { + type->tp_basicsize = instance_size; + } +#endif + PyObject *self = type->tp_alloc(type, 0); + auto inst = reinterpret_cast(self); + // Allocate the value/holder internals: + inst->allocate_layout(); + + inst->owned = true; + + return self; +} + +/// Instance creation function for all pybind11 types. It only allocates space for the +/// C++ object, but doesn't call the constructor -- an `__init__` function must do that. +extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) { + return make_new_instance(type); +} + +/// An `__init__` function constructs the C++ object. Users should provide at least one +/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the +/// following default function will be used which simply throws an exception. +extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) { + PyTypeObject *type = Py_TYPE(self); + std::string msg; +#if defined(PYPY_VERSION) + msg += handle((PyObject *) type).attr("__module__").cast() + "."; +#endif + msg += type->tp_name; + msg += ": No constructor defined!"; + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return -1; +} + +inline void add_patient(PyObject *nurse, PyObject *patient) { + auto &internals = get_internals(); + auto instance = reinterpret_cast(nurse); + instance->has_patients = true; + Py_INCREF(patient); + internals.patients[nurse].push_back(patient); +} + +inline void clear_patients(PyObject *self) { + auto instance = reinterpret_cast(self); + auto &internals = get_internals(); + auto pos = internals.patients.find(self); + assert(pos != internals.patients.end()); + // Clearing the patients can cause more Python code to run, which + // can invalidate the iterator. Extract the vector of patients + // from the unordered_map first. + auto patients = std::move(pos->second); + internals.patients.erase(pos); + instance->has_patients = false; + for (PyObject *&patient : patients) + Py_CLEAR(patient); +} + +/// Clears all internal data from the instance and removes it from registered instances in +/// preparation for deallocation. +inline void clear_instance(PyObject *self) { + auto instance = reinterpret_cast(self); + + // Deallocate any values/holders, if present: + for (auto &v_h : values_and_holders(instance)) { + if (v_h) { + + // We have to deregister before we call dealloc because, for virtual MI types, we still + // need to be able to get the parent pointers. + if (v_h.instance_registered() && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) + pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!"); + + if (instance->owned || v_h.holder_constructed()) + v_h.type->dealloc(v_h); + } + } + // Deallocate the value/holder layout internals: + instance->deallocate_layout(); + + if (instance->weakrefs) + PyObject_ClearWeakRefs(self); + + PyObject **dict_ptr = _PyObject_GetDictPtr(self); + if (dict_ptr) + Py_CLEAR(*dict_ptr); + + if (instance->has_patients) + clear_patients(self); +} + +/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc` +/// to destroy the C++ object itself, while the rest is Python bookkeeping. +extern "C" inline void pybind11_object_dealloc(PyObject *self) { + clear_instance(self); + + auto type = Py_TYPE(self); + type->tp_free(self); + + // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called + // as part of a derived type's dealloc, in which case we're not allowed to decref + // the type here. For cross-module compatibility, we shouldn't compare directly + // with `pybind11_object_dealloc`, but with the common one stashed in internals. + auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base; + if (type->tp_dealloc == pybind11_object_type->tp_dealloc) + Py_DECREF(type); +} + +/** Create the type which can be used as a common base for all classes. This is + needed in order to satisfy Python's requirements for multiple inheritance. + Return value: New reference. */ +inline PyObject *make_object_base_type(PyTypeObject *metaclass) { + constexpr auto *name = "pybind11_object"; + auto name_obj = reinterpret_steal(PYBIND11_FROM_STRING(name)); + + /* Danger zone: from now (and until PyType_Ready), make sure to + issue no Python C API calls which could potentially invoke the + garbage collector (the GC will call type_traverse(), which will in + turn find the newly constructed type in an invalid state) */ + auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); + if (!heap_type) + pybind11_fail("make_object_base_type(): error allocating type!"); + + heap_type->ht_name = name_obj.inc_ref().ptr(); +#ifdef PYBIND11_BUILTIN_QUALNAME + heap_type->ht_qualname = name_obj.inc_ref().ptr(); +#endif + + auto type = &heap_type->ht_type; + type->tp_name = name; + type->tp_base = type_incref(&PyBaseObject_Type); + type->tp_basicsize = static_cast(sizeof(instance)); + type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; + + type->tp_new = pybind11_object_new; + type->tp_init = pybind11_object_init; + type->tp_dealloc = pybind11_object_dealloc; + + /* Support weak references (needed for the keep_alive feature) */ + type->tp_weaklistoffset = offsetof(instance, weakrefs); + + if (PyType_Ready(type) < 0) + pybind11_fail("PyType_Ready failed in make_object_base_type():" + error_string()); + + setattr((PyObject *) type, "__module__", str("pybind11_builtins")); + PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); + + assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); + return (PyObject *) heap_type; +} + +/// dynamic_attr: Support for `d = instance.__dict__`. +extern "C" inline PyObject *pybind11_get_dict(PyObject *self, void *) { + PyObject *&dict = *_PyObject_GetDictPtr(self); + if (!dict) + dict = PyDict_New(); + Py_XINCREF(dict); + return dict; +} + +/// dynamic_attr: Support for `instance.__dict__ = dict()`. +extern "C" inline int pybind11_set_dict(PyObject *self, PyObject *new_dict, void *) { + if (!PyDict_Check(new_dict)) { + PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%.200s'", + Py_TYPE(new_dict)->tp_name); + return -1; + } + PyObject *&dict = *_PyObject_GetDictPtr(self); + Py_INCREF(new_dict); + Py_CLEAR(dict); + dict = new_dict; + return 0; +} + +/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`. +extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) { + PyObject *&dict = *_PyObject_GetDictPtr(self); + Py_VISIT(dict); + return 0; +} + +/// dynamic_attr: Allow the GC to clear the dictionary. +extern "C" inline int pybind11_clear(PyObject *self) { + PyObject *&dict = *_PyObject_GetDictPtr(self); + Py_CLEAR(dict); + return 0; +} + +/// Give instances of this type a `__dict__` and opt into garbage collection. +inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) { + auto type = &heap_type->ht_type; +#if defined(PYPY_VERSION) + pybind11_fail(std::string(type->tp_name) + ": dynamic attributes are " + "currently not supported in " + "conjunction with PyPy!"); +#endif + type->tp_flags |= Py_TPFLAGS_HAVE_GC; + type->tp_dictoffset = type->tp_basicsize; // place dict at the end + type->tp_basicsize += (ssize_t)sizeof(PyObject *); // and allocate enough space for it + type->tp_traverse = pybind11_traverse; + type->tp_clear = pybind11_clear; + + static PyGetSetDef getset[] = { + {const_cast("__dict__"), pybind11_get_dict, pybind11_set_dict, nullptr, nullptr}, + {nullptr, nullptr, nullptr, nullptr, nullptr} + }; + type->tp_getset = getset; +} + +/// buffer_protocol: Fill in the view as specified by flags. +extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) { + // Look for a `get_buffer` implementation in this type's info or any bases (following MRO). + type_info *tinfo = nullptr; + for (auto type : reinterpret_borrow(Py_TYPE(obj)->tp_mro)) { + tinfo = get_type_info((PyTypeObject *) type.ptr()); + if (tinfo && tinfo->get_buffer) + break; + } + if (view == nullptr || !tinfo || !tinfo->get_buffer) { + if (view) + view->obj = nullptr; + PyErr_SetString(PyExc_BufferError, "pybind11_getbuffer(): Internal error"); + return -1; + } + std::memset(view, 0, sizeof(Py_buffer)); + buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data); + view->obj = obj; + view->ndim = 1; + view->internal = info; + view->buf = info->ptr; + view->itemsize = info->itemsize; + view->len = view->itemsize; + for (auto s : info->shape) + view->len *= s; + if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) + view->format = const_cast(info->format.c_str()); + if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { + view->ndim = (int) info->ndim; + view->strides = &info->strides[0]; + view->shape = &info->shape[0]; + } + Py_INCREF(view->obj); + return 0; +} + +/// buffer_protocol: Release the resources of the buffer. +extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) { + delete (buffer_info *) view->internal; +} + +/// Give this type a buffer interface. +inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) { + heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer; +#if PY_MAJOR_VERSION < 3 + heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; +#endif + + heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer; + heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer; +} + +/** Create a brand new Python type according to the `type_record` specification. + Return value: New reference. */ +inline PyObject* make_new_python_type(const type_record &rec) { + auto name = reinterpret_steal(PYBIND11_FROM_STRING(rec.name)); + + auto qualname = name; + if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) { +#if PY_MAJOR_VERSION >= 3 + qualname = reinterpret_steal( + PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr())); +#else + qualname = str(rec.scope.attr("__qualname__").cast() + "." + rec.name); +#endif + } + + object module; + if (rec.scope) { + if (hasattr(rec.scope, "__module__")) + module = rec.scope.attr("__module__"); + else if (hasattr(rec.scope, "__name__")) + module = rec.scope.attr("__name__"); + } + + auto full_name = c_str( +#if !defined(PYPY_VERSION) + module ? str(module).cast() + "." + rec.name : +#endif + rec.name); + + char *tp_doc = nullptr; + if (rec.doc && options::show_user_defined_docstrings()) { + /* Allocate memory for docstring (using PyObject_MALLOC, since + Python will free this later on) */ + size_t size = strlen(rec.doc) + 1; + tp_doc = (char *) PyObject_MALLOC(size); + memcpy((void *) tp_doc, rec.doc, size); + } + + auto &internals = get_internals(); + auto bases = tuple(rec.bases); + auto base = (bases.size() == 0) ? internals.instance_base + : bases[0].ptr(); + + /* Danger zone: from now (and until PyType_Ready), make sure to + issue no Python C API calls which could potentially invoke the + garbage collector (the GC will call type_traverse(), which will in + turn find the newly constructed type in an invalid state) */ + auto metaclass = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() + : internals.default_metaclass; + + auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); + if (!heap_type) + pybind11_fail(std::string(rec.name) + ": Unable to create type object!"); + + heap_type->ht_name = name.release().ptr(); +#ifdef PYBIND11_BUILTIN_QUALNAME + heap_type->ht_qualname = qualname.inc_ref().ptr(); +#endif + + auto type = &heap_type->ht_type; + type->tp_name = full_name; + type->tp_doc = tp_doc; + type->tp_base = type_incref((PyTypeObject *)base); + type->tp_basicsize = static_cast(sizeof(instance)); + if (bases.size() > 0) + type->tp_bases = bases.release().ptr(); + + /* Don't inherit base __init__ */ + type->tp_init = pybind11_object_init; + + /* Supported protocols */ + type->tp_as_number = &heap_type->as_number; + type->tp_as_sequence = &heap_type->as_sequence; + type->tp_as_mapping = &heap_type->as_mapping; + + /* Flags */ + type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; +#if PY_MAJOR_VERSION < 3 + type->tp_flags |= Py_TPFLAGS_CHECKTYPES; +#endif + + if (rec.dynamic_attr) + enable_dynamic_attributes(heap_type); + + if (rec.buffer_protocol) + enable_buffer_protocol(heap_type); + + if (PyType_Ready(type) < 0) + pybind11_fail(std::string(rec.name) + ": PyType_Ready failed (" + error_string() + ")!"); + + assert(rec.dynamic_attr ? PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) + : !PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); + + /* Register type with the parent scope */ + if (rec.scope) + setattr(rec.scope, rec.name, (PyObject *) type); + else + Py_INCREF(type); // Keep it alive forever (reference leak) + + if (module) // Needed by pydoc + setattr((PyObject *) type, "__module__", module); + + PYBIND11_SET_OLDPY_QUALNAME(type, qualname); + + return (PyObject *) type; +} + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/detail/common.h b/python/src/pybind11/detail/common.h new file mode 100644 index 000000000..bec8ccf3b --- /dev/null +++ b/python/src/pybind11/detail/common.h @@ -0,0 +1,807 @@ +/* + pybind11/detail/common.h -- Basic macros + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#if !defined(NAMESPACE_BEGIN) +# define NAMESPACE_BEGIN(name) namespace name { +#endif +#if !defined(NAMESPACE_END) +# define NAMESPACE_END(name) } +#endif + +// Robust support for some features and loading modules compiled against different pybind versions +// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute on +// the main `pybind11` namespace. +#if !defined(PYBIND11_NAMESPACE) +# ifdef __GNUG__ +# define PYBIND11_NAMESPACE pybind11 __attribute__((visibility("hidden"))) +# else +# define PYBIND11_NAMESPACE pybind11 +# endif +#endif + +#if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER) +# if __cplusplus >= 201402L +# define PYBIND11_CPP14 +# if __cplusplus >= 201703L +# define PYBIND11_CPP17 +# endif +# endif +#elif defined(_MSC_VER) && __cplusplus == 199711L +// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented) +// Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 or newer +# if _MSVC_LANG >= 201402L +# define PYBIND11_CPP14 +# if _MSVC_LANG > 201402L && _MSC_VER >= 1910 +# define PYBIND11_CPP17 +# endif +# endif +#endif + +// Compiler version assertions +#if defined(__INTEL_COMPILER) +# if __INTEL_COMPILER < 1700 +# error pybind11 requires Intel C++ compiler v17 or newer +# endif +#elif defined(__clang__) && !defined(__apple_build_version__) +# if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3) +# error pybind11 requires clang 3.3 or newer +# endif +#elif defined(__clang__) +// Apple changes clang version macros to its Xcode version; the first Xcode release based on +// (upstream) clang 3.3 was Xcode 5: +# if __clang_major__ < 5 +# error pybind11 requires Xcode/clang 5.0 or newer +# endif +#elif defined(__GNUG__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) +# error pybind11 requires gcc 4.8 or newer +# endif +#elif defined(_MSC_VER) +// Pybind hits various compiler bugs in 2015u2 and earlier, and also makes use of some stl features +// (e.g. std::negation) added in 2015u3: +# if _MSC_FULL_VER < 190024210 +# error pybind11 requires MSVC 2015 update 3 or newer +# endif +#endif + +#if !defined(PYBIND11_EXPORT) +# if defined(WIN32) || defined(_WIN32) +# define PYBIND11_EXPORT __declspec(dllexport) +# else +# define PYBIND11_EXPORT __attribute__ ((visibility("default"))) +# endif +#endif + +#if defined(_MSC_VER) +# define PYBIND11_NOINLINE __declspec(noinline) +#else +# define PYBIND11_NOINLINE __attribute__ ((noinline)) +#endif + +#if defined(PYBIND11_CPP14) +# define PYBIND11_DEPRECATED(reason) [[deprecated(reason)]] +#else +# define PYBIND11_DEPRECATED(reason) __attribute__((deprecated(reason))) +#endif + +#define PYBIND11_VERSION_MAJOR 2 +#define PYBIND11_VERSION_MINOR 3 +#define PYBIND11_VERSION_PATCH 0 + +/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode +#if defined(_MSC_VER) +# if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 4) +# define HAVE_ROUND 1 +# endif +# pragma warning(push) +# pragma warning(disable: 4510 4610 4512 4005) +# if defined(_DEBUG) +# define PYBIND11_DEBUG_MARKER +# undef _DEBUG +# endif +#endif + +#include +#include +#include + +#if defined(_WIN32) && (defined(min) || defined(max)) +# error Macro clash with min and max -- define NOMINMAX when compiling your program on Windows +#endif + +#if defined(isalnum) +# undef isalnum +# undef isalpha +# undef islower +# undef isspace +# undef isupper +# undef tolower +# undef toupper +#endif + +#if defined(_MSC_VER) +# if defined(PYBIND11_DEBUG_MARKER) +# define _DEBUG +# undef PYBIND11_DEBUG_MARKER +# endif +# pragma warning(pop) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions +#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr) +#define PYBIND11_INSTANCE_METHOD_CHECK PyInstanceMethod_Check +#define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyInstanceMethod_GET_FUNCTION +#define PYBIND11_BYTES_CHECK PyBytes_Check +#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString +#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize +#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize +#define PYBIND11_BYTES_AS_STRING PyBytes_AsString +#define PYBIND11_BYTES_SIZE PyBytes_Size +#define PYBIND11_LONG_CHECK(o) PyLong_Check(o) +#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o) +#define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) o) +#define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) o) +#define PYBIND11_BYTES_NAME "bytes" +#define PYBIND11_STRING_NAME "str" +#define PYBIND11_SLICE_OBJECT PyObject +#define PYBIND11_FROM_STRING PyUnicode_FromString +#define PYBIND11_STR_TYPE ::pybind11::str +#define PYBIND11_BOOL_ATTR "__bool__" +#define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_bool) +#define PYBIND11_PLUGIN_IMPL(name) \ + extern "C" PYBIND11_EXPORT PyObject *PyInit_##name() + +#else +#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyMethod_New(ptr, nullptr, class_) +#define PYBIND11_INSTANCE_METHOD_CHECK PyMethod_Check +#define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyMethod_GET_FUNCTION +#define PYBIND11_BYTES_CHECK PyString_Check +#define PYBIND11_BYTES_FROM_STRING PyString_FromString +#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize +#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize +#define PYBIND11_BYTES_AS_STRING PyString_AsString +#define PYBIND11_BYTES_SIZE PyString_Size +#define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o)) +#define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o)) +#define PYBIND11_LONG_FROM_SIGNED(o) PyInt_FromSsize_t((ssize_t) o) // Returns long if needed. +#define PYBIND11_LONG_FROM_UNSIGNED(o) PyInt_FromSize_t((size_t) o) // Returns long if needed. +#define PYBIND11_BYTES_NAME "str" +#define PYBIND11_STRING_NAME "unicode" +#define PYBIND11_SLICE_OBJECT PySliceObject +#define PYBIND11_FROM_STRING PyString_FromString +#define PYBIND11_STR_TYPE ::pybind11::bytes +#define PYBIND11_BOOL_ATTR "__nonzero__" +#define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_nonzero) +#define PYBIND11_PLUGIN_IMPL(name) \ + static PyObject *pybind11_init_wrapper(); \ + extern "C" PYBIND11_EXPORT void init##name() { \ + (void)pybind11_init_wrapper(); \ + } \ + PyObject *pybind11_init_wrapper() +#endif + +#if PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03050200 +extern "C" { + struct _Py_atomic_address { void *value; }; + PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current; +} +#endif + +#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code +#define PYBIND11_STRINGIFY(x) #x +#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x) +#define PYBIND11_CONCAT(first, second) first##second + +#define PYBIND11_CHECK_PYTHON_VERSION \ + { \ + const char *compiled_ver = PYBIND11_TOSTRING(PY_MAJOR_VERSION) \ + "." PYBIND11_TOSTRING(PY_MINOR_VERSION); \ + const char *runtime_ver = Py_GetVersion(); \ + size_t len = std::strlen(compiled_ver); \ + if (std::strncmp(runtime_ver, compiled_ver, len) != 0 \ + || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) { \ + PyErr_Format(PyExc_ImportError, \ + "Python version mismatch: module was compiled for Python %s, " \ + "but the interpreter version is incompatible: %s.", \ + compiled_ver, runtime_ver); \ + return nullptr; \ + } \ + } + +#define PYBIND11_CATCH_INIT_EXCEPTIONS \ + catch (pybind11::error_already_set &e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } catch (const std::exception &e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } \ + +/** \rst + ***Deprecated in favor of PYBIND11_MODULE*** + + This macro creates the entry point that will be invoked when the Python interpreter + imports a plugin library. Please create a `module` in the function body and return + the pointer to its underlying Python object at the end. + + .. code-block:: cpp + + PYBIND11_PLUGIN(example) { + pybind11::module m("example", "pybind11 example plugin"); + /// Set up bindings here + return m.ptr(); + } +\endrst */ +#define PYBIND11_PLUGIN(name) \ + PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE") \ + static PyObject *pybind11_init(); \ + PYBIND11_PLUGIN_IMPL(name) { \ + PYBIND11_CHECK_PYTHON_VERSION \ + try { \ + return pybind11_init(); \ + } PYBIND11_CATCH_INIT_EXCEPTIONS \ + } \ + PyObject *pybind11_init() + +/** \rst + This macro creates the entry point that will be invoked when the Python interpreter + imports an extension module. The module name is given as the fist argument and it + should not be in quotes. The second macro argument defines a variable of type + `py::module` which can be used to initialize the module. + + .. code-block:: cpp + + PYBIND11_MODULE(example, m) { + m.doc() = "pybind11 example module"; + + // Add bindings here + m.def("foo", []() { + return "Hello, World!"; + }); + } +\endrst */ +#define PYBIND11_MODULE(name, variable) \ + static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ + PYBIND11_PLUGIN_IMPL(name) { \ + PYBIND11_CHECK_PYTHON_VERSION \ + auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ + try { \ + PYBIND11_CONCAT(pybind11_init_, name)(m); \ + return m.ptr(); \ + } PYBIND11_CATCH_INIT_EXCEPTIONS \ + } \ + void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) + + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +using ssize_t = Py_ssize_t; +using size_t = std::size_t; + +/// Approach used to cast a previously unknown C++ instance into a Python object +enum class return_value_policy : uint8_t { + /** This is the default return value policy, which falls back to the policy + return_value_policy::take_ownership when the return value is a pointer. + Otherwise, it uses return_value::move or return_value::copy for rvalue + and lvalue references, respectively. See below for a description of what + all of these different policies do. */ + automatic = 0, + + /** As above, but use policy return_value_policy::reference when the return + value is a pointer. This is the default conversion policy for function + arguments when calling Python functions manually from C++ code (i.e. via + handle::operator()). You probably won't need to use this. */ + automatic_reference, + + /** Reference an existing object (i.e. do not create a new copy) and take + ownership. Python will call the destructor and delete operator when the + object’s reference count reaches zero. Undefined behavior ensues when + the C++ side does the same.. */ + take_ownership, + + /** Create a new copy of the returned object, which will be owned by + Python. This policy is comparably safe because the lifetimes of the two + instances are decoupled. */ + copy, + + /** Use std::move to move the return value contents into a new instance + that will be owned by Python. This policy is comparably safe because the + lifetimes of the two instances (move source and destination) are + decoupled. */ + move, + + /** Reference an existing object, but do not take ownership. The C++ side + is responsible for managing the object’s lifetime and deallocating it + when it is no longer used. Warning: undefined behavior will ensue when + the C++ side deletes an object that is still referenced and used by + Python. */ + reference, + + /** This policy only applies to methods and properties. It references the + object without taking ownership similar to the above + return_value_policy::reference policy. In contrast to that policy, the + function or property’s implicit this argument (called the parent) is + considered to be the the owner of the return value (the child). + pybind11 then couples the lifetime of the parent to the child via a + reference relationship that ensures that the parent cannot be garbage + collected while Python is still using the child. More advanced + variations of this scheme are also possible using combinations of + return_value_policy::reference and the keep_alive call policy */ + reference_internal +}; + +NAMESPACE_BEGIN(detail) + +inline static constexpr int log2(size_t n, int k = 0) { return (n <= 1) ? k : log2(n >> 1, k + 1); } + +// Returns the size as a multiple of sizeof(void *), rounded up. +inline static constexpr size_t size_in_ptrs(size_t s) { return 1 + ((s - 1) >> log2(sizeof(void *))); } + +/** + * The space to allocate for simple layout instance holders (see below) in multiple of the size of + * a pointer (e.g. 2 means 16 bytes on 64-bit architectures). The default is the minimum required + * to holder either a std::unique_ptr or std::shared_ptr (which is almost always + * sizeof(std::shared_ptr)). + */ +constexpr size_t instance_simple_holder_in_ptrs() { + static_assert(sizeof(std::shared_ptr) >= sizeof(std::unique_ptr), + "pybind assumes std::shared_ptrs are at least as big as std::unique_ptrs"); + return size_in_ptrs(sizeof(std::shared_ptr)); +} + +// Forward declarations +struct type_info; +struct value_and_holder; + +struct nonsimple_values_and_holders { + void **values_and_holders; + uint8_t *status; +}; + +/// The 'instance' type which needs to be standard layout (need to be able to use 'offsetof') +struct instance { + PyObject_HEAD + /// Storage for pointers and holder; see simple_layout, below, for a description + union { + void *simple_value_holder[1 + instance_simple_holder_in_ptrs()]; + nonsimple_values_and_holders nonsimple; + }; + /// Weak references + PyObject *weakrefs; + /// If true, the pointer is owned which means we're free to manage it with a holder. + bool owned : 1; + /** + * An instance has two possible value/holder layouts. + * + * Simple layout (when this flag is true), means the `simple_value_holder` is set with a pointer + * and the holder object governing that pointer, i.e. [val1*][holder]. This layout is applied + * whenever there is no python-side multiple inheritance of bound C++ types *and* the type's + * holder will fit in the default space (which is large enough to hold either a std::unique_ptr + * or std::shared_ptr). + * + * Non-simple layout applies when using custom holders that require more space than `shared_ptr` + * (which is typically the size of two pointers), or when multiple inheritance is used on the + * python side. Non-simple layout allocates the required amount of memory to have multiple + * bound C++ classes as parents. Under this layout, `nonsimple.values_and_holders` is set to a + * pointer to allocated space of the required space to hold a sequence of value pointers and + * holders followed `status`, a set of bit flags (1 byte each), i.e. + * [val1*][holder1][val2*][holder2]...[bb...] where each [block] is rounded up to a multiple of + * `sizeof(void *)`. `nonsimple.status` is, for convenience, a pointer to the + * beginning of the [bb...] block (but not independently allocated). + * + * Status bits indicate whether the associated holder is constructed (& + * status_holder_constructed) and whether the value pointer is registered (& + * status_instance_registered) in `registered_instances`. + */ + bool simple_layout : 1; + /// For simple layout, tracks whether the holder has been constructed + bool simple_holder_constructed : 1; + /// For simple layout, tracks whether the instance is registered in `registered_instances` + bool simple_instance_registered : 1; + /// If true, get_internals().patients has an entry for this object + bool has_patients : 1; + + /// Initializes all of the above type/values/holders data (but not the instance values themselves) + void allocate_layout(); + + /// Destroys/deallocates all of the above + void deallocate_layout(); + + /// Returns the value_and_holder wrapper for the given type (or the first, if `find_type` + /// omitted). Returns a default-constructed (with `.inst = nullptr`) object on failure if + /// `throw_if_missing` is false. + value_and_holder get_value_and_holder(const type_info *find_type = nullptr, bool throw_if_missing = true); + + /// Bit values for the non-simple status flags + static constexpr uint8_t status_holder_constructed = 1; + static constexpr uint8_t status_instance_registered = 2; +}; + +static_assert(std::is_standard_layout::value, "Internal error: `pybind11::detail::instance` is not standard layout!"); + +/// from __cpp_future__ import (convenient aliases from C++14/17) +#if defined(PYBIND11_CPP14) && (!defined(_MSC_VER) || _MSC_VER >= 1910) +using std::enable_if_t; +using std::conditional_t; +using std::remove_cv_t; +using std::remove_reference_t; +#else +template using enable_if_t = typename std::enable_if::type; +template using conditional_t = typename std::conditional::type; +template using remove_cv_t = typename std::remove_cv::type; +template using remove_reference_t = typename std::remove_reference::type; +#endif + +/// Index sequences +#if defined(PYBIND11_CPP14) +using std::index_sequence; +using std::make_index_sequence; +#else +template struct index_sequence { }; +template struct make_index_sequence_impl : make_index_sequence_impl { }; +template struct make_index_sequence_impl <0, S...> { typedef index_sequence type; }; +template using make_index_sequence = typename make_index_sequence_impl::type; +#endif + +/// Make an index sequence of the indices of true arguments +template struct select_indices_impl { using type = ISeq; }; +template struct select_indices_impl, I, B, Bs...> + : select_indices_impl, index_sequence>, I + 1, Bs...> {}; +template using select_indices = typename select_indices_impl, 0, Bs...>::type; + +/// Backports of std::bool_constant and std::negation to accommodate older compilers +template using bool_constant = std::integral_constant; +template struct negation : bool_constant { }; + +template struct void_t_impl { using type = void; }; +template using void_t = typename void_t_impl::type; + +/// Compile-time all/any/none of that check the boolean value of all template types +#if defined(__cpp_fold_expressions) && !(defined(_MSC_VER) && (_MSC_VER < 1916)) +template using all_of = bool_constant<(Ts::value && ...)>; +template using any_of = bool_constant<(Ts::value || ...)>; +#elif !defined(_MSC_VER) +template struct bools {}; +template using all_of = std::is_same< + bools, + bools>; +template using any_of = negation...>>; +#else +// MSVC has trouble with the above, but supports std::conjunction, which we can use instead (albeit +// at a slight loss of compilation efficiency). +template using all_of = std::conjunction; +template using any_of = std::disjunction; +#endif +template using none_of = negation>; + +template class... Predicates> using satisfies_all_of = all_of...>; +template class... Predicates> using satisfies_any_of = any_of...>; +template class... Predicates> using satisfies_none_of = none_of...>; + +/// Strip the class from a method type +template struct remove_class { }; +template struct remove_class { typedef R type(A...); }; +template struct remove_class { typedef R type(A...); }; + +/// Helper template to strip away type modifiers +template struct intrinsic_type { typedef T type; }; +template struct intrinsic_type { typedef typename intrinsic_type::type type; }; +template struct intrinsic_type { typedef typename intrinsic_type::type type; }; +template struct intrinsic_type { typedef typename intrinsic_type::type type; }; +template struct intrinsic_type { typedef typename intrinsic_type::type type; }; +template struct intrinsic_type { typedef typename intrinsic_type::type type; }; +template struct intrinsic_type { typedef typename intrinsic_type::type type; }; +template using intrinsic_t = typename intrinsic_type::type; + +/// Helper type to replace 'void' in some expressions +struct void_type { }; + +/// Helper template which holds a list of types +template struct type_list { }; + +/// Compile-time integer sum +#ifdef __cpp_fold_expressions +template constexpr size_t constexpr_sum(Ts... ns) { return (0 + ... + size_t{ns}); } +#else +constexpr size_t constexpr_sum() { return 0; } +template +constexpr size_t constexpr_sum(T n, Ts... ns) { return size_t{n} + constexpr_sum(ns...); } +#endif + +NAMESPACE_BEGIN(constexpr_impl) +/// Implementation details for constexpr functions +constexpr int first(int i) { return i; } +template +constexpr int first(int i, T v, Ts... vs) { return v ? i : first(i + 1, vs...); } + +constexpr int last(int /*i*/, int result) { return result; } +template +constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); } +NAMESPACE_END(constexpr_impl) + +/// Return the index of the first type in Ts which satisfies Predicate. Returns sizeof...(Ts) if +/// none match. +template class Predicate, typename... Ts> +constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate::value...); } + +/// Return the index of the last type in Ts which satisfies Predicate, or -1 if none match. +template class Predicate, typename... Ts> +constexpr int constexpr_last() { return constexpr_impl::last(0, -1, Predicate::value...); } + +/// Return the Nth element from the parameter pack +template +struct pack_element { using type = typename pack_element::type; }; +template +struct pack_element<0, T, Ts...> { using type = T; }; + +/// Return the one and only type which matches the predicate, or Default if none match. +/// If more than one type matches the predicate, fail at compile-time. +template class Predicate, typename Default, typename... Ts> +struct exactly_one { + static constexpr auto found = constexpr_sum(Predicate::value...); + static_assert(found <= 1, "Found more than one type matching the predicate"); + + static constexpr auto index = found ? constexpr_first() : 0; + using type = conditional_t::type, Default>; +}; +template class P, typename Default> +struct exactly_one { using type = Default; }; + +template class Predicate, typename Default, typename... Ts> +using exactly_one_t = typename exactly_one::type; + +/// Defer the evaluation of type T until types Us are instantiated +template struct deferred_type { using type = T; }; +template using deferred_t = typename deferred_type::type; + +/// Like is_base_of, but requires a strict base (i.e. `is_strict_base_of::value == false`, +/// unlike `std::is_base_of`) +template using is_strict_base_of = bool_constant< + std::is_base_of::value && !std::is_same::value>; + +/// Like is_base_of, but also requires that the base type is accessible (i.e. that a Derived pointer +/// can be converted to a Base pointer) +template using is_accessible_base_of = bool_constant< + std::is_base_of::value && std::is_convertible::value>; + +template class Base> +struct is_template_base_of_impl { + template static std::true_type check(Base *); + static std::false_type check(...); +}; + +/// Check if a template is the base of a type. For example: +/// `is_template_base_of` is true if `struct T : Base {}` where U can be anything +template class Base, typename T> +#if !defined(_MSC_VER) +using is_template_base_of = decltype(is_template_base_of_impl::check((intrinsic_t*)nullptr)); +#else // MSVC2015 has trouble with decltype in template aliases +struct is_template_base_of : decltype(is_template_base_of_impl::check((intrinsic_t*)nullptr)) { }; +#endif + +/// Check if T is an instantiation of the template `Class`. For example: +/// `is_instantiation` is true if `T == shared_ptr` where U can be anything. +template class Class, typename T> +struct is_instantiation : std::false_type { }; +template class Class, typename... Us> +struct is_instantiation> : std::true_type { }; + +/// Check if T is std::shared_ptr where U can be anything +template using is_shared_ptr = is_instantiation; + +/// Check if T looks like an input iterator +template struct is_input_iterator : std::false_type {}; +template +struct is_input_iterator()), decltype(++std::declval())>> + : std::true_type {}; + +template using is_function_pointer = bool_constant< + std::is_pointer::value && std::is_function::type>::value>; + +template struct strip_function_object { + using type = typename remove_class::type; +}; + +// Extracts the function signature from a function, function pointer or lambda. +template > +using function_signature_t = conditional_t< + std::is_function::value, + F, + typename conditional_t< + std::is_pointer::value || std::is_member_pointer::value, + std::remove_pointer, + strip_function_object + >::type +>; + +/// Returns true if the type looks like a lambda: that is, isn't a function, pointer or member +/// pointer. Note that this can catch all sorts of other things, too; this is intended to be used +/// in a place where passing a lambda makes sense. +template using is_lambda = satisfies_none_of, + std::is_function, std::is_pointer, std::is_member_pointer>; + +/// Ignore that a variable is unused in compiler warnings +inline void ignore_unused(const int *) { } + +/// Apply a function over each element of a parameter pack +#ifdef __cpp_fold_expressions +#define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN) (((PATTERN), void()), ...) +#else +using expand_side_effects = bool[]; +#define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN) pybind11::detail::expand_side_effects{ ((PATTERN), void(), false)..., false } +#endif + +NAMESPACE_END(detail) + +/// C++ bindings of builtin Python exceptions +class builtin_exception : public std::runtime_error { +public: + using std::runtime_error::runtime_error; + /// Set the error using the Python C API + virtual void set_error() const = 0; +}; + +#define PYBIND11_RUNTIME_EXCEPTION(name, type) \ + class name : public builtin_exception { public: \ + using builtin_exception::builtin_exception; \ + name() : name("") { } \ + void set_error() const override { PyErr_SetString(type, what()); } \ + }; + +PYBIND11_RUNTIME_EXCEPTION(stop_iteration, PyExc_StopIteration) +PYBIND11_RUNTIME_EXCEPTION(index_error, PyExc_IndexError) +PYBIND11_RUNTIME_EXCEPTION(key_error, PyExc_KeyError) +PYBIND11_RUNTIME_EXCEPTION(value_error, PyExc_ValueError) +PYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError) +PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or handle::call fail due to a type casting error +PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally + +[[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } +[[noreturn]] PYBIND11_NOINLINE inline void pybind11_fail(const std::string &reason) { throw std::runtime_error(reason); } + +template struct format_descriptor { }; + +NAMESPACE_BEGIN(detail) +// Returns the index of the given type in the type char array below, and in the list in numpy.h +// The order here is: bool; 8 ints ((signed,unsigned)x(8,16,32,64)bits); float,double,long double; +// complex float,double,long double. Note that the long double types only participate when long +// double is actually longer than double (it isn't under MSVC). +// NB: not only the string below but also complex.h and numpy.h rely on this order. +template struct is_fmt_numeric { static constexpr bool value = false; }; +template struct is_fmt_numeric::value>> { + static constexpr bool value = true; + static constexpr int index = std::is_same::value ? 0 : 1 + ( + std::is_integral::value ? detail::log2(sizeof(T))*2 + std::is_unsigned::value : 8 + ( + std::is_same::value ? 1 : std::is_same::value ? 2 : 0)); +}; +NAMESPACE_END(detail) + +template struct format_descriptor::value>> { + static constexpr const char c = "?bBhHiIqQfdg"[detail::is_fmt_numeric::index]; + static constexpr const char value[2] = { c, '\0' }; + static std::string format() { return std::string(1, c); } +}; + +#if !defined(PYBIND11_CPP17) + +template constexpr const char format_descriptor< + T, detail::enable_if_t::value>>::value[2]; + +#endif + +/// RAII wrapper that temporarily clears any Python error state +struct error_scope { + PyObject *type, *value, *trace; + error_scope() { PyErr_Fetch(&type, &value, &trace); } + ~error_scope() { PyErr_Restore(type, value, trace); } +}; + +/// Dummy destructor wrapper that can be used to expose classes with a private destructor +struct nodelete { template void operator()(T*) { } }; + +// overload_cast requires variable templates: C++14 +#if defined(PYBIND11_CPP14) +#define PYBIND11_OVERLOAD_CAST 1 + +NAMESPACE_BEGIN(detail) +template +struct overload_cast_impl { + constexpr overload_cast_impl() {} // MSVC 2015 needs this + + template + constexpr auto operator()(Return (*pf)(Args...)) const noexcept + -> decltype(pf) { return pf; } + + template + constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept + -> decltype(pmf) { return pmf; } + + template + constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept + -> decltype(pmf) { return pmf; } +}; +NAMESPACE_END(detail) + +/// Syntax sugar for resolving overloaded function pointers: +/// - regular: static_cast(&Class::func) +/// - sweet: overload_cast(&Class::func) +template +static constexpr detail::overload_cast_impl overload_cast = {}; +// MSVC 2015 only accepts this particular initialization syntax for this variable template. + +/// Const member function selector for overload_cast +/// - regular: static_cast(&Class::func) +/// - sweet: overload_cast(&Class::func, const_) +static constexpr auto const_ = std::true_type{}; + +#else // no overload_cast: providing something that static_assert-fails: +template struct overload_cast { + static_assert(detail::deferred_t::value, + "pybind11::overload_cast<...> requires compiling in C++14 mode"); +}; +#endif // overload_cast + +NAMESPACE_BEGIN(detail) + +// Adaptor for converting arbitrary container arguments into a vector; implicitly convertible from +// any standard container (or C-style array) supporting std::begin/std::end, any singleton +// arithmetic type (if T is arithmetic), or explicitly constructible from an iterator pair. +template +class any_container { + std::vector v; +public: + any_container() = default; + + // Can construct from a pair of iterators + template ::value>> + any_container(It first, It last) : v(first, last) { } + + // Implicit conversion constructor from any arbitrary container type with values convertible to T + template ())), T>::value>> + any_container(const Container &c) : any_container(std::begin(c), std::end(c)) { } + + // initializer_list's aren't deducible, so don't get matched by the above template; we need this + // to explicitly allow implicit conversion from one: + template ::value>> + any_container(const std::initializer_list &c) : any_container(c.begin(), c.end()) { } + + // Avoid copying if given an rvalue vector of the correct type. + any_container(std::vector &&v) : v(std::move(v)) { } + + // Moves the vector out of an rvalue any_container + operator std::vector &&() && { return std::move(v); } + + // Dereferencing obtains a reference to the underlying vector + std::vector &operator*() { return v; } + const std::vector &operator*() const { return v; } + + // -> lets you call methods on the underlying vector + std::vector *operator->() { return &v; } + const std::vector *operator->() const { return &v; } +}; + +NAMESPACE_END(detail) + + + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/detail/descr.h b/python/src/pybind11/detail/descr.h new file mode 100644 index 000000000..8d404e534 --- /dev/null +++ b/python/src/pybind11/detail/descr.h @@ -0,0 +1,100 @@ +/* + pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "common.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +#if !defined(_MSC_VER) +# define PYBIND11_DESCR_CONSTEXPR static constexpr +#else +# define PYBIND11_DESCR_CONSTEXPR const +#endif + +/* Concatenate type signatures at compile time */ +template +struct descr { + char text[N + 1]; + + constexpr descr() : text{'\0'} { } + constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence()) { } + + template + constexpr descr(char const (&s)[N+1], index_sequence) : text{s[Is]..., '\0'} { } + + template + constexpr descr(char c, Chars... cs) : text{c, static_cast(cs)..., '\0'} { } + + static constexpr std::array types() { + return {{&typeid(Ts)..., nullptr}}; + } +}; + +template +constexpr descr plus_impl(const descr &a, const descr &b, + index_sequence, index_sequence) { + return {a.text[Is1]..., b.text[Is2]...}; +} + +template +constexpr descr operator+(const descr &a, const descr &b) { + return plus_impl(a, b, make_index_sequence(), make_index_sequence()); +} + +template +constexpr descr _(char const(&text)[N]) { return descr(text); } +constexpr descr<0> _(char const(&)[1]) { return {}; } + +template struct int_to_str : int_to_str { }; +template struct int_to_str<0, Digits...> { + static constexpr auto digits = descr(('0' + Digits)...); +}; + +// Ternary description (like std::conditional) +template +constexpr enable_if_t> _(char const(&text1)[N1], char const(&)[N2]) { + return _(text1); +} +template +constexpr enable_if_t> _(char const(&)[N1], char const(&text2)[N2]) { + return _(text2); +} + +template +constexpr enable_if_t _(const T1 &d, const T2 &) { return d; } +template +constexpr enable_if_t _(const T1 &, const T2 &d) { return d; } + +template auto constexpr _() -> decltype(int_to_str::digits) { + return int_to_str::digits; +} + +template constexpr descr<1, Type> _() { return {'%'}; } + +constexpr descr<0> concat() { return {}; } + +template +constexpr descr concat(const descr &descr) { return descr; } + +template +constexpr auto concat(const descr &d, const Args &...args) + -> decltype(std::declval>() + concat(args...)) { + return d + _(", ") + concat(args...); +} + +template +constexpr descr type_descr(const descr &descr) { + return _("{") + descr + _("}"); +} + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/detail/init.h b/python/src/pybind11/detail/init.h new file mode 100644 index 000000000..acfe00bdb --- /dev/null +++ b/python/src/pybind11/detail/init.h @@ -0,0 +1,335 @@ +/* + pybind11/detail/init.h: init factory function implementation and support code. + + Copyright (c) 2017 Jason Rhinelander + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "class.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +template <> +class type_caster { +public: + bool load(handle h, bool) { + value = reinterpret_cast(h.ptr()); + return true; + } + + template using cast_op_type = value_and_holder &; + operator value_and_holder &() { return *value; } + static constexpr auto name = _(); + +private: + value_and_holder *value = nullptr; +}; + +NAMESPACE_BEGIN(initimpl) + +inline void no_nullptr(void *ptr) { + if (!ptr) throw type_error("pybind11::init(): factory function returned nullptr"); +} + +// Implementing functions for all forms of py::init<...> and py::init(...) +template using Cpp = typename Class::type; +template using Alias = typename Class::type_alias; +template using Holder = typename Class::holder_type; + +template using is_alias_constructible = std::is_constructible, Cpp &&>; + +// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance. +template = 0> +bool is_alias(Cpp *ptr) { + return dynamic_cast *>(ptr) != nullptr; +} +// Failing fallback version of the above for a no-alias class (always returns false) +template +constexpr bool is_alias(void *) { return false; } + +// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall +// back to brace aggregate initiailization so that for aggregate initialization can be used with +// py::init, e.g. `py::init` to initialize a `struct T { int a; int b; }`. For +// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually +// works, but will not do the expected thing when `T` has an `initializer_list` constructor). +template ::value, int> = 0> +inline Class *construct_or_initialize(Args &&...args) { return new Class(std::forward(args)...); } +template ::value, int> = 0> +inline Class *construct_or_initialize(Args &&...args) { return new Class{std::forward(args)...}; } + +// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor. This allows types with +// an alias to provide only a single Cpp factory function as long as the Alias can be +// constructed from an rvalue reference of the base Cpp type. This means that Alias classes +// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to +// inherit all the base class constructors. +template +void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/, + value_and_holder &v_h, Cpp &&base) { + v_h.value_ptr() = new Alias(std::move(base)); +} +template +[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/, + value_and_holder &, Cpp &&) { + throw type_error("pybind11::init(): unable to convert returned instance to required " + "alias class: no `Alias(Class &&)` constructor available"); +} + +// Error-generating fallback for factories that don't match one of the below construction +// mechanisms. +template +void construct(...) { + static_assert(!std::is_same::value /* always false */, + "pybind11::init(): init function must return a compatible pointer, " + "holder, or value"); +} + +// Pointer return v1: the factory function returns a class pointer for a registered class. +// If we don't need an alias (because this class doesn't have one, or because the final type is +// inherited on the Python side) we can simply take over ownership. Otherwise we need to try to +// construct an Alias from the returned base instance. +template +void construct(value_and_holder &v_h, Cpp *ptr, bool need_alias) { + no_nullptr(ptr); + if (Class::has_alias && need_alias && !is_alias(ptr)) { + // We're going to try to construct an alias by moving the cpp type. Whether or not + // that succeeds, we still need to destroy the original cpp pointer (either the + // moved away leftover, if the alias construction works, or the value itself if we + // throw an error), but we can't just call `delete ptr`: it might have a special + // deleter, or might be shared_from_this. So we construct a holder around it as if + // it was a normal instance, then steal the holder away into a local variable; thus + // the holder and destruction happens when we leave the C++ scope, and the holder + // class gets to handle the destruction however it likes. + v_h.value_ptr() = ptr; + v_h.set_instance_registered(true); // To prevent init_instance from registering it + v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder + Holder temp_holder(std::move(v_h.holder>())); // Steal the holder + v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null + v_h.set_instance_registered(false); + + construct_alias_from_cpp(is_alias_constructible{}, v_h, std::move(*ptr)); + } else { + // Otherwise the type isn't inherited, so we don't need an Alias + v_h.value_ptr() = ptr; + } +} + +// Pointer return v2: a factory that always returns an alias instance ptr. We simply take over +// ownership of the pointer. +template = 0> +void construct(value_and_holder &v_h, Alias *alias_ptr, bool) { + no_nullptr(alias_ptr); + v_h.value_ptr() = static_cast *>(alias_ptr); +} + +// Holder return: copy its pointer, and move or copy the returned holder into the new instance's +// holder. This also handles types like std::shared_ptr and std::unique_ptr where T is a +// derived type (through those holder's implicit conversion from derived class holder constructors). +template +void construct(value_and_holder &v_h, Holder holder, bool need_alias) { + auto *ptr = holder_helper>::get(holder); + // If we need an alias, check that the held pointer is actually an alias instance + if (Class::has_alias && need_alias && !is_alias(ptr)) + throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance " + "is not an alias instance"); + + v_h.value_ptr() = ptr; + v_h.type->init_instance(v_h.inst, &holder); +} + +// return-by-value version 1: returning a cpp class by value. If the class has an alias and an +// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct +// the alias from the base when needed (i.e. because of Python-side inheritance). When we don't +// need it, we simply move-construct the cpp value into a new instance. +template +void construct(value_and_holder &v_h, Cpp &&result, bool need_alias) { + static_assert(std::is_move_constructible>::value, + "pybind11::init() return-by-value factory function requires a movable class"); + if (Class::has_alias && need_alias) + construct_alias_from_cpp(is_alias_constructible{}, v_h, std::move(result)); + else + v_h.value_ptr() = new Cpp(std::move(result)); +} + +// return-by-value version 2: returning a value of the alias type itself. We move-construct an +// Alias instance (even if no the python-side inheritance is involved). The is intended for +// cases where Alias initialization is always desired. +template +void construct(value_and_holder &v_h, Alias &&result, bool) { + static_assert(std::is_move_constructible>::value, + "pybind11::init() return-by-alias-value factory function requires a movable alias class"); + v_h.value_ptr() = new Alias(std::move(result)); +} + +// Implementing class for py::init<...>() +template +struct constructor { + template = 0> + static void execute(Class &cl, const Extra&... extra) { + cl.def("__init__", [](value_and_holder &v_h, Args... args) { + v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); + }, is_new_style_constructor(), extra...); + } + + template , Args...>::value, int> = 0> + static void execute(Class &cl, const Extra&... extra) { + cl.def("__init__", [](value_and_holder &v_h, Args... args) { + if (Py_TYPE(v_h.inst) == v_h.type->type) + v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); + else + v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); + }, is_new_style_constructor(), extra...); + } + + template , Args...>::value, int> = 0> + static void execute(Class &cl, const Extra&... extra) { + cl.def("__init__", [](value_and_holder &v_h, Args... args) { + v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); + }, is_new_style_constructor(), extra...); + } +}; + +// Implementing class for py::init_alias<...>() +template struct alias_constructor { + template , Args...>::value, int> = 0> + static void execute(Class &cl, const Extra&... extra) { + cl.def("__init__", [](value_and_holder &v_h, Args... args) { + v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); + }, is_new_style_constructor(), extra...); + } +}; + +// Implementation class for py::init(Func) and py::init(Func, AliasFunc) +template , typename = function_signature_t> +struct factory; + +// Specialization for py::init(Func) +template +struct factory { + remove_reference_t class_factory; + + factory(Func &&f) : class_factory(std::forward(f)) { } + + // The given class either has no alias or has no separate alias factory; + // this always constructs the class itself. If the class is registered with an alias + // type and an alias instance is needed (i.e. because the final type is a Python class + // inheriting from the C++ type) the returned value needs to either already be an alias + // instance, or the alias needs to be constructible from a `Class &&` argument. + template + void execute(Class &cl, const Extra &...extra) && { + #if defined(PYBIND11_CPP14) + cl.def("__init__", [func = std::move(class_factory)] + #else + auto &func = class_factory; + cl.def("__init__", [func] + #endif + (value_and_holder &v_h, Args... args) { + construct(v_h, func(std::forward(args)...), + Py_TYPE(v_h.inst) != v_h.type->type); + }, is_new_style_constructor(), extra...); + } +}; + +// Specialization for py::init(Func, AliasFunc) +template +struct factory { + static_assert(sizeof...(CArgs) == sizeof...(AArgs), + "pybind11::init(class_factory, alias_factory): class and alias factories " + "must have identical argument signatures"); + static_assert(all_of...>::value, + "pybind11::init(class_factory, alias_factory): class and alias factories " + "must have identical argument signatures"); + + remove_reference_t class_factory; + remove_reference_t alias_factory; + + factory(CFunc &&c, AFunc &&a) + : class_factory(std::forward(c)), alias_factory(std::forward(a)) { } + + // The class factory is called when the `self` type passed to `__init__` is the direct + // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype. + template + void execute(Class &cl, const Extra&... extra) && { + static_assert(Class::has_alias, "The two-argument version of `py::init()` can " + "only be used if the class has an alias"); + #if defined(PYBIND11_CPP14) + cl.def("__init__", [class_func = std::move(class_factory), alias_func = std::move(alias_factory)] + #else + auto &class_func = class_factory; + auto &alias_func = alias_factory; + cl.def("__init__", [class_func, alias_func] + #endif + (value_and_holder &v_h, CArgs... args) { + if (Py_TYPE(v_h.inst) == v_h.type->type) + // If the instance type equals the registered type we don't have inheritance, so + // don't need the alias and can construct using the class function: + construct(v_h, class_func(std::forward(args)...), false); + else + construct(v_h, alias_func(std::forward(args)...), true); + }, is_new_style_constructor(), extra...); + } +}; + +/// Set just the C++ state. Same as `__init__`. +template +void setstate(value_and_holder &v_h, T &&result, bool need_alias) { + construct(v_h, std::forward(result), need_alias); +} + +/// Set both the C++ and Python states +template ::value, int> = 0> +void setstate(value_and_holder &v_h, std::pair &&result, bool need_alias) { + construct(v_h, std::move(result.first), need_alias); + setattr((PyObject *) v_h.inst, "__dict__", result.second); +} + +/// Implementation for py::pickle(GetState, SetState) +template , typename = function_signature_t> +struct pickle_factory; + +template +struct pickle_factory { + static_assert(std::is_same, intrinsic_t>::value, + "The type returned by `__getstate__` must be the same " + "as the argument accepted by `__setstate__`"); + + remove_reference_t get; + remove_reference_t set; + + pickle_factory(Get get, Set set) + : get(std::forward(get)), set(std::forward(set)) { } + + template + void execute(Class &cl, const Extra &...extra) && { + cl.def("__getstate__", std::move(get)); + +#if defined(PYBIND11_CPP14) + cl.def("__setstate__", [func = std::move(set)] +#else + auto &func = set; + cl.def("__setstate__", [func] +#endif + (value_and_holder &v_h, ArgState state) { + setstate(v_h, func(std::forward(state)), + Py_TYPE(v_h.inst) != v_h.type->type); + }, is_new_style_constructor(), extra...); + } +}; + +NAMESPACE_END(initimpl) +NAMESPACE_END(detail) +NAMESPACE_END(pybind11) diff --git a/python/src/pybind11/detail/internals.h b/python/src/pybind11/detail/internals.h new file mode 100644 index 000000000..f1dd38764 --- /dev/null +++ b/python/src/pybind11/detail/internals.h @@ -0,0 +1,291 @@ +/* + pybind11/detail/internals.h: Internal data structure and related functions + + Copyright (c) 2017 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "../pytypes.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) +// Forward declarations +inline PyTypeObject *make_static_property_type(); +inline PyTypeObject *make_default_metaclass(); +inline PyObject *make_object_base_type(PyTypeObject *metaclass); + +// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new +// Thread Specific Storage (TSS) API. +#if PY_VERSION_HEX >= 0x03070000 +# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr +# define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key)) +# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value)) +# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr) +#else + // Usually an int but a long on Cygwin64 with Python 3.x +# define PYBIND11_TLS_KEY_INIT(var) decltype(PyThread_create_key()) var = 0 +# define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key)) +# if PY_MAJOR_VERSION < 3 +# define PYBIND11_TLS_DELETE_VALUE(key) \ + PyThread_delete_key_value(key) +# define PYBIND11_TLS_REPLACE_VALUE(key, value) \ + do { \ + PyThread_delete_key_value((key)); \ + PyThread_set_key_value((key), (value)); \ + } while (false) +# else +# define PYBIND11_TLS_DELETE_VALUE(key) \ + PyThread_set_key_value((key), nullptr) +# define PYBIND11_TLS_REPLACE_VALUE(key, value) \ + PyThread_set_key_value((key), (value)) +# endif +#endif + +// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly +// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module +// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under +// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name, +// which works. If not under a known-good stl, provide our own name-based hash and equality +// functions that use the type name. +#if defined(__GLIBCXX__) +inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; } +using type_hash = std::hash; +using type_equal_to = std::equal_to; +#else +inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { + return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; +} + +struct type_hash { + size_t operator()(const std::type_index &t) const { + size_t hash = 5381; + const char *ptr = t.name(); + while (auto c = static_cast(*ptr++)) + hash = (hash * 33) ^ c; + return hash; + } +}; + +struct type_equal_to { + bool operator()(const std::type_index &lhs, const std::type_index &rhs) const { + return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0; + } +}; +#endif + +template +using type_map = std::unordered_map; + +struct overload_hash { + inline size_t operator()(const std::pair& v) const { + size_t value = std::hash()(v.first); + value ^= std::hash()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2); + return value; + } +}; + +/// Internal data structure used to track registered instances and types. +/// Whenever binary incompatible changes are made to this structure, +/// `PYBIND11_INTERNALS_VERSION` must be incremented. +struct internals { + type_map registered_types_cpp; // std::type_index -> pybind11's type information + std::unordered_map> registered_types_py; // PyTypeObject* -> base type_info(s) + std::unordered_multimap registered_instances; // void * -> instance* + std::unordered_set, overload_hash> inactive_overload_cache; + type_map> direct_conversions; + std::unordered_map> patients; + std::forward_list registered_exception_translators; + std::unordered_map shared_data; // Custom data to be shared across extensions + std::vector loader_patient_stack; // Used by `loader_life_support` + std::forward_list static_strings; // Stores the std::strings backing detail::c_str() + PyTypeObject *static_property_type; + PyTypeObject *default_metaclass; + PyObject *instance_base; +#if defined(WITH_THREAD) + PYBIND11_TLS_KEY_INIT(tstate); + PyInterpreterState *istate = nullptr; +#endif +}; + +/// Additional type information which does not fit into the PyTypeObject. +/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`. +struct type_info { + PyTypeObject *type; + const std::type_info *cpptype; + size_t type_size, type_align, holder_size_in_ptrs; + void *(*operator_new)(size_t); + void (*init_instance)(instance *, const void *); + void (*dealloc)(value_and_holder &v_h); + std::vector implicit_conversions; + std::vector> implicit_casts; + std::vector *direct_conversions; + buffer_info *(*get_buffer)(PyObject *, void *) = nullptr; + void *get_buffer_data = nullptr; + void *(*module_local_load)(PyObject *, const type_info *) = nullptr; + /* A simple type never occurs as a (direct or indirect) parent + * of a class that makes use of multiple inheritance */ + bool simple_type : 1; + /* True if there is no multiple inheritance in this type's inheritance tree */ + bool simple_ancestors : 1; + /* for base vs derived holder_type checks */ + bool default_holder : 1; + /* true if this is a type registered with py::module_local */ + bool module_local : 1; +}; + +/// Tracks the `internals` and `type_info` ABI version independent of the main library version +#define PYBIND11_INTERNALS_VERSION 3 + +#if defined(_DEBUG) +# define PYBIND11_BUILD_TYPE "_debug" +#else +# define PYBIND11_BUILD_TYPE "" +#endif + +#if defined(WITH_THREAD) +# define PYBIND11_INTERNALS_KIND "" +#else +# define PYBIND11_INTERNALS_KIND "_without_thread" +#endif + +#define PYBIND11_INTERNALS_ID "__pybind11_internals_v" \ + PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND PYBIND11_BUILD_TYPE "__" + +#define PYBIND11_MODULE_LOCAL_ID "__pybind11_module_local_v" \ + PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) PYBIND11_INTERNALS_KIND PYBIND11_BUILD_TYPE "__" + +/// Each module locally stores a pointer to the `internals` data. The data +/// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`. +inline internals **&get_internals_pp() { + static internals **internals_pp = nullptr; + return internals_pp; +} + +/// Return a reference to the current `internals` data +PYBIND11_NOINLINE inline internals &get_internals() { + auto **&internals_pp = get_internals_pp(); + if (internals_pp && *internals_pp) + return **internals_pp; + + constexpr auto *id = PYBIND11_INTERNALS_ID; + auto builtins = handle(PyEval_GetBuiltins()); + if (builtins.contains(id) && isinstance(builtins[id])) { + internals_pp = static_cast(capsule(builtins[id])); + + // We loaded builtins through python's builtins, which means that our `error_already_set` + // and `builtin_exception` may be different local classes than the ones set up in the + // initial exception translator, below, so add another for our local exception classes. + // + // libstdc++ doesn't require this (types there are identified only by name) +#if !defined(__GLIBCXX__) + (*internals_pp)->registered_exception_translators.push_front( + [](std::exception_ptr p) -> void { + try { + if (p) std::rethrow_exception(p); + } catch (error_already_set &e) { e.restore(); return; + } catch (const builtin_exception &e) { e.set_error(); return; + } + } + ); +#endif + } else { + if (!internals_pp) internals_pp = new internals*(); + auto *&internals_ptr = *internals_pp; + internals_ptr = new internals(); +#if defined(WITH_THREAD) + PyEval_InitThreads(); + PyThreadState *tstate = PyThreadState_Get(); + #if PY_VERSION_HEX >= 0x03070000 + internals_ptr->tstate = PyThread_tss_alloc(); + if (!internals_ptr->tstate || PyThread_tss_create(internals_ptr->tstate)) + pybind11_fail("get_internals: could not successfully initialize the TSS key!"); + PyThread_tss_set(internals_ptr->tstate, tstate); + #else + internals_ptr->tstate = PyThread_create_key(); + if (internals_ptr->tstate == -1) + pybind11_fail("get_internals: could not successfully initialize the TLS key!"); + PyThread_set_key_value(internals_ptr->tstate, tstate); + #endif + internals_ptr->istate = tstate->interp; +#endif + builtins[id] = capsule(internals_pp); + internals_ptr->registered_exception_translators.push_front( + [](std::exception_ptr p) -> void { + try { + if (p) std::rethrow_exception(p); + } catch (error_already_set &e) { e.restore(); return; + } catch (const builtin_exception &e) { e.set_error(); return; + } catch (const std::bad_alloc &e) { PyErr_SetString(PyExc_MemoryError, e.what()); return; + } catch (const std::domain_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; + } catch (const std::invalid_argument &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; + } catch (const std::length_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; + } catch (const std::out_of_range &e) { PyErr_SetString(PyExc_IndexError, e.what()); return; + } catch (const std::range_error &e) { PyErr_SetString(PyExc_ValueError, e.what()); return; + } catch (const std::exception &e) { PyErr_SetString(PyExc_RuntimeError, e.what()); return; + } catch (...) { + PyErr_SetString(PyExc_RuntimeError, "Caught an unknown exception!"); + return; + } + } + ); + internals_ptr->static_property_type = make_static_property_type(); + internals_ptr->default_metaclass = make_default_metaclass(); + internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass); + } + return **internals_pp; +} + +/// Works like `internals.registered_types_cpp`, but for module-local registered types: +inline type_map ®istered_local_types_cpp() { + static type_map locals{}; + return locals; +} + +/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its +/// `c_str()`. Such strings objects have a long storage duration -- the internal strings are only +/// cleared when the program exits or after interpreter shutdown (when embedding), and so are +/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name). +template +const char *c_str(Args &&...args) { + auto &strings = get_internals().static_strings; + strings.emplace_front(std::forward(args)...); + return strings.front().c_str(); +} + +NAMESPACE_END(detail) + +/// Returns a named pointer that is shared among all extension modules (using the same +/// pybind11 version) running in the current interpreter. Names starting with underscores +/// are reserved for internal usage. Returns `nullptr` if no matching entry was found. +inline PYBIND11_NOINLINE void *get_shared_data(const std::string &name) { + auto &internals = detail::get_internals(); + auto it = internals.shared_data.find(name); + return it != internals.shared_data.end() ? it->second : nullptr; +} + +/// Set the shared data that can be later recovered by `get_shared_data()`. +inline PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) { + detail::get_internals().shared_data[name] = data; + return data; +} + +/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if +/// such entry exists. Otherwise, a new object of default-constructible type `T` is +/// added to the shared data under the given name and a reference to it is returned. +template +T &get_or_create_shared_data(const std::string &name) { + auto &internals = detail::get_internals(); + auto it = internals.shared_data.find(name); + T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr); + if (!ptr) { + ptr = new T(); + internals.shared_data[name] = ptr; + } + return *ptr; +} + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/detail/typeid.h b/python/src/pybind11/detail/typeid.h new file mode 100644 index 000000000..9c8a4fc69 --- /dev/null +++ b/python/src/pybind11/detail/typeid.h @@ -0,0 +1,55 @@ +/* + pybind11/detail/typeid.h: Compiler-independent access to type identifiers + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include +#include + +#if defined(__GNUG__) +#include +#endif + +#include "common.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) +/// Erase all occurrences of a substring +inline void erase_all(std::string &string, const std::string &search) { + for (size_t pos = 0;;) { + pos = string.find(search, pos); + if (pos == std::string::npos) break; + string.erase(pos, search.length()); + } +} + +PYBIND11_NOINLINE inline void clean_type_id(std::string &name) { +#if defined(__GNUG__) + int status = 0; + std::unique_ptr res { + abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free }; + if (status == 0) + name = res.get(); +#else + detail::erase_all(name, "class "); + detail::erase_all(name, "struct "); + detail::erase_all(name, "enum "); +#endif + detail::erase_all(name, "pybind11::"); +} +NAMESPACE_END(detail) + +/// Return a string representation of a C++ type +template static std::string type_id() { + std::string name(typeid(T).name()); + detail::clean_type_id(name); + return name; +} + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/eigen.h b/python/src/pybind11/eigen.h new file mode 100644 index 000000000..d963d9650 --- /dev/null +++ b/python/src/pybind11/eigen.h @@ -0,0 +1,607 @@ +/* + pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "numpy.h" + +#if defined(__INTEL_COMPILER) +# pragma warning(disable: 1682) // implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) +#elif defined(__GNUG__) || defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# ifdef __clang__ +// Eigen generates a bunch of implicit-copy-constructor-is-deprecated warnings with -Wdeprecated +// under Clang, so disable that warning here: +# pragma GCC diagnostic ignored "-Wdeprecated" +# endif +# if __GNUC__ >= 7 +# pragma GCC diagnostic ignored "-Wint-in-bool-context" +# endif +#endif + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant +# pragma warning(disable: 4996) // warning C4996: std::unary_negate is deprecated in C++17 +#endif + +#include +#include + +// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit +// move constructors that break things. We could detect this an explicitly copy, but an extra copy +// of matrices seems highly undesirable. +static_assert(EIGEN_VERSION_AT_LEAST(3,2,7), "Eigen support in pybind11 requires Eigen >= 3.2.7"); + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides: +using EigenDStride = Eigen::Stride; +template using EigenDRef = Eigen::Ref; +template using EigenDMap = Eigen::Map; + +NAMESPACE_BEGIN(detail) + +#if EIGEN_VERSION_AT_LEAST(3,3,0) +using EigenIndex = Eigen::Index; +#else +using EigenIndex = EIGEN_DEFAULT_DENSE_INDEX_TYPE; +#endif + +// Matches Eigen::Map, Eigen::Ref, blocks, etc: +template using is_eigen_dense_map = all_of, std::is_base_of, T>>; +template using is_eigen_mutable_map = std::is_base_of, T>; +template using is_eigen_dense_plain = all_of>, is_template_base_of>; +template using is_eigen_sparse = is_template_base_of; +// Test for objects inheriting from EigenBase that aren't captured by the above. This +// basically covers anything that can be assigned to a dense matrix but that don't have a typical +// matrix data layout that can be copied from their .data(). For example, DiagonalMatrix and +// SelfAdjointView fall into this category. +template using is_eigen_other = all_of< + is_template_base_of, + negation, is_eigen_dense_plain, is_eigen_sparse>> +>; + +// Captures numpy/eigen conformability status (returned by EigenProps::conformable()): +template struct EigenConformable { + bool conformable = false; + EigenIndex rows = 0, cols = 0; + EigenDStride stride{0, 0}; // Only valid if negativestrides is false! + bool negativestrides = false; // If true, do not use stride! + + EigenConformable(bool fits = false) : conformable{fits} {} + // Matrix type: + EigenConformable(EigenIndex r, EigenIndex c, + EigenIndex rstride, EigenIndex cstride) : + conformable{true}, rows{r}, cols{c} { + // TODO: when Eigen bug #747 is fixed, remove the tests for non-negativity. http://eigen.tuxfamily.org/bz/show_bug.cgi?id=747 + if (rstride < 0 || cstride < 0) { + negativestrides = true; + } else { + stride = {EigenRowMajor ? rstride : cstride /* outer stride */, + EigenRowMajor ? cstride : rstride /* inner stride */ }; + } + } + // Vector type: + EigenConformable(EigenIndex r, EigenIndex c, EigenIndex stride) + : EigenConformable(r, c, r == 1 ? c*stride : stride, c == 1 ? r : r*stride) {} + + template bool stride_compatible() const { + // To have compatible strides, we need (on both dimensions) one of fully dynamic strides, + // matching strides, or a dimension size of 1 (in which case the stride value is irrelevant) + return + !negativestrides && + (props::inner_stride == Eigen::Dynamic || props::inner_stride == stride.inner() || + (EigenRowMajor ? cols : rows) == 1) && + (props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer() || + (EigenRowMajor ? rows : cols) == 1); + } + operator bool() const { return conformable; } +}; + +template struct eigen_extract_stride { using type = Type; }; +template +struct eigen_extract_stride> { using type = StrideType; }; +template +struct eigen_extract_stride> { using type = StrideType; }; + +// Helper struct for extracting information from an Eigen type +template struct EigenProps { + using Type = Type_; + using Scalar = typename Type::Scalar; + using StrideType = typename eigen_extract_stride::type; + static constexpr EigenIndex + rows = Type::RowsAtCompileTime, + cols = Type::ColsAtCompileTime, + size = Type::SizeAtCompileTime; + static constexpr bool + row_major = Type::IsRowMajor, + vector = Type::IsVectorAtCompileTime, // At least one dimension has fixed size 1 + fixed_rows = rows != Eigen::Dynamic, + fixed_cols = cols != Eigen::Dynamic, + fixed = size != Eigen::Dynamic, // Fully-fixed size + dynamic = !fixed_rows && !fixed_cols; // Fully-dynamic size + + template using if_zero = std::integral_constant; + static constexpr EigenIndex inner_stride = if_zero::value, + outer_stride = if_zero::value; + static constexpr bool dynamic_stride = inner_stride == Eigen::Dynamic && outer_stride == Eigen::Dynamic; + static constexpr bool requires_row_major = !dynamic_stride && !vector && (row_major ? inner_stride : outer_stride) == 1; + static constexpr bool requires_col_major = !dynamic_stride && !vector && (row_major ? outer_stride : inner_stride) == 1; + + // Takes an input array and determines whether we can make it fit into the Eigen type. If + // the array is a vector, we attempt to fit it into either an Eigen 1xN or Nx1 vector + // (preferring the latter if it will fit in either, i.e. for a fully dynamic matrix type). + static EigenConformable conformable(const array &a) { + const auto dims = a.ndim(); + if (dims < 1 || dims > 2) + return false; + + if (dims == 2) { // Matrix type: require exact match (or dynamic) + + EigenIndex + np_rows = a.shape(0), + np_cols = a.shape(1), + np_rstride = a.strides(0) / static_cast(sizeof(Scalar)), + np_cstride = a.strides(1) / static_cast(sizeof(Scalar)); + if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) + return false; + + return {np_rows, np_cols, np_rstride, np_cstride}; + } + + // Otherwise we're storing an n-vector. Only one of the strides will be used, but whichever + // is used, we want the (single) numpy stride value. + const EigenIndex n = a.shape(0), + stride = a.strides(0) / static_cast(sizeof(Scalar)); + + if (vector) { // Eigen type is a compile-time vector + if (fixed && size != n) + return false; // Vector size mismatch + return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride}; + } + else if (fixed) { + // The type has a fixed size, but is not a vector: abort + return false; + } + else if (fixed_cols) { + // Since this isn't a vector, cols must be != 1. We allow this only if it exactly + // equals the number of elements (rows is Dynamic, and so 1 row is allowed). + if (cols != n) return false; + return {1, n, stride}; + } + else { + // Otherwise it's either fully dynamic, or column dynamic; both become a column vector + if (fixed_rows && rows != n) return false; + return {n, 1, stride}; + } + } + + static constexpr bool show_writeable = is_eigen_dense_map::value && is_eigen_mutable_map::value; + static constexpr bool show_order = is_eigen_dense_map::value; + static constexpr bool show_c_contiguous = show_order && requires_row_major; + static constexpr bool show_f_contiguous = !show_c_contiguous && show_order && requires_col_major; + + static constexpr auto descriptor = + _("numpy.ndarray[") + npy_format_descriptor::name + + _("[") + _(_<(size_t) rows>(), _("m")) + + _(", ") + _(_<(size_t) cols>(), _("n")) + + _("]") + + // For a reference type (e.g. Ref) we have other constraints that might need to be + // satisfied: writeable=True (for a mutable reference), and, depending on the map's stride + // options, possibly f_contiguous or c_contiguous. We include them in the descriptor output + // to provide some hint as to why a TypeError is occurring (otherwise it can be confusing to + // see that a function accepts a 'numpy.ndarray[float64[3,2]]' and an error message that you + // *gave* a numpy.ndarray of the right type and dimensions. + _(", flags.writeable", "") + + _(", flags.c_contiguous", "") + + _(", flags.f_contiguous", "") + + _("]"); +}; + +// Casts an Eigen type to numpy array. If given a base, the numpy array references the src data, +// otherwise it'll make a copy. writeable lets you turn off the writeable flag for the array. +template handle eigen_array_cast(typename props::Type const &src, handle base = handle(), bool writeable = true) { + constexpr ssize_t elem_size = sizeof(typename props::Scalar); + array a; + if (props::vector) + a = array({ src.size() }, { elem_size * src.innerStride() }, src.data(), base); + else + a = array({ src.rows(), src.cols() }, { elem_size * src.rowStride(), elem_size * src.colStride() }, + src.data(), base); + + if (!writeable) + array_proxy(a.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_; + + return a.release(); +} + +// Takes an lvalue ref to some Eigen type and a (python) base object, creating a numpy array that +// reference the Eigen object's data with `base` as the python-registered base class (if omitted, +// the base will be set to None, and lifetime management is up to the caller). The numpy array is +// non-writeable if the given type is const. +template +handle eigen_ref_array(Type &src, handle parent = none()) { + // none here is to get past array's should-we-copy detection, which currently always + // copies when there is no base. Setting the base to None should be harmless. + return eigen_array_cast(src, parent, !std::is_const::value); +} + +// Takes a pointer to some dense, plain Eigen type, builds a capsule around it, then returns a numpy +// array that references the encapsulated data with a python-side reference to the capsule to tie +// its destruction to that of any dependent python objects. Const-ness is determined by whether or +// not the Type of the pointer given is const. +template ::value>> +handle eigen_encapsulate(Type *src) { + capsule base(src, [](void *o) { delete static_cast(o); }); + return eigen_ref_array(*src, base); +} + +// Type caster for regular, dense matrix types (e.g. MatrixXd), but not maps/refs/etc. of dense +// types. +template +struct type_caster::value>> { + using Scalar = typename Type::Scalar; + using props = EigenProps; + + bool load(handle src, bool convert) { + // If we're in no-convert mode, only load if given an array of the correct type + if (!convert && !isinstance>(src)) + return false; + + // Coerce into an array, but don't do type conversion yet; the copy below handles it. + auto buf = array::ensure(src); + + if (!buf) + return false; + + auto dims = buf.ndim(); + if (dims < 1 || dims > 2) + return false; + + auto fits = props::conformable(buf); + if (!fits) + return false; + + // Allocate the new type, then build a numpy reference into it + value = Type(fits.rows, fits.cols); + auto ref = reinterpret_steal(eigen_ref_array(value)); + if (dims == 1) ref = ref.squeeze(); + else if (ref.ndim() == 1) buf = buf.squeeze(); + + int result = detail::npy_api::get().PyArray_CopyInto_(ref.ptr(), buf.ptr()); + + if (result < 0) { // Copy failed! + PyErr_Clear(); + return false; + } + + return true; + } + +private: + + // Cast implementation + template + static handle cast_impl(CType *src, return_value_policy policy, handle parent) { + switch (policy) { + case return_value_policy::take_ownership: + case return_value_policy::automatic: + return eigen_encapsulate(src); + case return_value_policy::move: + return eigen_encapsulate(new CType(std::move(*src))); + case return_value_policy::copy: + return eigen_array_cast(*src); + case return_value_policy::reference: + case return_value_policy::automatic_reference: + return eigen_ref_array(*src); + case return_value_policy::reference_internal: + return eigen_ref_array(*src, parent); + default: + throw cast_error("unhandled return_value_policy: should not happen!"); + }; + } + +public: + + // Normal returned non-reference, non-const value: + static handle cast(Type &&src, return_value_policy /* policy */, handle parent) { + return cast_impl(&src, return_value_policy::move, parent); + } + // If you return a non-reference const, we mark the numpy array readonly: + static handle cast(const Type &&src, return_value_policy /* policy */, handle parent) { + return cast_impl(&src, return_value_policy::move, parent); + } + // lvalue reference return; default (automatic) becomes copy + static handle cast(Type &src, return_value_policy policy, handle parent) { + if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) + policy = return_value_policy::copy; + return cast_impl(&src, policy, parent); + } + // const lvalue reference return; default (automatic) becomes copy + static handle cast(const Type &src, return_value_policy policy, handle parent) { + if (policy == return_value_policy::automatic || policy == return_value_policy::automatic_reference) + policy = return_value_policy::copy; + return cast(&src, policy, parent); + } + // non-const pointer return + static handle cast(Type *src, return_value_policy policy, handle parent) { + return cast_impl(src, policy, parent); + } + // const pointer return + static handle cast(const Type *src, return_value_policy policy, handle parent) { + return cast_impl(src, policy, parent); + } + + static constexpr auto name = props::descriptor; + + operator Type*() { return &value; } + operator Type&() { return value; } + operator Type&&() && { return std::move(value); } + template using cast_op_type = movable_cast_op_type; + +private: + Type value; +}; + +// Base class for casting reference/map/block/etc. objects back to python. +template struct eigen_map_caster { +private: + using props = EigenProps; + +public: + + // Directly referencing a ref/map's data is a bit dangerous (whatever the map/ref points to has + // to stay around), but we'll allow it under the assumption that you know what you're doing (and + // have an appropriate keep_alive in place). We return a numpy array pointing directly at the + // ref's data (The numpy array ends up read-only if the ref was to a const matrix type.) Note + // that this means you need to ensure you don't destroy the object in some other way (e.g. with + // an appropriate keep_alive, or with a reference to a statically allocated matrix). + static handle cast(const MapType &src, return_value_policy policy, handle parent) { + switch (policy) { + case return_value_policy::copy: + return eigen_array_cast(src); + case return_value_policy::reference_internal: + return eigen_array_cast(src, parent, is_eigen_mutable_map::value); + case return_value_policy::reference: + case return_value_policy::automatic: + case return_value_policy::automatic_reference: + return eigen_array_cast(src, none(), is_eigen_mutable_map::value); + default: + // move, take_ownership don't make any sense for a ref/map: + pybind11_fail("Invalid return_value_policy for Eigen Map/Ref/Block type"); + } + } + + static constexpr auto name = props::descriptor; + + // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return + // types but not bound arguments). We still provide them (with an explicitly delete) so that + // you end up here if you try anyway. + bool load(handle, bool) = delete; + operator MapType() = delete; + template using cast_op_type = MapType; +}; + +// We can return any map-like object (but can only load Refs, specialized next): +template struct type_caster::value>> + : eigen_map_caster {}; + +// Loader for Ref<...> arguments. See the documentation for info on how to make this work without +// copying (it requires some extra effort in many cases). +template +struct type_caster< + Eigen::Ref, + enable_if_t>::value> +> : public eigen_map_caster> { +private: + using Type = Eigen::Ref; + using props = EigenProps; + using Scalar = typename props::Scalar; + using MapType = Eigen::Map; + using Array = array_t; + static constexpr bool need_writeable = is_eigen_mutable_map::value; + // Delay construction (these have no default constructor) + std::unique_ptr map; + std::unique_ptr ref; + // Our array. When possible, this is just a numpy array pointing to the source data, but + // sometimes we can't avoid copying (e.g. input is not a numpy array at all, has an incompatible + // layout, or is an array of a type that needs to be converted). Using a numpy temporary + // (rather than an Eigen temporary) saves an extra copy when we need both type conversion and + // storage order conversion. (Note that we refuse to use this temporary copy when loading an + // argument for a Ref with M non-const, i.e. a read-write reference). + Array copy_or_ref; +public: + bool load(handle src, bool convert) { + // First check whether what we have is already an array of the right type. If not, we can't + // avoid a copy (because the copy is also going to do type conversion). + bool need_copy = !isinstance(src); + + EigenConformable fits; + if (!need_copy) { + // We don't need a converting copy, but we also need to check whether the strides are + // compatible with the Ref's stride requirements + Array aref = reinterpret_borrow(src); + + if (aref && (!need_writeable || aref.writeable())) { + fits = props::conformable(aref); + if (!fits) return false; // Incompatible dimensions + if (!fits.template stride_compatible()) + need_copy = true; + else + copy_or_ref = std::move(aref); + } + else { + need_copy = true; + } + } + + if (need_copy) { + // We need to copy: If we need a mutable reference, or we're not supposed to convert + // (either because we're in the no-convert overload pass, or because we're explicitly + // instructed not to copy (via `py::arg().noconvert()`) we have to fail loading. + if (!convert || need_writeable) return false; + + Array copy = Array::ensure(src); + if (!copy) return false; + fits = props::conformable(copy); + if (!fits || !fits.template stride_compatible()) + return false; + copy_or_ref = std::move(copy); + loader_life_support::add_patient(copy_or_ref); + } + + ref.reset(); + map.reset(new MapType(data(copy_or_ref), fits.rows, fits.cols, make_stride(fits.stride.outer(), fits.stride.inner()))); + ref.reset(new Type(*map)); + + return true; + } + + operator Type*() { return ref.get(); } + operator Type&() { return *ref; } + template using cast_op_type = pybind11::detail::cast_op_type<_T>; + +private: + template ::value, int> = 0> + Scalar *data(Array &a) { return a.mutable_data(); } + + template ::value, int> = 0> + const Scalar *data(Array &a) { return a.data(); } + + // Attempt to figure out a constructor of `Stride` that will work. + // If both strides are fixed, use a default constructor: + template using stride_ctor_default = bool_constant< + S::InnerStrideAtCompileTime != Eigen::Dynamic && S::OuterStrideAtCompileTime != Eigen::Dynamic && + std::is_default_constructible::value>; + // Otherwise, if there is a two-index constructor, assume it is (outer,inner) like + // Eigen::Stride, and use it: + template using stride_ctor_dual = bool_constant< + !stride_ctor_default::value && std::is_constructible::value>; + // Otherwise, if there is a one-index constructor, and just one of the strides is dynamic, use + // it (passing whichever stride is dynamic). + template using stride_ctor_outer = bool_constant< + !any_of, stride_ctor_dual>::value && + S::OuterStrideAtCompileTime == Eigen::Dynamic && S::InnerStrideAtCompileTime != Eigen::Dynamic && + std::is_constructible::value>; + template using stride_ctor_inner = bool_constant< + !any_of, stride_ctor_dual>::value && + S::InnerStrideAtCompileTime == Eigen::Dynamic && S::OuterStrideAtCompileTime != Eigen::Dynamic && + std::is_constructible::value>; + + template ::value, int> = 0> + static S make_stride(EigenIndex, EigenIndex) { return S(); } + template ::value, int> = 0> + static S make_stride(EigenIndex outer, EigenIndex inner) { return S(outer, inner); } + template ::value, int> = 0> + static S make_stride(EigenIndex outer, EigenIndex) { return S(outer); } + template ::value, int> = 0> + static S make_stride(EigenIndex, EigenIndex inner) { return S(inner); } + +}; + +// type_caster for special matrix types (e.g. DiagonalMatrix), which are EigenBase, but not +// EigenDense (i.e. they don't have a data(), at least not with the usual matrix layout). +// load() is not supported, but we can cast them into the python domain by first copying to a +// regular Eigen::Matrix, then casting that. +template +struct type_caster::value>> { +protected: + using Matrix = Eigen::Matrix; + using props = EigenProps; +public: + static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { + handle h = eigen_encapsulate(new Matrix(src)); + return h; + } + static handle cast(const Type *src, return_value_policy policy, handle parent) { return cast(*src, policy, parent); } + + static constexpr auto name = props::descriptor; + + // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return + // types but not bound arguments). We still provide them (with an explicitly delete) so that + // you end up here if you try anyway. + bool load(handle, bool) = delete; + operator Type() = delete; + template using cast_op_type = Type; +}; + +template +struct type_caster::value>> { + typedef typename Type::Scalar Scalar; + typedef remove_reference_t().outerIndexPtr())> StorageIndex; + typedef typename Type::Index Index; + static constexpr bool rowMajor = Type::IsRowMajor; + + bool load(handle src, bool) { + if (!src) + return false; + + auto obj = reinterpret_borrow(src); + object sparse_module = module::import("scipy.sparse"); + object matrix_type = sparse_module.attr( + rowMajor ? "csr_matrix" : "csc_matrix"); + + if (!obj.get_type().is(matrix_type)) { + try { + obj = matrix_type(obj); + } catch (const error_already_set &) { + return false; + } + } + + auto values = array_t((object) obj.attr("data")); + auto innerIndices = array_t((object) obj.attr("indices")); + auto outerIndices = array_t((object) obj.attr("indptr")); + auto shape = pybind11::tuple((pybind11::object) obj.attr("shape")); + auto nnz = obj.attr("nnz").cast(); + + if (!values || !innerIndices || !outerIndices) + return false; + + value = Eigen::MappedSparseMatrix( + shape[0].cast(), shape[1].cast(), nnz, + outerIndices.mutable_data(), innerIndices.mutable_data(), values.mutable_data()); + + return true; + } + + static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) { + const_cast(src).makeCompressed(); + + object matrix_type = module::import("scipy.sparse").attr( + rowMajor ? "csr_matrix" : "csc_matrix"); + + array data(src.nonZeros(), src.valuePtr()); + array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr()); + array innerIndices(src.nonZeros(), src.innerIndexPtr()); + + return matrix_type( + std::make_tuple(data, innerIndices, outerIndices), + std::make_pair(src.rows(), src.cols()) + ).release(); + } + + PYBIND11_TYPE_CASTER(Type, _<(Type::IsRowMajor) != 0>("scipy.sparse.csr_matrix[", "scipy.sparse.csc_matrix[") + + npy_format_descriptor::name + _("]")); +}; + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(__GNUG__) || defined(__clang__) +# pragma GCC diagnostic pop +#elif defined(_MSC_VER) +# pragma warning(pop) +#endif diff --git a/python/src/pybind11/embed.h b/python/src/pybind11/embed.h new file mode 100644 index 000000000..72655885e --- /dev/null +++ b/python/src/pybind11/embed.h @@ -0,0 +1,200 @@ +/* + pybind11/embed.h: Support for embedding the interpreter + + Copyright (c) 2017 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" +#include "eval.h" + +#if defined(PYPY_VERSION) +# error Embedding the interpreter is not supported with PyPy +#endif + +#if PY_MAJOR_VERSION >= 3 +# define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ + extern "C" PyObject *pybind11_init_impl_##name() { \ + return pybind11_init_wrapper_##name(); \ + } +#else +# define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ + extern "C" void pybind11_init_impl_##name() { \ + pybind11_init_wrapper_##name(); \ + } +#endif + +/** \rst + Add a new module to the table of builtins for the interpreter. Must be + defined in global scope. The first macro parameter is the name of the + module (without quotes). The second parameter is the variable which will + be used as the interface to add functions and classes to the module. + + .. code-block:: cpp + + PYBIND11_EMBEDDED_MODULE(example, m) { + // ... initialize functions and classes here + m.def("foo", []() { + return "Hello, World!"; + }); + } + \endrst */ +#define PYBIND11_EMBEDDED_MODULE(name, variable) \ + static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ + static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \ + auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ + try { \ + PYBIND11_CONCAT(pybind11_init_, name)(m); \ + return m.ptr(); \ + } catch (pybind11::error_already_set &e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } catch (const std::exception &e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } \ + } \ + PYBIND11_EMBEDDED_MODULE_IMPL(name) \ + pybind11::detail::embedded_module name(PYBIND11_TOSTRING(name), \ + PYBIND11_CONCAT(pybind11_init_impl_, name)); \ + void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) + + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +/// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks. +struct embedded_module { +#if PY_MAJOR_VERSION >= 3 + using init_t = PyObject *(*)(); +#else + using init_t = void (*)(); +#endif + embedded_module(const char *name, init_t init) { + if (Py_IsInitialized()) + pybind11_fail("Can't add new modules after the interpreter has been initialized"); + + auto result = PyImport_AppendInittab(name, init); + if (result == -1) + pybind11_fail("Insufficient memory to add a new module"); + } +}; + +NAMESPACE_END(detail) + +/** \rst + Initialize the Python interpreter. No other pybind11 or CPython API functions can be + called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The + optional parameter can be used to skip the registration of signal handlers (see the + `Python documentation`_ for details). Calling this function again after the interpreter + has already been initialized is a fatal error. + + If initializing the Python interpreter fails, then the program is terminated. (This + is controlled by the CPython runtime and is an exception to pybind11's normal behavior + of throwing exceptions on errors.) + + .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx + \endrst */ +inline void initialize_interpreter(bool init_signal_handlers = true) { + if (Py_IsInitialized()) + pybind11_fail("The interpreter is already running"); + + Py_InitializeEx(init_signal_handlers ? 1 : 0); + + // Make .py files in the working directory available by default + module::import("sys").attr("path").cast().append("."); +} + +/** \rst + Shut down the Python interpreter. No pybind11 or CPython API functions can be called + after this. In addition, pybind11 objects must not outlive the interpreter: + + .. code-block:: cpp + + { // BAD + py::initialize_interpreter(); + auto hello = py::str("Hello, World!"); + py::finalize_interpreter(); + } // <-- BOOM, hello's destructor is called after interpreter shutdown + + { // GOOD + py::initialize_interpreter(); + { // scoped + auto hello = py::str("Hello, World!"); + } // <-- OK, hello is cleaned up properly + py::finalize_interpreter(); + } + + { // BETTER + py::scoped_interpreter guard{}; + auto hello = py::str("Hello, World!"); + } + + .. warning:: + + The interpreter can be restarted by calling `initialize_interpreter` again. + Modules created using pybind11 can be safely re-initialized. However, Python + itself cannot completely unload binary extension modules and there are several + caveats with regard to interpreter restarting. All the details can be found + in the CPython documentation. In short, not all interpreter memory may be + freed, either due to reference cycles or user-created global data. + + \endrst */ +inline void finalize_interpreter() { + handle builtins(PyEval_GetBuiltins()); + const char *id = PYBIND11_INTERNALS_ID; + + // Get the internals pointer (without creating it if it doesn't exist). It's possible for the + // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()` + // during destruction), so we get the pointer-pointer here and check it after Py_Finalize(). + detail::internals **internals_ptr_ptr = detail::get_internals_pp(); + // It could also be stashed in builtins, so look there too: + if (builtins.contains(id) && isinstance(builtins[id])) + internals_ptr_ptr = capsule(builtins[id]); + + Py_Finalize(); + + if (internals_ptr_ptr) { + delete *internals_ptr_ptr; + *internals_ptr_ptr = nullptr; + } +} + +/** \rst + Scope guard version of `initialize_interpreter` and `finalize_interpreter`. + This a move-only guard and only a single instance can exist. + + .. code-block:: cpp + + #include + + int main() { + py::scoped_interpreter guard{}; + py::print(Hello, World!); + } // <-- interpreter shutdown + \endrst */ +class scoped_interpreter { +public: + scoped_interpreter(bool init_signal_handlers = true) { + initialize_interpreter(init_signal_handlers); + } + + scoped_interpreter(const scoped_interpreter &) = delete; + scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; } + scoped_interpreter &operator=(const scoped_interpreter &) = delete; + scoped_interpreter &operator=(scoped_interpreter &&) = delete; + + ~scoped_interpreter() { + if (is_valid) + finalize_interpreter(); + } + +private: + bool is_valid = true; +}; + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/eval.h b/python/src/pybind11/eval.h new file mode 100644 index 000000000..ea85ba1db --- /dev/null +++ b/python/src/pybind11/eval.h @@ -0,0 +1,117 @@ +/* + pybind11/exec.h: Support for evaluating Python expressions and statements + from strings and files + + Copyright (c) 2016 Klemens Morgenstern and + Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +enum eval_mode { + /// Evaluate a string containing an isolated expression + eval_expr, + + /// Evaluate a string containing a single statement. Returns \c none + eval_single_statement, + + /// Evaluate a string containing a sequence of statement. Returns \c none + eval_statements +}; + +template +object eval(str expr, object global = globals(), object local = object()) { + if (!local) + local = global; + + /* PyRun_String does not accept a PyObject / encoding specifier, + this seems to be the only alternative */ + std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; + + int start; + switch (mode) { + case eval_expr: start = Py_eval_input; break; + case eval_single_statement: start = Py_single_input; break; + case eval_statements: start = Py_file_input; break; + default: pybind11_fail("invalid evaluation mode"); + } + + PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); + if (!result) + throw error_already_set(); + return reinterpret_steal(result); +} + +template +object eval(const char (&s)[N], object global = globals(), object local = object()) { + /* Support raw string literals by removing common leading whitespace */ + auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s)) + : str(s); + return eval(expr, global, local); +} + +inline void exec(str expr, object global = globals(), object local = object()) { + eval(expr, global, local); +} + +template +void exec(const char (&s)[N], object global = globals(), object local = object()) { + eval(s, global, local); +} + +template +object eval_file(str fname, object global = globals(), object local = object()) { + if (!local) + local = global; + + int start; + switch (mode) { + case eval_expr: start = Py_eval_input; break; + case eval_single_statement: start = Py_single_input; break; + case eval_statements: start = Py_file_input; break; + default: pybind11_fail("invalid evaluation mode"); + } + + int closeFile = 1; + std::string fname_str = (std::string) fname; +#if PY_VERSION_HEX >= 0x03040000 + FILE *f = _Py_fopen_obj(fname.ptr(), "r"); +#elif PY_VERSION_HEX >= 0x03000000 + FILE *f = _Py_fopen(fname.ptr(), "r"); +#else + /* No unicode support in open() :( */ + auto fobj = reinterpret_steal(PyFile_FromString( + const_cast(fname_str.c_str()), + const_cast("r"))); + FILE *f = nullptr; + if (fobj) + f = PyFile_AsFile(fobj.ptr()); + closeFile = 0; +#endif + if (!f) { + PyErr_Clear(); + pybind11_fail("File \"" + fname_str + "\" could not be opened!"); + } + +#if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION) + PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), + local.ptr()); + (void) closeFile; +#else + PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), + local.ptr(), closeFile); +#endif + + if (!result) + throw error_already_set(); + return reinterpret_steal(result); +} + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/functional.h b/python/src/pybind11/functional.h new file mode 100644 index 000000000..7a0988ab0 --- /dev/null +++ b/python/src/pybind11/functional.h @@ -0,0 +1,94 @@ +/* + pybind11/functional.h: std::function<> support + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" +#include + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +template +struct type_caster> { + using type = std::function; + using retval_type = conditional_t::value, void_type, Return>; + using function_type = Return (*) (Args...); + +public: + bool load(handle src, bool convert) { + if (src.is_none()) { + // Defer accepting None to other overloads (if we aren't in convert mode): + if (!convert) return false; + return true; + } + + if (!isinstance(src)) + return false; + + auto func = reinterpret_borrow(src); + + /* + When passing a C++ function as an argument to another C++ + function via Python, every function call would normally involve + a full C++ -> Python -> C++ roundtrip, which can be prohibitive. + Here, we try to at least detect the case where the function is + stateless (i.e. function pointer or lambda function without + captured variables), in which case the roundtrip can be avoided. + */ + if (auto cfunc = func.cpp_function()) { + auto c = reinterpret_borrow(PyCFunction_GET_SELF(cfunc.ptr())); + auto rec = (function_record *) c; + + if (rec && rec->is_stateless && + same_type(typeid(function_type), *reinterpret_cast(rec->data[1]))) { + struct capture { function_type f; }; + value = ((capture *) &rec->data)->f; + return true; + } + } + + // ensure GIL is held during functor destruction + struct func_handle { + function f; + func_handle(function&& f_) : f(std::move(f_)) {} + func_handle(const func_handle&) = default; + ~func_handle() { + gil_scoped_acquire acq; + function kill_f(std::move(f)); + } + }; + + value = [hfunc = func_handle(std::move(func))](Args... args) -> Return { + gil_scoped_acquire acq; + object retval(hfunc.f(std::forward(args)...)); + /* Visual studio 2015 parser issue: need parentheses around this expression */ + return (retval.template cast()); + }; + return true; + } + + template + static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { + if (!f_) + return none().inc_ref(); + + auto result = f_.template target(); + if (result) + return cpp_function(*result, policy).release(); + else + return cpp_function(std::forward(f_), policy).release(); + } + + PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster::name...) + _("], ") + + make_caster::name + _("]")); +}; + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/iostream.h b/python/src/pybind11/iostream.h new file mode 100644 index 000000000..72baef8fd --- /dev/null +++ b/python/src/pybind11/iostream.h @@ -0,0 +1,207 @@ +/* + pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python + + Copyright (c) 2017 Henry F. Schreiner + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" + +#include +#include +#include +#include +#include + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +// Buffer that writes to Python instead of C++ +class pythonbuf : public std::streambuf { +private: + using traits_type = std::streambuf::traits_type; + + const size_t buf_size; + std::unique_ptr d_buffer; + object pywrite; + object pyflush; + + int overflow(int c) { + if (!traits_type::eq_int_type(c, traits_type::eof())) { + *pptr() = traits_type::to_char_type(c); + pbump(1); + } + return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof(); + } + + int sync() { + if (pbase() != pptr()) { + // This subtraction cannot be negative, so dropping the sign + str line(pbase(), static_cast(pptr() - pbase())); + + { + gil_scoped_acquire tmp; + pywrite(line); + pyflush(); + } + + setp(pbase(), epptr()); + } + return 0; + } + +public: + + pythonbuf(object pyostream, size_t buffer_size = 1024) + : buf_size(buffer_size), + d_buffer(new char[buf_size]), + pywrite(pyostream.attr("write")), + pyflush(pyostream.attr("flush")) { + setp(d_buffer.get(), d_buffer.get() + buf_size - 1); + } + + /// Sync before destroy + ~pythonbuf() { + sync(); + } +}; + +NAMESPACE_END(detail) + + +/** \rst + This a move-only guard that redirects output. + + .. code-block:: cpp + + #include + + ... + + { + py::scoped_ostream_redirect output; + std::cout << "Hello, World!"; // Python stdout + } // <-- return std::cout to normal + + You can explicitly pass the c++ stream and the python object, + for example to guard stderr instead. + + .. code-block:: cpp + + { + py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; + std::cerr << "Hello, World!"; + } + \endrst */ +class scoped_ostream_redirect { +protected: + std::streambuf *old; + std::ostream &costream; + detail::pythonbuf buffer; + +public: + scoped_ostream_redirect( + std::ostream &costream = std::cout, + object pyostream = module::import("sys").attr("stdout")) + : costream(costream), buffer(pyostream) { + old = costream.rdbuf(&buffer); + } + + ~scoped_ostream_redirect() { + costream.rdbuf(old); + } + + scoped_ostream_redirect(const scoped_ostream_redirect &) = delete; + scoped_ostream_redirect(scoped_ostream_redirect &&other) = default; + scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete; + scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete; +}; + + +/** \rst + Like `scoped_ostream_redirect`, but redirects cerr by default. This class + is provided primary to make ``py::call_guard`` easier to make. + + .. code-block:: cpp + + m.def("noisy_func", &noisy_func, + py::call_guard()); + +\endrst */ +class scoped_estream_redirect : public scoped_ostream_redirect { +public: + scoped_estream_redirect( + std::ostream &costream = std::cerr, + object pyostream = module::import("sys").attr("stderr")) + : scoped_ostream_redirect(costream,pyostream) {} +}; + + +NAMESPACE_BEGIN(detail) + +// Class to redirect output as a context manager. C++ backend. +class OstreamRedirect { + bool do_stdout_; + bool do_stderr_; + std::unique_ptr redirect_stdout; + std::unique_ptr redirect_stderr; + +public: + OstreamRedirect(bool do_stdout = true, bool do_stderr = true) + : do_stdout_(do_stdout), do_stderr_(do_stderr) {} + + void enter() { + if (do_stdout_) + redirect_stdout.reset(new scoped_ostream_redirect()); + if (do_stderr_) + redirect_stderr.reset(new scoped_estream_redirect()); + } + + void exit() { + redirect_stdout.reset(); + redirect_stderr.reset(); + } +}; + +NAMESPACE_END(detail) + +/** \rst + This is a helper function to add a C++ redirect context manager to Python + instead of using a C++ guard. To use it, add the following to your binding code: + + .. code-block:: cpp + + #include + + ... + + py::add_ostream_redirect(m, "ostream_redirect"); + + You now have a Python context manager that redirects your output: + + .. code-block:: python + + with m.ostream_redirect(): + m.print_to_cout_function() + + This manager can optionally be told which streams to operate on: + + .. code-block:: python + + with m.ostream_redirect(stdout=true, stderr=true): + m.noisy_function_with_error_printing() + + \endrst */ +inline class_ add_ostream_redirect(module m, std::string name = "ostream_redirect") { + return class_(m, name.c_str(), module_local()) + .def(init(), arg("stdout")=true, arg("stderr")=true) + .def("__enter__", &detail::OstreamRedirect::enter) + .def("__exit__", [](detail::OstreamRedirect &self_, args) { self_.exit(); }); +} + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/numpy.h b/python/src/pybind11/numpy.h new file mode 100644 index 000000000..b2a02e024 --- /dev/null +++ b/python/src/pybind11/numpy.h @@ -0,0 +1,1610 @@ +/* + pybind11/numpy.h: Basic NumPy support, vectorize() wrapper + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" +#include "complex.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant +#endif + +/* This will be true on all flat address space platforms and allows us to reduce the + whole npy_intp / ssize_t / Py_intptr_t business down to just ssize_t for all size + and dimension types (e.g. shape, strides, indexing), instead of inflicting this + upon the library user. */ +static_assert(sizeof(ssize_t) == sizeof(Py_intptr_t), "ssize_t != Py_intptr_t"); + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +class array; // Forward declaration + +NAMESPACE_BEGIN(detail) +template struct npy_format_descriptor; + +struct PyArrayDescr_Proxy { + PyObject_HEAD + PyObject *typeobj; + char kind; + char type; + char byteorder; + char flags; + int type_num; + int elsize; + int alignment; + char *subarray; + PyObject *fields; + PyObject *names; +}; + +struct PyArray_Proxy { + PyObject_HEAD + char *data; + int nd; + ssize_t *dimensions; + ssize_t *strides; + PyObject *base; + PyObject *descr; + int flags; +}; + +struct PyVoidScalarObject_Proxy { + PyObject_VAR_HEAD + char *obval; + PyArrayDescr_Proxy *descr; + int flags; + PyObject *base; +}; + +struct numpy_type_info { + PyObject* dtype_ptr; + std::string format_str; +}; + +struct numpy_internals { + std::unordered_map registered_dtypes; + + numpy_type_info *get_type_info(const std::type_info& tinfo, bool throw_if_missing = true) { + auto it = registered_dtypes.find(std::type_index(tinfo)); + if (it != registered_dtypes.end()) + return &(it->second); + if (throw_if_missing) + pybind11_fail(std::string("NumPy type info missing for ") + tinfo.name()); + return nullptr; + } + + template numpy_type_info *get_type_info(bool throw_if_missing = true) { + return get_type_info(typeid(typename std::remove_cv::type), throw_if_missing); + } +}; + +inline PYBIND11_NOINLINE void load_numpy_internals(numpy_internals* &ptr) { + ptr = &get_or_create_shared_data("_numpy_internals"); +} + +inline numpy_internals& get_numpy_internals() { + static numpy_internals* ptr = nullptr; + if (!ptr) + load_numpy_internals(ptr); + return *ptr; +} + +struct npy_api { + enum constants { + NPY_ARRAY_C_CONTIGUOUS_ = 0x0001, + NPY_ARRAY_F_CONTIGUOUS_ = 0x0002, + NPY_ARRAY_OWNDATA_ = 0x0004, + NPY_ARRAY_FORCECAST_ = 0x0010, + NPY_ARRAY_ENSUREARRAY_ = 0x0040, + NPY_ARRAY_ALIGNED_ = 0x0100, + NPY_ARRAY_WRITEABLE_ = 0x0400, + NPY_BOOL_ = 0, + NPY_BYTE_, NPY_UBYTE_, + NPY_SHORT_, NPY_USHORT_, + NPY_INT_, NPY_UINT_, + NPY_LONG_, NPY_ULONG_, + NPY_LONGLONG_, NPY_ULONGLONG_, + NPY_FLOAT_, NPY_DOUBLE_, NPY_LONGDOUBLE_, + NPY_CFLOAT_, NPY_CDOUBLE_, NPY_CLONGDOUBLE_, + NPY_OBJECT_ = 17, + NPY_STRING_, NPY_UNICODE_, NPY_VOID_ + }; + + typedef struct { + Py_intptr_t *ptr; + int len; + } PyArray_Dims; + + static npy_api& get() { + static npy_api api = lookup(); + return api; + } + + bool PyArray_Check_(PyObject *obj) const { + return (bool) PyObject_TypeCheck(obj, PyArray_Type_); + } + bool PyArrayDescr_Check_(PyObject *obj) const { + return (bool) PyObject_TypeCheck(obj, PyArrayDescr_Type_); + } + + unsigned int (*PyArray_GetNDArrayCFeatureVersion_)(); + PyObject *(*PyArray_DescrFromType_)(int); + PyObject *(*PyArray_NewFromDescr_) + (PyTypeObject *, PyObject *, int, Py_intptr_t *, + Py_intptr_t *, void *, int, PyObject *); + PyObject *(*PyArray_DescrNewFromType_)(int); + int (*PyArray_CopyInto_)(PyObject *, PyObject *); + PyObject *(*PyArray_NewCopy_)(PyObject *, int); + PyTypeObject *PyArray_Type_; + PyTypeObject *PyVoidArrType_Type_; + PyTypeObject *PyArrayDescr_Type_; + PyObject *(*PyArray_DescrFromScalar_)(PyObject *); + PyObject *(*PyArray_FromAny_) (PyObject *, PyObject *, int, int, int, PyObject *); + int (*PyArray_DescrConverter_) (PyObject *, PyObject **); + bool (*PyArray_EquivTypes_) (PyObject *, PyObject *); + int (*PyArray_GetArrayParamsFromObject_)(PyObject *, PyObject *, char, PyObject **, int *, + Py_ssize_t *, PyObject **, PyObject *); + PyObject *(*PyArray_Squeeze_)(PyObject *); + int (*PyArray_SetBaseObject_)(PyObject *, PyObject *); + PyObject* (*PyArray_Resize_)(PyObject*, PyArray_Dims*, int, int); +private: + enum functions { + API_PyArray_GetNDArrayCFeatureVersion = 211, + API_PyArray_Type = 2, + API_PyArrayDescr_Type = 3, + API_PyVoidArrType_Type = 39, + API_PyArray_DescrFromType = 45, + API_PyArray_DescrFromScalar = 57, + API_PyArray_FromAny = 69, + API_PyArray_Resize = 80, + API_PyArray_CopyInto = 82, + API_PyArray_NewCopy = 85, + API_PyArray_NewFromDescr = 94, + API_PyArray_DescrNewFromType = 9, + API_PyArray_DescrConverter = 174, + API_PyArray_EquivTypes = 182, + API_PyArray_GetArrayParamsFromObject = 278, + API_PyArray_Squeeze = 136, + API_PyArray_SetBaseObject = 282 + }; + + static npy_api lookup() { + module m = module::import("numpy.core.multiarray"); + auto c = m.attr("_ARRAY_API"); +#if PY_MAJOR_VERSION >= 3 + void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL); +#else + void **api_ptr = (void **) PyCObject_AsVoidPtr(c.ptr()); +#endif + npy_api api; +#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func]; + DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion); + if (api.PyArray_GetNDArrayCFeatureVersion_() < 0x7) + pybind11_fail("pybind11 numpy support requires numpy >= 1.7.0"); + DECL_NPY_API(PyArray_Type); + DECL_NPY_API(PyVoidArrType_Type); + DECL_NPY_API(PyArrayDescr_Type); + DECL_NPY_API(PyArray_DescrFromType); + DECL_NPY_API(PyArray_DescrFromScalar); + DECL_NPY_API(PyArray_FromAny); + DECL_NPY_API(PyArray_Resize); + DECL_NPY_API(PyArray_CopyInto); + DECL_NPY_API(PyArray_NewCopy); + DECL_NPY_API(PyArray_NewFromDescr); + DECL_NPY_API(PyArray_DescrNewFromType); + DECL_NPY_API(PyArray_DescrConverter); + DECL_NPY_API(PyArray_EquivTypes); + DECL_NPY_API(PyArray_GetArrayParamsFromObject); + DECL_NPY_API(PyArray_Squeeze); + DECL_NPY_API(PyArray_SetBaseObject); +#undef DECL_NPY_API + return api; + } +}; + +inline PyArray_Proxy* array_proxy(void* ptr) { + return reinterpret_cast(ptr); +} + +inline const PyArray_Proxy* array_proxy(const void* ptr) { + return reinterpret_cast(ptr); +} + +inline PyArrayDescr_Proxy* array_descriptor_proxy(PyObject* ptr) { + return reinterpret_cast(ptr); +} + +inline const PyArrayDescr_Proxy* array_descriptor_proxy(const PyObject* ptr) { + return reinterpret_cast(ptr); +} + +inline bool check_flags(const void* ptr, int flag) { + return (flag == (array_proxy(ptr)->flags & flag)); +} + +template struct is_std_array : std::false_type { }; +template struct is_std_array> : std::true_type { }; +template struct is_complex : std::false_type { }; +template struct is_complex> : std::true_type { }; + +template struct array_info_scalar { + typedef T type; + static constexpr bool is_array = false; + static constexpr bool is_empty = false; + static constexpr auto extents = _(""); + static void append_extents(list& /* shape */) { } +}; +// Computes underlying type and a comma-separated list of extents for array +// types (any mix of std::array and built-in arrays). An array of char is +// treated as scalar because it gets special handling. +template struct array_info : array_info_scalar { }; +template struct array_info> { + using type = typename array_info::type; + static constexpr bool is_array = true; + static constexpr bool is_empty = (N == 0) || array_info::is_empty; + static constexpr size_t extent = N; + + // appends the extents to shape + static void append_extents(list& shape) { + shape.append(N); + array_info::append_extents(shape); + } + + static constexpr auto extents = _::is_array>( + concat(_(), array_info::extents), _() + ); +}; +// For numpy we have special handling for arrays of characters, so we don't include +// the size in the array extents. +template struct array_info : array_info_scalar { }; +template struct array_info> : array_info_scalar> { }; +template struct array_info : array_info> { }; +template using remove_all_extents_t = typename array_info::type; + +template using is_pod_struct = all_of< + std::is_standard_layout, // since we're accessing directly in memory we need a standard layout type +#if !defined(__GNUG__) || defined(_LIBCPP_VERSION) || defined(_GLIBCXX_USE_CXX11_ABI) + // _GLIBCXX_USE_CXX11_ABI indicates that we're using libstdc++ from GCC 5 or newer, independent + // of the actual compiler (Clang can also use libstdc++, but it always defines __GNUC__ == 4). + std::is_trivially_copyable, +#else + // GCC 4 doesn't implement is_trivially_copyable, so approximate it + std::is_trivially_destructible, + satisfies_any_of, +#endif + satisfies_none_of +>; + +template ssize_t byte_offset_unsafe(const Strides &) { return 0; } +template +ssize_t byte_offset_unsafe(const Strides &strides, ssize_t i, Ix... index) { + return i * strides[Dim] + byte_offset_unsafe(strides, index...); +} + +/** + * Proxy class providing unsafe, unchecked const access to array data. This is constructed through + * the `unchecked()` method of `array` or the `unchecked()` method of `array_t`. `Dims` + * will be -1 for dimensions determined at runtime. + */ +template +class unchecked_reference { +protected: + static constexpr bool Dynamic = Dims < 0; + const unsigned char *data_; + // Storing the shape & strides in local variables (i.e. these arrays) allows the compiler to + // make large performance gains on big, nested loops, but requires compile-time dimensions + conditional_t> + shape_, strides_; + const ssize_t dims_; + + friend class pybind11::array; + // Constructor for compile-time dimensions: + template + unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t) + : data_{reinterpret_cast(data)}, dims_{Dims} { + for (size_t i = 0; i < (size_t) dims_; i++) { + shape_[i] = shape[i]; + strides_[i] = strides[i]; + } + } + // Constructor for runtime dimensions: + template + unchecked_reference(const void *data, const ssize_t *shape, const ssize_t *strides, enable_if_t dims) + : data_{reinterpret_cast(data)}, shape_{shape}, strides_{strides}, dims_{dims} {} + +public: + /** + * Unchecked const reference access to data at the given indices. For a compile-time known + * number of dimensions, this requires the correct number of arguments; for run-time + * dimensionality, this is not checked (and so is up to the caller to use safely). + */ + template const T &operator()(Ix... index) const { + static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic, + "Invalid number of indices for unchecked array reference"); + return *reinterpret_cast(data_ + byte_offset_unsafe(strides_, ssize_t(index)...)); + } + /** + * Unchecked const reference access to data; this operator only participates if the reference + * is to a 1-dimensional array. When present, this is exactly equivalent to `obj(index)`. + */ + template > + const T &operator[](ssize_t index) const { return operator()(index); } + + /// Pointer access to the data at the given indices. + template const T *data(Ix... ix) const { return &operator()(ssize_t(ix)...); } + + /// Returns the item size, i.e. sizeof(T) + constexpr static ssize_t itemsize() { return sizeof(T); } + + /// Returns the shape (i.e. size) of dimension `dim` + ssize_t shape(ssize_t dim) const { return shape_[(size_t) dim]; } + + /// Returns the number of dimensions of the array + ssize_t ndim() const { return dims_; } + + /// Returns the total number of elements in the referenced array, i.e. the product of the shapes + template + enable_if_t size() const { + return std::accumulate(shape_.begin(), shape_.end(), (ssize_t) 1, std::multiplies()); + } + template + enable_if_t size() const { + return std::accumulate(shape_, shape_ + ndim(), (ssize_t) 1, std::multiplies()); + } + + /// Returns the total number of bytes used by the referenced data. Note that the actual span in + /// memory may be larger if the referenced array has non-contiguous strides (e.g. for a slice). + ssize_t nbytes() const { + return size() * itemsize(); + } +}; + +template +class unchecked_mutable_reference : public unchecked_reference { + friend class pybind11::array; + using ConstBase = unchecked_reference; + using ConstBase::ConstBase; + using ConstBase::Dynamic; +public: + /// Mutable, unchecked access to data at the given indices. + template T& operator()(Ix... index) { + static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic, + "Invalid number of indices for unchecked array reference"); + return const_cast(ConstBase::operator()(index...)); + } + /** + * Mutable, unchecked access data at the given index; this operator only participates if the + * reference is to a 1-dimensional array (or has runtime dimensions). When present, this is + * exactly equivalent to `obj(index)`. + */ + template > + T &operator[](ssize_t index) { return operator()(index); } + + /// Mutable pointer access to the data at the given indices. + template T *mutable_data(Ix... ix) { return &operator()(ssize_t(ix)...); } +}; + +template +struct type_caster> { + static_assert(Dim == 0 && Dim > 0 /* always fail */, "unchecked array proxy object is not castable"); +}; +template +struct type_caster> : type_caster> {}; + +NAMESPACE_END(detail) + +class dtype : public object { +public: + PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_); + + explicit dtype(const buffer_info &info) { + dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format))); + // If info.itemsize == 0, use the value calculated from the format string + m_ptr = descr.strip_padding(info.itemsize ? info.itemsize : descr.itemsize()).release().ptr(); + } + + explicit dtype(const std::string &format) { + m_ptr = from_args(pybind11::str(format)).release().ptr(); + } + + dtype(const char *format) : dtype(std::string(format)) { } + + dtype(list names, list formats, list offsets, ssize_t itemsize) { + dict args; + args["names"] = names; + args["formats"] = formats; + args["offsets"] = offsets; + args["itemsize"] = pybind11::int_(itemsize); + m_ptr = from_args(args).release().ptr(); + } + + /// This is essentially the same as calling numpy.dtype(args) in Python. + static dtype from_args(object args) { + PyObject *ptr = nullptr; + if (!detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) || !ptr) + throw error_already_set(); + return reinterpret_steal(ptr); + } + + /// Return dtype associated with a C++ type. + template static dtype of() { + return detail::npy_format_descriptor::type>::dtype(); + } + + /// Size of the data type in bytes. + ssize_t itemsize() const { + return detail::array_descriptor_proxy(m_ptr)->elsize; + } + + /// Returns true for structured data types. + bool has_fields() const { + return detail::array_descriptor_proxy(m_ptr)->names != nullptr; + } + + /// Single-character type code. + char kind() const { + return detail::array_descriptor_proxy(m_ptr)->kind; + } + +private: + static object _dtype_from_pep3118() { + static PyObject *obj = module::import("numpy.core._internal") + .attr("_dtype_from_pep3118").cast().release().ptr(); + return reinterpret_borrow(obj); + } + + dtype strip_padding(ssize_t itemsize) { + // Recursively strip all void fields with empty names that are generated for + // padding fields (as of NumPy v1.11). + if (!has_fields()) + return *this; + + struct field_descr { PYBIND11_STR_TYPE name; object format; pybind11::int_ offset; }; + std::vector field_descriptors; + + for (auto field : attr("fields").attr("items")()) { + auto spec = field.cast(); + auto name = spec[0].cast(); + auto format = spec[1].cast()[0].cast(); + auto offset = spec[1].cast()[1].cast(); + if (!len(name) && format.kind() == 'V') + continue; + field_descriptors.push_back({(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset}); + } + + std::sort(field_descriptors.begin(), field_descriptors.end(), + [](const field_descr& a, const field_descr& b) { + return a.offset.cast() < b.offset.cast(); + }); + + list names, formats, offsets; + for (auto& descr : field_descriptors) { + names.append(descr.name); + formats.append(descr.format); + offsets.append(descr.offset); + } + return dtype(names, formats, offsets, itemsize); + } +}; + +class array : public buffer { +public: + PYBIND11_OBJECT_CVT(array, buffer, detail::npy_api::get().PyArray_Check_, raw_array) + + enum { + c_style = detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_, + f_style = detail::npy_api::NPY_ARRAY_F_CONTIGUOUS_, + forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_ + }; + + array() : array({{0}}, static_cast(nullptr)) {} + + using ShapeContainer = detail::any_container; + using StridesContainer = detail::any_container; + + // Constructs an array taking shape/strides from arbitrary container types + array(const pybind11::dtype &dt, ShapeContainer shape, StridesContainer strides, + const void *ptr = nullptr, handle base = handle()) { + + if (strides->empty()) + *strides = c_strides(*shape, dt.itemsize()); + + auto ndim = shape->size(); + if (ndim != strides->size()) + pybind11_fail("NumPy: shape ndim doesn't match strides ndim"); + auto descr = dt; + + int flags = 0; + if (base && ptr) { + if (isinstance(base)) + /* Copy flags from base (except ownership bit) */ + flags = reinterpret_borrow(base).flags() & ~detail::npy_api::NPY_ARRAY_OWNDATA_; + else + /* Writable by default, easy to downgrade later on if needed */ + flags = detail::npy_api::NPY_ARRAY_WRITEABLE_; + } + + auto &api = detail::npy_api::get(); + auto tmp = reinterpret_steal(api.PyArray_NewFromDescr_( + api.PyArray_Type_, descr.release().ptr(), (int) ndim, shape->data(), strides->data(), + const_cast(ptr), flags, nullptr)); + if (!tmp) + throw error_already_set(); + if (ptr) { + if (base) { + api.PyArray_SetBaseObject_(tmp.ptr(), base.inc_ref().ptr()); + } else { + tmp = reinterpret_steal(api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */)); + } + } + m_ptr = tmp.release().ptr(); + } + + array(const pybind11::dtype &dt, ShapeContainer shape, const void *ptr = nullptr, handle base = handle()) + : array(dt, std::move(shape), {}, ptr, base) { } + + template ::value && !std::is_same::value>> + array(const pybind11::dtype &dt, T count, const void *ptr = nullptr, handle base = handle()) + : array(dt, {{count}}, ptr, base) { } + + template + array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle()) + : array(pybind11::dtype::of(), std::move(shape), std::move(strides), ptr, base) { } + + template + array(ShapeContainer shape, const T *ptr, handle base = handle()) + : array(std::move(shape), {}, ptr, base) { } + + template + explicit array(ssize_t count, const T *ptr, handle base = handle()) : array({count}, {}, ptr, base) { } + + explicit array(const buffer_info &info) + : array(pybind11::dtype(info), info.shape, info.strides, info.ptr) { } + + /// Array descriptor (dtype) + pybind11::dtype dtype() const { + return reinterpret_borrow(detail::array_proxy(m_ptr)->descr); + } + + /// Total number of elements + ssize_t size() const { + return std::accumulate(shape(), shape() + ndim(), (ssize_t) 1, std::multiplies()); + } + + /// Byte size of a single element + ssize_t itemsize() const { + return detail::array_descriptor_proxy(detail::array_proxy(m_ptr)->descr)->elsize; + } + + /// Total number of bytes + ssize_t nbytes() const { + return size() * itemsize(); + } + + /// Number of dimensions + ssize_t ndim() const { + return detail::array_proxy(m_ptr)->nd; + } + + /// Base object + object base() const { + return reinterpret_borrow(detail::array_proxy(m_ptr)->base); + } + + /// Dimensions of the array + const ssize_t* shape() const { + return detail::array_proxy(m_ptr)->dimensions; + } + + /// Dimension along a given axis + ssize_t shape(ssize_t dim) const { + if (dim >= ndim()) + fail_dim_check(dim, "invalid axis"); + return shape()[dim]; + } + + /// Strides of the array + const ssize_t* strides() const { + return detail::array_proxy(m_ptr)->strides; + } + + /// Stride along a given axis + ssize_t strides(ssize_t dim) const { + if (dim >= ndim()) + fail_dim_check(dim, "invalid axis"); + return strides()[dim]; + } + + /// Return the NumPy array flags + int flags() const { + return detail::array_proxy(m_ptr)->flags; + } + + /// If set, the array is writeable (otherwise the buffer is read-only) + bool writeable() const { + return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_WRITEABLE_); + } + + /// If set, the array owns the data (will be freed when the array is deleted) + bool owndata() const { + return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_OWNDATA_); + } + + /// Pointer to the contained data. If index is not provided, points to the + /// beginning of the buffer. May throw if the index would lead to out of bounds access. + template const void* data(Ix... index) const { + return static_cast(detail::array_proxy(m_ptr)->data + offset_at(index...)); + } + + /// Mutable pointer to the contained data. If index is not provided, points to the + /// beginning of the buffer. May throw if the index would lead to out of bounds access. + /// May throw if the array is not writeable. + template void* mutable_data(Ix... index) { + check_writeable(); + return static_cast(detail::array_proxy(m_ptr)->data + offset_at(index...)); + } + + /// Byte offset from beginning of the array to a given index (full or partial). + /// May throw if the index would lead to out of bounds access. + template ssize_t offset_at(Ix... index) const { + if ((ssize_t) sizeof...(index) > ndim()) + fail_dim_check(sizeof...(index), "too many indices for an array"); + return byte_offset(ssize_t(index)...); + } + + ssize_t offset_at() const { return 0; } + + /// Item count from beginning of the array to a given index (full or partial). + /// May throw if the index would lead to out of bounds access. + template ssize_t index_at(Ix... index) const { + return offset_at(index...) / itemsize(); + } + + /** + * Returns a proxy object that provides access to the array's data without bounds or + * dimensionality checking. Will throw if the array is missing the `writeable` flag. Use with + * care: the array must not be destroyed or reshaped for the duration of the returned object, + * and the caller must take care not to access invalid dimensions or dimension indices. + */ + template detail::unchecked_mutable_reference mutable_unchecked() & { + if (Dims >= 0 && ndim() != Dims) + throw std::domain_error("array has incorrect number of dimensions: " + std::to_string(ndim()) + + "; expected " + std::to_string(Dims)); + return detail::unchecked_mutable_reference(mutable_data(), shape(), strides(), ndim()); + } + + /** + * Returns a proxy object that provides const access to the array's data without bounds or + * dimensionality checking. Unlike `mutable_unchecked()`, this does not require that the + * underlying array have the `writable` flag. Use with care: the array must not be destroyed or + * reshaped for the duration of the returned object, and the caller must take care not to access + * invalid dimensions or dimension indices. + */ + template detail::unchecked_reference unchecked() const & { + if (Dims >= 0 && ndim() != Dims) + throw std::domain_error("array has incorrect number of dimensions: " + std::to_string(ndim()) + + "; expected " + std::to_string(Dims)); + return detail::unchecked_reference(data(), shape(), strides(), ndim()); + } + + /// Return a new view with all of the dimensions of length 1 removed + array squeeze() { + auto& api = detail::npy_api::get(); + return reinterpret_steal(api.PyArray_Squeeze_(m_ptr)); + } + + /// Resize array to given shape + /// If refcheck is true and more that one reference exist to this array + /// then resize will succeed only if it makes a reshape, i.e. original size doesn't change + void resize(ShapeContainer new_shape, bool refcheck = true) { + detail::npy_api::PyArray_Dims d = { + new_shape->data(), int(new_shape->size()) + }; + // try to resize, set ordering param to -1 cause it's not used anyway + object new_array = reinterpret_steal( + detail::npy_api::get().PyArray_Resize_(m_ptr, &d, int(refcheck), -1) + ); + if (!new_array) throw error_already_set(); + if (isinstance(new_array)) { *this = std::move(new_array); } + } + + /// Ensure that the argument is a NumPy array + /// In case of an error, nullptr is returned and the Python error is cleared. + static array ensure(handle h, int ExtraFlags = 0) { + auto result = reinterpret_steal(raw_array(h.ptr(), ExtraFlags)); + if (!result) + PyErr_Clear(); + return result; + } + +protected: + template friend struct detail::npy_format_descriptor; + + void fail_dim_check(ssize_t dim, const std::string& msg) const { + throw index_error(msg + ": " + std::to_string(dim) + + " (ndim = " + std::to_string(ndim()) + ")"); + } + + template ssize_t byte_offset(Ix... index) const { + check_dimensions(index...); + return detail::byte_offset_unsafe(strides(), ssize_t(index)...); + } + + void check_writeable() const { + if (!writeable()) + throw std::domain_error("array is not writeable"); + } + + // Default, C-style strides + static std::vector c_strides(const std::vector &shape, ssize_t itemsize) { + auto ndim = shape.size(); + std::vector strides(ndim, itemsize); + if (ndim > 0) + for (size_t i = ndim - 1; i > 0; --i) + strides[i - 1] = strides[i] * shape[i]; + return strides; + } + + // F-style strides; default when constructing an array_t with `ExtraFlags & f_style` + static std::vector f_strides(const std::vector &shape, ssize_t itemsize) { + auto ndim = shape.size(); + std::vector strides(ndim, itemsize); + for (size_t i = 1; i < ndim; ++i) + strides[i] = strides[i - 1] * shape[i - 1]; + return strides; + } + + template void check_dimensions(Ix... index) const { + check_dimensions_impl(ssize_t(0), shape(), ssize_t(index)...); + } + + void check_dimensions_impl(ssize_t, const ssize_t*) const { } + + template void check_dimensions_impl(ssize_t axis, const ssize_t* shape, ssize_t i, Ix... index) const { + if (i >= *shape) { + throw index_error(std::string("index ") + std::to_string(i) + + " is out of bounds for axis " + std::to_string(axis) + + " with size " + std::to_string(*shape)); + } + check_dimensions_impl(axis + 1, shape + 1, index...); + } + + /// Create array from any object -- always returns a new reference + static PyObject *raw_array(PyObject *ptr, int ExtraFlags = 0) { + if (ptr == nullptr) { + PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array from a nullptr"); + return nullptr; + } + return detail::npy_api::get().PyArray_FromAny_( + ptr, nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr); + } +}; + +template class array_t : public array { +private: + struct private_ctor {}; + // Delegating constructor needed when both moving and accessing in the same constructor + array_t(private_ctor, ShapeContainer &&shape, StridesContainer &&strides, const T *ptr, handle base) + : array(std::move(shape), std::move(strides), ptr, base) {} +public: + static_assert(!detail::array_info::is_array, "Array types cannot be used with array_t"); + + using value_type = T; + + array_t() : array(0, static_cast(nullptr)) {} + array_t(handle h, borrowed_t) : array(h, borrowed_t{}) { } + array_t(handle h, stolen_t) : array(h, stolen_t{}) { } + + PYBIND11_DEPRECATED("Use array_t::ensure() instead") + array_t(handle h, bool is_borrowed) : array(raw_array_t(h.ptr()), stolen_t{}) { + if (!m_ptr) PyErr_Clear(); + if (!is_borrowed) Py_XDECREF(h.ptr()); + } + + array_t(const object &o) : array(raw_array_t(o.ptr()), stolen_t{}) { + if (!m_ptr) throw error_already_set(); + } + + explicit array_t(const buffer_info& info) : array(info) { } + + array_t(ShapeContainer shape, StridesContainer strides, const T *ptr = nullptr, handle base = handle()) + : array(std::move(shape), std::move(strides), ptr, base) { } + + explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle()) + : array_t(private_ctor{}, std::move(shape), + ExtraFlags & f_style ? f_strides(*shape, itemsize()) : c_strides(*shape, itemsize()), + ptr, base) { } + + explicit array_t(size_t count, const T *ptr = nullptr, handle base = handle()) + : array({count}, {}, ptr, base) { } + + constexpr ssize_t itemsize() const { + return sizeof(T); + } + + template ssize_t index_at(Ix... index) const { + return offset_at(index...) / itemsize(); + } + + template const T* data(Ix... index) const { + return static_cast(array::data(index...)); + } + + template T* mutable_data(Ix... index) { + return static_cast(array::mutable_data(index...)); + } + + // Reference to element at a given index + template const T& at(Ix... index) const { + if ((ssize_t) sizeof...(index) != ndim()) + fail_dim_check(sizeof...(index), "index dimension mismatch"); + return *(static_cast(array::data()) + byte_offset(ssize_t(index)...) / itemsize()); + } + + // Mutable reference to element at a given index + template T& mutable_at(Ix... index) { + if ((ssize_t) sizeof...(index) != ndim()) + fail_dim_check(sizeof...(index), "index dimension mismatch"); + return *(static_cast(array::mutable_data()) + byte_offset(ssize_t(index)...) / itemsize()); + } + + /** + * Returns a proxy object that provides access to the array's data without bounds or + * dimensionality checking. Will throw if the array is missing the `writeable` flag. Use with + * care: the array must not be destroyed or reshaped for the duration of the returned object, + * and the caller must take care not to access invalid dimensions or dimension indices. + */ + template detail::unchecked_mutable_reference mutable_unchecked() & { + return array::mutable_unchecked(); + } + + /** + * Returns a proxy object that provides const access to the array's data without bounds or + * dimensionality checking. Unlike `unchecked()`, this does not require that the underlying + * array have the `writable` flag. Use with care: the array must not be destroyed or reshaped + * for the duration of the returned object, and the caller must take care not to access invalid + * dimensions or dimension indices. + */ + template detail::unchecked_reference unchecked() const & { + return array::unchecked(); + } + + /// Ensure that the argument is a NumPy array of the correct dtype (and if not, try to convert + /// it). In case of an error, nullptr is returned and the Python error is cleared. + static array_t ensure(handle h) { + auto result = reinterpret_steal(raw_array_t(h.ptr())); + if (!result) + PyErr_Clear(); + return result; + } + + static bool check_(handle h) { + const auto &api = detail::npy_api::get(); + return api.PyArray_Check_(h.ptr()) + && api.PyArray_EquivTypes_(detail::array_proxy(h.ptr())->descr, dtype::of().ptr()); + } + +protected: + /// Create array from any object -- always returns a new reference + static PyObject *raw_array_t(PyObject *ptr) { + if (ptr == nullptr) { + PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array_t from a nullptr"); + return nullptr; + } + return detail::npy_api::get().PyArray_FromAny_( + ptr, dtype::of().release().ptr(), 0, 0, + detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr); + } +}; + +template +struct format_descriptor::value>> { + static std::string format() { + return detail::npy_format_descriptor::type>::format(); + } +}; + +template struct format_descriptor { + static std::string format() { return std::to_string(N) + "s"; } +}; +template struct format_descriptor> { + static std::string format() { return std::to_string(N) + "s"; } +}; + +template +struct format_descriptor::value>> { + static std::string format() { + return format_descriptor< + typename std::remove_cv::type>::type>::format(); + } +}; + +template +struct format_descriptor::is_array>> { + static std::string format() { + using namespace detail; + static constexpr auto extents = _("(") + array_info::extents + _(")"); + return extents.text + format_descriptor>::format(); + } +}; + +NAMESPACE_BEGIN(detail) +template +struct pyobject_caster> { + using type = array_t; + + bool load(handle src, bool convert) { + if (!convert && !type::check_(src)) + return false; + value = type::ensure(src); + return static_cast(value); + } + + static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) { + return src.inc_ref(); + } + PYBIND11_TYPE_CASTER(type, handle_type_name::name); +}; + +template +struct compare_buffer_info::value>> { + static bool compare(const buffer_info& b) { + return npy_api::get().PyArray_EquivTypes_(dtype::of().ptr(), dtype(b).ptr()); + } +}; + +template +struct npy_format_descriptor_name; + +template +struct npy_format_descriptor_name::value>> { + static constexpr auto name = _::value>( + _("bool"), _::value>("int", "uint") + _() + ); +}; + +template +struct npy_format_descriptor_name::value>> { + static constexpr auto name = _::value || std::is_same::value>( + _("float") + _(), _("longdouble") + ); +}; + +template +struct npy_format_descriptor_name::value>> { + static constexpr auto name = _::value + || std::is_same::value>( + _("complex") + _(), _("longcomplex") + ); +}; + +template +struct npy_format_descriptor::value>> + : npy_format_descriptor_name { +private: + // NB: the order here must match the one in common.h + constexpr static const int values[15] = { + npy_api::NPY_BOOL_, + npy_api::NPY_BYTE_, npy_api::NPY_UBYTE_, npy_api::NPY_SHORT_, npy_api::NPY_USHORT_, + npy_api::NPY_INT_, npy_api::NPY_UINT_, npy_api::NPY_LONGLONG_, npy_api::NPY_ULONGLONG_, + npy_api::NPY_FLOAT_, npy_api::NPY_DOUBLE_, npy_api::NPY_LONGDOUBLE_, + npy_api::NPY_CFLOAT_, npy_api::NPY_CDOUBLE_, npy_api::NPY_CLONGDOUBLE_ + }; + +public: + static constexpr int value = values[detail::is_fmt_numeric::index]; + + static pybind11::dtype dtype() { + if (auto ptr = npy_api::get().PyArray_DescrFromType_(value)) + return reinterpret_borrow(ptr); + pybind11_fail("Unsupported buffer format!"); + } +}; + +#define PYBIND11_DECL_CHAR_FMT \ + static constexpr auto name = _("S") + _(); \ + static pybind11::dtype dtype() { return pybind11::dtype(std::string("S") + std::to_string(N)); } +template struct npy_format_descriptor { PYBIND11_DECL_CHAR_FMT }; +template struct npy_format_descriptor> { PYBIND11_DECL_CHAR_FMT }; +#undef PYBIND11_DECL_CHAR_FMT + +template struct npy_format_descriptor::is_array>> { +private: + using base_descr = npy_format_descriptor::type>; +public: + static_assert(!array_info::is_empty, "Zero-sized arrays are not supported"); + + static constexpr auto name = _("(") + array_info::extents + _(")") + base_descr::name; + static pybind11::dtype dtype() { + list shape; + array_info::append_extents(shape); + return pybind11::dtype::from_args(pybind11::make_tuple(base_descr::dtype(), shape)); + } +}; + +template struct npy_format_descriptor::value>> { +private: + using base_descr = npy_format_descriptor::type>; +public: + static constexpr auto name = base_descr::name; + static pybind11::dtype dtype() { return base_descr::dtype(); } +}; + +struct field_descriptor { + const char *name; + ssize_t offset; + ssize_t size; + std::string format; + dtype descr; +}; + +inline PYBIND11_NOINLINE void register_structured_dtype( + any_container fields, + const std::type_info& tinfo, ssize_t itemsize, + bool (*direct_converter)(PyObject *, void *&)) { + + auto& numpy_internals = get_numpy_internals(); + if (numpy_internals.get_type_info(tinfo, false)) + pybind11_fail("NumPy: dtype is already registered"); + + list names, formats, offsets; + for (auto field : *fields) { + if (!field.descr) + pybind11_fail(std::string("NumPy: unsupported field dtype: `") + + field.name + "` @ " + tinfo.name()); + names.append(PYBIND11_STR_TYPE(field.name)); + formats.append(field.descr); + offsets.append(pybind11::int_(field.offset)); + } + auto dtype_ptr = pybind11::dtype(names, formats, offsets, itemsize).release().ptr(); + + // There is an existing bug in NumPy (as of v1.11): trailing bytes are + // not encoded explicitly into the format string. This will supposedly + // get fixed in v1.12; for further details, see these: + // - https://github.com/numpy/numpy/issues/7797 + // - https://github.com/numpy/numpy/pull/7798 + // Because of this, we won't use numpy's logic to generate buffer format + // strings and will just do it ourselves. + std::vector ordered_fields(std::move(fields)); + std::sort(ordered_fields.begin(), ordered_fields.end(), + [](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; }); + ssize_t offset = 0; + std::ostringstream oss; + // mark the structure as unaligned with '^', because numpy and C++ don't + // always agree about alignment (particularly for complex), and we're + // explicitly listing all our padding. This depends on none of the fields + // overriding the endianness. Putting the ^ in front of individual fields + // isn't guaranteed to work due to https://github.com/numpy/numpy/issues/9049 + oss << "^T{"; + for (auto& field : ordered_fields) { + if (field.offset > offset) + oss << (field.offset - offset) << 'x'; + oss << field.format << ':' << field.name << ':'; + offset = field.offset + field.size; + } + if (itemsize > offset) + oss << (itemsize - offset) << 'x'; + oss << '}'; + auto format_str = oss.str(); + + // Sanity check: verify that NumPy properly parses our buffer format string + auto& api = npy_api::get(); + auto arr = array(buffer_info(nullptr, itemsize, format_str, 1)); + if (!api.PyArray_EquivTypes_(dtype_ptr, arr.dtype().ptr())) + pybind11_fail("NumPy: invalid buffer descriptor!"); + + auto tindex = std::type_index(tinfo); + numpy_internals.registered_dtypes[tindex] = { dtype_ptr, format_str }; + get_internals().direct_conversions[tindex].push_back(direct_converter); +} + +template struct npy_format_descriptor { + static_assert(is_pod_struct::value, "Attempt to use a non-POD or unimplemented POD type as a numpy dtype"); + + static constexpr auto name = make_caster::name; + + static pybind11::dtype dtype() { + return reinterpret_borrow(dtype_ptr()); + } + + static std::string format() { + static auto format_str = get_numpy_internals().get_type_info(true)->format_str; + return format_str; + } + + static void register_dtype(any_container fields) { + register_structured_dtype(std::move(fields), typeid(typename std::remove_cv::type), + sizeof(T), &direct_converter); + } + +private: + static PyObject* dtype_ptr() { + static PyObject* ptr = get_numpy_internals().get_type_info(true)->dtype_ptr; + return ptr; + } + + static bool direct_converter(PyObject *obj, void*& value) { + auto& api = npy_api::get(); + if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_)) + return false; + if (auto descr = reinterpret_steal(api.PyArray_DescrFromScalar_(obj))) { + if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) { + value = ((PyVoidScalarObject_Proxy *) obj)->obval; + return true; + } + } + return false; + } +}; + +#ifdef __CLION_IDE__ // replace heavy macro with dummy code for the IDE (doesn't affect code) +# define PYBIND11_NUMPY_DTYPE(Type, ...) ((void)0) +# define PYBIND11_NUMPY_DTYPE_EX(Type, ...) ((void)0) +#else + +#define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \ + ::pybind11::detail::field_descriptor { \ + Name, offsetof(T, Field), sizeof(decltype(std::declval().Field)), \ + ::pybind11::format_descriptor().Field)>::format(), \ + ::pybind11::detail::npy_format_descriptor().Field)>::dtype() \ + } + +// Extract name, offset and format descriptor for a struct field +#define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #Field) + +// The main idea of this macro is borrowed from https://github.com/swansontec/map-macro +// (C) William Swanson, Paul Fultz +#define PYBIND11_EVAL0(...) __VA_ARGS__ +#define PYBIND11_EVAL1(...) PYBIND11_EVAL0 (PYBIND11_EVAL0 (PYBIND11_EVAL0 (__VA_ARGS__))) +#define PYBIND11_EVAL2(...) PYBIND11_EVAL1 (PYBIND11_EVAL1 (PYBIND11_EVAL1 (__VA_ARGS__))) +#define PYBIND11_EVAL3(...) PYBIND11_EVAL2 (PYBIND11_EVAL2 (PYBIND11_EVAL2 (__VA_ARGS__))) +#define PYBIND11_EVAL4(...) PYBIND11_EVAL3 (PYBIND11_EVAL3 (PYBIND11_EVAL3 (__VA_ARGS__))) +#define PYBIND11_EVAL(...) PYBIND11_EVAL4 (PYBIND11_EVAL4 (PYBIND11_EVAL4 (__VA_ARGS__))) +#define PYBIND11_MAP_END(...) +#define PYBIND11_MAP_OUT +#define PYBIND11_MAP_COMMA , +#define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END +#define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT +#define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0 (test, next, 0) +#define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1 (PYBIND11_MAP_GET_END test, next) +#ifdef _MSC_VER // MSVC is not as eager to expand macros, hence this workaround +#define PYBIND11_MAP_LIST_NEXT1(test, next) \ + PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) +#else +#define PYBIND11_MAP_LIST_NEXT1(test, next) \ + PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) +#endif +#define PYBIND11_MAP_LIST_NEXT(test, next) \ + PYBIND11_MAP_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) +#define PYBIND11_MAP_LIST0(f, t, x, peek, ...) \ + f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST1) (f, t, peek, __VA_ARGS__) +#define PYBIND11_MAP_LIST1(f, t, x, peek, ...) \ + f(t, x) PYBIND11_MAP_LIST_NEXT (peek, PYBIND11_MAP_LIST0) (f, t, peek, __VA_ARGS__) +// PYBIND11_MAP_LIST(f, t, a1, a2, ...) expands to f(t, a1), f(t, a2), ... +#define PYBIND11_MAP_LIST(f, t, ...) \ + PYBIND11_EVAL (PYBIND11_MAP_LIST1 (f, t, __VA_ARGS__, (), 0)) + +#define PYBIND11_NUMPY_DTYPE(Type, ...) \ + ::pybind11::detail::npy_format_descriptor::register_dtype \ + (::std::vector<::pybind11::detail::field_descriptor> \ + {PYBIND11_MAP_LIST (PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)}) + +#ifdef _MSC_VER +#define PYBIND11_MAP2_LIST_NEXT1(test, next) \ + PYBIND11_EVAL0 (PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0)) +#else +#define PYBIND11_MAP2_LIST_NEXT1(test, next) \ + PYBIND11_MAP_NEXT0 (test, PYBIND11_MAP_COMMA next, 0) +#endif +#define PYBIND11_MAP2_LIST_NEXT(test, next) \ + PYBIND11_MAP2_LIST_NEXT1 (PYBIND11_MAP_GET_END test, next) +#define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...) \ + f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST1) (f, t, peek, __VA_ARGS__) +#define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...) \ + f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT (peek, PYBIND11_MAP2_LIST0) (f, t, peek, __VA_ARGS__) +// PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ... +#define PYBIND11_MAP2_LIST(f, t, ...) \ + PYBIND11_EVAL (PYBIND11_MAP2_LIST1 (f, t, __VA_ARGS__, (), 0)) + +#define PYBIND11_NUMPY_DTYPE_EX(Type, ...) \ + ::pybind11::detail::npy_format_descriptor::register_dtype \ + (::std::vector<::pybind11::detail::field_descriptor> \ + {PYBIND11_MAP2_LIST (PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)}) + +#endif // __CLION_IDE__ + +template +using array_iterator = typename std::add_pointer::type; + +template +array_iterator array_begin(const buffer_info& buffer) { + return array_iterator(reinterpret_cast(buffer.ptr)); +} + +template +array_iterator array_end(const buffer_info& buffer) { + return array_iterator(reinterpret_cast(buffer.ptr) + buffer.size); +} + +class common_iterator { +public: + using container_type = std::vector; + using value_type = container_type::value_type; + using size_type = container_type::size_type; + + common_iterator() : p_ptr(0), m_strides() {} + + common_iterator(void* ptr, const container_type& strides, const container_type& shape) + : p_ptr(reinterpret_cast(ptr)), m_strides(strides.size()) { + m_strides.back() = static_cast(strides.back()); + for (size_type i = m_strides.size() - 1; i != 0; --i) { + size_type j = i - 1; + value_type s = static_cast(shape[i]); + m_strides[j] = strides[j] + m_strides[i] - strides[i] * s; + } + } + + void increment(size_type dim) { + p_ptr += m_strides[dim]; + } + + void* data() const { + return p_ptr; + } + +private: + char* p_ptr; + container_type m_strides; +}; + +template class multi_array_iterator { +public: + using container_type = std::vector; + + multi_array_iterator(const std::array &buffers, + const container_type &shape) + : m_shape(shape.size()), m_index(shape.size(), 0), + m_common_iterator() { + + // Manual copy to avoid conversion warning if using std::copy + for (size_t i = 0; i < shape.size(); ++i) + m_shape[i] = shape[i]; + + container_type strides(shape.size()); + for (size_t i = 0; i < N; ++i) + init_common_iterator(buffers[i], shape, m_common_iterator[i], strides); + } + + multi_array_iterator& operator++() { + for (size_t j = m_index.size(); j != 0; --j) { + size_t i = j - 1; + if (++m_index[i] != m_shape[i]) { + increment_common_iterator(i); + break; + } else { + m_index[i] = 0; + } + } + return *this; + } + + template T* data() const { + return reinterpret_cast(m_common_iterator[K].data()); + } + +private: + + using common_iter = common_iterator; + + void init_common_iterator(const buffer_info &buffer, + const container_type &shape, + common_iter &iterator, + container_type &strides) { + auto buffer_shape_iter = buffer.shape.rbegin(); + auto buffer_strides_iter = buffer.strides.rbegin(); + auto shape_iter = shape.rbegin(); + auto strides_iter = strides.rbegin(); + + while (buffer_shape_iter != buffer.shape.rend()) { + if (*shape_iter == *buffer_shape_iter) + *strides_iter = *buffer_strides_iter; + else + *strides_iter = 0; + + ++buffer_shape_iter; + ++buffer_strides_iter; + ++shape_iter; + ++strides_iter; + } + + std::fill(strides_iter, strides.rend(), 0); + iterator = common_iter(buffer.ptr, strides, shape); + } + + void increment_common_iterator(size_t dim) { + for (auto &iter : m_common_iterator) + iter.increment(dim); + } + + container_type m_shape; + container_type m_index; + std::array m_common_iterator; +}; + +enum class broadcast_trivial { non_trivial, c_trivial, f_trivial }; + +// Populates the shape and number of dimensions for the set of buffers. Returns a broadcast_trivial +// enum value indicating whether the broadcast is "trivial"--that is, has each buffer being either a +// singleton or a full-size, C-contiguous (`c_trivial`) or Fortran-contiguous (`f_trivial`) storage +// buffer; returns `non_trivial` otherwise. +template +broadcast_trivial broadcast(const std::array &buffers, ssize_t &ndim, std::vector &shape) { + ndim = std::accumulate(buffers.begin(), buffers.end(), ssize_t(0), [](ssize_t res, const buffer_info &buf) { + return std::max(res, buf.ndim); + }); + + shape.clear(); + shape.resize((size_t) ndim, 1); + + // Figure out the output size, and make sure all input arrays conform (i.e. are either size 1 or + // the full size). + for (size_t i = 0; i < N; ++i) { + auto res_iter = shape.rbegin(); + auto end = buffers[i].shape.rend(); + for (auto shape_iter = buffers[i].shape.rbegin(); shape_iter != end; ++shape_iter, ++res_iter) { + const auto &dim_size_in = *shape_iter; + auto &dim_size_out = *res_iter; + + // Each input dimension can either be 1 or `n`, but `n` values must match across buffers + if (dim_size_out == 1) + dim_size_out = dim_size_in; + else if (dim_size_in != 1 && dim_size_in != dim_size_out) + pybind11_fail("pybind11::vectorize: incompatible size/dimension of inputs!"); + } + } + + bool trivial_broadcast_c = true; + bool trivial_broadcast_f = true; + for (size_t i = 0; i < N && (trivial_broadcast_c || trivial_broadcast_f); ++i) { + if (buffers[i].size == 1) + continue; + + // Require the same number of dimensions: + if (buffers[i].ndim != ndim) + return broadcast_trivial::non_trivial; + + // Require all dimensions be full-size: + if (!std::equal(buffers[i].shape.cbegin(), buffers[i].shape.cend(), shape.cbegin())) + return broadcast_trivial::non_trivial; + + // Check for C contiguity (but only if previous inputs were also C contiguous) + if (trivial_broadcast_c) { + ssize_t expect_stride = buffers[i].itemsize; + auto end = buffers[i].shape.crend(); + for (auto shape_iter = buffers[i].shape.crbegin(), stride_iter = buffers[i].strides.crbegin(); + trivial_broadcast_c && shape_iter != end; ++shape_iter, ++stride_iter) { + if (expect_stride == *stride_iter) + expect_stride *= *shape_iter; + else + trivial_broadcast_c = false; + } + } + + // Check for Fortran contiguity (if previous inputs were also F contiguous) + if (trivial_broadcast_f) { + ssize_t expect_stride = buffers[i].itemsize; + auto end = buffers[i].shape.cend(); + for (auto shape_iter = buffers[i].shape.cbegin(), stride_iter = buffers[i].strides.cbegin(); + trivial_broadcast_f && shape_iter != end; ++shape_iter, ++stride_iter) { + if (expect_stride == *stride_iter) + expect_stride *= *shape_iter; + else + trivial_broadcast_f = false; + } + } + } + + return + trivial_broadcast_c ? broadcast_trivial::c_trivial : + trivial_broadcast_f ? broadcast_trivial::f_trivial : + broadcast_trivial::non_trivial; +} + +template +struct vectorize_arg { + static_assert(!std::is_rvalue_reference::value, "Functions with rvalue reference arguments cannot be vectorized"); + // The wrapped function gets called with this type: + using call_type = remove_reference_t; + // Is this a vectorized argument? + static constexpr bool vectorize = + satisfies_any_of::value && + satisfies_none_of::value && + (!std::is_reference::value || + (std::is_lvalue_reference::value && std::is_const::value)); + // Accept this type: an array for vectorized types, otherwise the type as-is: + using type = conditional_t, array::forcecast>, T>; +}; + +template +struct vectorize_helper { +private: + static constexpr size_t N = sizeof...(Args); + static constexpr size_t NVectorized = constexpr_sum(vectorize_arg::vectorize...); + static_assert(NVectorized >= 1, + "pybind11::vectorize(...) requires a function with at least one vectorizable argument"); + +public: + template + explicit vectorize_helper(T &&f) : f(std::forward(f)) { } + + object operator()(typename vectorize_arg::type... args) { + return run(args..., + make_index_sequence(), + select_indices::vectorize...>(), + make_index_sequence()); + } + +private: + remove_reference_t f; + + // Internal compiler error in MSVC 19.16.27025.1 (Visual Studio 2017 15.9.4), when compiling with "/permissive-" flag + // when arg_call_types is manually inlined. + using arg_call_types = std::tuple::call_type...>; + template using param_n_t = typename std::tuple_element::type; + + // Runs a vectorized function given arguments tuple and three index sequences: + // - Index is the full set of 0 ... (N-1) argument indices; + // - VIndex is the subset of argument indices with vectorized parameters, letting us access + // vectorized arguments (anything not in this sequence is passed through) + // - BIndex is a incremental sequence (beginning at 0) of the same size as VIndex, so that + // we can store vectorized buffer_infos in an array (argument VIndex has its buffer at + // index BIndex in the array). + template object run( + typename vectorize_arg::type &...args, + index_sequence i_seq, index_sequence vi_seq, index_sequence bi_seq) { + + // Pointers to values the function was called with; the vectorized ones set here will start + // out as array_t pointers, but they will be changed them to T pointers before we make + // call the wrapped function. Non-vectorized pointers are left as-is. + std::array params{{ &args... }}; + + // The array of `buffer_info`s of vectorized arguments: + std::array buffers{{ reinterpret_cast(params[VIndex])->request()... }}; + + /* Determine dimensions parameters of output array */ + ssize_t nd = 0; + std::vector shape(0); + auto trivial = broadcast(buffers, nd, shape); + size_t ndim = (size_t) nd; + + size_t size = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies()); + + // If all arguments are 0-dimension arrays (i.e. single values) return a plain value (i.e. + // not wrapped in an array). + if (size == 1 && ndim == 0) { + PYBIND11_EXPAND_SIDE_EFFECTS(params[VIndex] = buffers[BIndex].ptr); + return cast(f(*reinterpret_cast *>(params[Index])...)); + } + + array_t result; + if (trivial == broadcast_trivial::f_trivial) result = array_t(shape); + else result = array_t(shape); + + if (size == 0) return std::move(result); + + /* Call the function */ + if (trivial == broadcast_trivial::non_trivial) + apply_broadcast(buffers, params, result, i_seq, vi_seq, bi_seq); + else + apply_trivial(buffers, params, result.mutable_data(), size, i_seq, vi_seq, bi_seq); + + return std::move(result); + } + + template + void apply_trivial(std::array &buffers, + std::array ¶ms, + Return *out, + size_t size, + index_sequence, index_sequence, index_sequence) { + + // Initialize an array of mutable byte references and sizes with references set to the + // appropriate pointer in `params`; as we iterate, we'll increment each pointer by its size + // (except for singletons, which get an increment of 0). + std::array, NVectorized> vecparams{{ + std::pair( + reinterpret_cast(params[VIndex] = buffers[BIndex].ptr), + buffers[BIndex].size == 1 ? 0 : sizeof(param_n_t) + )... + }}; + + for (size_t i = 0; i < size; ++i) { + out[i] = f(*reinterpret_cast *>(params[Index])...); + for (auto &x : vecparams) x.first += x.second; + } + } + + template + void apply_broadcast(std::array &buffers, + std::array ¶ms, + array_t &output_array, + index_sequence, index_sequence, index_sequence) { + + buffer_info output = output_array.request(); + multi_array_iterator input_iter(buffers, output.shape); + + for (array_iterator iter = array_begin(output), end = array_end(output); + iter != end; + ++iter, ++input_iter) { + PYBIND11_EXPAND_SIDE_EFFECTS(( + params[VIndex] = input_iter.template data() + )); + *iter = f(*reinterpret_cast *>(std::get(params))...); + } + } +}; + +template +vectorize_helper +vectorize_extractor(const Func &f, Return (*) (Args ...)) { + return detail::vectorize_helper(f); +} + +template struct handle_type_name> { + static constexpr auto name = _("numpy.ndarray[") + npy_format_descriptor::name + _("]"); +}; + +NAMESPACE_END(detail) + +// Vanilla pointer vectorizer: +template +detail::vectorize_helper +vectorize(Return (*f) (Args ...)) { + return detail::vectorize_helper(f); +} + +// lambda vectorizer: +template ::value, int> = 0> +auto vectorize(Func &&f) -> decltype( + detail::vectorize_extractor(std::forward(f), (detail::function_signature_t *) nullptr)) { + return detail::vectorize_extractor(std::forward(f), (detail::function_signature_t *) nullptr); +} + +// Vectorize a class method (non-const): +template ())), Return, Class *, Args...>> +Helper vectorize(Return (Class::*f)(Args...)) { + return Helper(std::mem_fn(f)); +} + +// Vectorize a class method (const): +template ())), Return, const Class *, Args...>> +Helper vectorize(Return (Class::*f)(Args...) const) { + return Helper(std::mem_fn(f)); +} + +NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif diff --git a/python/src/pybind11/operators.h b/python/src/pybind11/operators.h new file mode 100644 index 000000000..b3dd62c3b --- /dev/null +++ b/python/src/pybind11/operators.h @@ -0,0 +1,168 @@ +/* + pybind11/operator.h: Metatemplates for operator overloading + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" + +#if defined(__clang__) && !defined(__INTEL_COMPILER) +# pragma clang diagnostic ignored "-Wunsequenced" // multiple unsequenced modifications to 'self' (when using def(py::self OP Type())) +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant +#endif + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +/// Enumeration with all supported operator types +enum op_id : int { + op_add, op_sub, op_mul, op_div, op_mod, op_divmod, op_pow, op_lshift, + op_rshift, op_and, op_xor, op_or, op_neg, op_pos, op_abs, op_invert, + op_int, op_long, op_float, op_str, op_cmp, op_gt, op_ge, op_lt, op_le, + op_eq, op_ne, op_iadd, op_isub, op_imul, op_idiv, op_imod, op_ilshift, + op_irshift, op_iand, op_ixor, op_ior, op_complex, op_bool, op_nonzero, + op_repr, op_truediv, op_itruediv, op_hash +}; + +enum op_type : int { + op_l, /* base type on left */ + op_r, /* base type on right */ + op_u /* unary operator */ +}; + +struct self_t { }; +static const self_t self = self_t(); + +/// Type for an unused type slot +struct undefined_t { }; + +/// Don't warn about an unused variable +inline self_t __self() { return self; } + +/// base template of operator implementations +template struct op_impl { }; + +/// Operator implementation generator +template struct op_ { + template void execute(Class &cl, const Extra&... extra) const { + using Base = typename Class::type; + using L_type = conditional_t::value, Base, L>; + using R_type = conditional_t::value, Base, R>; + using op = op_impl; + cl.def(op::name(), &op::execute, is_operator(), extra...); + #if PY_MAJOR_VERSION < 3 + if (id == op_truediv || id == op_itruediv) + cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", + &op::execute, is_operator(), extra...); + #endif + } + template void execute_cast(Class &cl, const Extra&... extra) const { + using Base = typename Class::type; + using L_type = conditional_t::value, Base, L>; + using R_type = conditional_t::value, Base, R>; + using op = op_impl; + cl.def(op::name(), &op::execute_cast, is_operator(), extra...); + #if PY_MAJOR_VERSION < 3 + if (id == op_truediv || id == op_itruediv) + cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", + &op::execute, is_operator(), extra...); + #endif + } +}; + +#define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \ +template struct op_impl { \ + static char const* name() { return "__" #id "__"; } \ + static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \ + static B execute_cast(const L &l, const R &r) { return B(expr); } \ +}; \ +template struct op_impl { \ + static char const* name() { return "__" #rid "__"; } \ + static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \ + static B execute_cast(const R &r, const L &l) { return B(expr); } \ +}; \ +inline op_ op(const self_t &, const self_t &) { \ + return op_(); \ +} \ +template op_ op(const self_t &, const T &) { \ + return op_(); \ +} \ +template op_ op(const T &, const self_t &) { \ + return op_(); \ +} + +#define PYBIND11_INPLACE_OPERATOR(id, op, expr) \ +template struct op_impl { \ + static char const* name() { return "__" #id "__"; } \ + static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \ + static B execute_cast(L &l, const R &r) { return B(expr); } \ +}; \ +template op_ op(const self_t &, const T &) { \ + return op_(); \ +} + +#define PYBIND11_UNARY_OPERATOR(id, op, expr) \ +template struct op_impl { \ + static char const* name() { return "__" #id "__"; } \ + static auto execute(const L &l) -> decltype(expr) { return expr; } \ + static B execute_cast(const L &l) { return B(expr); } \ +}; \ +inline op_ op(const self_t &) { \ + return op_(); \ +} + +PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) +PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) +PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) +PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) +PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) +PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) +PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) +PYBIND11_BINARY_OPERATOR(and, rand, operator&, l & r) +PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r) +PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r) +PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r) +PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r) +PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r) +PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r) +PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r) +PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) +//PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r)) +PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) +PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) +PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) +PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r) +PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) +PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) +PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) +PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r) +PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r) +PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r) +PYBIND11_UNARY_OPERATOR(neg, operator-, -l) +PYBIND11_UNARY_OPERATOR(pos, operator+, +l) +PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l)) +PYBIND11_UNARY_OPERATOR(hash, hash, std::hash()(l)) +PYBIND11_UNARY_OPERATOR(invert, operator~, (~l)) +PYBIND11_UNARY_OPERATOR(bool, operator!, !!l) +PYBIND11_UNARY_OPERATOR(int, int_, (int) l) +PYBIND11_UNARY_OPERATOR(float, float_, (double) l) + +#undef PYBIND11_BINARY_OPERATOR +#undef PYBIND11_INPLACE_OPERATOR +#undef PYBIND11_UNARY_OPERATOR +NAMESPACE_END(detail) + +using detail::self; + +NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif diff --git a/python/src/pybind11/options.h b/python/src/pybind11/options.h new file mode 100644 index 000000000..cc1e1f6f0 --- /dev/null +++ b/python/src/pybind11/options.h @@ -0,0 +1,65 @@ +/* + pybind11/options.h: global settings that are configurable at runtime. + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "detail/common.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +class options { +public: + + // Default RAII constructor, which leaves settings as they currently are. + options() : previous_state(global_state()) {} + + // Class is non-copyable. + options(const options&) = delete; + options& operator=(const options&) = delete; + + // Destructor, which restores settings that were in effect before. + ~options() { + global_state() = previous_state; + } + + // Setter methods (affect the global state): + + options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; } + + options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; } + + options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; } + + options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; } + + // Getter methods (return the global state): + + static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; } + + static bool show_function_signatures() { return global_state().show_function_signatures; } + + // This type is not meant to be allocated on the heap. + void* operator new(size_t) = delete; + +private: + + struct state { + bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. + bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. + }; + + static state &global_state() { + static state instance; + return instance; + } + + state previous_state; +}; + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/pybind11.h b/python/src/pybind11/pybind11.h new file mode 100644 index 000000000..f1d91c788 --- /dev/null +++ b/python/src/pybind11/pybind11.h @@ -0,0 +1,2162 @@ +/* + pybind11/pybind11.h: Main header file of the C++11 python + binding generator library + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#if defined(__INTEL_COMPILER) +# pragma warning push +# pragma warning disable 68 // integer conversion resulted in a change of sign +# pragma warning disable 186 // pointless comparison of unsigned integer with zero +# pragma warning disable 878 // incompatible exception specifications +# pragma warning disable 1334 // the "template" keyword used for syntactic disambiguation may only be used within a template +# pragma warning disable 1682 // implicit conversion of a 64-bit integral type to a smaller integral type (potential portability problem) +# pragma warning disable 1786 // function "strdup" was declared deprecated +# pragma warning disable 1875 // offsetof applied to non-POD (Plain Old Data) types is nonstandard +# pragma warning disable 2196 // warning #2196: routine is both "inline" and "noinline" +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4100) // warning C4100: Unreferenced formal parameter +# pragma warning(disable: 4127) // warning C4127: Conditional expression is constant +# pragma warning(disable: 4512) // warning C4512: Assignment operator was implicitly defined as deleted +# pragma warning(disable: 4800) // warning C4800: 'int': forcing value to bool 'true' or 'false' (performance warning) +# pragma warning(disable: 4996) // warning C4996: The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name +# pragma warning(disable: 4702) // warning C4702: unreachable code +# pragma warning(disable: 4522) // warning C4522: multiple assignment operators specified +#elif defined(__GNUG__) && !defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-but-set-parameter" +# pragma GCC diagnostic ignored "-Wunused-but-set-variable" +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +# pragma GCC diagnostic ignored "-Wstrict-aliasing" +# pragma GCC diagnostic ignored "-Wattributes" +# if __GNUC__ >= 7 +# pragma GCC diagnostic ignored "-Wnoexcept-type" +# endif +#endif + +#if defined(__GNUG__) && !defined(__clang__) + #include +#endif + + +#include "attr.h" +#include "options.h" +#include "detail/class.h" +#include "detail/init.h" + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object +class cpp_function : public function { +public: + cpp_function() { } + cpp_function(std::nullptr_t) { } + + /// Construct a cpp_function from a vanilla function pointer + template + cpp_function(Return (*f)(Args...), const Extra&... extra) { + initialize(f, f, extra...); + } + + /// Construct a cpp_function from a lambda function (possibly with internal state) + template ::value>> + cpp_function(Func &&f, const Extra&... extra) { + initialize(std::forward(f), + (detail::function_signature_t *) nullptr, extra...); + } + + /// Construct a cpp_function from a class method (non-const) + template + cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) { + initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); }, + (Return (*) (Class *, Arg...)) nullptr, extra...); + } + + /// Construct a cpp_function from a class method (const) + template + cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) { + initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); }, + (Return (*)(const Class *, Arg ...)) nullptr, extra...); + } + + /// Return the function name + object name() const { return attr("__name__"); } + +protected: + /// Space optimization: don't inline this frequently instantiated fragment + PYBIND11_NOINLINE detail::function_record *make_function_record() { + return new detail::function_record(); + } + + /// Special internal constructor for functors, lambda functions, etc. + template + void initialize(Func &&f, Return (*)(Args...), const Extra&... extra) { + using namespace detail; + struct capture { remove_reference_t f; }; + + /* Store the function including any extra state it might have (e.g. a lambda capture object) */ + auto rec = make_function_record(); + + /* Store the capture object directly in the function record if there is enough space */ + if (sizeof(capture) <= sizeof(rec->data)) { + /* Without these pragmas, GCC warns that there might not be + enough space to use the placement new operator. However, the + 'if' statement above ensures that this is the case. */ +#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wplacement-new" +#endif + new ((capture *) &rec->data) capture { std::forward(f) }; +#if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 +# pragma GCC diagnostic pop +#endif + if (!std::is_trivially_destructible::value) + rec->free_data = [](function_record *r) { ((capture *) &r->data)->~capture(); }; + } else { + rec->data[0] = new capture { std::forward(f) }; + rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); }; + } + + /* Type casters for the function arguments and return value */ + using cast_in = argument_loader; + using cast_out = make_caster< + conditional_t::value, void_type, Return> + >; + + static_assert(expected_num_args(sizeof...(Args), cast_in::has_args, cast_in::has_kwargs), + "The number of argument annotations does not match the number of function arguments"); + + /* Dispatch code which converts function arguments and performs the actual function call */ + rec->impl = [](function_call &call) -> handle { + cast_in args_converter; + + /* Try to cast the function arguments into the C++ domain */ + if (!args_converter.load_args(call)) + return PYBIND11_TRY_NEXT_OVERLOAD; + + /* Invoke call policy pre-call hook */ + process_attributes::precall(call); + + /* Get a pointer to the capture object */ + auto data = (sizeof(capture) <= sizeof(call.func.data) + ? &call.func.data : call.func.data[0]); + capture *cap = const_cast(reinterpret_cast(data)); + + /* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */ + return_value_policy policy = return_value_policy_override::policy(call.func.policy); + + /* Function scope guard -- defaults to the compile-to-nothing `void_type` */ + using Guard = extract_guard_t; + + /* Perform the function call */ + handle result = cast_out::cast( + std::move(args_converter).template call(cap->f), policy, call.parent); + + /* Invoke call policy post-call hook */ + process_attributes::postcall(call, result); + + return result; + }; + + /* Process any user-provided function attributes */ + process_attributes::init(extra..., rec); + + /* Generate a readable signature describing the function's arguments and return value types */ + static constexpr auto signature = _("(") + cast_in::arg_names + _(") -> ") + cast_out::name; + PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types(); + + /* Register the function with Python from generic (non-templated) code */ + initialize_generic(rec, signature.text, types.data(), sizeof...(Args)); + + if (cast_in::has_args) rec->has_args = true; + if (cast_in::has_kwargs) rec->has_kwargs = true; + + /* Stash some additional information used by an important optimization in 'functional.h' */ + using FunctionType = Return (*)(Args...); + constexpr bool is_function_ptr = + std::is_convertible::value && + sizeof(capture) == sizeof(void *); + if (is_function_ptr) { + rec->is_stateless = true; + rec->data[1] = const_cast(reinterpret_cast(&typeid(FunctionType))); + } + } + + /// Register a function call with Python (generic non-templated code goes here) + void initialize_generic(detail::function_record *rec, const char *text, + const std::type_info *const *types, size_t args) { + + /* Create copies of all referenced C-style strings */ + rec->name = strdup(rec->name ? rec->name : ""); + if (rec->doc) rec->doc = strdup(rec->doc); + for (auto &a: rec->args) { + if (a.name) + a.name = strdup(a.name); + if (a.descr) + a.descr = strdup(a.descr); + else if (a.value) + a.descr = strdup(a.value.attr("__repr__")().cast().c_str()); + } + + rec->is_constructor = !strcmp(rec->name, "__init__") || !strcmp(rec->name, "__setstate__"); + +#if !defined(NDEBUG) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING) + if (rec->is_constructor && !rec->is_new_style_constructor) { + const auto class_name = std::string(((PyTypeObject *) rec->scope.ptr())->tp_name); + const auto func_name = std::string(rec->name); + PyErr_WarnEx( + PyExc_FutureWarning, + ("pybind11-bound class '" + class_name + "' is using an old-style " + "placement-new '" + func_name + "' which has been deprecated. See " + "the upgrade guide in pybind11's docs. This message is only visible " + "when compiled in debug mode.").c_str(), 0 + ); + } +#endif + + /* Generate a proper function signature */ + std::string signature; + size_t type_index = 0, arg_index = 0; + for (auto *pc = text; *pc != '\0'; ++pc) { + const auto c = *pc; + + if (c == '{') { + // Write arg name for everything except *args and **kwargs. + if (*(pc + 1) == '*') + continue; + + if (arg_index < rec->args.size() && rec->args[arg_index].name) { + signature += rec->args[arg_index].name; + } else if (arg_index == 0 && rec->is_method) { + signature += "self"; + } else { + signature += "arg" + std::to_string(arg_index - (rec->is_method ? 1 : 0)); + } + signature += ": "; + } else if (c == '}') { + // Write default value if available. + if (arg_index < rec->args.size() && rec->args[arg_index].descr) { + signature += " = "; + signature += rec->args[arg_index].descr; + } + arg_index++; + } else if (c == '%') { + const std::type_info *t = types[type_index++]; + if (!t) + pybind11_fail("Internal error while parsing type signature (1)"); + if (auto tinfo = detail::get_type_info(*t)) { + handle th((PyObject *) tinfo->type); + signature += + th.attr("__module__").cast() + "." + + th.attr("__qualname__").cast(); // Python 3.3+, but we backport it to earlier versions + } else if (rec->is_new_style_constructor && arg_index == 0) { + // A new-style `__init__` takes `self` as `value_and_holder`. + // Rewrite it to the proper class type. + signature += + rec->scope.attr("__module__").cast() + "." + + rec->scope.attr("__qualname__").cast(); + } else { + std::string tname(t->name()); + detail::clean_type_id(tname); + signature += tname; + } + } else { + signature += c; + } + } + if (arg_index != args || types[type_index] != nullptr) + pybind11_fail("Internal error while parsing type signature (2)"); + +#if PY_MAJOR_VERSION < 3 + if (strcmp(rec->name, "__next__") == 0) { + std::free(rec->name); + rec->name = strdup("next"); + } else if (strcmp(rec->name, "__bool__") == 0) { + std::free(rec->name); + rec->name = strdup("__nonzero__"); + } +#endif + rec->signature = strdup(signature.c_str()); + rec->args.shrink_to_fit(); + rec->nargs = (std::uint16_t) args; + + if (rec->sibling && PYBIND11_INSTANCE_METHOD_CHECK(rec->sibling.ptr())) + rec->sibling = PYBIND11_INSTANCE_METHOD_GET_FUNCTION(rec->sibling.ptr()); + + detail::function_record *chain = nullptr, *chain_start = rec; + if (rec->sibling) { + if (PyCFunction_Check(rec->sibling.ptr())) { + auto rec_capsule = reinterpret_borrow(PyCFunction_GET_SELF(rec->sibling.ptr())); + chain = (detail::function_record *) rec_capsule; + /* Never append a method to an overload chain of a parent class; + instead, hide the parent's overloads in this case */ + if (!chain->scope.is(rec->scope)) + chain = nullptr; + } + // Don't trigger for things like the default __init__, which are wrapper_descriptors that we are intentionally replacing + else if (!rec->sibling.is_none() && rec->name[0] != '_') + pybind11_fail("Cannot overload existing non-function object \"" + std::string(rec->name) + + "\" with a function of the same name"); + } + + if (!chain) { + /* No existing overload was found, create a new function object */ + rec->def = new PyMethodDef(); + std::memset(rec->def, 0, sizeof(PyMethodDef)); + rec->def->ml_name = rec->name; + rec->def->ml_meth = reinterpret_cast(reinterpret_cast(*dispatcher)); + rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS; + + capsule rec_capsule(rec, [](void *ptr) { + destruct((detail::function_record *) ptr); + }); + + object scope_module; + if (rec->scope) { + if (hasattr(rec->scope, "__module__")) { + scope_module = rec->scope.attr("__module__"); + } else if (hasattr(rec->scope, "__name__")) { + scope_module = rec->scope.attr("__name__"); + } + } + + m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr()); + if (!m_ptr) + pybind11_fail("cpp_function::cpp_function(): Could not allocate function object"); + } else { + /* Append at the end of the overload chain */ + m_ptr = rec->sibling.ptr(); + inc_ref(); + chain_start = chain; + if (chain->is_method != rec->is_method) + pybind11_fail("overloading a method with both static and instance methods is not supported; " + #if defined(NDEBUG) + "compile in debug mode for more details" + #else + "error while attempting to bind " + std::string(rec->is_method ? "instance" : "static") + " method " + + std::string(pybind11::str(rec->scope.attr("__name__"))) + "." + std::string(rec->name) + signature + #endif + ); + while (chain->next) + chain = chain->next; + chain->next = rec; + } + + std::string signatures; + int index = 0; + /* Create a nice pydoc rec including all signatures and + docstrings of the functions in the overload chain */ + if (chain && options::show_function_signatures()) { + // First a generic signature + signatures += rec->name; + signatures += "(*args, **kwargs)\n"; + signatures += "Overloaded function.\n\n"; + } + // Then specific overload signatures + bool first_user_def = true; + for (auto it = chain_start; it != nullptr; it = it->next) { + if (options::show_function_signatures()) { + if (index > 0) signatures += "\n"; + if (chain) + signatures += std::to_string(++index) + ". "; + signatures += rec->name; + signatures += it->signature; + signatures += "\n"; + } + if (it->doc && strlen(it->doc) > 0 && options::show_user_defined_docstrings()) { + // If we're appending another docstring, and aren't printing function signatures, we + // need to append a newline first: + if (!options::show_function_signatures()) { + if (first_user_def) first_user_def = false; + else signatures += "\n"; + } + if (options::show_function_signatures()) signatures += "\n"; + signatures += it->doc; + if (options::show_function_signatures()) signatures += "\n"; + } + } + + /* Install docstring */ + PyCFunctionObject *func = (PyCFunctionObject *) m_ptr; + if (func->m_ml->ml_doc) + std::free(const_cast(func->m_ml->ml_doc)); + func->m_ml->ml_doc = strdup(signatures.c_str()); + + if (rec->is_method) { + m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr()); + if (!m_ptr) + pybind11_fail("cpp_function::cpp_function(): Could not allocate instance method object"); + Py_DECREF(func); + } + } + + /// When a cpp_function is GCed, release any memory allocated by pybind11 + static void destruct(detail::function_record *rec) { + while (rec) { + detail::function_record *next = rec->next; + if (rec->free_data) + rec->free_data(rec); + std::free((char *) rec->name); + std::free((char *) rec->doc); + std::free((char *) rec->signature); + for (auto &arg: rec->args) { + std::free(const_cast(arg.name)); + std::free(const_cast(arg.descr)); + arg.value.dec_ref(); + } + if (rec->def) { + std::free(const_cast(rec->def->ml_doc)); + delete rec->def; + } + delete rec; + rec = next; + } + } + + /// Main dispatch logic for calls to functions bound using pybind11 + static PyObject *dispatcher(PyObject *self, PyObject *args_in, PyObject *kwargs_in) { + using namespace detail; + + /* Iterator over the list of potentially admissible overloads */ + const function_record *overloads = (function_record *) PyCapsule_GetPointer(self, nullptr), + *it = overloads; + + /* Need to know how many arguments + keyword arguments there are to pick the right overload */ + const size_t n_args_in = (size_t) PyTuple_GET_SIZE(args_in); + + handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr, + result = PYBIND11_TRY_NEXT_OVERLOAD; + + auto self_value_and_holder = value_and_holder(); + if (overloads->is_constructor) { + const auto tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr()); + const auto pi = reinterpret_cast(parent.ptr()); + self_value_and_holder = pi->get_value_and_holder(tinfo, false); + + if (!self_value_and_holder.type || !self_value_and_holder.inst) { + PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid `self` argument"); + return nullptr; + } + + // If this value is already registered it must mean __init__ is invoked multiple times; + // we really can't support that in C++, so just ignore the second __init__. + if (self_value_and_holder.instance_registered()) + return none().release().ptr(); + } + + try { + // We do this in two passes: in the first pass, we load arguments with `convert=false`; + // in the second, we allow conversion (except for arguments with an explicit + // py::arg().noconvert()). This lets us prefer calls without conversion, with + // conversion as a fallback. + std::vector second_pass; + + // However, if there are no overloads, we can just skip the no-convert pass entirely + const bool overloaded = it != nullptr && it->next != nullptr; + + for (; it != nullptr; it = it->next) { + + /* For each overload: + 1. Copy all positional arguments we were given, also checking to make sure that + named positional arguments weren't *also* specified via kwarg. + 2. If we weren't given enough, try to make up the omitted ones by checking + whether they were provided by a kwarg matching the `py::arg("name")` name. If + so, use it (and remove it from kwargs; if not, see if the function binding + provided a default that we can use. + 3. Ensure that either all keyword arguments were "consumed", or that the function + takes a kwargs argument to accept unconsumed kwargs. + 4. Any positional arguments still left get put into a tuple (for args), and any + leftover kwargs get put into a dict. + 5. Pack everything into a vector; if we have py::args or py::kwargs, they are an + extra tuple or dict at the end of the positional arguments. + 6. Call the function call dispatcher (function_record::impl) + + If one of these fail, move on to the next overload and keep trying until we get a + result other than PYBIND11_TRY_NEXT_OVERLOAD. + */ + + const function_record &func = *it; + size_t pos_args = func.nargs; // Number of positional arguments that we need + if (func.has_args) --pos_args; // (but don't count py::args + if (func.has_kwargs) --pos_args; // or py::kwargs) + + if (!func.has_args && n_args_in > pos_args) + continue; // Too many arguments for this overload + + if (n_args_in < pos_args && func.args.size() < pos_args) + continue; // Not enough arguments given, and not enough defaults to fill in the blanks + + function_call call(func, parent); + + size_t args_to_copy = std::min(pos_args, n_args_in); + size_t args_copied = 0; + + // 0. Inject new-style `self` argument + if (func.is_new_style_constructor) { + // The `value` may have been preallocated by an old-style `__init__` + // if it was a preceding candidate for overload resolution. + if (self_value_and_holder) + self_value_and_holder.type->dealloc(self_value_and_holder); + + call.init_self = PyTuple_GET_ITEM(args_in, 0); + call.args.push_back(reinterpret_cast(&self_value_and_holder)); + call.args_convert.push_back(false); + ++args_copied; + } + + // 1. Copy any position arguments given. + bool bad_arg = false; + for (; args_copied < args_to_copy; ++args_copied) { + const argument_record *arg_rec = args_copied < func.args.size() ? &func.args[args_copied] : nullptr; + if (kwargs_in && arg_rec && arg_rec->name && PyDict_GetItemString(kwargs_in, arg_rec->name)) { + bad_arg = true; + break; + } + + handle arg(PyTuple_GET_ITEM(args_in, args_copied)); + if (arg_rec && !arg_rec->none && arg.is_none()) { + bad_arg = true; + break; + } + call.args.push_back(arg); + call.args_convert.push_back(arg_rec ? arg_rec->convert : true); + } + if (bad_arg) + continue; // Maybe it was meant for another overload (issue #688) + + // We'll need to copy this if we steal some kwargs for defaults + dict kwargs = reinterpret_borrow(kwargs_in); + + // 2. Check kwargs and, failing that, defaults that may help complete the list + if (args_copied < pos_args) { + bool copied_kwargs = false; + + for (; args_copied < pos_args; ++args_copied) { + const auto &arg = func.args[args_copied]; + + handle value; + if (kwargs_in && arg.name) + value = PyDict_GetItemString(kwargs.ptr(), arg.name); + + if (value) { + // Consume a kwargs value + if (!copied_kwargs) { + kwargs = reinterpret_steal(PyDict_Copy(kwargs.ptr())); + copied_kwargs = true; + } + PyDict_DelItemString(kwargs.ptr(), arg.name); + } else if (arg.value) { + value = arg.value; + } + + if (value) { + call.args.push_back(value); + call.args_convert.push_back(arg.convert); + } + else + break; + } + + if (args_copied < pos_args) + continue; // Not enough arguments, defaults, or kwargs to fill the positional arguments + } + + // 3. Check everything was consumed (unless we have a kwargs arg) + if (kwargs && kwargs.size() > 0 && !func.has_kwargs) + continue; // Unconsumed kwargs, but no py::kwargs argument to accept them + + // 4a. If we have a py::args argument, create a new tuple with leftovers + if (func.has_args) { + tuple extra_args; + if (args_to_copy == 0) { + // We didn't copy out any position arguments from the args_in tuple, so we + // can reuse it directly without copying: + extra_args = reinterpret_borrow(args_in); + } else if (args_copied >= n_args_in) { + extra_args = tuple(0); + } else { + size_t args_size = n_args_in - args_copied; + extra_args = tuple(args_size); + for (size_t i = 0; i < args_size; ++i) { + extra_args[i] = PyTuple_GET_ITEM(args_in, args_copied + i); + } + } + call.args.push_back(extra_args); + call.args_convert.push_back(false); + call.args_ref = std::move(extra_args); + } + + // 4b. If we have a py::kwargs, pass on any remaining kwargs + if (func.has_kwargs) { + if (!kwargs.ptr()) + kwargs = dict(); // If we didn't get one, send an empty one + call.args.push_back(kwargs); + call.args_convert.push_back(false); + call.kwargs_ref = std::move(kwargs); + } + + // 5. Put everything in a vector. Not technically step 5, we've been building it + // in `call.args` all along. + #if !defined(NDEBUG) + if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) + pybind11_fail("Internal error: function call dispatcher inserted wrong number of arguments!"); + #endif + + std::vector second_pass_convert; + if (overloaded) { + // We're in the first no-convert pass, so swap out the conversion flags for a + // set of all-false flags. If the call fails, we'll swap the flags back in for + // the conversion-allowed call below. + second_pass_convert.resize(func.nargs, false); + call.args_convert.swap(second_pass_convert); + } + + // 6. Call the function. + try { + loader_life_support guard{}; + result = func.impl(call); + } catch (reference_cast_error &) { + result = PYBIND11_TRY_NEXT_OVERLOAD; + } + + if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) + break; + + if (overloaded) { + // The (overloaded) call failed; if the call has at least one argument that + // permits conversion (i.e. it hasn't been explicitly specified `.noconvert()`) + // then add this call to the list of second pass overloads to try. + for (size_t i = func.is_method ? 1 : 0; i < pos_args; i++) { + if (second_pass_convert[i]) { + // Found one: swap the converting flags back in and store the call for + // the second pass. + call.args_convert.swap(second_pass_convert); + second_pass.push_back(std::move(call)); + break; + } + } + } + } + + if (overloaded && !second_pass.empty() && result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) { + // The no-conversion pass finished without success, try again with conversion allowed + for (auto &call : second_pass) { + try { + loader_life_support guard{}; + result = call.func.impl(call); + } catch (reference_cast_error &) { + result = PYBIND11_TRY_NEXT_OVERLOAD; + } + + if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) { + // The error reporting logic below expects 'it' to be valid, as it would be + // if we'd encountered this failure in the first-pass loop. + if (!result) + it = &call.func; + break; + } + } + } + } catch (error_already_set &e) { + e.restore(); + return nullptr; +#if defined(__GNUG__) && !defined(__clang__) + } catch ( abi::__forced_unwind& ) { + throw; +#endif + } catch (...) { + /* When an exception is caught, give each registered exception + translator a chance to translate it to a Python exception + in reverse order of registration. + + A translator may choose to do one of the following: + + - catch the exception and call PyErr_SetString or PyErr_SetObject + to set a standard (or custom) Python exception, or + - do nothing and let the exception fall through to the next translator, or + - delegate translation to the next translator by throwing a new type of exception. */ + + auto last_exception = std::current_exception(); + auto ®istered_exception_translators = get_internals().registered_exception_translators; + for (auto& translator : registered_exception_translators) { + try { + translator(last_exception); + } catch (...) { + last_exception = std::current_exception(); + continue; + } + return nullptr; + } + PyErr_SetString(PyExc_SystemError, "Exception escaped from default exception translator!"); + return nullptr; + } + + auto append_note_if_missing_header_is_suspected = [](std::string &msg) { + if (msg.find("std::") != std::string::npos) { + msg += "\n\n" + "Did you forget to `#include `? Or ,\n" + ", , etc. Some automatic\n" + "conversions are optional and require extra headers to be included\n" + "when compiling your pybind11 module."; + } + }; + + if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) { + if (overloads->is_operator) + return handle(Py_NotImplemented).inc_ref().ptr(); + + std::string msg = std::string(overloads->name) + "(): incompatible " + + std::string(overloads->is_constructor ? "constructor" : "function") + + " arguments. The following argument types are supported:\n"; + + int ctr = 0; + for (const function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) { + msg += " "+ std::to_string(++ctr) + ". "; + + bool wrote_sig = false; + if (overloads->is_constructor) { + // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as `Object(arg0, ...)` + std::string sig = it2->signature; + size_t start = sig.find('(') + 7; // skip "(self: " + if (start < sig.size()) { + // End at the , for the next argument + size_t end = sig.find(", "), next = end + 2; + size_t ret = sig.rfind(" -> "); + // Or the ), if there is no comma: + if (end >= sig.size()) next = end = sig.find(')'); + if (start < end && next < sig.size()) { + msg.append(sig, start, end - start); + msg += '('; + msg.append(sig, next, ret - next); + wrote_sig = true; + } + } + } + if (!wrote_sig) msg += it2->signature; + + msg += "\n"; + } + msg += "\nInvoked with: "; + auto args_ = reinterpret_borrow(args_in); + bool some_args = false; + for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) { + if (!some_args) some_args = true; + else msg += ", "; + msg += pybind11::repr(args_[ti]); + } + if (kwargs_in) { + auto kwargs = reinterpret_borrow(kwargs_in); + if (kwargs.size() > 0) { + if (some_args) msg += "; "; + msg += "kwargs: "; + bool first = true; + for (auto kwarg : kwargs) { + if (first) first = false; + else msg += ", "; + msg += pybind11::str("{}={!r}").format(kwarg.first, kwarg.second); + } + } + } + + append_note_if_missing_header_is_suspected(msg); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return nullptr; + } else if (!result) { + std::string msg = "Unable to convert function return value to a " + "Python type! The signature was\n\t"; + msg += it->signature; + append_note_if_missing_header_is_suspected(msg); + PyErr_SetString(PyExc_TypeError, msg.c_str()); + return nullptr; + } else { + if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) { + auto *pi = reinterpret_cast(parent.ptr()); + self_value_and_holder.type->init_instance(pi, nullptr); + } + return result.ptr(); + } + } +}; + +/// Wrapper for Python extension modules +class module : public object { +public: + PYBIND11_OBJECT_DEFAULT(module, object, PyModule_Check) + + /// Create a new top-level Python module with the given name and docstring + explicit module(const char *name, const char *doc = nullptr) { + if (!options::show_user_defined_docstrings()) doc = nullptr; +#if PY_MAJOR_VERSION >= 3 + PyModuleDef *def = new PyModuleDef(); + std::memset(def, 0, sizeof(PyModuleDef)); + def->m_name = name; + def->m_doc = doc; + def->m_size = -1; + Py_INCREF(def); + m_ptr = PyModule_Create(def); +#else + m_ptr = Py_InitModule3(name, nullptr, doc); +#endif + if (m_ptr == nullptr) + pybind11_fail("Internal error in module::module()"); + inc_ref(); + } + + /** \rst + Create Python binding for a new function within the module scope. ``Func`` + can be a plain C++ function, a function pointer, or a lambda function. For + details on the ``Extra&& ... extra`` argument, see section :ref:`extras`. + \endrst */ + template + module &def(const char *name_, Func &&f, const Extra& ... extra) { + cpp_function func(std::forward(f), name(name_), scope(*this), + sibling(getattr(*this, name_, none())), extra...); + // NB: allow overwriting here because cpp_function sets up a chain with the intention of + // overwriting (and has already checked internally that it isn't overwriting non-functions). + add_object(name_, func, true /* overwrite */); + return *this; + } + + /** \rst + Create and return a new Python submodule with the given name and docstring. + This also works recursively, i.e. + + .. code-block:: cpp + + py::module m("example", "pybind11 example plugin"); + py::module m2 = m.def_submodule("sub", "A submodule of 'example'"); + py::module m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'"); + \endrst */ + module def_submodule(const char *name, const char *doc = nullptr) { + std::string full_name = std::string(PyModule_GetName(m_ptr)) + + std::string(".") + std::string(name); + auto result = reinterpret_borrow(PyImport_AddModule(full_name.c_str())); + if (doc && options::show_user_defined_docstrings()) + result.attr("__doc__") = pybind11::str(doc); + attr(name) = result; + return result; + } + + /// Import and return a module or throws `error_already_set`. + static module import(const char *name) { + PyObject *obj = PyImport_ImportModule(name); + if (!obj) + throw error_already_set(); + return reinterpret_steal(obj); + } + + /// Reload the module or throws `error_already_set`. + void reload() { + PyObject *obj = PyImport_ReloadModule(ptr()); + if (!obj) + throw error_already_set(); + *this = reinterpret_steal(obj); + } + + // Adds an object to the module using the given name. Throws if an object with the given name + // already exists. + // + // overwrite should almost always be false: attempting to overwrite objects that pybind11 has + // established will, in most cases, break things. + PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) { + if (!overwrite && hasattr(*this, name)) + pybind11_fail("Error during initialization: multiple incompatible definitions with name \"" + + std::string(name) + "\""); + + PyModule_AddObject(ptr(), name, obj.inc_ref().ptr() /* steals a reference */); + } +}; + +/// \ingroup python_builtins +/// Return a dictionary representing the global variables in the current execution frame, +/// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded). +inline dict globals() { + PyObject *p = PyEval_GetGlobals(); + return reinterpret_borrow(p ? p : module::import("__main__").attr("__dict__").ptr()); +} + +NAMESPACE_BEGIN(detail) +/// Generic support for creating new Python heap types +class generic_type : public object { + template friend class class_; +public: + PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check) +protected: + void initialize(const type_record &rec) { + if (rec.scope && hasattr(rec.scope, rec.name)) + pybind11_fail("generic_type: cannot initialize type \"" + std::string(rec.name) + + "\": an object with that name is already defined"); + + if (rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type)) + pybind11_fail("generic_type: type \"" + std::string(rec.name) + + "\" is already registered!"); + + m_ptr = make_new_python_type(rec); + + /* Register supplemental type information in C++ dict */ + auto *tinfo = new detail::type_info(); + tinfo->type = (PyTypeObject *) m_ptr; + tinfo->cpptype = rec.type; + tinfo->type_size = rec.type_size; + tinfo->type_align = rec.type_align; + tinfo->operator_new = rec.operator_new; + tinfo->holder_size_in_ptrs = size_in_ptrs(rec.holder_size); + tinfo->init_instance = rec.init_instance; + tinfo->dealloc = rec.dealloc; + tinfo->simple_type = true; + tinfo->simple_ancestors = true; + tinfo->default_holder = rec.default_holder; + tinfo->module_local = rec.module_local; + + auto &internals = get_internals(); + auto tindex = std::type_index(*rec.type); + tinfo->direct_conversions = &internals.direct_conversions[tindex]; + if (rec.module_local) + registered_local_types_cpp()[tindex] = tinfo; + else + internals.registered_types_cpp[tindex] = tinfo; + internals.registered_types_py[(PyTypeObject *) m_ptr] = { tinfo }; + + if (rec.bases.size() > 1 || rec.multiple_inheritance) { + mark_parents_nonsimple(tinfo->type); + tinfo->simple_ancestors = false; + } + else if (rec.bases.size() == 1) { + auto parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr()); + tinfo->simple_ancestors = parent_tinfo->simple_ancestors; + } + + if (rec.module_local) { + // Stash the local typeinfo and loader so that external modules can access it. + tinfo->module_local_load = &type_caster_generic::local_load; + setattr(m_ptr, PYBIND11_MODULE_LOCAL_ID, capsule(tinfo)); + } + } + + /// Helper function which tags all parents of a type using mult. inheritance + void mark_parents_nonsimple(PyTypeObject *value) { + auto t = reinterpret_borrow(value->tp_bases); + for (handle h : t) { + auto tinfo2 = get_type_info((PyTypeObject *) h.ptr()); + if (tinfo2) + tinfo2->simple_type = false; + mark_parents_nonsimple((PyTypeObject *) h.ptr()); + } + } + + void install_buffer_funcs( + buffer_info *(*get_buffer)(PyObject *, void *), + void *get_buffer_data) { + PyHeapTypeObject *type = (PyHeapTypeObject*) m_ptr; + auto tinfo = detail::get_type_info(&type->ht_type); + + if (!type->ht_type.tp_as_buffer) + pybind11_fail( + "To be able to register buffer protocol support for the type '" + + std::string(tinfo->type->tp_name) + + "' the associated class<>(..) invocation must " + "include the pybind11::buffer_protocol() annotation!"); + + tinfo->get_buffer = get_buffer; + tinfo->get_buffer_data = get_buffer_data; + } + + // rec_func must be set for either fget or fset. + void def_property_static_impl(const char *name, + handle fget, handle fset, + detail::function_record *rec_func) { + const auto is_static = rec_func && !(rec_func->is_method && rec_func->scope); + const auto has_doc = rec_func && rec_func->doc && pybind11::options::show_user_defined_docstrings(); + auto property = handle((PyObject *) (is_static ? get_internals().static_property_type + : &PyProperty_Type)); + attr(name) = property(fget.ptr() ? fget : none(), + fset.ptr() ? fset : none(), + /*deleter*/none(), + pybind11::str(has_doc ? rec_func->doc : "")); + } +}; + +/// Set the pointer to operator new if it exists. The cast is needed because it can be overloaded. +template (T::operator new))>> +void set_operator_new(type_record *r) { r->operator_new = &T::operator new; } + +template void set_operator_new(...) { } + +template struct has_operator_delete : std::false_type { }; +template struct has_operator_delete(T::operator delete))>> + : std::true_type { }; +template struct has_operator_delete_size : std::false_type { }; +template struct has_operator_delete_size(T::operator delete))>> + : std::true_type { }; +/// Call class-specific delete if it exists or global otherwise. Can also be an overload set. +template ::value, int> = 0> +void call_operator_delete(T *p, size_t, size_t) { T::operator delete(p); } +template ::value && has_operator_delete_size::value, int> = 0> +void call_operator_delete(T *p, size_t s, size_t) { T::operator delete(p, s); } + +inline void call_operator_delete(void *p, size_t s, size_t a) { + (void)s; (void)a; +#if defined(PYBIND11_CPP17) + if (a > __STDCPP_DEFAULT_NEW_ALIGNMENT__) + ::operator delete(p, s, std::align_val_t(a)); + else + ::operator delete(p, s); +#else + ::operator delete(p); +#endif +} + +NAMESPACE_END(detail) + +/// Given a pointer to a member function, cast it to its `Derived` version. +/// Forward everything else unchanged. +template +auto method_adaptor(F &&f) -> decltype(std::forward(f)) { return std::forward(f); } + +template +auto method_adaptor(Return (Class::*pmf)(Args...)) -> Return (Derived::*)(Args...) { + static_assert(detail::is_accessible_base_of::value, + "Cannot bind an inaccessible base class method; use a lambda definition instead"); + return pmf; +} + +template +auto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(Args...) const { + static_assert(detail::is_accessible_base_of::value, + "Cannot bind an inaccessible base class method; use a lambda definition instead"); + return pmf; +} + +template +class class_ : public detail::generic_type { + template using is_holder = detail::is_holder_type; + template using is_subtype = detail::is_strict_base_of; + template using is_base = detail::is_strict_base_of; + // struct instead of using here to help MSVC: + template struct is_valid_class_option : + detail::any_of, is_subtype, is_base> {}; + +public: + using type = type_; + using type_alias = detail::exactly_one_t; + constexpr static bool has_alias = !std::is_void::value; + using holder_type = detail::exactly_one_t, options...>; + + static_assert(detail::all_of...>::value, + "Unknown/invalid class_ template parameters provided"); + + static_assert(!has_alias || std::is_polymorphic::value, + "Cannot use an alias class with a non-polymorphic type"); + + PYBIND11_OBJECT(class_, generic_type, PyType_Check) + + template + class_(handle scope, const char *name, const Extra &... extra) { + using namespace detail; + + // MI can only be specified via class_ template options, not constructor parameters + static_assert( + none_of...>::value || // no base class arguments, or: + ( constexpr_sum(is_pyobject::value...) == 1 && // Exactly one base + constexpr_sum(is_base::value...) == 0 && // no template option bases + none_of...>::value), // no multiple_inheritance attr + "Error: multiple inheritance bases must be specified via class_ template options"); + + type_record record; + record.scope = scope; + record.name = name; + record.type = &typeid(type); + record.type_size = sizeof(conditional_t); + record.type_align = alignof(conditional_t&); + record.holder_size = sizeof(holder_type); + record.init_instance = init_instance; + record.dealloc = dealloc; + record.default_holder = detail::is_instantiation::value; + + set_operator_new(&record); + + /* Register base classes specified via template arguments to class_, if any */ + PYBIND11_EXPAND_SIDE_EFFECTS(add_base(record)); + + /* Process optional arguments, if any */ + process_attributes::init(extra..., &record); + + generic_type::initialize(record); + + if (has_alias) { + auto &instances = record.module_local ? registered_local_types_cpp() : get_internals().registered_types_cpp; + instances[std::type_index(typeid(type_alias))] = instances[std::type_index(typeid(type))]; + } + } + + template ::value, int> = 0> + static void add_base(detail::type_record &rec) { + rec.add_base(typeid(Base), [](void *src) -> void * { + return static_cast(reinterpret_cast(src)); + }); + } + + template ::value, int> = 0> + static void add_base(detail::type_record &) { } + + template + class_ &def(const char *name_, Func&& f, const Extra&... extra) { + cpp_function cf(method_adaptor(std::forward(f)), name(name_), is_method(*this), + sibling(getattr(*this, name_, none())), extra...); + attr(cf.name()) = cf; + return *this; + } + + template class_ & + def_static(const char *name_, Func &&f, const Extra&... extra) { + static_assert(!std::is_member_function_pointer::value, + "def_static(...) called with a non-static member function pointer"); + cpp_function cf(std::forward(f), name(name_), scope(*this), + sibling(getattr(*this, name_, none())), extra...); + attr(cf.name()) = staticmethod(cf); + return *this; + } + + template + class_ &def(const detail::op_ &op, const Extra&... extra) { + op.execute(*this, extra...); + return *this; + } + + template + class_ & def_cast(const detail::op_ &op, const Extra&... extra) { + op.execute_cast(*this, extra...); + return *this; + } + + template + class_ &def(const detail::initimpl::constructor &init, const Extra&... extra) { + init.execute(*this, extra...); + return *this; + } + + template + class_ &def(const detail::initimpl::alias_constructor &init, const Extra&... extra) { + init.execute(*this, extra...); + return *this; + } + + template + class_ &def(detail::initimpl::factory &&init, const Extra&... extra) { + std::move(init).execute(*this, extra...); + return *this; + } + + template + class_ &def(detail::initimpl::pickle_factory &&pf, const Extra &...extra) { + std::move(pf).execute(*this, extra...); + return *this; + } + + template class_& def_buffer(Func &&func) { + struct capture { Func func; }; + capture *ptr = new capture { std::forward(func) }; + install_buffer_funcs([](PyObject *obj, void *ptr) -> buffer_info* { + detail::make_caster caster; + if (!caster.load(obj, false)) + return nullptr; + return new buffer_info(((capture *) ptr)->func(caster)); + }, ptr); + return *this; + } + + template + class_ &def_buffer(Return (Class::*func)(Args...)) { + return def_buffer([func] (type &obj) { return (obj.*func)(); }); + } + + template + class_ &def_buffer(Return (Class::*func)(Args...) const) { + return def_buffer([func] (const type &obj) { return (obj.*func)(); }); + } + + template + class_ &def_readwrite(const char *name, D C::*pm, const Extra&... extra) { + static_assert(std::is_same::value || std::is_base_of::value, "def_readwrite() requires a class member (or base class member)"); + cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this)), + fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this)); + def_property(name, fget, fset, return_value_policy::reference_internal, extra...); + return *this; + } + + template + class_ &def_readonly(const char *name, const D C::*pm, const Extra& ...extra) { + static_assert(std::is_same::value || std::is_base_of::value, "def_readonly() requires a class member (or base class member)"); + cpp_function fget([pm](const type &c) -> const D &{ return c.*pm; }, is_method(*this)); + def_property_readonly(name, fget, return_value_policy::reference_internal, extra...); + return *this; + } + + template + class_ &def_readwrite_static(const char *name, D *pm, const Extra& ...extra) { + cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)), + fset([pm](object, const D &value) { *pm = value; }, scope(*this)); + def_property_static(name, fget, fset, return_value_policy::reference, extra...); + return *this; + } + + template + class_ &def_readonly_static(const char *name, const D *pm, const Extra& ...extra) { + cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)); + def_property_readonly_static(name, fget, return_value_policy::reference, extra...); + return *this; + } + + /// Uses return_value_policy::reference_internal by default + template + class_ &def_property_readonly(const char *name, const Getter &fget, const Extra& ...extra) { + return def_property_readonly(name, cpp_function(method_adaptor(fget)), + return_value_policy::reference_internal, extra...); + } + + /// Uses cpp_function's return_value_policy by default + template + class_ &def_property_readonly(const char *name, const cpp_function &fget, const Extra& ...extra) { + return def_property(name, fget, nullptr, extra...); + } + + /// Uses return_value_policy::reference by default + template + class_ &def_property_readonly_static(const char *name, const Getter &fget, const Extra& ...extra) { + return def_property_readonly_static(name, cpp_function(fget), return_value_policy::reference, extra...); + } + + /// Uses cpp_function's return_value_policy by default + template + class_ &def_property_readonly_static(const char *name, const cpp_function &fget, const Extra& ...extra) { + return def_property_static(name, fget, nullptr, extra...); + } + + /// Uses return_value_policy::reference_internal by default + template + class_ &def_property(const char *name, const Getter &fget, const Setter &fset, const Extra& ...extra) { + return def_property(name, fget, cpp_function(method_adaptor(fset)), extra...); + } + template + class_ &def_property(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { + return def_property(name, cpp_function(method_adaptor(fget)), fset, + return_value_policy::reference_internal, extra...); + } + + /// Uses cpp_function's return_value_policy by default + template + class_ &def_property(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { + return def_property_static(name, fget, fset, is_method(*this), extra...); + } + + /// Uses return_value_policy::reference by default + template + class_ &def_property_static(const char *name, const Getter &fget, const cpp_function &fset, const Extra& ...extra) { + return def_property_static(name, cpp_function(fget), fset, return_value_policy::reference, extra...); + } + + /// Uses cpp_function's return_value_policy by default + template + class_ &def_property_static(const char *name, const cpp_function &fget, const cpp_function &fset, const Extra& ...extra) { + static_assert( 0 == detail::constexpr_sum(std::is_base_of::value...), + "Argument annotations are not allowed for properties"); + auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset); + auto *rec_active = rec_fget; + if (rec_fget) { + char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific documentation string */ + detail::process_attributes::init(extra..., rec_fget); + if (rec_fget->doc && rec_fget->doc != doc_prev) { + free(doc_prev); + rec_fget->doc = strdup(rec_fget->doc); + } + } + if (rec_fset) { + char *doc_prev = rec_fset->doc; + detail::process_attributes::init(extra..., rec_fset); + if (rec_fset->doc && rec_fset->doc != doc_prev) { + free(doc_prev); + rec_fset->doc = strdup(rec_fset->doc); + } + if (! rec_active) rec_active = rec_fset; + } + def_property_static_impl(name, fget, fset, rec_active); + return *this; + } + +private: + /// Initialize holder object, variant 1: object derives from enable_shared_from_this + template + static void init_holder(detail::instance *inst, detail::value_and_holder &v_h, + const holder_type * /* unused */, const std::enable_shared_from_this * /* dummy */) { + try { + auto sh = std::dynamic_pointer_cast( + v_h.value_ptr()->shared_from_this()); + if (sh) { + new (std::addressof(v_h.holder())) holder_type(std::move(sh)); + v_h.set_holder_constructed(); + } + } catch (const std::bad_weak_ptr &) {} + + if (!v_h.holder_constructed() && inst->owned) { + new (std::addressof(v_h.holder())) holder_type(v_h.value_ptr()); + v_h.set_holder_constructed(); + } + } + + static void init_holder_from_existing(const detail::value_and_holder &v_h, + const holder_type *holder_ptr, std::true_type /*is_copy_constructible*/) { + new (std::addressof(v_h.holder())) holder_type(*reinterpret_cast(holder_ptr)); + } + + static void init_holder_from_existing(const detail::value_and_holder &v_h, + const holder_type *holder_ptr, std::false_type /*is_copy_constructible*/) { + new (std::addressof(v_h.holder())) holder_type(std::move(*const_cast(holder_ptr))); + } + + /// Initialize holder object, variant 2: try to construct from existing holder object, if possible + static void init_holder(detail::instance *inst, detail::value_and_holder &v_h, + const holder_type *holder_ptr, const void * /* dummy -- not enable_shared_from_this) */) { + if (holder_ptr) { + init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible()); + v_h.set_holder_constructed(); + } else if (inst->owned || detail::always_construct_holder::value) { + new (std::addressof(v_h.holder())) holder_type(v_h.value_ptr()); + v_h.set_holder_constructed(); + } + } + + /// Performs instance initialization including constructing a holder and registering the known + /// instance. Should be called as soon as the `type` value_ptr is set for an instance. Takes an + /// optional pointer to an existing holder to use; if not specified and the instance is + /// `.owned`, a new holder will be constructed to manage the value pointer. + static void init_instance(detail::instance *inst, const void *holder_ptr) { + auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type))); + if (!v_h.instance_registered()) { + register_instance(inst, v_h.value_ptr(), v_h.type); + v_h.set_instance_registered(); + } + init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr()); + } + + /// Deallocates an instance; via holder, if constructed; otherwise via operator delete. + static void dealloc(detail::value_and_holder &v_h) { + if (v_h.holder_constructed()) { + v_h.holder().~holder_type(); + v_h.set_holder_constructed(false); + } + else { + detail::call_operator_delete(v_h.value_ptr(), + v_h.type->type_size, + v_h.type->type_align + ); + } + v_h.value_ptr() = nullptr; + } + + static detail::function_record *get_function_record(handle h) { + h = detail::get_function(h); + return h ? (detail::function_record *) reinterpret_borrow(PyCFunction_GET_SELF(h.ptr())) + : nullptr; + } +}; + +/// Binds an existing constructor taking arguments Args... +template detail::initimpl::constructor init() { return {}; } +/// Like `init()`, but the instance is always constructed through the alias class (even +/// when not inheriting on the Python side). +template detail::initimpl::alias_constructor init_alias() { return {}; } + +/// Binds a factory function as a constructor +template > +Ret init(Func &&f) { return {std::forward(f)}; } + +/// Dual-argument factory function: the first function is called when no alias is needed, the second +/// when an alias is needed (i.e. due to python-side inheritance). Arguments must be identical. +template > +Ret init(CFunc &&c, AFunc &&a) { + return {std::forward(c), std::forward(a)}; +} + +/// Binds pickling functions `__getstate__` and `__setstate__` and ensures that the type +/// returned by `__getstate__` is the same as the argument accepted by `__setstate__`. +template +detail::initimpl::pickle_factory pickle(GetState &&g, SetState &&s) { + return {std::forward(g), std::forward(s)}; +} + +NAMESPACE_BEGIN(detail) +struct enum_base { + enum_base(handle base, handle parent) : m_base(base), m_parent(parent) { } + + PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) { + m_base.attr("__entries") = dict(); + auto property = handle((PyObject *) &PyProperty_Type); + auto static_property = handle((PyObject *) get_internals().static_property_type); + + m_base.attr("__repr__") = cpp_function( + [](handle arg) -> str { + handle type = arg.get_type(); + object type_name = type.attr("__name__"); + dict entries = type.attr("__entries"); + for (const auto &kv : entries) { + object other = kv.second[int_(0)]; + if (other.equal(arg)) + return pybind11::str("{}.{}").format(type_name, kv.first); + } + return pybind11::str("{}.???").format(type_name); + }, is_method(m_base) + ); + + m_base.attr("name") = property(cpp_function( + [](handle arg) -> str { + dict entries = arg.get_type().attr("__entries"); + for (const auto &kv : entries) { + if (handle(kv.second[int_(0)]).equal(arg)) + return pybind11::str(kv.first); + } + return "???"; + }, is_method(m_base) + )); + + m_base.attr("__doc__") = static_property(cpp_function( + [](handle arg) -> std::string { + std::string docstring; + dict entries = arg.attr("__entries"); + if (((PyTypeObject *) arg.ptr())->tp_doc) + docstring += std::string(((PyTypeObject *) arg.ptr())->tp_doc) + "\n\n"; + docstring += "Members:"; + for (const auto &kv : entries) { + auto key = std::string(pybind11::str(kv.first)); + auto comment = kv.second[int_(1)]; + docstring += "\n\n " + key; + if (!comment.is_none()) + docstring += " : " + (std::string) pybind11::str(comment); + } + return docstring; + } + ), none(), none(), ""); + + m_base.attr("__members__") = static_property(cpp_function( + [](handle arg) -> dict { + dict entries = arg.attr("__entries"), m; + for (const auto &kv : entries) + m[kv.first] = kv.second[int_(0)]; + return m; + }), none(), none(), "" + ); + + #define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior) \ + m_base.attr(op) = cpp_function( \ + [](object a, object b) { \ + if (!a.get_type().is(b.get_type())) \ + strict_behavior; \ + return expr; \ + }, \ + is_method(m_base)) + + #define PYBIND11_ENUM_OP_CONV(op, expr) \ + m_base.attr(op) = cpp_function( \ + [](object a_, object b_) { \ + int_ a(a_), b(b_); \ + return expr; \ + }, \ + is_method(m_base)) + + if (is_convertible) { + PYBIND11_ENUM_OP_CONV("__eq__", !b.is_none() && a.equal(b)); + PYBIND11_ENUM_OP_CONV("__ne__", b.is_none() || !a.equal(b)); + + if (is_arithmetic) { + PYBIND11_ENUM_OP_CONV("__lt__", a < b); + PYBIND11_ENUM_OP_CONV("__gt__", a > b); + PYBIND11_ENUM_OP_CONV("__le__", a <= b); + PYBIND11_ENUM_OP_CONV("__ge__", a >= b); + PYBIND11_ENUM_OP_CONV("__and__", a & b); + PYBIND11_ENUM_OP_CONV("__rand__", a & b); + PYBIND11_ENUM_OP_CONV("__or__", a | b); + PYBIND11_ENUM_OP_CONV("__ror__", a | b); + PYBIND11_ENUM_OP_CONV("__xor__", a ^ b); + PYBIND11_ENUM_OP_CONV("__rxor__", a ^ b); + } + } else { + PYBIND11_ENUM_OP_STRICT("__eq__", int_(a).equal(int_(b)), return false); + PYBIND11_ENUM_OP_STRICT("__ne__", !int_(a).equal(int_(b)), return true); + + if (is_arithmetic) { + #define PYBIND11_THROW throw type_error("Expected an enumeration of matching type!"); + PYBIND11_ENUM_OP_STRICT("__lt__", int_(a) < int_(b), PYBIND11_THROW); + PYBIND11_ENUM_OP_STRICT("__gt__", int_(a) > int_(b), PYBIND11_THROW); + PYBIND11_ENUM_OP_STRICT("__le__", int_(a) <= int_(b), PYBIND11_THROW); + PYBIND11_ENUM_OP_STRICT("__ge__", int_(a) >= int_(b), PYBIND11_THROW); + #undef PYBIND11_THROW + } + } + + #undef PYBIND11_ENUM_OP_CONV + #undef PYBIND11_ENUM_OP_STRICT + + object getstate = cpp_function( + [](object arg) { return int_(arg); }, is_method(m_base)); + + m_base.attr("__getstate__") = getstate; + m_base.attr("__hash__") = getstate; + } + + PYBIND11_NOINLINE void value(char const* name_, object value, const char *doc = nullptr) { + dict entries = m_base.attr("__entries"); + str name(name_); + if (entries.contains(name)) { + std::string type_name = (std::string) str(m_base.attr("__name__")); + throw value_error(type_name + ": element \"" + std::string(name_) + "\" already exists!"); + } + + entries[name] = std::make_pair(value, doc); + m_base.attr(name) = value; + } + + PYBIND11_NOINLINE void export_values() { + dict entries = m_base.attr("__entries"); + for (const auto &kv : entries) + m_parent.attr(kv.first) = kv.second[int_(0)]; + } + + handle m_base; + handle m_parent; +}; + +NAMESPACE_END(detail) + +/// Binds C++ enumerations and enumeration classes to Python +template class enum_ : public class_ { +public: + using Base = class_; + using Base::def; + using Base::attr; + using Base::def_property_readonly; + using Base::def_property_readonly_static; + using Scalar = typename std::underlying_type::type; + + template + enum_(const handle &scope, const char *name, const Extra&... extra) + : class_(scope, name, extra...), m_base(*this, scope) { + constexpr bool is_arithmetic = detail::any_of...>::value; + constexpr bool is_convertible = std::is_convertible::value; + m_base.init(is_arithmetic, is_convertible); + + def(init([](Scalar i) { return static_cast(i); })); + def("__int__", [](Type value) { return (Scalar) value; }); + #if PY_MAJOR_VERSION < 3 + def("__long__", [](Type value) { return (Scalar) value; }); + #endif + cpp_function setstate( + [](Type &value, Scalar arg) { value = static_cast(arg); }, + is_method(*this)); + attr("__setstate__") = setstate; + } + + /// Export enumeration entries into the parent scope + enum_& export_values() { + m_base.export_values(); + return *this; + } + + /// Add an enumeration entry + enum_& value(char const* name, Type value, const char *doc = nullptr) { + m_base.value(name, pybind11::cast(value, return_value_policy::copy), doc); + return *this; + } + +private: + detail::enum_base m_base; +}; + +NAMESPACE_BEGIN(detail) + + +inline void keep_alive_impl(handle nurse, handle patient) { + if (!nurse || !patient) + pybind11_fail("Could not activate keep_alive!"); + + if (patient.is_none() || nurse.is_none()) + return; /* Nothing to keep alive or nothing to be kept alive by */ + + auto tinfo = all_type_info(Py_TYPE(nurse.ptr())); + if (!tinfo.empty()) { + /* It's a pybind-registered type, so we can store the patient in the + * internal list. */ + add_patient(nurse.ptr(), patient.ptr()); + } + else { + /* Fall back to clever approach based on weak references taken from + * Boost.Python. This is not used for pybind-registered types because + * the objects can be destroyed out-of-order in a GC pass. */ + cpp_function disable_lifesupport( + [patient](handle weakref) { patient.dec_ref(); weakref.dec_ref(); }); + + weakref wr(nurse, disable_lifesupport); + + patient.inc_ref(); /* reference patient and leak the weak reference */ + (void) wr.release(); + } +} + +PYBIND11_NOINLINE inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) { + auto get_arg = [&](size_t n) { + if (n == 0) + return ret; + else if (n == 1 && call.init_self) + return call.init_self; + else if (n <= call.args.size()) + return call.args[n - 1]; + return handle(); + }; + + keep_alive_impl(get_arg(Nurse), get_arg(Patient)); +} + +inline std::pair all_type_info_get_cache(PyTypeObject *type) { + auto res = get_internals().registered_types_py +#ifdef __cpp_lib_unordered_map_try_emplace + .try_emplace(type); +#else + .emplace(type, std::vector()); +#endif + if (res.second) { + // New cache entry created; set up a weak reference to automatically remove it if the type + // gets destroyed: + weakref((PyObject *) type, cpp_function([type](handle wr) { + get_internals().registered_types_py.erase(type); + wr.dec_ref(); + })).release(); + } + + return res; +} + +template +struct iterator_state { + Iterator it; + Sentinel end; + bool first_or_done; +}; + +NAMESPACE_END(detail) + +/// Makes a python iterator from a first and past-the-end C++ InputIterator. +template ()), + typename... Extra> +iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) { + typedef detail::iterator_state state; + + if (!detail::get_type_info(typeid(state), false)) { + class_(handle(), "iterator", pybind11::module_local()) + .def("__iter__", [](state &s) -> state& { return s; }) + .def("__next__", [](state &s) -> ValueType { + if (!s.first_or_done) + ++s.it; + else + s.first_or_done = false; + if (s.it == s.end) { + s.first_or_done = true; + throw stop_iteration(); + } + return *s.it; + }, std::forward(extra)..., Policy); + } + + return cast(state{first, last, true}); +} + +/// Makes an python iterator over the keys (`.first`) of a iterator over pairs from a +/// first and past-the-end InputIterator. +template ()).first), + typename... Extra> +iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) { + typedef detail::iterator_state state; + + if (!detail::get_type_info(typeid(state), false)) { + class_(handle(), "iterator", pybind11::module_local()) + .def("__iter__", [](state &s) -> state& { return s; }) + .def("__next__", [](state &s) -> KeyType { + if (!s.first_or_done) + ++s.it; + else + s.first_or_done = false; + if (s.it == s.end) { + s.first_or_done = true; + throw stop_iteration(); + } + return (*s.it).first; + }, std::forward(extra)..., Policy); + } + + return cast(state{first, last, true}); +} + +/// Makes an iterator over values of an stl container or other container supporting +/// `std::begin()`/`std::end()` +template iterator make_iterator(Type &value, Extra&&... extra) { + return make_iterator(std::begin(value), std::end(value), extra...); +} + +/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting +/// `std::begin()`/`std::end()` +template iterator make_key_iterator(Type &value, Extra&&... extra) { + return make_key_iterator(std::begin(value), std::end(value), extra...); +} + +template void implicitly_convertible() { + struct set_flag { + bool &flag; + set_flag(bool &flag) : flag(flag) { flag = true; } + ~set_flag() { flag = false; } + }; + auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * { + static bool currently_used = false; + if (currently_used) // implicit conversions are non-reentrant + return nullptr; + set_flag flag_helper(currently_used); + if (!detail::make_caster().load(obj, false)) + return nullptr; + tuple args(1); + args[0] = obj; + PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr); + if (result == nullptr) + PyErr_Clear(); + return result; + }; + + if (auto tinfo = detail::get_type_info(typeid(OutputType))) + tinfo->implicit_conversions.push_back(implicit_caster); + else + pybind11_fail("implicitly_convertible: Unable to find type " + type_id()); +} + +template +void register_exception_translator(ExceptionTranslator&& translator) { + detail::get_internals().registered_exception_translators.push_front( + std::forward(translator)); +} + +/** + * Wrapper to generate a new Python exception type. + * + * This should only be used with PyErr_SetString for now. + * It is not (yet) possible to use as a py::base. + * Template type argument is reserved for future use. + */ +template +class exception : public object { +public: + exception() = default; + exception(handle scope, const char *name, PyObject *base = PyExc_Exception) { + std::string full_name = scope.attr("__name__").cast() + + std::string(".") + name; + m_ptr = PyErr_NewException(const_cast(full_name.c_str()), base, NULL); + if (hasattr(scope, name)) + pybind11_fail("Error during initialization: multiple incompatible " + "definitions with name \"" + std::string(name) + "\""); + scope.attr(name) = *this; + } + + // Sets the current python exception to this exception object with the given message + void operator()(const char *message) { + PyErr_SetString(m_ptr, message); + } +}; + +NAMESPACE_BEGIN(detail) +// Returns a reference to a function-local static exception object used in the simple +// register_exception approach below. (It would be simpler to have the static local variable +// directly in register_exception, but that makes clang <3.5 segfault - issue #1349). +template +exception &get_exception_object() { static exception ex; return ex; } +NAMESPACE_END(detail) + +/** + * Registers a Python exception in `m` of the given `name` and installs an exception translator to + * translate the C++ exception to the created Python exception using the exceptions what() method. + * This is intended for simple exception translations; for more complex translation, register the + * exception object and translator directly. + */ +template +exception ®ister_exception(handle scope, + const char *name, + PyObject *base = PyExc_Exception) { + auto &ex = detail::get_exception_object(); + if (!ex) ex = exception(scope, name, base); + + register_exception_translator([](std::exception_ptr p) { + if (!p) return; + try { + std::rethrow_exception(p); + } catch (const CppException &e) { + detail::get_exception_object()(e.what()); + } + }); + return ex; +} + +NAMESPACE_BEGIN(detail) +PYBIND11_NOINLINE inline void print(tuple args, dict kwargs) { + auto strings = tuple(args.size()); + for (size_t i = 0; i < args.size(); ++i) { + strings[i] = str(args[i]); + } + auto sep = kwargs.contains("sep") ? kwargs["sep"] : cast(" "); + auto line = sep.attr("join")(strings); + + object file; + if (kwargs.contains("file")) { + file = kwargs["file"].cast(); + } else { + try { + file = module::import("sys").attr("stdout"); + } catch (const error_already_set &) { + /* If print() is called from code that is executed as + part of garbage collection during interpreter shutdown, + importing 'sys' can fail. Give up rather than crashing the + interpreter in this case. */ + return; + } + } + + auto write = file.attr("write"); + write(line); + write(kwargs.contains("end") ? kwargs["end"] : cast("\n")); + + if (kwargs.contains("flush") && kwargs["flush"].cast()) + file.attr("flush")(); +} +NAMESPACE_END(detail) + +template +void print(Args &&...args) { + auto c = detail::collect_arguments(std::forward(args)...); + detail::print(c.args(), c.kwargs()); +} + +#if defined(WITH_THREAD) && !defined(PYPY_VERSION) + +/* The functions below essentially reproduce the PyGILState_* API using a RAII + * pattern, but there are a few important differences: + * + * 1. When acquiring the GIL from an non-main thread during the finalization + * phase, the GILState API blindly terminates the calling thread, which + * is often not what is wanted. This API does not do this. + * + * 2. The gil_scoped_release function can optionally cut the relationship + * of a PyThreadState and its associated thread, which allows moving it to + * another thread (this is a fairly rare/advanced use case). + * + * 3. The reference count of an acquired thread state can be controlled. This + * can be handy to prevent cases where callbacks issued from an external + * thread would otherwise constantly construct and destroy thread state data + * structures. + * + * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an + * example which uses features 2 and 3 to migrate the Python thread of + * execution to another thread (to run the event loop on the original thread, + * in this case). + */ + +class gil_scoped_acquire { +public: + PYBIND11_NOINLINE gil_scoped_acquire() { + auto const &internals = detail::get_internals(); + tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate); + + if (!tstate) { + /* Check if the GIL was acquired using the PyGILState_* API instead (e.g. if + calling from a Python thread). Since we use a different key, this ensures + we don't create a new thread state and deadlock in PyEval_AcquireThread + below. Note we don't save this state with internals.tstate, since we don't + create it we would fail to clear it (its reference count should be > 0). */ + tstate = PyGILState_GetThisThreadState(); + } + + if (!tstate) { + tstate = PyThreadState_New(internals.istate); + #if !defined(NDEBUG) + if (!tstate) + pybind11_fail("scoped_acquire: could not create thread state!"); + #endif + tstate->gilstate_counter = 0; + PYBIND11_TLS_REPLACE_VALUE(internals.tstate, tstate); + } else { + release = detail::get_thread_state_unchecked() != tstate; + } + + if (release) { + /* Work around an annoying assertion in PyThreadState_Swap */ + #if defined(Py_DEBUG) + PyInterpreterState *interp = tstate->interp; + tstate->interp = nullptr; + #endif + PyEval_AcquireThread(tstate); + #if defined(Py_DEBUG) + tstate->interp = interp; + #endif + } + + inc_ref(); + } + + void inc_ref() { + ++tstate->gilstate_counter; + } + + PYBIND11_NOINLINE void dec_ref() { + --tstate->gilstate_counter; + #if !defined(NDEBUG) + if (detail::get_thread_state_unchecked() != tstate) + pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!"); + if (tstate->gilstate_counter < 0) + pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!"); + #endif + if (tstate->gilstate_counter == 0) { + #if !defined(NDEBUG) + if (!release) + pybind11_fail("scoped_acquire::dec_ref(): internal error!"); + #endif + PyThreadState_Clear(tstate); + PyThreadState_DeleteCurrent(); + PYBIND11_TLS_DELETE_VALUE(detail::get_internals().tstate); + release = false; + } + } + + PYBIND11_NOINLINE ~gil_scoped_acquire() { + dec_ref(); + if (release) + PyEval_SaveThread(); + } +private: + PyThreadState *tstate = nullptr; + bool release = true; +}; + +class gil_scoped_release { +public: + explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) { + // `get_internals()` must be called here unconditionally in order to initialize + // `internals.tstate` for subsequent `gil_scoped_acquire` calls. Otherwise, an + // initialization race could occur as multiple threads try `gil_scoped_acquire`. + const auto &internals = detail::get_internals(); + tstate = PyEval_SaveThread(); + if (disassoc) { + auto key = internals.tstate; + PYBIND11_TLS_DELETE_VALUE(key); + } + } + ~gil_scoped_release() { + if (!tstate) + return; + PyEval_RestoreThread(tstate); + if (disassoc) { + auto key = detail::get_internals().tstate; + PYBIND11_TLS_REPLACE_VALUE(key, tstate); + } + } +private: + PyThreadState *tstate; + bool disassoc; +}; +#elif defined(PYPY_VERSION) +class gil_scoped_acquire { + PyGILState_STATE state; +public: + gil_scoped_acquire() { state = PyGILState_Ensure(); } + ~gil_scoped_acquire() { PyGILState_Release(state); } +}; + +class gil_scoped_release { + PyThreadState *state; +public: + gil_scoped_release() { state = PyEval_SaveThread(); } + ~gil_scoped_release() { PyEval_RestoreThread(state); } +}; +#else +class gil_scoped_acquire { }; +class gil_scoped_release { }; +#endif + +error_already_set::~error_already_set() { + if (m_type) { + error_scope scope; + gil_scoped_acquire gil; + m_type.release().dec_ref(); + m_value.release().dec_ref(); + m_trace.release().dec_ref(); + } +} + +inline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) { + handle self = detail::get_object_handle(this_ptr, this_type); + if (!self) + return function(); + handle type = self.get_type(); + auto key = std::make_pair(type.ptr(), name); + + /* Cache functions that aren't overloaded in Python to avoid + many costly Python dictionary lookups below */ + auto &cache = detail::get_internals().inactive_overload_cache; + if (cache.find(key) != cache.end()) + return function(); + + function overload = getattr(self, name, function()); + if (overload.is_cpp_function()) { + cache.insert(key); + return function(); + } + + /* Don't call dispatch code if invoked from overridden function. + Unfortunately this doesn't work on PyPy. */ +#if !defined(PYPY_VERSION) + PyFrameObject *frame = PyThreadState_Get()->frame; + if (frame && (std::string) str(frame->f_code->co_name) == name && + frame->f_code->co_argcount > 0) { + PyFrame_FastToLocals(frame); + PyObject *self_caller = PyDict_GetItem( + frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0)); + if (self_caller == self.ptr()) + return function(); + } +#else + /* PyPy currently doesn't provide a detailed cpyext emulation of + frame objects, so we have to emulate this using Python. This + is going to be slow..*/ + dict d; d["self"] = self; d["name"] = pybind11::str(name); + PyObject *result = PyRun_String( + "import inspect\n" + "frame = inspect.currentframe()\n" + "if frame is not None:\n" + " frame = frame.f_back\n" + " if frame is not None and str(frame.f_code.co_name) == name and " + "frame.f_code.co_argcount > 0:\n" + " self_caller = frame.f_locals[frame.f_code.co_varnames[0]]\n" + " if self_caller == self:\n" + " self = None\n", + Py_file_input, d.ptr(), d.ptr()); + if (result == nullptr) + throw error_already_set(); + if (d["self"].is_none()) + return function(); + Py_DECREF(result); +#endif + + return overload; +} + +/** \rst + Try to retrieve a python method by the provided name from the instance pointed to by the this_ptr. + + :this_ptr: The pointer to the object the overload should be retrieved for. This should be the first + non-trampoline class encountered in the inheritance chain. + :name: The name of the overloaded Python method to retrieve. + :return: The Python method by this name from the object or an empty function wrapper. + \endrst */ +template function get_overload(const T *this_ptr, const char *name) { + auto tinfo = detail::get_type_info(typeid(T)); + return tinfo ? get_type_overload(this_ptr, tinfo, name) : function(); +} + +#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) { \ + pybind11::gil_scoped_acquire gil; \ + pybind11::function overload = pybind11::get_overload(static_cast(this), name); \ + if (overload) { \ + auto o = overload(__VA_ARGS__); \ + if (pybind11::detail::cast_is_temporary_value_reference::value) { \ + static pybind11::detail::overload_caster_t caster; \ + return pybind11::detail::cast_ref(std::move(o), caster); \ + } \ + else return pybind11::detail::cast_safe(std::move(o)); \ + } \ + } + +/** \rst + Macro to populate the virtual method in the trampoline class. This macro tries to look up a method named 'fn' + from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return + the appropriate type. See :ref:`overriding_virtuals` for more information. This macro should be used when the method + name in C is not the same as the method name in Python. For example with `__str__`. + + .. code-block:: cpp + + std::string toString() override { + PYBIND11_OVERLOAD_NAME( + std::string, // Return type (ret_type) + Animal, // Parent class (cname) + toString, // Name of function in C++ (name) + "__str__", // Name of method in Python (fn) + ); + } +\endrst */ +#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \ + PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \ + return cname::fn(__VA_ARGS__) + +/** \rst + Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERLOAD_NAME`, except that it + throws if no overload can be found. +\endrst */ +#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \ + PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \ + pybind11::pybind11_fail("Tried to call pure virtual function \"" PYBIND11_STRINGIFY(cname) "::" name "\""); + +/** \rst + Macro to populate the virtual method in the trampoline class. This macro tries to look up the method + from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return + the appropriate type. This macro should be used if the method name in C and in Python are identical. + See :ref:`overriding_virtuals` for more information. + + .. code-block:: cpp + + class PyAnimal : public Animal { + public: + // Inherit the constructors + using Animal::Animal; + + // Trampoline (need one for each virtual function) + std::string go(int n_times) override { + PYBIND11_OVERLOAD_PURE( + std::string, // Return type (ret_type) + Animal, // Parent class (cname) + go, // Name of function in C++ (must match Python name) (fn) + n_times // Argument(s) (...) + ); + } + }; +\endrst */ +#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \ + PYBIND11_OVERLOAD_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) + +/** \rst + Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERLOAD`, except that it throws + if no overload can be found. +\endrst */ +#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \ + PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) + +NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) +# pragma warning(pop) +#elif defined(__GNUG__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif diff --git a/python/src/pybind11/pytypes.h b/python/src/pybind11/pytypes.h new file mode 100644 index 000000000..2d573dfad --- /dev/null +++ b/python/src/pybind11/pytypes.h @@ -0,0 +1,1471 @@ +/* + pybind11/pytypes.h: Convenience wrapper classes for basic Python types + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "detail/common.h" +#include "buffer_info.h" +#include +#include + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) + +/* A few forward declarations */ +class handle; class object; +class str; class iterator; +struct arg; struct arg_v; + +NAMESPACE_BEGIN(detail) +class args_proxy; +inline bool isinstance_generic(handle obj, const std::type_info &tp); + +// Accessor forward declarations +template class accessor; +namespace accessor_policies { + struct obj_attr; + struct str_attr; + struct generic_item; + struct sequence_item; + struct list_item; + struct tuple_item; +} +using obj_attr_accessor = accessor; +using str_attr_accessor = accessor; +using item_accessor = accessor; +using sequence_accessor = accessor; +using list_accessor = accessor; +using tuple_accessor = accessor; + +/// Tag and check to identify a class which implements the Python object API +class pyobject_tag { }; +template using is_pyobject = std::is_base_of>; + +/** \rst + A mixin class which adds common functions to `handle`, `object` and various accessors. + The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``. +\endrst */ +template +class object_api : public pyobject_tag { + const Derived &derived() const { return static_cast(*this); } + +public: + /** \rst + Return an iterator equivalent to calling ``iter()`` in Python. The object + must be a collection which supports the iteration protocol. + \endrst */ + iterator begin() const; + /// Return a sentinel which ends iteration. + iterator end() const; + + /** \rst + Return an internal functor to invoke the object's sequence protocol. Casting + the returned ``detail::item_accessor`` instance to a `handle` or `object` + subclass causes a corresponding call to ``__getitem__``. Assigning a `handle` + or `object` subclass causes a call to ``__setitem__``. + \endrst */ + item_accessor operator[](handle key) const; + /// See above (the only difference is that they key is provided as a string literal) + item_accessor operator[](const char *key) const; + + /** \rst + Return an internal functor to access the object's attributes. Casting the + returned ``detail::obj_attr_accessor`` instance to a `handle` or `object` + subclass causes a corresponding call to ``getattr``. Assigning a `handle` + or `object` subclass causes a call to ``setattr``. + \endrst */ + obj_attr_accessor attr(handle key) const; + /// See above (the only difference is that they key is provided as a string literal) + str_attr_accessor attr(const char *key) const; + + /** \rst + Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple`` + or ``list`` for a function call. Applying another * to the result yields + ** unpacking, e.g. to unpack a dict as function keyword arguments. + See :ref:`calling_python_functions`. + \endrst */ + args_proxy operator*() const; + + /// Check if the given item is contained within this object, i.e. ``item in obj``. + template bool contains(T &&item) const; + + /** \rst + Assuming the Python object is a function or implements the ``__call__`` + protocol, ``operator()`` invokes the underlying function, passing an + arbitrary set of parameters. The result is returned as a `object` and + may need to be converted back into a Python object using `handle::cast()`. + + When some of the arguments cannot be converted to Python objects, the + function will throw a `cast_error` exception. When the Python function + call fails, a `error_already_set` exception is thrown. + \endrst */ + template + object operator()(Args &&...args) const; + template + PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)") + object call(Args&&... args) const; + + /// Equivalent to ``obj is other`` in Python. + bool is(object_api const& other) const { return derived().ptr() == other.derived().ptr(); } + /// Equivalent to ``obj is None`` in Python. + bool is_none() const { return derived().ptr() == Py_None; } + /// Equivalent to obj == other in Python + bool equal(object_api const &other) const { return rich_compare(other, Py_EQ); } + bool not_equal(object_api const &other) const { return rich_compare(other, Py_NE); } + bool operator<(object_api const &other) const { return rich_compare(other, Py_LT); } + bool operator<=(object_api const &other) const { return rich_compare(other, Py_LE); } + bool operator>(object_api const &other) const { return rich_compare(other, Py_GT); } + bool operator>=(object_api const &other) const { return rich_compare(other, Py_GE); } + + object operator-() const; + object operator~() const; + object operator+(object_api const &other) const; + object operator+=(object_api const &other) const; + object operator-(object_api const &other) const; + object operator-=(object_api const &other) const; + object operator*(object_api const &other) const; + object operator*=(object_api const &other) const; + object operator/(object_api const &other) const; + object operator/=(object_api const &other) const; + object operator|(object_api const &other) const; + object operator|=(object_api const &other) const; + object operator&(object_api const &other) const; + object operator&=(object_api const &other) const; + object operator^(object_api const &other) const; + object operator^=(object_api const &other) const; + object operator<<(object_api const &other) const; + object operator<<=(object_api const &other) const; + object operator>>(object_api const &other) const; + object operator>>=(object_api const &other) const; + + PYBIND11_DEPRECATED("Use py::str(obj) instead") + pybind11::str str() const; + + /// Get or set the object's docstring, i.e. ``obj.__doc__``. + str_attr_accessor doc() const; + + /// Return the object's current reference count + int ref_count() const { return static_cast(Py_REFCNT(derived().ptr())); } + /// Return a handle to the Python type object underlying the instance + handle get_type() const; + +private: + bool rich_compare(object_api const &other, int value) const; +}; + +NAMESPACE_END(detail) + +/** \rst + Holds a reference to a Python object (no reference counting) + + The `handle` class is a thin wrapper around an arbitrary Python object (i.e. a + ``PyObject *`` in Python's C API). It does not perform any automatic reference + counting and merely provides a basic C++ interface to various Python API functions. + + .. seealso:: + The `object` class inherits from `handle` and adds automatic reference + counting features. +\endrst */ +class handle : public detail::object_api { +public: + /// The default constructor creates a handle with a ``nullptr``-valued pointer + handle() = default; + /// Creates a ``handle`` from the given raw Python object pointer + handle(PyObject *ptr) : m_ptr(ptr) { } // Allow implicit conversion from PyObject* + + /// Return the underlying ``PyObject *`` pointer + PyObject *ptr() const { return m_ptr; } + PyObject *&ptr() { return m_ptr; } + + /** \rst + Manually increase the reference count of the Python object. Usually, it is + preferable to use the `object` class which derives from `handle` and calls + this function automatically. Returns a reference to itself. + \endrst */ + const handle& inc_ref() const & { Py_XINCREF(m_ptr); return *this; } + + /** \rst + Manually decrease the reference count of the Python object. Usually, it is + preferable to use the `object` class which derives from `handle` and calls + this function automatically. Returns a reference to itself. + \endrst */ + const handle& dec_ref() const & { Py_XDECREF(m_ptr); return *this; } + + /** \rst + Attempt to cast the Python object into the given C++ type. A `cast_error` + will be throw upon failure. + \endrst */ + template T cast() const; + /// Return ``true`` when the `handle` wraps a valid Python object + explicit operator bool() const { return m_ptr != nullptr; } + /** \rst + Deprecated: Check that the underlying pointers are the same. + Equivalent to ``obj1 is obj2`` in Python. + \endrst */ + PYBIND11_DEPRECATED("Use obj1.is(obj2) instead") + bool operator==(const handle &h) const { return m_ptr == h.m_ptr; } + PYBIND11_DEPRECATED("Use !obj1.is(obj2) instead") + bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; } + PYBIND11_DEPRECATED("Use handle::operator bool() instead") + bool check() const { return m_ptr != nullptr; } +protected: + PyObject *m_ptr = nullptr; +}; + +/** \rst + Holds a reference to a Python object (with reference counting) + + Like `handle`, the `object` class is a thin wrapper around an arbitrary Python + object (i.e. a ``PyObject *`` in Python's C API). In contrast to `handle`, it + optionally increases the object's reference count upon construction, and it + *always* decreases the reference count when the `object` instance goes out of + scope and is destructed. When using `object` instances consistently, it is much + easier to get reference counting right at the first attempt. +\endrst */ +class object : public handle { +public: + object() = default; + PYBIND11_DEPRECATED("Use reinterpret_borrow() or reinterpret_steal()") + object(handle h, bool is_borrowed) : handle(h) { if (is_borrowed) inc_ref(); } + /// Copy constructor; always increases the reference count + object(const object &o) : handle(o) { inc_ref(); } + /// Move constructor; steals the object from ``other`` and preserves its reference count + object(object &&other) noexcept { m_ptr = other.m_ptr; other.m_ptr = nullptr; } + /// Destructor; automatically calls `handle::dec_ref()` + ~object() { dec_ref(); } + + /** \rst + Resets the internal pointer to ``nullptr`` without without decreasing the + object's reference count. The function returns a raw handle to the original + Python object. + \endrst */ + handle release() { + PyObject *tmp = m_ptr; + m_ptr = nullptr; + return handle(tmp); + } + + object& operator=(const object &other) { + other.inc_ref(); + dec_ref(); + m_ptr = other.m_ptr; + return *this; + } + + object& operator=(object &&other) noexcept { + if (this != &other) { + handle temp(m_ptr); + m_ptr = other.m_ptr; + other.m_ptr = nullptr; + temp.dec_ref(); + } + return *this; + } + + // Calling cast() on an object lvalue just copies (via handle::cast) + template T cast() const &; + // Calling on an object rvalue does a move, if needed and/or possible + template T cast() &&; + +protected: + // Tags for choosing constructors from raw PyObject * + struct borrowed_t { }; + struct stolen_t { }; + + template friend T reinterpret_borrow(handle); + template friend T reinterpret_steal(handle); + +public: + // Only accessible from derived classes and the reinterpret_* functions + object(handle h, borrowed_t) : handle(h) { inc_ref(); } + object(handle h, stolen_t) : handle(h) { } +}; + +/** \rst + Declare that a `handle` or ``PyObject *`` is a certain type and borrow the reference. + The target type ``T`` must be `object` or one of its derived classes. The function + doesn't do any conversions or checks. It's up to the user to make sure that the + target type is correct. + + .. code-block:: cpp + + PyObject *p = PyList_GetItem(obj, index); + py::object o = reinterpret_borrow(p); + // or + py::tuple t = reinterpret_borrow(p); // <-- `p` must be already be a `tuple` +\endrst */ +template T reinterpret_borrow(handle h) { return {h, object::borrowed_t{}}; } + +/** \rst + Like `reinterpret_borrow`, but steals the reference. + + .. code-block:: cpp + + PyObject *p = PyObject_Str(obj); + py::str s = reinterpret_steal(p); // <-- `p` must be already be a `str` +\endrst */ +template T reinterpret_steal(handle h) { return {h, object::stolen_t{}}; } + +NAMESPACE_BEGIN(detail) +inline std::string error_string(); +NAMESPACE_END(detail) + +/// Fetch and hold an error which was already set in Python. An instance of this is typically +/// thrown to propagate python-side errors back through C++ which can either be caught manually or +/// else falls back to the function dispatcher (which then raises the captured error back to +/// python). +class error_already_set : public std::runtime_error { +public: + /// Constructs a new exception from the current Python error indicator, if any. The current + /// Python error indicator will be cleared. + error_already_set() : std::runtime_error(detail::error_string()) { + PyErr_Fetch(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr()); + } + + error_already_set(const error_already_set &) = default; + error_already_set(error_already_set &&) = default; + + inline ~error_already_set(); + + /// Give the currently-held error back to Python, if any. If there is currently a Python error + /// already set it is cleared first. After this call, the current object no longer stores the + /// error variables (but the `.what()` string is still available). + void restore() { PyErr_Restore(m_type.release().ptr(), m_value.release().ptr(), m_trace.release().ptr()); } + + // Does nothing; provided for backwards compatibility. + PYBIND11_DEPRECATED("Use of error_already_set.clear() is deprecated") + void clear() {} + + /// Check if the currently trapped error type matches the given Python exception class (or a + /// subclass thereof). May also be passed a tuple to search for any exception class matches in + /// the given tuple. + bool matches(handle exc) const { return PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()); } + + const object& type() const { return m_type; } + const object& value() const { return m_value; } + const object& trace() const { return m_trace; } + +private: + object m_type, m_value, m_trace; +}; + +/** \defgroup python_builtins _ + Unless stated otherwise, the following C++ functions behave the same + as their Python counterparts. + */ + +/** \ingroup python_builtins + \rst + Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of + `object` or a class which was exposed to Python as ``py::class_``. +\endrst */ +template ::value, int> = 0> +bool isinstance(handle obj) { return T::check_(obj); } + +template ::value, int> = 0> +bool isinstance(handle obj) { return detail::isinstance_generic(obj, typeid(T)); } + +template <> inline bool isinstance(handle obj) = delete; +template <> inline bool isinstance(handle obj) { return obj.ptr() != nullptr; } + +/// \ingroup python_builtins +/// Return true if ``obj`` is an instance of the ``type``. +inline bool isinstance(handle obj, handle type) { + const auto result = PyObject_IsInstance(obj.ptr(), type.ptr()); + if (result == -1) + throw error_already_set(); + return result != 0; +} + +/// \addtogroup python_builtins +/// @{ +inline bool hasattr(handle obj, handle name) { + return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1; +} + +inline bool hasattr(handle obj, const char *name) { + return PyObject_HasAttrString(obj.ptr(), name) == 1; +} + +inline void delattr(handle obj, handle name) { + if (PyObject_DelAttr(obj.ptr(), name.ptr()) != 0) { throw error_already_set(); } +} + +inline void delattr(handle obj, const char *name) { + if (PyObject_DelAttrString(obj.ptr(), name) != 0) { throw error_already_set(); } +} + +inline object getattr(handle obj, handle name) { + PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr()); + if (!result) { throw error_already_set(); } + return reinterpret_steal(result); +} + +inline object getattr(handle obj, const char *name) { + PyObject *result = PyObject_GetAttrString(obj.ptr(), name); + if (!result) { throw error_already_set(); } + return reinterpret_steal(result); +} + +inline object getattr(handle obj, handle name, handle default_) { + if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) { + return reinterpret_steal(result); + } else { + PyErr_Clear(); + return reinterpret_borrow(default_); + } +} + +inline object getattr(handle obj, const char *name, handle default_) { + if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) { + return reinterpret_steal(result); + } else { + PyErr_Clear(); + return reinterpret_borrow(default_); + } +} + +inline void setattr(handle obj, handle name, handle value) { + if (PyObject_SetAttr(obj.ptr(), name.ptr(), value.ptr()) != 0) { throw error_already_set(); } +} + +inline void setattr(handle obj, const char *name, handle value) { + if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) { throw error_already_set(); } +} + +inline ssize_t hash(handle obj) { + auto h = PyObject_Hash(obj.ptr()); + if (h == -1) { throw error_already_set(); } + return h; +} + +/// @} python_builtins + +NAMESPACE_BEGIN(detail) +inline handle get_function(handle value) { + if (value) { +#if PY_MAJOR_VERSION >= 3 + if (PyInstanceMethod_Check(value.ptr())) + value = PyInstanceMethod_GET_FUNCTION(value.ptr()); + else +#endif + if (PyMethod_Check(value.ptr())) + value = PyMethod_GET_FUNCTION(value.ptr()); + } + return value; +} + +// Helper aliases/functions to support implicit casting of values given to python accessors/methods. +// When given a pyobject, this simply returns the pyobject as-is; for other C++ type, the value goes +// through pybind11::cast(obj) to convert it to an `object`. +template ::value, int> = 0> +auto object_or_cast(T &&o) -> decltype(std::forward(o)) { return std::forward(o); } +// The following casting version is implemented in cast.h: +template ::value, int> = 0> +object object_or_cast(T &&o); +// Match a PyObject*, which we want to convert directly to handle via its converting constructor +inline handle object_or_cast(PyObject *ptr) { return ptr; } + +template +class accessor : public object_api> { + using key_type = typename Policy::key_type; + +public: + accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) { } + accessor(const accessor &) = default; + accessor(accessor &&) = default; + + // accessor overload required to override default assignment operator (templates are not allowed + // to replace default compiler-generated assignments). + void operator=(const accessor &a) && { std::move(*this).operator=(handle(a)); } + void operator=(const accessor &a) & { operator=(handle(a)); } + + template void operator=(T &&value) && { + Policy::set(obj, key, object_or_cast(std::forward(value))); + } + template void operator=(T &&value) & { + get_cache() = reinterpret_borrow(object_or_cast(std::forward(value))); + } + + template + PYBIND11_DEPRECATED("Use of obj.attr(...) as bool is deprecated in favor of pybind11::hasattr(obj, ...)") + explicit operator enable_if_t::value || + std::is_same::value, bool>() const { + return hasattr(obj, key); + } + template + PYBIND11_DEPRECATED("Use of obj[key] as bool is deprecated in favor of obj.contains(key)") + explicit operator enable_if_t::value, bool>() const { + return obj.contains(key); + } + + operator object() const { return get_cache(); } + PyObject *ptr() const { return get_cache().ptr(); } + template T cast() const { return get_cache().template cast(); } + +private: + object &get_cache() const { + if (!cache) { cache = Policy::get(obj, key); } + return cache; + } + +private: + handle obj; + key_type key; + mutable object cache; +}; + +NAMESPACE_BEGIN(accessor_policies) +struct obj_attr { + using key_type = object; + static object get(handle obj, handle key) { return getattr(obj, key); } + static void set(handle obj, handle key, handle val) { setattr(obj, key, val); } +}; + +struct str_attr { + using key_type = const char *; + static object get(handle obj, const char *key) { return getattr(obj, key); } + static void set(handle obj, const char *key, handle val) { setattr(obj, key, val); } +}; + +struct generic_item { + using key_type = object; + + static object get(handle obj, handle key) { + PyObject *result = PyObject_GetItem(obj.ptr(), key.ptr()); + if (!result) { throw error_already_set(); } + return reinterpret_steal(result); + } + + static void set(handle obj, handle key, handle val) { + if (PyObject_SetItem(obj.ptr(), key.ptr(), val.ptr()) != 0) { throw error_already_set(); } + } +}; + +struct sequence_item { + using key_type = size_t; + + static object get(handle obj, size_t index) { + PyObject *result = PySequence_GetItem(obj.ptr(), static_cast(index)); + if (!result) { throw error_already_set(); } + return reinterpret_steal(result); + } + + static void set(handle obj, size_t index, handle val) { + // PySequence_SetItem does not steal a reference to 'val' + if (PySequence_SetItem(obj.ptr(), static_cast(index), val.ptr()) != 0) { + throw error_already_set(); + } + } +}; + +struct list_item { + using key_type = size_t; + + static object get(handle obj, size_t index) { + PyObject *result = PyList_GetItem(obj.ptr(), static_cast(index)); + if (!result) { throw error_already_set(); } + return reinterpret_borrow(result); + } + + static void set(handle obj, size_t index, handle val) { + // PyList_SetItem steals a reference to 'val' + if (PyList_SetItem(obj.ptr(), static_cast(index), val.inc_ref().ptr()) != 0) { + throw error_already_set(); + } + } +}; + +struct tuple_item { + using key_type = size_t; + + static object get(handle obj, size_t index) { + PyObject *result = PyTuple_GetItem(obj.ptr(), static_cast(index)); + if (!result) { throw error_already_set(); } + return reinterpret_borrow(result); + } + + static void set(handle obj, size_t index, handle val) { + // PyTuple_SetItem steals a reference to 'val' + if (PyTuple_SetItem(obj.ptr(), static_cast(index), val.inc_ref().ptr()) != 0) { + throw error_already_set(); + } + } +}; +NAMESPACE_END(accessor_policies) + +/// STL iterator template used for tuple, list, sequence and dict +template +class generic_iterator : public Policy { + using It = generic_iterator; + +public: + using difference_type = ssize_t; + using iterator_category = typename Policy::iterator_category; + using value_type = typename Policy::value_type; + using reference = typename Policy::reference; + using pointer = typename Policy::pointer; + + generic_iterator() = default; + generic_iterator(handle seq, ssize_t index) : Policy(seq, index) { } + + reference operator*() const { return Policy::dereference(); } + reference operator[](difference_type n) const { return *(*this + n); } + pointer operator->() const { return **this; } + + It &operator++() { Policy::increment(); return *this; } + It operator++(int) { auto copy = *this; Policy::increment(); return copy; } + It &operator--() { Policy::decrement(); return *this; } + It operator--(int) { auto copy = *this; Policy::decrement(); return copy; } + It &operator+=(difference_type n) { Policy::advance(n); return *this; } + It &operator-=(difference_type n) { Policy::advance(-n); return *this; } + + friend It operator+(const It &a, difference_type n) { auto copy = a; return copy += n; } + friend It operator+(difference_type n, const It &b) { return b + n; } + friend It operator-(const It &a, difference_type n) { auto copy = a; return copy -= n; } + friend difference_type operator-(const It &a, const It &b) { return a.distance_to(b); } + + friend bool operator==(const It &a, const It &b) { return a.equal(b); } + friend bool operator!=(const It &a, const It &b) { return !(a == b); } + friend bool operator< (const It &a, const It &b) { return b - a > 0; } + friend bool operator> (const It &a, const It &b) { return b < a; } + friend bool operator>=(const It &a, const It &b) { return !(a < b); } + friend bool operator<=(const It &a, const It &b) { return !(a > b); } +}; + +NAMESPACE_BEGIN(iterator_policies) +/// Quick proxy class needed to implement ``operator->`` for iterators which can't return pointers +template +struct arrow_proxy { + T value; + + arrow_proxy(T &&value) : value(std::move(value)) { } + T *operator->() const { return &value; } +}; + +/// Lightweight iterator policy using just a simple pointer: see ``PySequence_Fast_ITEMS`` +class sequence_fast_readonly { +protected: + using iterator_category = std::random_access_iterator_tag; + using value_type = handle; + using reference = const handle; + using pointer = arrow_proxy; + + sequence_fast_readonly(handle obj, ssize_t n) : ptr(PySequence_Fast_ITEMS(obj.ptr()) + n) { } + + reference dereference() const { return *ptr; } + void increment() { ++ptr; } + void decrement() { --ptr; } + void advance(ssize_t n) { ptr += n; } + bool equal(const sequence_fast_readonly &b) const { return ptr == b.ptr; } + ssize_t distance_to(const sequence_fast_readonly &b) const { return ptr - b.ptr; } + +private: + PyObject **ptr; +}; + +/// Full read and write access using the sequence protocol: see ``detail::sequence_accessor`` +class sequence_slow_readwrite { +protected: + using iterator_category = std::random_access_iterator_tag; + using value_type = object; + using reference = sequence_accessor; + using pointer = arrow_proxy; + + sequence_slow_readwrite(handle obj, ssize_t index) : obj(obj), index(index) { } + + reference dereference() const { return {obj, static_cast(index)}; } + void increment() { ++index; } + void decrement() { --index; } + void advance(ssize_t n) { index += n; } + bool equal(const sequence_slow_readwrite &b) const { return index == b.index; } + ssize_t distance_to(const sequence_slow_readwrite &b) const { return index - b.index; } + +private: + handle obj; + ssize_t index; +}; + +/// Python's dictionary protocol permits this to be a forward iterator +class dict_readonly { +protected: + using iterator_category = std::forward_iterator_tag; + using value_type = std::pair; + using reference = const value_type; + using pointer = arrow_proxy; + + dict_readonly() = default; + dict_readonly(handle obj, ssize_t pos) : obj(obj), pos(pos) { increment(); } + + reference dereference() const { return {key, value}; } + void increment() { if (!PyDict_Next(obj.ptr(), &pos, &key, &value)) { pos = -1; } } + bool equal(const dict_readonly &b) const { return pos == b.pos; } + +private: + handle obj; + PyObject *key = nullptr, *value = nullptr; + ssize_t pos = -1; +}; +NAMESPACE_END(iterator_policies) + +#if !defined(PYPY_VERSION) +using tuple_iterator = generic_iterator; +using list_iterator = generic_iterator; +#else +using tuple_iterator = generic_iterator; +using list_iterator = generic_iterator; +#endif + +using sequence_iterator = generic_iterator; +using dict_iterator = generic_iterator; + +inline bool PyIterable_Check(PyObject *obj) { + PyObject *iter = PyObject_GetIter(obj); + if (iter) { + Py_DECREF(iter); + return true; + } else { + PyErr_Clear(); + return false; + } +} + +inline bool PyNone_Check(PyObject *o) { return o == Py_None; } +#if PY_MAJOR_VERSION >= 3 +inline bool PyEllipsis_Check(PyObject *o) { return o == Py_Ellipsis; } +#endif + +inline bool PyUnicode_Check_Permissive(PyObject *o) { return PyUnicode_Check(o) || PYBIND11_BYTES_CHECK(o); } + +inline bool PyStaticMethod_Check(PyObject *o) { return o->ob_type == &PyStaticMethod_Type; } + +class kwargs_proxy : public handle { +public: + explicit kwargs_proxy(handle h) : handle(h) { } +}; + +class args_proxy : public handle { +public: + explicit args_proxy(handle h) : handle(h) { } + kwargs_proxy operator*() const { return kwargs_proxy(*this); } +}; + +/// Python argument categories (using PEP 448 terms) +template using is_keyword = std::is_base_of; +template using is_s_unpacking = std::is_same; // * unpacking +template using is_ds_unpacking = std::is_same; // ** unpacking +template using is_positional = satisfies_none_of; +template using is_keyword_or_ds = satisfies_any_of; + +// Call argument collector forward declarations +template +class simple_collector; +template +class unpacking_collector; + +NAMESPACE_END(detail) + +// TODO: After the deprecated constructors are removed, this macro can be simplified by +// inheriting ctors: `using Parent::Parent`. It's not an option right now because +// the `using` statement triggers the parent deprecation warning even if the ctor +// isn't even used. +#define PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ + public: \ + PYBIND11_DEPRECATED("Use reinterpret_borrow<"#Name">() or reinterpret_steal<"#Name">()") \ + Name(handle h, bool is_borrowed) : Parent(is_borrowed ? Parent(h, borrowed_t{}) : Parent(h, stolen_t{})) { } \ + Name(handle h, borrowed_t) : Parent(h, borrowed_t{}) { } \ + Name(handle h, stolen_t) : Parent(h, stolen_t{}) { } \ + PYBIND11_DEPRECATED("Use py::isinstance(obj) instead") \ + bool check() const { return m_ptr != nullptr && (bool) CheckFun(m_ptr); } \ + static bool check_(handle h) { return h.ptr() != nullptr && CheckFun(h.ptr()); } + +#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun) \ + PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ + /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \ + Name(const object &o) \ + : Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) \ + { if (!m_ptr) throw error_already_set(); } \ + Name(object &&o) \ + : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) \ + { if (!m_ptr) throw error_already_set(); } \ + template \ + Name(const ::pybind11::detail::accessor &a) : Name(object(a)) { } + +#define PYBIND11_OBJECT(Name, Parent, CheckFun) \ + PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \ + /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \ + Name(const object &o) : Parent(o) { } \ + Name(object &&o) : Parent(std::move(o)) { } + +#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun) \ + PYBIND11_OBJECT(Name, Parent, CheckFun) \ + Name() : Parent() { } + +/// \addtogroup pytypes +/// @{ + +/** \rst + Wraps a Python iterator so that it can also be used as a C++ input iterator + + Caveat: copying an iterator does not (and cannot) clone the internal + state of the Python iterable. This also applies to the post-increment + operator. This iterator should only be used to retrieve the current + value using ``operator*()``. +\endrst */ +class iterator : public object { +public: + using iterator_category = std::input_iterator_tag; + using difference_type = ssize_t; + using value_type = handle; + using reference = const handle; + using pointer = const handle *; + + PYBIND11_OBJECT_DEFAULT(iterator, object, PyIter_Check) + + iterator& operator++() { + advance(); + return *this; + } + + iterator operator++(int) { + auto rv = *this; + advance(); + return rv; + } + + reference operator*() const { + if (m_ptr && !value.ptr()) { + auto& self = const_cast(*this); + self.advance(); + } + return value; + } + + pointer operator->() const { operator*(); return &value; } + + /** \rst + The value which marks the end of the iteration. ``it == iterator::sentinel()`` + is equivalent to catching ``StopIteration`` in Python. + + .. code-block:: cpp + + void foo(py::iterator it) { + while (it != py::iterator::sentinel()) { + // use `*it` + ++it; + } + } + \endrst */ + static iterator sentinel() { return {}; } + + friend bool operator==(const iterator &a, const iterator &b) { return a->ptr() == b->ptr(); } + friend bool operator!=(const iterator &a, const iterator &b) { return a->ptr() != b->ptr(); } + +private: + void advance() { + value = reinterpret_steal(PyIter_Next(m_ptr)); + if (PyErr_Occurred()) { throw error_already_set(); } + } + +private: + object value = {}; +}; + +class iterable : public object { +public: + PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check) +}; + +class bytes; + +class str : public object { +public: + PYBIND11_OBJECT_CVT(str, object, detail::PyUnicode_Check_Permissive, raw_str) + + str(const char *c, size_t n) + : object(PyUnicode_FromStringAndSize(c, (ssize_t) n), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate string object!"); + } + + // 'explicit' is explicitly omitted from the following constructors to allow implicit conversion to py::str from C++ string-like objects + str(const char *c = "") + : object(PyUnicode_FromString(c), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate string object!"); + } + + str(const std::string &s) : str(s.data(), s.size()) { } + + explicit str(const bytes &b); + + /** \rst + Return a string representation of the object. This is analogous to + the ``str()`` function in Python. + \endrst */ + explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) { } + + operator std::string() const { + object temp = *this; + if (PyUnicode_Check(m_ptr)) { + temp = reinterpret_steal(PyUnicode_AsUTF8String(m_ptr)); + if (!temp) + pybind11_fail("Unable to extract string contents! (encoding issue)"); + } + char *buffer; + ssize_t length; + if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) + pybind11_fail("Unable to extract string contents! (invalid type)"); + return std::string(buffer, (size_t) length); + } + + template + str format(Args &&...args) const { + return attr("format")(std::forward(args)...); + } + +private: + /// Return string representation -- always returns a new reference, even if already a str + static PyObject *raw_str(PyObject *op) { + PyObject *str_value = PyObject_Str(op); +#if PY_MAJOR_VERSION < 3 + if (!str_value) throw error_already_set(); + PyObject *unicode = PyUnicode_FromEncodedObject(str_value, "utf-8", nullptr); + Py_XDECREF(str_value); str_value = unicode; +#endif + return str_value; + } +}; +/// @} pytypes + +inline namespace literals { +/** \rst + String literal version of `str` + \endrst */ +inline str operator"" _s(const char *s, size_t size) { return {s, size}; } +} + +/// \addtogroup pytypes +/// @{ +class bytes : public object { +public: + PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK) + + // Allow implicit conversion: + bytes(const char *c = "") + : object(PYBIND11_BYTES_FROM_STRING(c), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate bytes object!"); + } + + bytes(const char *c, size_t n) + : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(c, (ssize_t) n), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate bytes object!"); + } + + // Allow implicit conversion: + bytes(const std::string &s) : bytes(s.data(), s.size()) { } + + explicit bytes(const pybind11::str &s); + + operator std::string() const { + char *buffer; + ssize_t length; + if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) + pybind11_fail("Unable to extract bytes contents!"); + return std::string(buffer, (size_t) length); + } +}; + +inline bytes::bytes(const pybind11::str &s) { + object temp = s; + if (PyUnicode_Check(s.ptr())) { + temp = reinterpret_steal(PyUnicode_AsUTF8String(s.ptr())); + if (!temp) + pybind11_fail("Unable to extract string contents! (encoding issue)"); + } + char *buffer; + ssize_t length; + if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) + pybind11_fail("Unable to extract string contents! (invalid type)"); + auto obj = reinterpret_steal(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length)); + if (!obj) + pybind11_fail("Could not allocate bytes object!"); + m_ptr = obj.release().ptr(); +} + +inline str::str(const bytes& b) { + char *buffer; + ssize_t length; + if (PYBIND11_BYTES_AS_STRING_AND_SIZE(b.ptr(), &buffer, &length)) + pybind11_fail("Unable to extract bytes contents!"); + auto obj = reinterpret_steal(PyUnicode_FromStringAndSize(buffer, (ssize_t) length)); + if (!obj) + pybind11_fail("Could not allocate string object!"); + m_ptr = obj.release().ptr(); +} + +class none : public object { +public: + PYBIND11_OBJECT(none, object, detail::PyNone_Check) + none() : object(Py_None, borrowed_t{}) { } +}; + +#if PY_MAJOR_VERSION >= 3 +class ellipsis : public object { +public: + PYBIND11_OBJECT(ellipsis, object, detail::PyEllipsis_Check) + ellipsis() : object(Py_Ellipsis, borrowed_t{}) { } +}; +#endif + +class bool_ : public object { +public: + PYBIND11_OBJECT_CVT(bool_, object, PyBool_Check, raw_bool) + bool_() : object(Py_False, borrowed_t{}) { } + // Allow implicit conversion from and to `bool`: + bool_(bool value) : object(value ? Py_True : Py_False, borrowed_t{}) { } + operator bool() const { return m_ptr && PyLong_AsLong(m_ptr) != 0; } + +private: + /// Return the truth value of an object -- always returns a new reference + static PyObject *raw_bool(PyObject *op) { + const auto value = PyObject_IsTrue(op); + if (value == -1) return nullptr; + return handle(value ? Py_True : Py_False).inc_ref().ptr(); + } +}; + +NAMESPACE_BEGIN(detail) +// Converts a value to the given unsigned type. If an error occurs, you get back (Unsigned) -1; +// otherwise you get back the unsigned long or unsigned long long value cast to (Unsigned). +// (The distinction is critically important when casting a returned -1 error value to some other +// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes). +template +Unsigned as_unsigned(PyObject *o) { + if (sizeof(Unsigned) <= sizeof(unsigned long) +#if PY_VERSION_HEX < 0x03000000 + || PyInt_Check(o) +#endif + ) { + unsigned long v = PyLong_AsUnsignedLong(o); + return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v; + } + else { + unsigned long long v = PyLong_AsUnsignedLongLong(o); + return v == (unsigned long long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v; + } +} +NAMESPACE_END(detail) + +class int_ : public object { +public: + PYBIND11_OBJECT_CVT(int_, object, PYBIND11_LONG_CHECK, PyNumber_Long) + int_() : object(PyLong_FromLong(0), stolen_t{}) { } + // Allow implicit conversion from C++ integral types: + template ::value, int> = 0> + int_(T value) { + if (sizeof(T) <= sizeof(long)) { + if (std::is_signed::value) + m_ptr = PyLong_FromLong((long) value); + else + m_ptr = PyLong_FromUnsignedLong((unsigned long) value); + } else { + if (std::is_signed::value) + m_ptr = PyLong_FromLongLong((long long) value); + else + m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value); + } + if (!m_ptr) pybind11_fail("Could not allocate int object!"); + } + + template ::value, int> = 0> + operator T() const { + return std::is_unsigned::value + ? detail::as_unsigned(m_ptr) + : sizeof(T) <= sizeof(long) + ? (T) PyLong_AsLong(m_ptr) + : (T) PYBIND11_LONG_AS_LONGLONG(m_ptr); + } +}; + +class float_ : public object { +public: + PYBIND11_OBJECT_CVT(float_, object, PyFloat_Check, PyNumber_Float) + // Allow implicit conversion from float/double: + float_(float value) : object(PyFloat_FromDouble((double) value), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate float object!"); + } + float_(double value = .0) : object(PyFloat_FromDouble((double) value), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate float object!"); + } + operator float() const { return (float) PyFloat_AsDouble(m_ptr); } + operator double() const { return (double) PyFloat_AsDouble(m_ptr); } +}; + +class weakref : public object { +public: + PYBIND11_OBJECT_DEFAULT(weakref, object, PyWeakref_Check) + explicit weakref(handle obj, handle callback = {}) + : object(PyWeakref_NewRef(obj.ptr(), callback.ptr()), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate weak reference!"); + } +}; + +class slice : public object { +public: + PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check) + slice(ssize_t start_, ssize_t stop_, ssize_t step_) { + int_ start(start_), stop(stop_), step(step_); + m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr()); + if (!m_ptr) pybind11_fail("Could not allocate slice object!"); + } + bool compute(size_t length, size_t *start, size_t *stop, size_t *step, + size_t *slicelength) const { + return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr, + (ssize_t) length, (ssize_t *) start, + (ssize_t *) stop, (ssize_t *) step, + (ssize_t *) slicelength) == 0; + } + bool compute(ssize_t length, ssize_t *start, ssize_t *stop, ssize_t *step, + ssize_t *slicelength) const { + return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr, + length, start, + stop, step, + slicelength) == 0; + } +}; + +class capsule : public object { +public: + PYBIND11_OBJECT_DEFAULT(capsule, object, PyCapsule_CheckExact) + PYBIND11_DEPRECATED("Use reinterpret_borrow() or reinterpret_steal()") + capsule(PyObject *ptr, bool is_borrowed) : object(is_borrowed ? object(ptr, borrowed_t{}) : object(ptr, stolen_t{})) { } + + explicit capsule(const void *value, const char *name = nullptr, void (*destructor)(PyObject *) = nullptr) + : object(PyCapsule_New(const_cast(value), name, destructor), stolen_t{}) { + if (!m_ptr) + pybind11_fail("Could not allocate capsule object!"); + } + + PYBIND11_DEPRECATED("Please pass a destructor that takes a void pointer as input") + capsule(const void *value, void (*destruct)(PyObject *)) + : object(PyCapsule_New(const_cast(value), nullptr, destruct), stolen_t{}) { + if (!m_ptr) + pybind11_fail("Could not allocate capsule object!"); + } + + capsule(const void *value, void (*destructor)(void *)) { + m_ptr = PyCapsule_New(const_cast(value), nullptr, [](PyObject *o) { + auto destructor = reinterpret_cast(PyCapsule_GetContext(o)); + void *ptr = PyCapsule_GetPointer(o, nullptr); + destructor(ptr); + }); + + if (!m_ptr) + pybind11_fail("Could not allocate capsule object!"); + + if (PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) + pybind11_fail("Could not set capsule context!"); + } + + capsule(void (*destructor)()) { + m_ptr = PyCapsule_New(reinterpret_cast(destructor), nullptr, [](PyObject *o) { + auto destructor = reinterpret_cast(PyCapsule_GetPointer(o, nullptr)); + destructor(); + }); + + if (!m_ptr) + pybind11_fail("Could not allocate capsule object!"); + } + + template operator T *() const { + auto name = this->name(); + T * result = static_cast(PyCapsule_GetPointer(m_ptr, name)); + if (!result) pybind11_fail("Unable to extract capsule contents!"); + return result; + } + + const char *name() const { return PyCapsule_GetName(m_ptr); } +}; + +class tuple : public object { +public: + PYBIND11_OBJECT_CVT(tuple, object, PyTuple_Check, PySequence_Tuple) + explicit tuple(size_t size = 0) : object(PyTuple_New((ssize_t) size), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate tuple object!"); + } + size_t size() const { return (size_t) PyTuple_Size(m_ptr); } + detail::tuple_accessor operator[](size_t index) const { return {*this, index}; } + detail::item_accessor operator[](handle h) const { return object::operator[](h); } + detail::tuple_iterator begin() const { return {*this, 0}; } + detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; } +}; + +class dict : public object { +public: + PYBIND11_OBJECT_CVT(dict, object, PyDict_Check, raw_dict) + dict() : object(PyDict_New(), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate dict object!"); + } + template ...>::value>, + // MSVC workaround: it can't compile an out-of-line definition, so defer the collector + typename collector = detail::deferred_t, Args...>> + explicit dict(Args &&...args) : dict(collector(std::forward(args)...).kwargs()) { } + + size_t size() const { return (size_t) PyDict_Size(m_ptr); } + detail::dict_iterator begin() const { return {*this, 0}; } + detail::dict_iterator end() const { return {}; } + void clear() const { PyDict_Clear(ptr()); } + bool contains(handle key) const { return PyDict_Contains(ptr(), key.ptr()) == 1; } + bool contains(const char *key) const { return PyDict_Contains(ptr(), pybind11::str(key).ptr()) == 1; } + +private: + /// Call the `dict` Python type -- always returns a new reference + static PyObject *raw_dict(PyObject *op) { + if (PyDict_Check(op)) + return handle(op).inc_ref().ptr(); + return PyObject_CallFunctionObjArgs((PyObject *) &PyDict_Type, op, nullptr); + } +}; + +class sequence : public object { +public: + PYBIND11_OBJECT_DEFAULT(sequence, object, PySequence_Check) + size_t size() const { return (size_t) PySequence_Size(m_ptr); } + detail::sequence_accessor operator[](size_t index) const { return {*this, index}; } + detail::item_accessor operator[](handle h) const { return object::operator[](h); } + detail::sequence_iterator begin() const { return {*this, 0}; } + detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; } +}; + +class list : public object { +public: + PYBIND11_OBJECT_CVT(list, object, PyList_Check, PySequence_List) + explicit list(size_t size = 0) : object(PyList_New((ssize_t) size), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate list object!"); + } + size_t size() const { return (size_t) PyList_Size(m_ptr); } + detail::list_accessor operator[](size_t index) const { return {*this, index}; } + detail::item_accessor operator[](handle h) const { return object::operator[](h); } + detail::list_iterator begin() const { return {*this, 0}; } + detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; } + template void append(T &&val) const { + PyList_Append(m_ptr, detail::object_or_cast(std::forward(val)).ptr()); + } +}; + +class args : public tuple { PYBIND11_OBJECT_DEFAULT(args, tuple, PyTuple_Check) }; +class kwargs : public dict { PYBIND11_OBJECT_DEFAULT(kwargs, dict, PyDict_Check) }; + +class set : public object { +public: + PYBIND11_OBJECT_CVT(set, object, PySet_Check, PySet_New) + set() : object(PySet_New(nullptr), stolen_t{}) { + if (!m_ptr) pybind11_fail("Could not allocate set object!"); + } + size_t size() const { return (size_t) PySet_Size(m_ptr); } + template bool add(T &&val) const { + return PySet_Add(m_ptr, detail::object_or_cast(std::forward(val)).ptr()) == 0; + } + void clear() const { PySet_Clear(m_ptr); } +}; + +class function : public object { +public: + PYBIND11_OBJECT_DEFAULT(function, object, PyCallable_Check) + handle cpp_function() const { + handle fun = detail::get_function(m_ptr); + if (fun && PyCFunction_Check(fun.ptr())) + return fun; + return handle(); + } + bool is_cpp_function() const { return (bool) cpp_function(); } +}; + +class staticmethod : public object { +public: + PYBIND11_OBJECT_CVT(staticmethod, object, detail::PyStaticMethod_Check, PyStaticMethod_New) +}; + +class buffer : public object { +public: + PYBIND11_OBJECT_DEFAULT(buffer, object, PyObject_CheckBuffer) + + buffer_info request(bool writable = false) { + int flags = PyBUF_STRIDES | PyBUF_FORMAT; + if (writable) flags |= PyBUF_WRITABLE; + Py_buffer *view = new Py_buffer(); + if (PyObject_GetBuffer(m_ptr, view, flags) != 0) { + delete view; + throw error_already_set(); + } + return buffer_info(view); + } +}; + +class memoryview : public object { +public: + explicit memoryview(const buffer_info& info) { + static Py_buffer buf { }; + // Py_buffer uses signed sizes, strides and shape!.. + static std::vector py_strides { }; + static std::vector py_shape { }; + buf.buf = info.ptr; + buf.itemsize = info.itemsize; + buf.format = const_cast(info.format.c_str()); + buf.ndim = (int) info.ndim; + buf.len = info.size; + py_strides.clear(); + py_shape.clear(); + for (size_t i = 0; i < (size_t) info.ndim; ++i) { + py_strides.push_back(info.strides[i]); + py_shape.push_back(info.shape[i]); + } + buf.strides = py_strides.data(); + buf.shape = py_shape.data(); + buf.suboffsets = nullptr; + buf.readonly = false; + buf.internal = nullptr; + + m_ptr = PyMemoryView_FromBuffer(&buf); + if (!m_ptr) + pybind11_fail("Unable to create memoryview from buffer descriptor"); + } + + PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject) +}; +/// @} pytypes + +/// \addtogroup python_builtins +/// @{ +inline size_t len(handle h) { + ssize_t result = PyObject_Length(h.ptr()); + if (result < 0) + pybind11_fail("Unable to compute length of object"); + return (size_t) result; +} + +inline size_t len_hint(handle h) { +#if PY_VERSION_HEX >= 0x03040000 + ssize_t result = PyObject_LengthHint(h.ptr(), 0); +#else + ssize_t result = PyObject_Length(h.ptr()); +#endif + if (result < 0) { + // Sometimes a length can't be determined at all (eg generators) + // In which case simply return 0 + PyErr_Clear(); + return 0; + } + return (size_t) result; +} + +inline str repr(handle h) { + PyObject *str_value = PyObject_Repr(h.ptr()); + if (!str_value) throw error_already_set(); +#if PY_MAJOR_VERSION < 3 + PyObject *unicode = PyUnicode_FromEncodedObject(str_value, "utf-8", nullptr); + Py_XDECREF(str_value); str_value = unicode; + if (!str_value) throw error_already_set(); +#endif + return reinterpret_steal(str_value); +} + +inline iterator iter(handle obj) { + PyObject *result = PyObject_GetIter(obj.ptr()); + if (!result) { throw error_already_set(); } + return reinterpret_steal(result); +} +/// @} python_builtins + +NAMESPACE_BEGIN(detail) +template iterator object_api::begin() const { return iter(derived()); } +template iterator object_api::end() const { return iterator::sentinel(); } +template item_accessor object_api::operator[](handle key) const { + return {derived(), reinterpret_borrow(key)}; +} +template item_accessor object_api::operator[](const char *key) const { + return {derived(), pybind11::str(key)}; +} +template obj_attr_accessor object_api::attr(handle key) const { + return {derived(), reinterpret_borrow(key)}; +} +template str_attr_accessor object_api::attr(const char *key) const { + return {derived(), key}; +} +template args_proxy object_api::operator*() const { + return args_proxy(derived().ptr()); +} +template template bool object_api::contains(T &&item) const { + return attr("__contains__")(std::forward(item)).template cast(); +} + +template +pybind11::str object_api::str() const { return pybind11::str(derived()); } + +template +str_attr_accessor object_api::doc() const { return attr("__doc__"); } + +template +handle object_api::get_type() const { return (PyObject *) Py_TYPE(derived().ptr()); } + +template +bool object_api::rich_compare(object_api const &other, int value) const { + int rv = PyObject_RichCompareBool(derived().ptr(), other.derived().ptr(), value); + if (rv == -1) + throw error_already_set(); + return rv == 1; +} + +#define PYBIND11_MATH_OPERATOR_UNARY(op, fn) \ + template object object_api::op() const { \ + object result = reinterpret_steal(fn(derived().ptr())); \ + if (!result.ptr()) \ + throw error_already_set(); \ + return result; \ + } + +#define PYBIND11_MATH_OPERATOR_BINARY(op, fn) \ + template \ + object object_api::op(object_api const &other) const { \ + object result = reinterpret_steal( \ + fn(derived().ptr(), other.derived().ptr())); \ + if (!result.ptr()) \ + throw error_already_set(); \ + return result; \ + } + +PYBIND11_MATH_OPERATOR_UNARY (operator~, PyNumber_Invert) +PYBIND11_MATH_OPERATOR_UNARY (operator-, PyNumber_Negative) +PYBIND11_MATH_OPERATOR_BINARY(operator+, PyNumber_Add) +PYBIND11_MATH_OPERATOR_BINARY(operator+=, PyNumber_InPlaceAdd) +PYBIND11_MATH_OPERATOR_BINARY(operator-, PyNumber_Subtract) +PYBIND11_MATH_OPERATOR_BINARY(operator-=, PyNumber_InPlaceSubtract) +PYBIND11_MATH_OPERATOR_BINARY(operator*, PyNumber_Multiply) +PYBIND11_MATH_OPERATOR_BINARY(operator*=, PyNumber_InPlaceMultiply) +PYBIND11_MATH_OPERATOR_BINARY(operator/, PyNumber_TrueDivide) +PYBIND11_MATH_OPERATOR_BINARY(operator/=, PyNumber_InPlaceTrueDivide) +PYBIND11_MATH_OPERATOR_BINARY(operator|, PyNumber_Or) +PYBIND11_MATH_OPERATOR_BINARY(operator|=, PyNumber_InPlaceOr) +PYBIND11_MATH_OPERATOR_BINARY(operator&, PyNumber_And) +PYBIND11_MATH_OPERATOR_BINARY(operator&=, PyNumber_InPlaceAnd) +PYBIND11_MATH_OPERATOR_BINARY(operator^, PyNumber_Xor) +PYBIND11_MATH_OPERATOR_BINARY(operator^=, PyNumber_InPlaceXor) +PYBIND11_MATH_OPERATOR_BINARY(operator<<, PyNumber_Lshift) +PYBIND11_MATH_OPERATOR_BINARY(operator<<=, PyNumber_InPlaceLshift) +PYBIND11_MATH_OPERATOR_BINARY(operator>>, PyNumber_Rshift) +PYBIND11_MATH_OPERATOR_BINARY(operator>>=, PyNumber_InPlaceRshift) + +#undef PYBIND11_MATH_OPERATOR_UNARY +#undef PYBIND11_MATH_OPERATOR_BINARY + +NAMESPACE_END(detail) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/pybind11/stl.h b/python/src/pybind11/stl.h new file mode 100644 index 000000000..32f8d294a --- /dev/null +++ b/python/src/pybind11/stl.h @@ -0,0 +1,386 @@ +/* + pybind11/stl.h: Transparent conversion for STL data types + + Copyright (c) 2016 Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "pybind11.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4127) // warning C4127: Conditional expression is constant +#endif + +#ifdef __has_include +// std::optional (but including it in c++14 mode isn't allowed) +# if defined(PYBIND11_CPP17) && __has_include() +# include +# define PYBIND11_HAS_OPTIONAL 1 +# endif +// std::experimental::optional (but not allowed in c++11 mode) +# if defined(PYBIND11_CPP14) && (__has_include() && \ + !__has_include()) +# include +# define PYBIND11_HAS_EXP_OPTIONAL 1 +# endif +// std::variant +# if defined(PYBIND11_CPP17) && __has_include() +# include +# define PYBIND11_HAS_VARIANT 1 +# endif +#elif defined(_MSC_VER) && defined(PYBIND11_CPP17) +# include +# include +# define PYBIND11_HAS_OPTIONAL 1 +# define PYBIND11_HAS_VARIANT 1 +#endif + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +/// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for +/// forwarding a container element). Typically used indirect via forwarded_type(), below. +template +using forwarded_type = conditional_t< + std::is_lvalue_reference::value, remove_reference_t &, remove_reference_t &&>; + +/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically +/// used for forwarding a container's elements. +template +forwarded_type forward_like(U &&u) { + return std::forward>(std::forward(u)); +} + +template struct set_caster { + using type = Type; + using key_conv = make_caster; + + bool load(handle src, bool convert) { + if (!isinstance(src)) + return false; + auto s = reinterpret_borrow(src); + value.clear(); + for (auto entry : s) { + key_conv conv; + if (!conv.load(entry, convert)) + return false; + value.insert(cast_op(std::move(conv))); + } + return true; + } + + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + if (!std::is_lvalue_reference::value) + policy = return_value_policy_override::policy(policy); + pybind11::set s; + for (auto &&value : src) { + auto value_ = reinterpret_steal(key_conv::cast(forward_like(value), policy, parent)); + if (!value_ || !s.add(value_)) + return handle(); + } + return s.release(); + } + + PYBIND11_TYPE_CASTER(type, _("Set[") + key_conv::name + _("]")); +}; + +template struct map_caster { + using key_conv = make_caster; + using value_conv = make_caster; + + bool load(handle src, bool convert) { + if (!isinstance(src)) + return false; + auto d = reinterpret_borrow(src); + value.clear(); + for (auto it : d) { + key_conv kconv; + value_conv vconv; + if (!kconv.load(it.first.ptr(), convert) || + !vconv.load(it.second.ptr(), convert)) + return false; + value.emplace(cast_op(std::move(kconv)), cast_op(std::move(vconv))); + } + return true; + } + + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + dict d; + return_value_policy policy_key = policy; + return_value_policy policy_value = policy; + if (!std::is_lvalue_reference::value) { + policy_key = return_value_policy_override::policy(policy_key); + policy_value = return_value_policy_override::policy(policy_value); + } + for (auto &&kv : src) { + auto key = reinterpret_steal(key_conv::cast(forward_like(kv.first), policy_key, parent)); + auto value = reinterpret_steal(value_conv::cast(forward_like(kv.second), policy_value, parent)); + if (!key || !value) + return handle(); + d[key] = value; + } + return d.release(); + } + + PYBIND11_TYPE_CASTER(Type, _("Dict[") + key_conv::name + _(", ") + value_conv::name + _("]")); +}; + +template struct list_caster { + using value_conv = make_caster; + + bool load(handle src, bool convert) { + if (!isinstance(src) || isinstance(src)) + return false; + auto s = reinterpret_borrow(src); + value.clear(); + reserve_maybe(s, &value); + for (auto it : s) { + value_conv conv; + if (!conv.load(it, convert)) + return false; + value.push_back(cast_op(std::move(conv))); + } + return true; + } + +private: + template ().reserve(0)), void>::value, int> = 0> + void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); } + void reserve_maybe(sequence, void *) { } + +public: + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + if (!std::is_lvalue_reference::value) + policy = return_value_policy_override::policy(policy); + list l(src.size()); + size_t index = 0; + for (auto &&value : src) { + auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); + if (!value_) + return handle(); + PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference + } + return l.release(); + } + + PYBIND11_TYPE_CASTER(Type, _("List[") + value_conv::name + _("]")); +}; + +template struct type_caster> + : list_caster, Type> { }; + +template struct type_caster> + : list_caster, Type> { }; + +template struct type_caster> + : list_caster, Type> { }; + +template struct array_caster { + using value_conv = make_caster; + +private: + template + bool require_size(enable_if_t size) { + if (value.size() != size) + value.resize(size); + return true; + } + template + bool require_size(enable_if_t size) { + return size == Size; + } + +public: + bool load(handle src, bool convert) { + if (!isinstance(src)) + return false; + auto l = reinterpret_borrow(src); + if (!require_size(l.size())) + return false; + size_t ctr = 0; + for (auto it : l) { + value_conv conv; + if (!conv.load(it, convert)) + return false; + value[ctr++] = cast_op(std::move(conv)); + } + return true; + } + + template + static handle cast(T &&src, return_value_policy policy, handle parent) { + list l(src.size()); + size_t index = 0; + for (auto &&value : src) { + auto value_ = reinterpret_steal(value_conv::cast(forward_like(value), policy, parent)); + if (!value_) + return handle(); + PyList_SET_ITEM(l.ptr(), (ssize_t) index++, value_.release().ptr()); // steals a reference + } + return l.release(); + } + + PYBIND11_TYPE_CASTER(ArrayType, _("List[") + value_conv::name + _(_(""), _("[") + _() + _("]")) + _("]")); +}; + +template struct type_caster> + : array_caster, Type, false, Size> { }; + +template struct type_caster> + : array_caster, Type, true> { }; + +template struct type_caster> + : set_caster, Key> { }; + +template struct type_caster> + : set_caster, Key> { }; + +template struct type_caster> + : map_caster, Key, Value> { }; + +template struct type_caster> + : map_caster, Key, Value> { }; + +// This type caster is intended to be used for std::optional and std::experimental::optional +template struct optional_caster { + using value_conv = make_caster; + + template + static handle cast(T_ &&src, return_value_policy policy, handle parent) { + if (!src) + return none().inc_ref(); + policy = return_value_policy_override::policy(policy); + return value_conv::cast(*std::forward(src), policy, parent); + } + + bool load(handle src, bool convert) { + if (!src) { + return false; + } else if (src.is_none()) { + return true; // default-constructed value is already empty + } + value_conv inner_caster; + if (!inner_caster.load(src, convert)) + return false; + + value.emplace(cast_op(std::move(inner_caster))); + return true; + } + + PYBIND11_TYPE_CASTER(T, _("Optional[") + value_conv::name + _("]")); +}; + +#if PYBIND11_HAS_OPTIONAL +template struct type_caster> + : public optional_caster> {}; + +template<> struct type_caster + : public void_caster {}; +#endif + +#if PYBIND11_HAS_EXP_OPTIONAL +template struct type_caster> + : public optional_caster> {}; + +template<> struct type_caster + : public void_caster {}; +#endif + +/// Visit a variant and cast any found type to Python +struct variant_caster_visitor { + return_value_policy policy; + handle parent; + + using result_type = handle; // required by boost::variant in C++11 + + template + result_type operator()(T &&src) const { + return make_caster::cast(std::forward(src), policy, parent); + } +}; + +/// Helper class which abstracts away variant's `visit` function. `std::variant` and similar +/// `namespace::variant` types which provide a `namespace::visit()` function are handled here +/// automatically using argument-dependent lookup. Users can provide specializations for other +/// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`. +template class Variant> +struct visit_helper { + template + static auto call(Args &&...args) -> decltype(visit(std::forward(args)...)) { + return visit(std::forward(args)...); + } +}; + +/// Generic variant caster +template struct variant_caster; + +template class V, typename... Ts> +struct variant_caster> { + static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative."); + + template + bool load_alternative(handle src, bool convert, type_list) { + auto caster = make_caster(); + if (caster.load(src, convert)) { + value = cast_op(caster); + return true; + } + return load_alternative(src, convert, type_list{}); + } + + bool load_alternative(handle, bool, type_list<>) { return false; } + + bool load(handle src, bool convert) { + // Do a first pass without conversions to improve constructor resolution. + // E.g. `py::int_(1).cast>()` needs to fill the `int` + // slot of the variant. Without two-pass loading `double` would be filled + // because it appears first and a conversion is possible. + if (convert && load_alternative(src, false, type_list{})) + return true; + return load_alternative(src, convert, type_list{}); + } + + template + static handle cast(Variant &&src, return_value_policy policy, handle parent) { + return visit_helper::call(variant_caster_visitor{policy, parent}, + std::forward(src)); + } + + using Type = V; + PYBIND11_TYPE_CASTER(Type, _("Union[") + detail::concat(make_caster::name...) + _("]")); +}; + +#if PYBIND11_HAS_VARIANT +template +struct type_caster> : variant_caster> { }; +#endif + +NAMESPACE_END(detail) + +inline std::ostream &operator<<(std::ostream &os, const handle &obj) { + os << (std::string) str(obj); + return os; +} + +NAMESPACE_END(PYBIND11_NAMESPACE) + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif diff --git a/python/src/pybind11/stl_bind.h b/python/src/pybind11/stl_bind.h new file mode 100644 index 000000000..1f8725260 --- /dev/null +++ b/python/src/pybind11/stl_bind.h @@ -0,0 +1,630 @@ +/* + pybind11/std_bind.h: Binding generators for STL data types + + Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob + + All rights reserved. Use of this source code is governed by a + BSD-style license that can be found in the LICENSE file. +*/ + +#pragma once + +#include "detail/common.h" +#include "operators.h" + +#include +#include + +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) +NAMESPACE_BEGIN(detail) + +/* SFINAE helper class used by 'is_comparable */ +template struct container_traits { + template static std::true_type test_comparable(decltype(std::declval() == std::declval())*); + template static std::false_type test_comparable(...); + template static std::true_type test_value(typename T2::value_type *); + template static std::false_type test_value(...); + template static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *); + template static std::false_type test_pair(...); + + static constexpr const bool is_comparable = std::is_same(nullptr))>::value; + static constexpr const bool is_pair = std::is_same(nullptr, nullptr))>::value; + static constexpr const bool is_vector = std::is_same(nullptr))>::value; + static constexpr const bool is_element = !is_pair && !is_vector; +}; + +/* Default: is_comparable -> std::false_type */ +template +struct is_comparable : std::false_type { }; + +/* For non-map data structures, check whether operator== can be instantiated */ +template +struct is_comparable< + T, enable_if_t::is_element && + container_traits::is_comparable>> + : std::true_type { }; + +/* For a vector/map data structure, recursively check the value type (which is std::pair for maps) */ +template +struct is_comparable::is_vector>> { + static constexpr const bool value = + is_comparable::value; +}; + +/* For pairs, recursively check the two data types */ +template +struct is_comparable::is_pair>> { + static constexpr const bool value = + is_comparable::value && + is_comparable::value; +}; + +/* Fallback functions */ +template void vector_if_copy_constructible(const Args &...) { } +template void vector_if_equal_operator(const Args &...) { } +template void vector_if_insertion_operator(const Args &...) { } +template void vector_modifiers(const Args &...) { } + +template +void vector_if_copy_constructible(enable_if_t::value, Class_> &cl) { + cl.def(init(), "Copy constructor"); +} + +template +void vector_if_equal_operator(enable_if_t::value, Class_> &cl) { + using T = typename Vector::value_type; + + cl.def(self == self); + cl.def(self != self); + + cl.def("count", + [](const Vector &v, const T &x) { + return std::count(v.begin(), v.end(), x); + }, + arg("x"), + "Return the number of times ``x`` appears in the list" + ); + + cl.def("remove", [](Vector &v, const T &x) { + auto p = std::find(v.begin(), v.end(), x); + if (p != v.end()) + v.erase(p); + else + throw value_error(); + }, + arg("x"), + "Remove the first item from the list whose value is x. " + "It is an error if there is no such item." + ); + + cl.def("__contains__", + [](const Vector &v, const T &x) { + return std::find(v.begin(), v.end(), x) != v.end(); + }, + arg("x"), + "Return true the container contains ``x``" + ); +} + +// Vector modifiers -- requires a copyable vector_type: +// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it seems +// silly to allow deletion but not insertion, so include them here too.) +template +void vector_modifiers(enable_if_t::value, Class_> &cl) { + using T = typename Vector::value_type; + using SizeType = typename Vector::size_type; + using DiffType = typename Vector::difference_type; + + cl.def("append", + [](Vector &v, const T &value) { v.push_back(value); }, + arg("x"), + "Add an item to the end of the list"); + + cl.def(init([](iterable it) { + auto v = std::unique_ptr(new Vector()); + v->reserve(len_hint(it)); + for (handle h : it) + v->push_back(h.cast()); + return v.release(); + })); + + cl.def("extend", + [](Vector &v, const Vector &src) { + v.insert(v.end(), src.begin(), src.end()); + }, + arg("L"), + "Extend the list by appending all the items in the given list" + ); + + cl.def("extend", + [](Vector &v, iterable it) { + const size_t old_size = v.size(); + v.reserve(old_size + len_hint(it)); + try { + for (handle h : it) { + v.push_back(h.cast()); + } + } catch (const cast_error &) { + v.erase(v.begin() + static_cast(old_size), v.end()); + try { + v.shrink_to_fit(); + } catch (const std::exception &) { + // Do nothing + } + throw; + } + }, + arg("L"), + "Extend the list by appending all the items in the given list" + ); + + cl.def("insert", + [](Vector &v, SizeType i, const T &x) { + if (i > v.size()) + throw index_error(); + v.insert(v.begin() + (DiffType) i, x); + }, + arg("i") , arg("x"), + "Insert an item at a given position." + ); + + cl.def("pop", + [](Vector &v) { + if (v.empty()) + throw index_error(); + T t = v.back(); + v.pop_back(); + return t; + }, + "Remove and return the last item" + ); + + cl.def("pop", + [](Vector &v, SizeType i) { + if (i >= v.size()) + throw index_error(); + T t = v[i]; + v.erase(v.begin() + (DiffType) i); + return t; + }, + arg("i"), + "Remove and return the item at index ``i``" + ); + + cl.def("__setitem__", + [](Vector &v, SizeType i, const T &t) { + if (i >= v.size()) + throw index_error(); + v[i] = t; + } + ); + + /// Slicing protocol + cl.def("__getitem__", + [](const Vector &v, slice slice) -> Vector * { + size_t start, stop, step, slicelength; + + if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) + throw error_already_set(); + + Vector *seq = new Vector(); + seq->reserve((size_t) slicelength); + + for (size_t i=0; ipush_back(v[start]); + start += step; + } + return seq; + }, + arg("s"), + "Retrieve list elements using a slice object" + ); + + cl.def("__setitem__", + [](Vector &v, slice slice, const Vector &value) { + size_t start, stop, step, slicelength; + if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) + throw error_already_set(); + + if (slicelength != value.size()) + throw std::runtime_error("Left and right hand size of slice assignment have different sizes!"); + + for (size_t i=0; i= v.size()) + throw index_error(); + v.erase(v.begin() + DiffType(i)); + }, + "Delete the list elements at index ``i``" + ); + + cl.def("__delitem__", + [](Vector &v, slice slice) { + size_t start, stop, step, slicelength; + + if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) + throw error_already_set(); + + if (step == 1 && false) { + v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength)); + } else { + for (size_t i = 0; i < slicelength; ++i) { + v.erase(v.begin() + DiffType(start)); + start += step - 1; + } + } + }, + "Delete list elements using a slice object" + ); + +} + +// If the type has an operator[] that doesn't return a reference (most notably std::vector), +// we have to access by copying; otherwise we return by reference. +template using vector_needs_copy = negation< + std::is_same()[typename Vector::size_type()]), typename Vector::value_type &>>; + +// The usual case: access and iterate by reference +template +void vector_accessor(enable_if_t::value, Class_> &cl) { + using T = typename Vector::value_type; + using SizeType = typename Vector::size_type; + using ItType = typename Vector::iterator; + + cl.def("__getitem__", + [](Vector &v, SizeType i) -> T & { + if (i >= v.size()) + throw index_error(); + return v[i]; + }, + return_value_policy::reference_internal // ref + keepalive + ); + + cl.def("__iter__", + [](Vector &v) { + return make_iterator< + return_value_policy::reference_internal, ItType, ItType, T&>( + v.begin(), v.end()); + }, + keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ + ); +} + +// The case for special objects, like std::vector, that have to be returned-by-copy: +template +void vector_accessor(enable_if_t::value, Class_> &cl) { + using T = typename Vector::value_type; + using SizeType = typename Vector::size_type; + using ItType = typename Vector::iterator; + cl.def("__getitem__", + [](const Vector &v, SizeType i) -> T { + if (i >= v.size()) + throw index_error(); + return v[i]; + } + ); + + cl.def("__iter__", + [](Vector &v) { + return make_iterator< + return_value_policy::copy, ItType, ItType, T>( + v.begin(), v.end()); + }, + keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ + ); +} + +template auto vector_if_insertion_operator(Class_ &cl, std::string const &name) + -> decltype(std::declval() << std::declval(), void()) { + using size_type = typename Vector::size_type; + + cl.def("__repr__", + [name](Vector &v) { + std::ostringstream s; + s << name << '['; + for (size_type i=0; i < v.size(); ++i) { + s << v[i]; + if (i != v.size() - 1) + s << ", "; + } + s << ']'; + return s.str(); + }, + "Return the canonical string representation of this list." + ); +} + +// Provide the buffer interface for vectors if we have data() and we have a format for it +// GCC seems to have "void std::vector::data()" - doing SFINAE on the existence of data() is insufficient, we need to check it returns an appropriate pointer +template +struct vector_has_data_and_format : std::false_type {}; +template +struct vector_has_data_and_format::format(), std::declval().data()), typename Vector::value_type*>::value>> : std::true_type {}; + +// Add the buffer interface to a vector +template +enable_if_t...>::value> +vector_buffer(Class_& cl) { + using T = typename Vector::value_type; + + static_assert(vector_has_data_and_format::value, "There is not an appropriate format descriptor for this vector"); + + // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here + format_descriptor::format(); + + cl.def_buffer([](Vector& v) -> buffer_info { + return buffer_info(v.data(), static_cast(sizeof(T)), format_descriptor::format(), 1, {v.size()}, {sizeof(T)}); + }); + + cl.def(init([](buffer buf) { + auto info = buf.request(); + if (info.ndim != 1 || info.strides[0] % static_cast(sizeof(T))) + throw type_error("Only valid 1D buffers can be copied to a vector"); + if (!detail::compare_buffer_info::compare(info) || (ssize_t) sizeof(T) != info.itemsize) + throw type_error("Format mismatch (Python: " + info.format + " C++: " + format_descriptor::format() + ")"); + + auto vec = std::unique_ptr(new Vector()); + vec->reserve((size_t) info.shape[0]); + T *p = static_cast(info.ptr); + ssize_t step = info.strides[0] / static_cast(sizeof(T)); + T *end = p + info.shape[0] * step; + for (; p != end; p += step) + vec->push_back(*p); + return vec.release(); + })); + + return; +} + +template +enable_if_t...>::value> vector_buffer(Class_&) {} + +NAMESPACE_END(detail) + +// +// std::vector +// +template , typename... Args> +class_ bind_vector(handle scope, std::string const &name, Args&&... args) { + using Class_ = class_; + + // If the value_type is unregistered (e.g. a converting type) or is itself registered + // module-local then make the vector binding module-local as well: + using vtype = typename Vector::value_type; + auto vtype_info = detail::get_type_info(typeid(vtype)); + bool local = !vtype_info || vtype_info->module_local; + + Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); + + // Declare the buffer interface if a buffer_protocol() is passed in + detail::vector_buffer(cl); + + cl.def(init<>()); + + // Register copy constructor (if possible) + detail::vector_if_copy_constructible(cl); + + // Register comparison-related operators and functions (if possible) + detail::vector_if_equal_operator(cl); + + // Register stream insertion operator (if possible) + detail::vector_if_insertion_operator(cl, name); + + // Modifiers require copyable vector value type + detail::vector_modifiers(cl); + + // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive + detail::vector_accessor(cl); + + cl.def("__bool__", + [](const Vector &v) -> bool { + return !v.empty(); + }, + "Check whether the list is nonempty" + ); + + cl.def("__len__", &Vector::size); + + + + +#if 0 + // C++ style functions deprecated, leaving it here as an example + cl.def(init()); + + cl.def("resize", + (void (Vector::*) (size_type count)) & Vector::resize, + "changes the number of elements stored"); + + cl.def("erase", + [](Vector &v, SizeType i) { + if (i >= v.size()) + throw index_error(); + v.erase(v.begin() + i); + }, "erases element at index ``i``"); + + cl.def("empty", &Vector::empty, "checks whether the container is empty"); + cl.def("size", &Vector::size, "returns the number of elements"); + cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end"); + cl.def("pop_back", &Vector::pop_back, "removes the last element"); + + cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements"); + cl.def("reserve", &Vector::reserve, "reserves storage"); + cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage"); + cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory"); + + cl.def("clear", &Vector::clear, "clears the contents"); + cl.def("swap", &Vector::swap, "swaps the contents"); + + cl.def("front", [](Vector &v) { + if (v.size()) return v.front(); + else throw index_error(); + }, "access the first element"); + + cl.def("back", [](Vector &v) { + if (v.size()) return v.back(); + else throw index_error(); + }, "access the last element "); + +#endif + + return cl; +} + + + +// +// std::map, std::unordered_map +// + +NAMESPACE_BEGIN(detail) + +/* Fallback functions */ +template void map_if_insertion_operator(const Args &...) { } +template void map_assignment(const Args &...) { } + +// Map assignment when copy-assignable: just copy the value +template +void map_assignment(enable_if_t::value, Class_> &cl) { + using KeyType = typename Map::key_type; + using MappedType = typename Map::mapped_type; + + cl.def("__setitem__", + [](Map &m, const KeyType &k, const MappedType &v) { + auto it = m.find(k); + if (it != m.end()) it->second = v; + else m.emplace(k, v); + } + ); +} + +// Not copy-assignable, but still copy-constructible: we can update the value by erasing and reinserting +template +void map_assignment(enable_if_t< + !std::is_copy_assignable::value && + is_copy_constructible::value, + Class_> &cl) { + using KeyType = typename Map::key_type; + using MappedType = typename Map::mapped_type; + + cl.def("__setitem__", + [](Map &m, const KeyType &k, const MappedType &v) { + // We can't use m[k] = v; because value type might not be default constructable + auto r = m.emplace(k, v); + if (!r.second) { + // value type is not copy assignable so the only way to insert it is to erase it first... + m.erase(r.first); + m.emplace(k, v); + } + } + ); +} + + +template auto map_if_insertion_operator(Class_ &cl, std::string const &name) +-> decltype(std::declval() << std::declval() << std::declval(), void()) { + + cl.def("__repr__", + [name](Map &m) { + std::ostringstream s; + s << name << '{'; + bool f = false; + for (auto const &kv : m) { + if (f) + s << ", "; + s << kv.first << ": " << kv.second; + f = true; + } + s << '}'; + return s.str(); + }, + "Return the canonical string representation of this map." + ); +} + + +NAMESPACE_END(detail) + +template , typename... Args> +class_ bind_map(handle scope, const std::string &name, Args&&... args) { + using KeyType = typename Map::key_type; + using MappedType = typename Map::mapped_type; + using Class_ = class_; + + // If either type is a non-module-local bound type then make the map binding non-local as well; + // otherwise (e.g. both types are either module-local or converting) the map will be + // module-local. + auto tinfo = detail::get_type_info(typeid(MappedType)); + bool local = !tinfo || tinfo->module_local; + if (local) { + tinfo = detail::get_type_info(typeid(KeyType)); + local = !tinfo || tinfo->module_local; + } + + Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward(args)...); + + cl.def(init<>()); + + // Register stream insertion operator (if possible) + detail::map_if_insertion_operator(cl, name); + + cl.def("__bool__", + [](const Map &m) -> bool { return !m.empty(); }, + "Check whether the map is nonempty" + ); + + cl.def("__iter__", + [](Map &m) { return make_key_iterator(m.begin(), m.end()); }, + keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ + ); + + cl.def("items", + [](Map &m) { return make_iterator(m.begin(), m.end()); }, + keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ + ); + + cl.def("__getitem__", + [](Map &m, const KeyType &k) -> MappedType & { + auto it = m.find(k); + if (it == m.end()) + throw key_error(); + return it->second; + }, + return_value_policy::reference_internal // ref + keepalive + ); + + cl.def("__contains__", + [](Map &m, const KeyType &k) -> bool { + auto it = m.find(k); + if (it == m.end()) + return false; + return true; + } + ); + + // Assignment provided only if the type is copyable + detail::map_assignment(cl); + + cl.def("__delitem__", + [](Map &m, const KeyType &k) { + auto it = m.find(k); + if (it == m.end()) + throw key_error(); + m.erase(it); + } + ); + + cl.def("__len__", &Map::size); + + return cl; +} + +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/python/src/tensorflow.cpp b/python/src/tensorflow.cpp new file mode 100644 index 000000000..12e64fa4f --- /dev/null +++ b/python/src/tensorflow.cpp @@ -0,0 +1,224 @@ +#include +#include +#include +#include +#include +#include "triton/codegen/selection/selection.h" +#include "triton/runtime/function.h" +#include "triton/lang/lang.h" +#include "triton/driver/device.h" +#include "triton/driver/stream.h" +#include "triton/driver/kernel.h" +#include "triton/driver/module.h" +#include "triton/ir/module.h" +#include "triton/ir/function.h" +#include "triton/tools/bench.hpp" + +typedef struct yy_buffer_state * YY_BUFFER_STATE; +extern int yyparse(); +extern YY_BUFFER_STATE yy_scan_string(const char * str); +extern void yy_delete_buffer(YY_BUFFER_STATE buffer); +extern triton::lang::translation_unit *ast_root; + +using namespace triton; + +inline std::string to_tf_ty(ir::type *ty) { + if(ty->is_integer_ty(1)) + return "bool"; + if(ty->is_integer_ty(8)) + return "int8"; + if(ty->is_integer_ty(16)) + return "int16"; + if(ty->is_integer_ty(32)) + return "int32"; + if(ty->is_integer_ty(64)) + return "int64"; + if(ty->is_half_ty()) + return "float16"; + if(ty->is_float_ty()) + return "float32"; + if(ty->is_double_ty()) + return "float64"; + if(ty->is_pointer_ty()) + return "Tensor"; + throw std::runtime_error("unknown type"); +} + +inline std::string to_tf_scalar_ty(ir::type *ty) { + if(ty->is_pointer_ty()) + return to_tf_ty(ty->get_pointer_element_ty()); + else { + return to_tf_ty(ty); + } +} + +inline std::string ref_to_tf_ty(ir::type *ty) { + std::string res = to_tf_ty(ty); + if(ty->is_pointer_ty()) + res = "const " + res + "&"; + return res; +} + +inline triton::lang::translation_unit *make_ast(const char *src) { + YY_BUFFER_STATE buffer = yy_scan_string(src); + yyparse(); + yy_delete_buffer(buffer); + triton::lang::translation_unit *program = ast_root; + return program; +} + +inline std::unique_ptr make_ir(ir::context& ctx, triton::lang::translation_unit *program) { + // create Triton-IR from AST + ir::module* module = new ir::module("", ctx); + program->codegen(module); + return std::unique_ptr(module); +} + +std::string make_tensorflow_src(const std::string src, + const std::vector& outputs, + const std::string& macro) { + triton::lang::translation_unit *ast = make_ast(src.c_str()); + triton::ir::context context; + std::unique_ptr ir = make_ir(context, ast); + // extract function signature + ir::function* fn = ir->get_function_list().front(); + ir::function_type* fn_ty = fn->get_fn_type(); + // numberof arguments + size_t n_args = fn_ty->get_num_params(); + size_t n_outputs = outputs.size(); + // extract function name + std::string name = fn->get_name(); + name[0] = static_cast(std::toupper(name[0])); + std::string classname = name + "Op"; + // extract argument name + std::vector arg_names; + for(ir::argument *arg: fn->args()) + arg_names.push_back(arg->get_name()); + // cached int to str + std::vector str_i; + for(size_t i = 0; i < fn_ty->get_num_params(); i++) + str_i.push_back(std::to_string(i)); + // index of tensors + std::vector ptr_idx; + for(unsigned i = 0; i < fn_ty->get_num_params(); i++) + if(fn_ty->get_param_ty(i)->is_pointer_ty()) + ptr_idx.push_back(i); + // extract tensorflow types + std::vector tf_scalar_tys; + std::transform(fn_ty->params_begin(), fn_ty->params_end(), std::back_inserter(tf_scalar_tys), to_tf_scalar_ty); + std::vector tf_cref_tys; + std::transform(fn_ty->params_begin(), fn_ty->params_end(), std::back_inserter(tf_cref_tys), ref_to_tf_ty); + + std::ostringstream oss; + + std::string result = R"( +#include "triton/driver/buffer.h" +#include "triton/driver/backend.h" +#include "triton/driver/stream.h" +#include "triton/runtime/function.h" + +#define EIGEN_USE_GPU +#include "tensorflow/core/framework/op.h" +#include "tensorflow/core/framework/shape_inference.h" +#include "tensorflow/core/framework/op_kernel.h" +#include "tensorflow/core/util/cuda_kernel_helper.h" +#include "tensorflow/core/util/padding.h" +#include "tensorflow/core/util/tensor_format.h" +#include "tensorflow/core/framework/common_shape_fns.h" + +using namespace tensorflow; +using GPUDevice = Eigen::GpuDevice; +namespace rt = triton::runtime; +namespace drv = triton::driver; + +std::string src = R"TTKERNSRC( )" + src + ")TTKERNSRC\";" + R"( + +class )" + classname + R"(: public OpKernel { + public: + explicit )" + classname + R"((OpKernelConstruction* context) + : OpKernel(context), fn_(src) { } + + void Compute(OpKernelContext* context){ + + // get device/stream + GPUDevice device = context->eigen_device(); + drv::cu_stream sstream(device.stream(), false); + drv::context* ctx = sstream.context(); + drv::stream* stream = &sstream; + + // extract inputs)"; +for(unsigned i = 0; i < n_args; i++){ + std::string suffix = ""; + std::string ty = tf_cref_tys[i]; + if(!fn_ty->get_param_ty(i)->is_pointer_ty()) + suffix = ".scalar<" + ty + ">()()"; + result += R"( + )" + ty + " " + arg_names[i] + " = context->input(" + str_i[i] + ")" + suffix + ";"; +} + +result += R"( + + // extract outputs)"; +for(unsigned i = 0; i < n_outputs; i++) + result += R"( + context->set_output()" + str_i[i] + ", " + arg_names[outputs[i]] + ");"; + +result += R"( + + // wrap tensors)"; +for(size_t i: ptr_idx) +result += R"( + drv::cu_buffer cu_)" + arg_names[i] + "(ctx, " + arg_names[i] + ".tensor_data().size(), (CUdeviceptr)" + arg_names[i] + R"(.tensor_data().data(), false);)"; + + +std::regex regex("#([a-zA-Z]([a-zA-Z]|[0-9])*)"); +std::string grid_str = std::regex_replace(macro, regex, "x.at(\"$1\")"); + +result += R"( + + // create launch grid; + auto grid = [&](const rt::params_t& x) { return rt::grid_t{)" + grid_str + R"(}; };)"; + +result += R"( + + // execute function + fn_({ + )"; +for(unsigned i = 0; i < n_args; i++){ + std::string arg = arg_names[i]; + if(fn_ty->get_param_ty(i)->is_pointer_ty()) + arg = "&cu_" + arg; + if(i > 0) + result += ", "; + result += arg; +} +result += R"( + }, grid, stream); + + } + +private: + rt::function fn_; +}; + +REGISTER_KERNEL_BUILDER(Name(")" + name + "\").Device(DEVICE_GPU), " + classname + R"(); + +REGISTER_OP(")" + name + "\")\n"; +for(size_t i = 0; i < tf_scalar_tys.size(); i++){ + bool is_output = std::find(outputs.begin(), outputs.end(), i) != outputs.end(); + std::string mode = is_output ? "Output" : "Input" ; + std::string arg_name = arg_names[i]; + std::transform(arg_name.begin(), arg_name.end(), arg_name.begin(), [](char c) { return std::tolower(c);}); + result += " ." + mode + "(\"" + arg_name + ": " + tf_scalar_tys[i] + "\")\n"; +} +result += ";\n"; + + + return result; +} + + +PYBIND11_MODULE(libtriton, m) { + m.doc() = "Python bindings to the C++ Triton API"; + m.def("make_tensorflow_src", &make_tensorflow_src, "Creates C++ source code for a custom Tensorflow op corresponding to the specified Triton kernel"); +}