main.cpp 6.22 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
#include <bob.extension/documentation.h>

extern bool init_BlitzArray(PyObject* module);

auto as_blitz = bob::extension::FunctionDoc(
  "as_blitz",
  "Converts any compatible python object into a shallow :py:class:`" BOB_EXT_MODULE_PREFIX ".array`",
  "This function works by first converting the input object ``x`` into a :py:class:`numpy.ndarray` and then shallow wrapping that ``ndarray`` into a new :py:class:`" BOB_EXT_MODULE_PREFIX ".array`. "
  "You can access the converted ``ndarray`` using the returned value's :py:meth:`" BOB_EXT_MODULE_PREFIX ".array.base` attribute. "
  "If the ``ndarray`` cannot be shallow-wrapped, a :py:class:`ValueError` is raised.\n\n"
  "In the case the input object ``x`` is already a behaved (C-style, memory-aligned, contiguous) :py:class:`numpy.ndarray`, then this function only shallow wrap's it into a :py:class:`" BOB_EXT_MODULE_PREFIX ".array` skin."
)
.add_prototype("x", "array")
.add_parameter("x", "object", "Any object convertible into a :py:class:`numpy.ndarray`")
.add_return("array", ":py:class:`" BOB_EXT_MODULE_PREFIX ".array`", "The converted array")
;
30
31
32
33
34
35
36
37
38
39
40
41
42
43

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;

}

André Anjos's avatar
André Anjos committed
44
static PyMethodDef module_methods[] = {
45
    {
46
      as_blitz.name(),
47
48
      (PyCFunction)PyBlitzArray_as_blitz,
      METH_VARARGS|METH_KEYWORDS,
49
      as_blitz.doc()
50
51
52
53
    },
    {0}  /* Sentinel */
};

André Anjos's avatar
André Anjos committed
54
int PyBlitzArray_APIVersion = BOB_BLITZ_API_VERSION;
55

André Anjos's avatar
André Anjos committed
56
PyDoc_STRVAR(module_docstr, "Blitz++ array definition and generic functions");
André Anjos's avatar
André Anjos committed
57
58
59
60

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

André Anjos's avatar
André Anjos committed
69
static PyObject* create_module (void) {
70
71

  PyBlitzArray_Type.tp_new = PyType_GenericNew;
72
  if (PyType_Ready(&PyBlitzArray_Type) < 0) return 0;
André Anjos's avatar
André Anjos committed
73
74
75
76

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

  /* register the type object to python */
83
  if (!init_BlitzArray(m)) return NULL;
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114

  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;
115
  PyBlitzArray_API[PyBlitzArray_SimpleInit_NUM] = (void *)PyBlitzArray_SimpleInit;
116
117
118
119

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

122
123
  // Converter Functions for PyArg_Parse* family
  PyBlitzArray_API[PyBlitzArray_Converter_NUM] = (void *)PyBlitzArray_Converter;
124
  PyBlitzArray_API[PyBlitzArray_BehavedConverter_NUM] = (void *)PyBlitzArray_BehavedConverter;
125
126
127
128
129
130
  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
131
  PyBlitzArray_API[PyBlitzArray_TypenumSize_NUM] = (void *)PyBlitzArray_TypenumSize;
132
  PyBlitzArray_API[PyBlitzArray_Cast_NUM] = (void *)PyBlitzArray_Cast;
133
134
135
136
137

#if PY_VERSION_HEX >= 0x02070000

  /* defines the PyCapsule */

138
  PyObject* c_api_object = PyCapsule_New((void *)PyBlitzArray_API,
André Anjos's avatar
André Anjos committed
139
      BOB_EXT_MODULE_PREFIX "." BOB_EXT_MODULE_NAME "._C_API", 0);
140
141
142
143
144
145
146

#else

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

#endif

147
148
149
  if (!c_api_object) return 0;

  if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) return 0;
150
151

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

154
  return Py_BuildValue("O", m);
155
}
156

André Anjos's avatar
André Anjos committed
157
PyMODINIT_FUNC BOB_EXT_ENTRY_NAME (void) {
158
159
160
161
162
# if PY_VERSION_HEX >= 0x03000000
  return
# endif
    create_module();
}