xref: /petsc/src/binding/petsc4py/src/petsc4py/include/petsc4py/pybuffer.h (revision 9d47de495d3c23378050c1b4a410c12a375cb6c6)
1 #if !defined(PETSC4PY_PYBUFFER_H)
2 #define PETSC4PY_PYBUFFER_H
3 
4 #include <Python.h>
5 #include <petscsystypes.h>
6 
7 #if defined(PETSC_USE_64BIT_INDICES)
8 # define _PyPetsc_FMT_PETSC_INT     "q"
9 #else
10 # define _PyPetsc_FMT_PETSC_INT     "i"
11 #endif
12 
13 #if   defined(PETSC_USE_REAL_SINGLE)
14 # define _PyPetsc_FMT_PETSC_REAL    "f"
15 # define _PyPetsc_FMT_PETSC_COMPLEX "Zf"
16 #elif defined(PETSC_USE_REAL_DOUBLE)
17 # define _PyPetsc_FMT_PETSC_REAL    "d"
18 # define _PyPetsc_FMT_PETSC_COMPLEX "Zd"
19 #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
20 # define _PyPetsc_FMT_PETSC_REAL    "g"
21 # define _PyPetsc_FMT_PETSC_COMPLEX "Zg"
22 #elif defined(PETSC_USE_REAL___FLOAT128)
23 # define _PyPetsc_FMT_PETSC_REAL    "g"
24 # define _PyPetsc_FMT_PETSC_COMPLEX "Zg"
25 #else
26 # error "unsupported real precision"
27 #endif
28 
29 #if   defined(PETSC_USE_COMPLEX)
30 # define _PyPetsc_FMT_PETSC_SCALAR  _PyPetsc_FMT_PETSC_COMPLEX
31 #else
32 # define _PyPetsc_FMT_PETSC_SCALAR  _PyPetsc_FMT_PETSC_REAL
33 #endif
34 
35 static inline
PyPetscBuffer_FillInfo(Py_buffer * view,void * buf,PetscInt count,char typechar,int readonly,int flags)36 int PyPetscBuffer_FillInfo(Py_buffer *view,
37                            void *buf, PetscInt count, char typechar,
38                            int readonly, int flags)
39 {
40   if (view == NULL) return 0;
41   if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (readonly == 1)) {
42     PyErr_SetString(PyExc_BufferError, "Object is not writable.");
43     return -1;
44   }
45   view->buf = buf;
46   switch (typechar) {
47   case 'i': view->itemsize = sizeof(PetscInt);    break;
48   case 'r': view->itemsize = sizeof(PetscReal);   break;
49   case 's': view->itemsize = sizeof(PetscScalar); break;
50   case 'c': view->itemsize = sizeof(PetscReal)*2; break;
51   default:  view->itemsize = 1;
52   }
53   view->len = count*view->itemsize;
54   view->readonly = readonly;
55   view->format = NULL;
56   if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
57     switch (typechar) {
58     case 'i': view->format = (char *) _PyPetsc_FMT_PETSC_INT;     break;
59     case 'r': view->format = (char *) _PyPetsc_FMT_PETSC_REAL;    break;
60     case 's': view->format = (char *) _PyPetsc_FMT_PETSC_SCALAR;  break;
61     case 'c': view->format = (char *) _PyPetsc_FMT_PETSC_COMPLEX; break;
62     default:  view->format = (char *) "B";
63     }
64   }
65   view->ndim = 0;
66   view->shape = NULL;
67   view->strides = NULL;
68   view->suboffsets = NULL;
69   view->internal = NULL;
70   if ((flags & PyBUF_ND) == PyBUF_ND) {
71     view->ndim = 1;
72 #if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030D0000
73     view->internal = malloc(2*sizeof(Py_ssize_t));
74 #else
75     view->internal = PyMem_Malloc(2*sizeof(Py_ssize_t));
76 #endif
77     if (!view->internal) { PyErr_NoMemory(); return -1; }
78     view->shape = (Py_ssize_t *) view->internal;
79     view->shape[0] = view->len/view->itemsize;
80     if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
81       view->strides = view->shape + 1;
82       view->strides[0] = view->itemsize;
83     }
84   }
85   return 0;
86 }
87 
88 static inline
PyPetscBuffer_Release(Py_buffer * view)89 void PyPetscBuffer_Release(Py_buffer *view)
90 {
91   if (view == NULL) return;
92 #if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030D0000
93   if (view->internal) free(view->internal);
94 #else
95   if (view->internal) PyMem_Free(view->internal);
96 #endif
97   view->internal = NULL;
98 }
99 
100 #undef _PyPetsc_FMT_PETSC_INT
101 #undef _PyPetsc_FMT_PETSC_REAL
102 #undef _PyPetsc_FMT_PETSC_SCALAR
103 #undef _PyPetsc_FMT_PETSC_COMPLEX
104 
105 #endif/*!PETSC4PY_PYBUFFER_H*/
106