Apache Arrow (C++)
A columnar in-memory analytics layer designed to accelerate big data.
numpy-internal.h
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 // Internal utilities for dealing with NumPy
19 
20 #ifndef ARROW_PYTHON_NUMPY_INTERNAL_H
21 #define ARROW_PYTHON_NUMPY_INTERNAL_H
22 
24 
25 #include "arrow/status.h"
26 
27 #include "arrow/python/platform.h"
28 
29 #include <cstdint>
30 #include <string>
31 
32 namespace arrow {
33 namespace py {
34 
36 template <typename T>
38  public:
39  typedef int64_t size_type;
40 
41  Ndarray1DIndexer() : arr_(NULLPTR), data_(NULLPTR) {}
42 
43  explicit Ndarray1DIndexer(PyArrayObject* arr) : Ndarray1DIndexer() { Init(arr); }
44 
45  void Init(PyArrayObject* arr) {
46  arr_ = arr;
47  DCHECK_EQ(1, PyArray_NDIM(arr)) << "Only works with 1-dimensional arrays";
48  Py_INCREF(arr);
49  data_ = reinterpret_cast<T*>(PyArray_DATA(arr));
50  stride_ = PyArray_STRIDES(arr)[0] / sizeof(T);
51  }
52 
53  ~Ndarray1DIndexer() { Py_XDECREF(arr_); }
54 
55  int64_t size() const { return PyArray_SIZE(arr_); }
56 
57  T* data() const { return data_; }
58 
59  bool is_strided() const { return stride_ != 1; }
60 
61  T& operator[](size_type index) { return data_[index * stride_]; }
62  T& operator[](size_type index) const { return data_[index * stride_]; }
63 
64  private:
65  PyArrayObject* arr_;
66  T* data_;
67  int64_t stride_;
68 };
69 
70 // Handling of Numpy Types by their static numbers
71 // (the NPY_TYPES enum and related defines)
72 
73 static inline std::string GetNumPyTypeName(int npy_type) {
74 #define TYPE_CASE(TYPE, NAME) \
75  case NPY_##TYPE: \
76  return NAME;
77 
78  switch (npy_type) {
79  TYPE_CASE(BOOL, "bool")
80  TYPE_CASE(INT8, "int8")
81  TYPE_CASE(INT16, "int16")
82  TYPE_CASE(INT32, "int32")
83  TYPE_CASE(INT64, "int64")
84 #if !NPY_INT32_IS_INT
85  TYPE_CASE(INT, "intc")
86 #endif
87 #if !NPY_INT64_IS_LONG_LONG
88  TYPE_CASE(LONGLONG, "longlong")
89 #endif
90  TYPE_CASE(UINT8, "uint8")
91  TYPE_CASE(UINT16, "uint16")
92  TYPE_CASE(UINT32, "uint32")
93  TYPE_CASE(UINT64, "uint64")
94 #if !NPY_INT32_IS_INT
95  TYPE_CASE(UINT, "uintc")
96 #endif
97 #if !NPY_INT64_IS_LONG_LONG
98  TYPE_CASE(ULONGLONG, "ulonglong")
99 #endif
100  TYPE_CASE(FLOAT16, "float16")
101  TYPE_CASE(FLOAT32, "float32")
102  TYPE_CASE(FLOAT64, "float64")
103  TYPE_CASE(DATETIME, "datetime64")
104  TYPE_CASE(OBJECT, "object")
105  TYPE_CASE(VOID, "void")
106  default:
107  break;
108  }
109 
110 #undef TYPE_CASE
111  std::stringstream ss;
112  ss << "unrecognized type (" << npy_type << ") in GetNumPyTypeName";
113  return ss.str();
114 }
115 
116 #define TYPE_VISIT_INLINE(TYPE) \
117  case NPY_##TYPE: \
118  return visitor->template Visit<NPY_##TYPE>(arr);
119 
120 template <typename VISITOR>
121 inline Status VisitNumpyArrayInline(PyArrayObject* arr, VISITOR* visitor) {
122  switch (PyArray_TYPE(arr)) {
123  TYPE_VISIT_INLINE(BOOL);
124  TYPE_VISIT_INLINE(INT8);
125  TYPE_VISIT_INLINE(UINT8);
126  TYPE_VISIT_INLINE(INT16);
127  TYPE_VISIT_INLINE(UINT16);
128  TYPE_VISIT_INLINE(INT32);
129  TYPE_VISIT_INLINE(UINT32);
130  TYPE_VISIT_INLINE(INT64);
131  TYPE_VISIT_INLINE(UINT64);
132 #if !NPY_INT32_IS_INT
133  TYPE_VISIT_INLINE(INT);
134  TYPE_VISIT_INLINE(UINT);
135 #endif
136 #if !NPY_INT64_IS_LONG_LONG
137  TYPE_VISIT_INLINE(LONGLONG);
138  TYPE_VISIT_INLINE(ULONGLONG);
139 #endif
140  TYPE_VISIT_INLINE(FLOAT16);
141  TYPE_VISIT_INLINE(FLOAT32);
142  TYPE_VISIT_INLINE(FLOAT64);
143  TYPE_VISIT_INLINE(DATETIME);
144  TYPE_VISIT_INLINE(OBJECT);
145  }
146  std::stringstream ss;
147  ss << "NumPy type not implemented: " << GetNumPyTypeName(PyArray_TYPE(arr));
148  return Status::NotImplemented(ss.str());
149 }
150 
151 #undef TYPE_VISIT_INLINE
152 
153 namespace internal {
154 
155 inline bool PyFloatScalar_Check(PyObject* obj) {
156  return PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating);
157 }
158 
159 inline bool PyIntScalar_Check(PyObject* obj) {
160 #if PY_MAJOR_VERSION < 3
161  if (PyInt_Check(obj)) {
162  return true;
163  }
164 #endif
165  return PyLong_Check(obj) || PyArray_IsScalar(obj, Integer);
166 }
167 
168 inline bool PyBoolScalar_Check(PyObject* obj) {
169  return PyBool_Check(obj) || PyArray_IsScalar(obj, Bool);
170 }
171 
172 } // namespace internal
173 
174 } // namespace py
175 } // namespace arrow
176 
177 #endif // ARROW_PYTHON_NUMPY_INTERNAL_H
T * data() const
Definition: numpy-internal.h:57
int8_t int8
Definition: types.h:25
#define NULLPTR
Definition: macros.h:69
int16_t int16
Definition: types.h:26
~Ndarray1DIndexer()
Definition: numpy-internal.h:53
int32_t int32
Definition: types.h:27
uint64_t uint64
Definition: types.h:32
void Init(PyArrayObject *arr)
Definition: numpy-internal.h:45
int64_t int64
Definition: types.h:28
Definition: status.h:95
double float64
Definition: types.h:34
float float32
Definition: types.h:33
#define TYPE_VISIT_INLINE(TYPE)
Definition: numpy-internal.h:116
int64_t size() const
Definition: numpy-internal.h:55
#define DCHECK_EQ(val1, val2)
Definition: logging.h:94
T & operator[](size_type index)
Definition: numpy-internal.h:61
Ndarray1DIndexer()
Definition: numpy-internal.h:41
Status VisitNumpyArrayInline(PyArrayObject *arr, VISITOR *visitor)
Definition: numpy-internal.h:121
bool is_strided() const
Definition: numpy-internal.h:59
uint32_t uint32
Definition: types.h:31
#define TYPE_CASE(TYPE, NAME)
Top-level namespace for Apache Arrow C++ API.
Definition: adapter.h:32
Ndarray1DIndexer(PyArrayObject *arr)
Definition: numpy-internal.h:43
T & operator[](size_type index) const
Definition: numpy-internal.h:62
static Status NotImplemented(const std::string &msg)
Definition: status.h:146
int64_t size_type
Definition: numpy-internal.h:39
Indexing convenience for interacting with strided 1-dim ndarray objects.
Definition: numpy-internal.h:37
uint16_t uint16
Definition: types.h:30
_object PyObject
Definition: serialize.h:30