@@ -93,12 +93,7 @@ def take_1d_%(name)s_%(dest)s(ndarray[%(c_type_in)s] values,
9393
9494"""
9595
96- take_2d_axis0_template = """@cython.wraparound(False)
97- @cython.boundscheck(False)
98- def take_2d_axis0_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
99- ndarray[int64_t] indexer,
100- %(c_type_out)s[:, :] out,
101- fill_value=np.nan):
96+ inner_take_2d_axis0_template = """\
10297 cdef:
10398 Py_ssize_t i, j, k, n, idx
10499 %(c_type_out)s fv
@@ -140,12 +135,34 @@ def take_2d_axis0_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
140135
141136"""
142137
143- take_2d_axis1_template = """@cython.wraparound(False)
138+ take_2d_axis0_template = """\
139+ @cython.wraparound(False)
144140@cython.boundscheck(False)
145- def take_2d_axis1_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
141+ cdef inline take_2d_axis0_%(name)s_%(dest)s_memview(%(c_type_in)s[:, :] values,
142+ int64_t[:] indexer,
143+ %(c_type_out)s[:, :] out,
144+ fill_value=np.nan):
145+ """ + inner_take_2d_axis0_template + """
146+
147+ @cython.wraparound(False)
148+ @cython.boundscheck(False)
149+ def take_2d_axis0_%(name)s_%(dest)s(ndarray[%(c_type_in)s, ndim=2] values,
146150 ndarray[int64_t] indexer,
147151 %(c_type_out)s[:, :] out,
148152 fill_value=np.nan):
153+ if values.flags.writeable:
154+ # We can call the memoryview version of the code
155+ take_2d_axis0_%(name)s_%(dest)s_memview(values, indexer, out,
156+ fill_value=fill_value)
157+ return
158+
159+ # We cannot use the memoryview version on readonly-buffers due to
160+ # a limitation of Cython's typed memoryviews. Instead we can use
161+ # the slightly slower Cython ndarray type directly.
162+ """ + inner_take_2d_axis0_template
163+
164+
165+ inner_take_2d_axis1_template = """\
149166 cdef:
150167 Py_ssize_t i, j, k, n, idx
151168 %(c_type_out)s fv
@@ -165,9 +182,36 @@ def take_2d_axis1_%(name)s_%(dest)s(%(c_type_in)s[:, :] values,
165182 out[i, j] = fv
166183 else:
167184 out[i, j] = %(preval)svalues[i, idx]%(postval)s
168-
169185"""
170186
187+ take_2d_axis1_template = """\
188+ @cython.wraparound(False)
189+ @cython.boundscheck(False)
190+ cdef inline take_2d_axis1_%(name)s_%(dest)s_memview(%(c_type_in)s[:, :] values,
191+ int64_t[:] indexer,
192+ %(c_type_out)s[:, :] out,
193+ fill_value=np.nan):
194+ """ + inner_take_2d_axis1_template + """
195+
196+ @cython.wraparound(False)
197+ @cython.boundscheck(False)
198+ def take_2d_axis1_%(name)s_%(dest)s(ndarray[%(c_type_in)s, ndim=2] values,
199+ ndarray[int64_t] indexer,
200+ %(c_type_out)s[:, :] out,
201+ fill_value=np.nan):
202+
203+ if values.flags.writeable:
204+ # We can call the memoryview version of the code
205+ take_2d_axis1_%(name)s_%(dest)s_memview(values, indexer, out,
206+ fill_value=fill_value)
207+ return
208+
209+ # We cannot use the memoryview version on readonly-buffers due to
210+ # a limitation of Cython's typed memoryviews. Instead we can use
211+ # the slightly slower Cython ndarray type directly.
212+ """ + inner_take_2d_axis1_template
213+
214+
171215take_2d_multi_template = """@cython.wraparound(False)
172216@cython.boundscheck(False)
173217def take_2d_multi_%(name)s_%(dest)s(ndarray[%(c_type_in)s, ndim=2] values,
0 commit comments