19 print_created(
this, std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
20 m_data =
new float[(
size_t) (rows*cols)];
21 memset(m_data, 0,
sizeof(
float) * (
size_t) (rows * cols));
24 Matrix(
const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) {
25 print_copy_created(
this, std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
26 m_data =
new float[(
size_t) (m_rows * m_cols)];
27 memcpy(m_data, s.m_data,
sizeof(
float) * (
size_t) (m_rows * m_cols));
30 Matrix(Matrix &&s) : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) {
38 print_destroyed(
this, std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
42 Matrix &operator=(
const Matrix &s) {
43 print_copy_assigned(
this, std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
47 m_data =
new float[(
size_t) (m_rows * m_cols)];
48 memcpy(m_data, s.m_data,
sizeof(
float) * (
size_t) (m_rows * m_cols));
52 Matrix &operator=(Matrix &&s) {
53 print_move_assigned(
this, std::to_string(m_rows) +
"x" + std::to_string(m_cols) +
" matrix");
56 m_rows = s.m_rows; m_cols = s.m_cols; m_data = s.m_data;
57 s.m_rows = 0; s.m_cols = 0; s.m_data =
nullptr;
63 return m_data[(
size_t) (
i*m_cols + j)];
67 return m_data[(
size_t) (
i*m_cols + j)];
70 float *
data() {
return m_data; }
79 py::class_<Matrix>(
m,
"Matrix", py::buffer_protocol())
80 .def(py::init<py::ssize_t, py::ssize_t>())
82 .def(
py::init([](py::buffer
const b) {
83 py::buffer_info info = b.request();
84 if (info.format != py::format_descriptor<float>::format() || info.ndim != 2)
85 throw std::runtime_error(
"Incompatible buffer format!");
87 auto v =
new Matrix(info.shape[0], info.shape[1]);
88 memcpy(v->data(), info.ptr,
sizeof(
float) * (
size_t) (v->rows() * v->cols()));
92 .def(
"rows", &Matrix::rows)
93 .def(
"cols", &Matrix::cols)
96 .def(
"__getitem__", [](
const Matrix &
m, std::pair<py::ssize_t, py::ssize_t>
i) {
97 if (
i.first >=
m.rows() ||
i.second >=
m.cols())
98 throw py::index_error();
99 return m(
i.first,
i.second);
101 .
def(
"__setitem__", [](Matrix &
m, std::pair<py::ssize_t, py::ssize_t>
i,
float v) {
102 if (
i.first >=
m.rows() ||
i.second >=
m.cols())
103 throw py::index_error();
104 m(
i.first,
i.second) = v;
107 .def_buffer([](Matrix &
m) -> py::buffer_info {
108 return py::buffer_info(
110 { m.rows(), m.cols() },
111 { sizeof(float) * size_t(m.cols()),
119 class SquareMatrix :
public Matrix {
124 py::class_<SquareMatrix, Matrix>(
m,
"SquareMatrix")
125 .def(py::init<py::ssize_t>());
134 py::buffer_info get_buffer_info() {
136 py::format_descriptor<int32_t>::format(), 1);
139 py::class_<Buffer>(
m,
"Buffer", py::buffer_protocol())
142 .def_buffer(&Buffer::get_buffer_info);
146 std::unique_ptr<int32_t>
value;
149 int32_t get_value()
const {
return *
value; }
150 void set_value(int32_t v) { *
value = v; }
152 py::buffer_info get_buffer_info()
const {
153 return py::buffer_info(
value.get(),
sizeof(*
value),
154 py::format_descriptor<int32_t>::format(), 1);
157 ConstBuffer() :
value(
new int32_t{0}) { };
159 py::class_<ConstBuffer>(
m,
"ConstBuffer", py::buffer_protocol())
161 .def_property(
"value", &ConstBuffer::get_value, &ConstBuffer::set_value)
162 .def_buffer(&ConstBuffer::get_buffer_info);
164 struct DerivedBuffer :
public Buffer { };
165 py::class_<DerivedBuffer>(
m,
"DerivedBuffer", py::buffer_protocol())
168 .def_buffer(&DerivedBuffer::get_buffer_info);
170 struct BufferReadOnly {
171 const uint8_t
value = 0;
174 py::buffer_info get_buffer_info() {
175 return py::buffer_info(&
value, 1);
178 py::class_<BufferReadOnly>(
m,
"BufferReadOnly", py::buffer_protocol())
179 .def(py::init<uint8_t>())
180 .def_buffer(&BufferReadOnly::get_buffer_info);
182 struct BufferReadOnlySelect {
184 bool readonly =
false;
186 py::buffer_info get_buffer_info() {
187 return py::buffer_info(&
value, 1, readonly);
190 py::class_<BufferReadOnlySelect>(
m,
"BufferReadOnlySelect", py::buffer_protocol())
193 .def_readwrite(
"readonly", &BufferReadOnlySelect::readonly)
194 .def_buffer(&BufferReadOnlySelect::get_buffer_info);
197 py::class_<py::buffer_info>(
m,
"buffer_info")
199 .def_readonly(
"itemsize", &py::buffer_info::itemsize)
201 .def_readonly(
"format", &py::buffer_info::format)
202 .def_readonly(
"ndim", &py::buffer_info::ndim)
203 .def_readonly(
"shape", &py::buffer_info::shape)
204 .def_readonly(
"strides", &py::buffer_info::strides)
205 .def_readonly(
"readonly", &py::buffer_info::readonly)
206 .def(
"__repr__", [](py::handle
self) {
207 return py::str(
"itemsize={0.itemsize!r}, size={0.size!r}, format={0.format!r}, ndim={0.ndim!r}, shape={0.shape!r}, strides={0.strides!r}, readonly={0.readonly!r}").format(
self);
211 m.def(
"get_buffer_info", [](py::buffer
buffer) {