34 #include "../generic/py_capi_utils.h"
47 const Py_ssize_t *shape_a,
48 const Py_ssize_t *shape_b)
50 return (
bool)memcmp(shape_a, shape_b, ndim *
sizeof(Py_ssize_t));
55 switch (data_format) {
82 const Py_ssize_t *shape,
89 buffer->shape_len = shape_len;
91 memcpy(
buffer->shape, shape, shape_len *
sizeof(*
buffer->shape));
104 if (i >=
self->shape[0] || i < 0) {
105 PyErr_SetString(PyExc_IndexError,
"array index out of range");
111 if (
self->shape_len == 1) {
112 switch (
self->format) {
114 return Py_BuildValue(formatstr,
self->buf.as_float[i]);
116 return Py_BuildValue(formatstr,
self->buf.as_int[i]);
118 return Py_BuildValue(formatstr,
self->buf.as_byte[i]);
122 return Py_BuildValue(formatstr,
self->buf.as_uint[i]);
127 for (
int j = 1; j <
self->shape_len; j++) {
128 offset *=
self->shape[j];
135 self->buf.as_byte + offset);
143 int i,
len =
self->shape[0];
144 PyObject *list = PyList_New(
len);
146 for (i = 0; i <
len; i++) {
157 if (
self->shape_len > 1) {
158 int i,
len =
self->shape[0];
159 list = PyList_New(
len);
161 for (i = 0; i <
len; i++) {
179 PyObject *list = PyList_New(
self->shape_len);
182 for (i = 0; i <
self->shape_len; i++) {
183 PyList_SET_ITEM(list, i, PyLong_FromLong(
self->shape[i]));
191 Py_VISIT(
self->parent);
197 Py_CLEAR(
self->parent);
204 PyObject_GC_UnTrack(
self);
205 Py_CLEAR(
self->parent);
213 PyObject_GC_Del(
self);
223 repr = PyUnicode_FromFormat(
"Buffer(%s, %R)", typestr, list);
242 if (end >
self->shape[0]) {
243 end =
self->shape[0];
249 if (!PySequence_Check(seq)) {
250 PyErr_Format(PyExc_TypeError,
251 "buffer[:] = value, invalid assignment. "
252 "Expected a sequence, not an %.200s type",
253 Py_TYPE(seq)->tp_name);
258 if ((
count = PySequence_Size(seq)) != (end - begin)) {
259 PyErr_Format(PyExc_TypeError,
260 "buffer[:] = value, size mismatch in assignment. "
261 "Expected: %d (given: %d)",
268 item = PySequence_GetItem(seq,
count - begin);
283 #define MAX_DIMENSIONS 64
290 Py_ssize_t i, shape_len = 0;
292 if (kwds && PyDict_Size(kwds)) {
293 PyErr_SetString(PyExc_TypeError,
"Buffer(): takes no keyword args");
298 if (!PyArg_ParseTuple(
303 if (PyLong_Check(length_ob)) {
305 if (((shape[0] = PyLong_AsLong(length_ob)) < 1)) {
306 PyErr_SetString(PyExc_AttributeError,
"dimension must be greater than or equal to 1");
310 else if (PySequence_Check(length_ob)) {
311 shape_len = PySequence_Size(length_ob);
313 PyErr_SetString(PyExc_AttributeError,
318 PyErr_SetString(PyExc_AttributeError,
"sequence must have at least one dimension");
322 for (i = 0; i < shape_len; i++) {
323 PyObject *ob = PySequence_GetItem(length_ob, i);
324 if (!PyLong_Check(ob)) {
325 PyErr_Format(PyExc_TypeError,
326 "invalid dimension %i, expected an int, not a %.200s",
328 Py_TYPE(ob)->tp_name);
332 shape[i] = PyLong_AsLong(ob);
336 PyErr_SetString(PyExc_AttributeError,
"dimension must be greater than or equal to 1");
342 PyErr_Format(PyExc_TypeError,
343 "invalid second argument argument expected a sequence "
344 "or an int, not a %.200s",
345 Py_TYPE(length_ob)->tp_name);
349 if (
init && PyObject_CheckBuffer(
init)) {
352 if (PyObject_GetBuffer(
init, &pybuffer, PyBUF_ND | PyBUF_FORMAT) == -1) {
357 if (shape_len != pybuffer.ndim ||
359 PyErr_Format(PyExc_TypeError,
"array size does not match");
363 init, pygpu_dataformat.
value_found, pybuffer.ndim, shape, pybuffer.buf);
366 PyBuffer_Release(&pybuffer);
376 return (PyObject *)
buffer;
383 return self->shape[0];
394 if (end >
self->shape[0]) {
395 end =
self->shape[0];
401 list = PyList_New(end - begin);
411 if (i >=
self->shape[0] || i < 0) {
412 PyErr_SetString(PyExc_IndexError,
"array assignment index out of range");
416 if (
self->shape_len != 1) {
428 switch (
self->format) {
430 return PyArg_Parse(
v,
"f:Expected floats", &
self->buf.as_float[i]) ? 0 : -1;
432 return PyArg_Parse(
v,
"i:Expected ints", &
self->buf.as_int[i]) ? 0 : -1;
434 return PyArg_Parse(
v,
"b:Expected ints", &
self->buf.as_byte[i]) ? 0 : -1;
438 return PyArg_Parse(
v,
"b:Expected ints", &
self->buf.as_uint[i]) ? 0 : -1;
446 if (PyIndex_Check(item)) {
448 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
449 if (i == -1 && PyErr_Occurred()) {
457 if (PySlice_Check(item)) {
458 Py_ssize_t start, stop, step, slicelength;
460 if (PySlice_GetIndicesEx(item,
self->shape[0], &start, &stop, &step, &slicelength) < 0) {
464 if (slicelength <= 0) {
465 return PyTuple_New(0);
471 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
476 PyExc_TypeError,
"buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
482 if (PyIndex_Check(item)) {
483 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
484 if (i == -1 && PyErr_Occurred()) {
492 if (PySlice_Check(item)) {
493 Py_ssize_t start, stop, step, slicelength;
495 if (PySlice_GetIndicesEx(item,
self->shape[0], &start, &stop, &step, &slicelength) < 0) {
503 PyErr_SetString(PyExc_IndexError,
"slice steps not supported with vectors");
508 PyExc_TypeError,
"buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
516 "return the buffer as a list"},
530 (ssizessizeargfunc)
NULL,
532 (ssizessizeobjargproc)
NULL,
544 #ifdef PYGPU_BUFFER_PROTOCOL
547 const Py_ssize_t *shape,
548 Py_ssize_t *r_strides)
551 for (
int i = 1; i < shape_len; i++) {
552 r_strides[i] = r_strides[i - 1] * shape[i - 1];
557 static int pygpu_buffer__bf_getbuffer(
BPyGPUBuffer *
self, Py_buffer *
view,
int flags)
560 PyErr_SetString(PyExc_ValueError,
"NULL view in getbuffer");
564 view->obj = (PyObject *)
self;
565 view->buf = (
void *)
self->buf.as_void;
570 view->ndim =
self->shape_len;
571 view->shape =
self->shape;
573 pygpu_buffer_strides_calc(
self->format,
view->ndim,
view->shape,
view->strides);
581 static void pygpu_buffer__bf_releasebuffer(PyObject *
UNUSED(exporter), Py_buffer *
view)
586 static PyBufferProcs pygpu_buffer__tp_as_buffer = {
587 (getbufferproc)pygpu_buffer__bf_getbuffer,
588 (releasebufferproc)pygpu_buffer__bf_releasebuffer,
593 pygpu_buffer__tp_doc,
594 ".. class:: Buffer(format, dimensions, data)\n"
596 " For Python access to GPU functions requiring a pointer.\n"
598 " :arg format: Format type to interpret the buffer.\n"
599 " Possible values are `FLOAT`, `INT`, `UINT`, `UBYTE`, `UINT_24_8` and `10_11_11_REV`.\n"
601 " :arg dimensions: Array describing the dimensions.\n"
602 " :type dimensions: int\n"
603 " :arg data: Optional data array.\n"
604 " :type data: sequence\n");
606 PyVarObject_HEAD_INIT(
NULL, 0).tp_name =
"Buffer",
612 #ifdef PYGPU_BUFFER_PROTOCOL
613 .tp_as_buffer = &pygpu_buffer__tp_as_buffer,
615 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
616 .tp_doc = pygpu_buffer__tp_doc,
626 const Py_ssize_t *shape)
630 for (
int i = 0; i < shape_len; i++) {
650 const Py_ssize_t *shape,
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
size_t GPU_texture_dataformat_size(eGPUDataFormat data_format)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
struct PyC_StringEnumItems bpygpu_dataformat_items[]
BPyGPUBuffer * BPyGPU_Buffer_CreatePyObject(const int format, const Py_ssize_t *shape, const int shape_len, void *buffer)
static size_t pygpu_buffer_calc_size(const int format, const int shape_len, const Py_ssize_t *shape)
static PyObject * pygpu_buffer__sq_item(BPyGPUBuffer *self, int i)
static int pygpu_buffer__tp_traverse(BPyGPUBuffer *self, visitproc visit, void *arg)
PyTypeObject BPyGPU_BufferType
static bool pygpu_buffer_dimensions_compare(int ndim, const Py_ssize_t *shape_a, const Py_ssize_t *shape_b)
static PyMappingMethods pygpu_buffer__tp_as_mapping
static PySequenceMethods pygpu_buffer__tp_as_sequence
static PyObject * pygpu_buffer__tp_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
static PyObject * pygpu_buffer_to_list_recursive(BPyGPUBuffer *self)
static int pygpu_buffer__sq_ass_item(BPyGPUBuffer *self, int i, PyObject *v)
static int pygpu_buffer__sq_length(BPyGPUBuffer *self)
static PyObject * pygpu_buffer_slice(BPyGPUBuffer *self, Py_ssize_t begin, Py_ssize_t end)
static PyObject * pygpu_buffer_to_list(BPyGPUBuffer *self)
static int pygpu_buffer__mp_ass_subscript(BPyGPUBuffer *self, PyObject *item, PyObject *value)
static PyObject * pygpu_buffer__tp_repr(BPyGPUBuffer *self)
static PyMethodDef pygpu_buffer__tp_methods[]
static PyGetSetDef pygpu_buffer_getseters[]
static int pygpu_buffer_ass_slice(BPyGPUBuffer *self, Py_ssize_t begin, Py_ssize_t end, PyObject *seq)
static PyObject * pygpu_buffer_dimensions(BPyGPUBuffer *self, void *UNUSED(arg))
size_t bpygpu_Buffer_size(BPyGPUBuffer *buffer)
static BPyGPUBuffer * pygpu_buffer_make_from_data(PyObject *parent, const eGPUDataFormat format, const int shape_len, const Py_ssize_t *shape, void *buf)
static const char * pygpu_buffer_formatstr(eGPUDataFormat data_format)
static PyObject * pygpu_buffer__mp_subscript(BPyGPUBuffer *self, PyObject *item)
static void pygpu_buffer__tp_dealloc(BPyGPUBuffer *self)
PyDoc_STRVAR(pygpu_buffer__tp_doc, ".. class:: Buffer(format, dimensions, data)\n" "\n" " For Python access to GPU functions requiring a pointer.\n" "\n" " :arg format: Format type to interpret the buffer.\n" " Possible values are `FLOAT`, `INT`, `UINT`, `UBYTE`, `UINT_24_8` and `10_11_11_REV`.\n" " :type type: str\n" " :arg dimensions: Array describing the dimensions.\n" " :type dimensions: int\n" " :arg data: Optional data array.\n" " :type data: sequence\n")
static int pygpu_buffer__tp_clear(BPyGPUBuffer *self)
struct BPyGPUBuffer BPyGPUBuffer
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
int PyC_ParseStringEnum(PyObject *o, void *p)
const char * PyC_StringEnum_FindIDFromValue(const struct PyC_StringEnumItems *items, const int value)