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