main.cpp 6.16 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/**
 * @author Andre Anjos <andre.anjos@idiap.ch>
 * @date Tue 01 Oct 2013 15:37:07 CEST
 *
 * @brief Pure python bindings for Blitz Arrays
 */

#ifdef NO_IMPORT_ARRAY
#undef NO_IMPORT_ARRAY
#endif
André Anjos's avatar
André Anjos committed
11
12
13
#define BOB_BLITZ_MODULE
#include <bob.blitz/capi.h>
#include <bob.blitz/cleanup.h>
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

static PyObject* PyBlitzArray_as_blitz(PyObject*, PyObject* args, PyObject* kwds) {

  /* Parses input arguments in a single shot */
  static const char* const_kwlist[] = {"o", 0};
  static char** kwlist = const_cast<char**>(const_kwlist);

  PyObject* retval = 0;
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, &PyBlitzArray_Converter, &retval)) return 0;

  return retval;

}

PyDoc_STRVAR(s_as_blitz_str, "as_blitz");
PyDoc_STRVAR(s_as_blitz__doc__,
André Anjos's avatar
André Anjos committed
30
"as_blitz(x) -> bob.blitz.array\n\
31
\n\
André Anjos's avatar
André Anjos committed
32
Converts any compatible python object into a shallow " BOB_EXT_MODULE_PREFIX ".array\n\
33
34
35
\n\
This function works by first converting the input object ``x`` into\n\
a :py:class:`numpy.ndarray` and then shallow wrapping that ``ndarray``\n\
André Anjos's avatar
André Anjos committed
36
into a new :py:class:`" BOB_EXT_MODULE_PREFIX ".array`. You can access the converted\n\
37
38
39
40
41
42
``ndarray`` using the returned value's ``base`` attribute. If the\n\
``ndarray`` cannot be shallow-wrapped, a :py:class:`ValueError` is\n\
raised.\n\
\n\
In the case the input object ``x`` is already a behaved (C-style,\n\
memory-aligned, contiguous) :py:class:`numpy.ndarray`, then this\n\
André Anjos's avatar
André Anjos committed
43
function only shallow wrap's it into a ``" BOB_EXT_MODULE_PREFIX ".array`` skin.\n\
44
45
46
"
);

André Anjos's avatar
André Anjos committed
47
static PyMethodDef module_methods[] = {
48
49
50
51
52
53
54
55
56
    {
      s_as_blitz_str,
      (PyCFunction)PyBlitzArray_as_blitz,
      METH_VARARGS|METH_KEYWORDS,
      s_as_blitz__doc__
    },
    {0}  /* Sentinel */
};

André Anjos's avatar
André Anjos committed
57
int PyBlitzArray_APIVersion = BOB_BLITZ_API_VERSION;
58

André Anjos's avatar
André Anjos committed
59
PyDoc_STRVAR(module_docstr, "Blitz++ array definition and generic functions");
André Anjos's avatar
André Anjos committed
60
61
62
63

#if PY_VERSION_HEX >= 0x03000000
static PyModuleDef module_definition = {
  PyModuleDef_HEAD_INIT,
André Anjos's avatar
André Anjos committed
64
  BOB_EXT_MODULE_NAME,
André Anjos's avatar
André Anjos committed
65
  module_docstr,
André Anjos's avatar
André Anjos committed
66
  -1,
67
  module_methods,
André Anjos's avatar
André Anjos committed
68
69
70
71
  0, 0, 0, 0
};
#endif

André Anjos's avatar
André Anjos committed
72
static PyObject* create_module (void) {
73
74

  PyBlitzArray_Type.tp_new = PyType_GenericNew;
75
  if (PyType_Ready(&PyBlitzArray_Type) < 0) return 0;
André Anjos's avatar
André Anjos committed
76
77
78
79

# if PY_VERSION_HEX >= 0x03000000
  PyObject* m = PyModule_Create(&module_definition);
# else
André Anjos's avatar
André Anjos committed
80
  PyObject* m = Py_InitModule3(BOB_EXT_MODULE_NAME, module_methods, module_docstr);
André Anjos's avatar
André Anjos committed
81
# endif
82
83
  if (!m) return 0;
  auto m_ = make_safe(m); ///< protects against early returns
84
85

  /* register version numbers and constants */
André Anjos's avatar
André Anjos committed
86
  if (PyModule_AddIntConstant(m, "__api_version__", BOB_BLITZ_API_VERSION) < 0)
87
    return 0;
André Anjos's avatar
André Anjos committed
88
  if (PyModule_AddStringConstant(m, "__version__", BOB_EXT_MODULE_VERSION) < 0)
89
    return 0;
90
91
92

  /* register the type object to python */
  Py_INCREF(&PyBlitzArray_Type);
93
  if (PyModule_AddObject(m, "array", (PyObject *)&PyBlitzArray_Type) < 0) return 0;
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

  static void* PyBlitzArray_API[PyBlitzArray_API_pointers];

  /* exhaustive list of C APIs */
  PyBlitzArray_API[PyBlitzArray_APIVersion_NUM] = (void *)&PyBlitzArray_APIVersion;

  // Basic Properties and Checking
  PyBlitzArray_API[PyBlitzArray_Type_NUM] = (void *)&PyBlitzArray_Type;
  PyBlitzArray_API[PyBlitzArray_Check_NUM] = (void *)PyBlitzArray_Check;
  PyBlitzArray_API[PyBlitzArray_CheckNumpyBase_NUM] = (void *)PyBlitzArray_CheckNumpyBase;
  PyBlitzArray_API[PyBlitzArray_TYPE_NUM] = (void *)PyBlitzArray_TYPE;
  PyBlitzArray_API[PyBlitzArray_PyDTYPE_NUM] = (void *)PyBlitzArray_PyDTYPE;
  PyBlitzArray_API[PyBlitzArray_NDIM_NUM] = (void *)PyBlitzArray_NDIM;
  PyBlitzArray_API[PyBlitzArray_SHAPE_NUM] = (void *)PyBlitzArray_SHAPE;
  PyBlitzArray_API[PyBlitzArray_PySHAPE_NUM] = (void *)PyBlitzArray_PySHAPE;
  PyBlitzArray_API[PyBlitzArray_STRIDE_NUM] = (void *)PyBlitzArray_STRIDE;
  PyBlitzArray_API[PyBlitzArray_PySTRIDE_NUM] = (void *)PyBlitzArray_PySTRIDE;
  PyBlitzArray_API[PyBlitzArray_WRITEABLE_NUM] = (void *)PyBlitzArray_WRITEABLE;
  PyBlitzArray_API[PyBlitzArray_PyWRITEABLE_NUM] = (void *)PyBlitzArray_PyWRITEABLE;
  PyBlitzArray_API[PyBlitzArray_BASE_NUM] = (void *)PyBlitzArray_BASE;
  PyBlitzArray_API[PyBlitzArray_PyBASE_NUM] = (void *)PyBlitzArray_PyBASE;

  // Indexing
  PyBlitzArray_API[PyBlitzArray_GetItem_NUM] = (void *)PyBlitzArray_GetItem;
  PyBlitzArray_API[PyBlitzArray_SetItem_NUM] = (void *)PyBlitzArray_SetItem;

  // Construction and Destruction
  PyBlitzArray_API[PyBlitzArray_New_NUM] = (void *)PyBlitzArray_New;
  PyBlitzArray_API[PyBlitzArray_Delete_NUM] = (void *)PyBlitzArray_Delete;
  PyBlitzArray_API[PyBlitzArray_SimpleNew_NUM] = (void *)PyBlitzArray_SimpleNew;
  PyBlitzArray_API[PyBlitzArray_SimpleNewFromData_NUM] = (void *)PyBlitzArray_SimpleNewFromData;

  // From/To NumPy Converters
  PyBlitzArray_API[PyBlitzArray_AsNumpyArray_NUM] = (void *)PyBlitzArray_AsNumpyArray;
  PyBlitzArray_API[PyBlitzArray_FromNumpyArray_NUM] = (void *)PyBlitzArray_FromNumpyArray;
129
  PyBlitzArray_API[PyBlitzArray_NUMPY_WRAP_NUM] = (void *)PyBlitzArray_NUMPY_WRAP;
130

131
132
  // Converter Functions for PyArg_Parse* family
  PyBlitzArray_API[PyBlitzArray_Converter_NUM] = (void *)PyBlitzArray_Converter;
133
  PyBlitzArray_API[PyBlitzArray_BehavedConverter_NUM] = (void *)PyBlitzArray_BehavedConverter;
134
135
136
137
138
139
  PyBlitzArray_API[PyBlitzArray_OutputConverter_NUM] = (void *)PyBlitzArray_OutputConverter;
  PyBlitzArray_API[PyBlitzArray_IndexConverter_NUM] = (void *)PyBlitzArray_IndexConverter;
  PyBlitzArray_API[PyBlitzArray_TypenumConverter_NUM] = (void *)PyBlitzArray_TypenumConverter;

  // Utilities
  PyBlitzArray_API[PyBlitzArray_TypenumAsString_NUM] = (void *)PyBlitzArray_TypenumAsString;
André Anjos's avatar
André Anjos committed
140
  PyBlitzArray_API[PyBlitzArray_TypenumSize_NUM] = (void *)PyBlitzArray_TypenumSize;
141
  PyBlitzArray_API[PyBlitzArray_Cast_NUM] = (void *)PyBlitzArray_Cast;
142
143
144
145
146

#if PY_VERSION_HEX >= 0x02070000

  /* defines the PyCapsule */

147
  PyObject* c_api_object = PyCapsule_New((void *)PyBlitzArray_API,
André Anjos's avatar
André Anjos committed
148
      BOB_EXT_MODULE_PREFIX "." BOB_EXT_MODULE_NAME "._C_API", 0);
149
150
151
152
153
154
155

#else

  PyObject* c_api_object = PyCObject_FromVoidPtr((void *)PyBlitzArray_API, 0);

#endif

156
157
158
  if (!c_api_object) return 0;

  if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) return 0;
159
160

  /* imports the NumPy C-API as well */
161
  import_array1(0);
André Anjos's avatar
André Anjos committed
162

163
  Py_INCREF(m);
André Anjos's avatar
André Anjos committed
164
165
  return m;

166
}
167

André Anjos's avatar
André Anjos committed
168
PyMODINIT_FUNC BOB_EXT_ENTRY_NAME (void) {
169
170
171
172
173
# if PY_VERSION_HEX >= 0x03000000
  return
# endif
    create_module();
}