From c79706ff4ce591df2151db5504d3c224f3c9965f Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Mon, 27 Feb 2017 13:17:51 +0000 Subject: ext: Add pybind rev f4b81b3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I52e4fc9ebf2f59da57d8cf8f3e37cc79598c2f5f Signed-off-by: Andreas Sandberg Reviewed-by: Andreas Hansson Reviewed-by: Curtis Dunham Reviewed-on: https://gem5-review.googlesource.com/2229 Reviewed-by: Tony Gutierrez Reviewed-by: Jason Lowe-Power Reviewed-by: Pierre-Yves PĂ©neau --- ext/pybind11/tests/test_buffers.cpp | 117 ++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 ext/pybind11/tests/test_buffers.cpp (limited to 'ext/pybind11/tests/test_buffers.cpp') diff --git a/ext/pybind11/tests/test_buffers.cpp b/ext/pybind11/tests/test_buffers.cpp new file mode 100644 index 000000000..c3a7a9e02 --- /dev/null +++ b/ext/pybind11/tests/test_buffers.cpp @@ -0,0 +1,117 @@ +/* + tests/test_buffers.cpp -- supporting Pythons' buffer protocol + + 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. +*/ + +#include "pybind11_tests.h" +#include "constructor_stats.h" + +class Matrix { +public: + Matrix(size_t rows, size_t cols) : m_rows(rows), m_cols(cols) { + print_created(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); + m_data = new float[rows*cols]; + memset(m_data, 0, sizeof(float) * rows * cols); + } + + Matrix(const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) { + print_copy_created(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); + m_data = new float[m_rows * m_cols]; + memcpy(m_data, s.m_data, sizeof(float) * m_rows * m_cols); + } + + Matrix(Matrix &&s) : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) { + print_move_created(this); + s.m_rows = 0; + s.m_cols = 0; + s.m_data = nullptr; + } + + ~Matrix() { + print_destroyed(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); + delete[] m_data; + } + + Matrix &operator=(const Matrix &s) { + print_copy_assigned(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); + delete[] m_data; + m_rows = s.m_rows; + m_cols = s.m_cols; + m_data = new float[m_rows * m_cols]; + memcpy(m_data, s.m_data, sizeof(float) * m_rows * m_cols); + return *this; + } + + Matrix &operator=(Matrix &&s) { + print_move_assigned(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix"); + if (&s != this) { + delete[] m_data; + m_rows = s.m_rows; m_cols = s.m_cols; m_data = s.m_data; + s.m_rows = 0; s.m_cols = 0; s.m_data = nullptr; + } + return *this; + } + + float operator()(size_t i, size_t j) const { + return m_data[i*m_cols + j]; + } + + float &operator()(size_t i, size_t j) { + return m_data[i*m_cols + j]; + } + + float *data() { return m_data; } + + size_t rows() const { return m_rows; } + size_t cols() const { return m_cols; } +private: + size_t m_rows; + size_t m_cols; + float *m_data; +}; + +test_initializer buffers([](py::module &m) { + py::class_ mtx(m, "Matrix"); + + mtx.def(py::init()) + /// Construct from a buffer + .def("__init__", [](Matrix &v, py::buffer b) { + py::buffer_info info = b.request(); + if (info.format != py::format_descriptor::format() || info.ndim != 2) + throw std::runtime_error("Incompatible buffer format!"); + new (&v) Matrix(info.shape[0], info.shape[1]); + memcpy(v.data(), info.ptr, sizeof(float) * v.rows() * v.cols()); + }) + + .def("rows", &Matrix::rows) + .def("cols", &Matrix::cols) + + /// Bare bones interface + .def("__getitem__", [](const Matrix &m, std::pair i) { + if (i.first >= m.rows() || i.second >= m.cols()) + throw py::index_error(); + return m(i.first, i.second); + }) + .def("__setitem__", [](Matrix &m, std::pair i, float v) { + if (i.first >= m.rows() || i.second >= m.cols()) + throw py::index_error(); + m(i.first, i.second) = v; + }) + /// Provide buffer access + .def_buffer([](Matrix &m) -> py::buffer_info { + return py::buffer_info( + m.data(), /* Pointer to buffer */ + sizeof(float), /* Size of one scalar */ + py::format_descriptor::format(), /* Python struct-style format descriptor */ + 2, /* Number of dimensions */ + { m.rows(), m.cols() }, /* Buffer dimensions */ + { sizeof(float) * m.rows(), /* Strides (in bytes) for each index */ + sizeof(float) } + ); + }) + ; +}); -- cgit v1.2.3