main.cpp 6.51 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
#define BOB_BLITZ_MODULE
12
#include <bob.blitz/cppapi.h>
André Anjos's avatar
André Anjos committed
13
#include <bob.blitz/cleanup.h>
14
15
16
17
18
19
20
21
22
#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. "
André Anjos's avatar
André Anjos committed
23
  "If the ``ndarray`` cannot be shallow-wrapped, a :py:exc:`ValueError` is raised.\n\n"
24
25
26
27
28
29
  "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

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;
41
42
43
44
45
46
47
48
}

static PyObject* PyBlitzArray_test_const_numpy(PyObject*, PyObject* , PyObject* ) {
  // test function,
  blitz::Array<int,2> example(5,2);
  for (int i = 0; i < 10; ++i){
    example(i%5,i/5) = i;
  }
49

50
  return PyBlitzArrayCxx_AsConstNumpy(example);
51
52
}

53

André Anjos's avatar
André Anjos committed
54
static PyMethodDef module_methods[] = {
55
    {
56
      as_blitz.name(),
57
58
      (PyCFunction)PyBlitzArray_as_blitz,
      METH_VARARGS|METH_KEYWORDS,
59
      as_blitz.doc()
60
    },
61
62
63
64
65
66
    {
      "_test_const_numpy",
      (PyCFunction)PyBlitzArray_test_const_numpy,
      METH_VARARGS|METH_KEYWORDS,
      0
    },
67
68
69
    {0}  /* Sentinel */
};

André Anjos's avatar
André Anjos committed
70
int PyBlitzArray_APIVersion = BOB_BLITZ_API_VERSION;
71

André Anjos's avatar
André Anjos committed
72
PyDoc_STRVAR(module_docstr, "Blitz++ array definition and generic functions");
André Anjos's avatar
André Anjos committed
73
74
75
76

#if PY_VERSION_HEX >= 0x03000000
static PyModuleDef module_definition = {
  PyModuleDef_HEAD_INIT,
André Anjos's avatar
André Anjos committed
77
  BOB_EXT_MODULE_NAME,
André Anjos's avatar
André Anjos committed
78
  module_docstr,
André Anjos's avatar
André Anjos committed
79
  -1,
80
  module_methods,
André Anjos's avatar
André Anjos committed
81
82
83
84
  0, 0, 0, 0
};
#endif

André Anjos's avatar
André Anjos committed
85
static PyObject* create_module (void) {
86

André Anjos's avatar
André Anjos committed
87
88
# if PY_VERSION_HEX >= 0x03000000
  PyObject* m = PyModule_Create(&module_definition);
89
90
  auto m_ = make_xsafe(m);
  const char* ret = "O";
André Anjos's avatar
André Anjos committed
91
# else
André Anjos's avatar
André Anjos committed
92
  PyObject* m = Py_InitModule3(BOB_EXT_MODULE_NAME, module_methods, module_docstr);
93
  const char* ret = "N";
André Anjos's avatar
André Anjos committed
94
# endif
95
  if (!m) return 0;
96
97

  /* register the type object to python */
98
  if (!init_BlitzArray(m)) return NULL;
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
129

  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;
130
  PyBlitzArray_API[PyBlitzArray_SimpleInit_NUM] = (void *)PyBlitzArray_SimpleInit;
131
132
133
134

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

137
138
  // Converter Functions for PyArg_Parse* family
  PyBlitzArray_API[PyBlitzArray_Converter_NUM] = (void *)PyBlitzArray_Converter;
139
  PyBlitzArray_API[PyBlitzArray_BehavedConverter_NUM] = (void *)PyBlitzArray_BehavedConverter;
140
141
142
143
144
145
  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
146
  PyBlitzArray_API[PyBlitzArray_TypenumSize_NUM] = (void *)PyBlitzArray_TypenumSize;
147
  PyBlitzArray_API[PyBlitzArray_Cast_NUM] = (void *)PyBlitzArray_Cast;
148
149
150
151
152

#if PY_VERSION_HEX >= 0x02070000

  /* defines the PyCapsule */

153
  PyObject* c_api_object = PyCapsule_New((void *)PyBlitzArray_API,
André Anjos's avatar
André Anjos committed
154
      BOB_EXT_MODULE_PREFIX "." BOB_EXT_MODULE_NAME "._C_API", 0);
155
156
157
158
159
160
161

#else

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

#endif

162
163
164
  if (!c_api_object) return 0;

  if (PyModule_AddObject(m, "_C_API", c_api_object) < 0) return 0;
165
166

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

169
  return Py_BuildValue(ret, m);
170
}
171

André Anjos's avatar
André Anjos committed
172
PyMODINIT_FUNC BOB_EXT_ENTRY_NAME (void) {
173
174
175
176
177
# if PY_VERSION_HEX >= 0x03000000
  return
# endif
    create_module();
}