Skip to content

Commit 698cbf5

Browse files
committed
Support all shapes,chunks and blocks
1 parent 06407d5 commit 698cbf5

File tree

2 files changed

+59
-17
lines changed

2 files changed

+59
-17
lines changed

blosc2/blosc2_ext.pyx

+16-17
Original file line numberDiff line numberDiff line change
@@ -1566,44 +1566,43 @@ cdef int general_filler(blosc2_prefilter_params *params):
15661566

15671567
cdef int general_numba(blosc2_prefilter_params *params):
15681568
cdef numba_udata *udata = <numba_udata *> params.user_data
1569-
cdef uint8_t nd = udata.ndim
1569+
cdef uint8_t nd = udata.array.ndim
15701570
# off caldrà sumar-li blockshape també
1571-
cdef int64_t offset = params.nchunk * udata.chunkshape + params.output_offset // params.output_typesize
1572-
# shape normal, no extshape, revisar-ho quan hi haja padding
1571+
cdef int64_t offset = params.nchunk * udata.array.sc.chunksize + params.output_offset // params.output_typesize
15731572
cdef int64_t chunk_ndim[B2ND_MAX_DIM]
15741573
cdef int64_t chunks_in_array[B2ND_MAX_DIM]
15751574
for i in range(nd):
1576-
# Canviar-ho a extshape i chunkshape normal
1577-
chunks_in_array[i] = udata.ext_shape[i] // udata.chunkshape_ndim[i]
1575+
chunks_in_array[i] = udata.array.extshape[i] // udata.array.chunkshape[i]
15781576
blosc2_unidim_to_multidim(nd, chunks_in_array, params.nchunk, chunk_ndim)
1579-
# print("nchunk ", params.nchunk)
15801577

15811578
cdef int64_t block_ndim[B2ND_MAX_DIM]
15821579
cdef int64_t blocks_in_chunk[B2ND_MAX_DIM]
15831580
for i in range(nd):
1584-
blocks_in_chunk[i] = udata.chunkshape_ndim[i] // udata.blockshape[i]
1585-
blosc2_unidim_to_multidim(nd, chunks_in_array, params.nblock, block_ndim)
1581+
blocks_in_chunk[i] = udata.array.extchunkshape[i] // udata.array.blockshape[i]
1582+
blosc2_unidim_to_multidim(nd, blocks_in_chunk, params.nblock, block_ndim)
15861583

15871584
cdef int64_t start_ndim[B2ND_MAX_DIM]
15881585
for i in range(nd):
1589-
start_ndim[i] = chunk_ndim[i] * udata.chunkshape_ndim[i] + block_ndim[i] * udata.blockshape[i]
1586+
start_ndim[i] = chunk_ndim[i] * udata.array.chunkshape[i] + block_ndim[i] * udata.array.blockshape[i]
15901587
# print("start_ndim[", i, "] = ", start_ndim[i])
15911588

15921589
padding = False
15931590
blockshape = []
15941591
for i in range(nd):
15951592
if start_ndim[i] + udata.blockshape[i] > udata.shape[i]:
15961593
padding = True
1597-
blockshape.append(udata.shape[i] - start_ndim[i])
1594+
blockshape.append(udata.array.shape[i] - start_ndim[i])
1595+
if blockshape[i] <= 0:
1596+
# This block contains only padding, skip it
1597+
return 0
15981598
else:
1599-
blockshape.append(udata.blockshape[i])
1599+
blockshape.append(udata.array.blockshape[i])
16001600
cdef np.npy_intp dims[B2ND_MAX_DIM]
16011601
for i in range(nd):
16021602
dims[i] = blockshape[i]
16031603

16041604
if padding:
1605-
output = np.empty(blockshape, udata.array.dtype) # igual toca crear un py dtype
1606-
print(output.dtype)
1605+
output = np.empty(blockshape, udata.array.dtype)
16071606
else:
16081607
output = np.PyArray_SimpleNewFromData(nd, dims, udata.output_cdtype, <void*>params.output)
16091608
inputs_tuple = _ctypes.PyObj_FromPtr(udata.inputs_id)
@@ -1612,13 +1611,13 @@ cdef int general_numba(blosc2_prefilter_params *params):
16121611
# Enviar-ho a fer la mà quan nd = 1 ? o ho puc suportar sense problemes??
16131612
for obj, dtype in inputs_tuple:
16141613
if isinstance(obj, blosc2.SChunk):
1615-
out = np.empty(udata.blockshape[0], dtype=dtype)
1614+
out = np.empty(udata.array.blockshape[0], dtype=dtype)
16161615
obj.get_slice(start=offset, stop=offset + dims[0], out=out)
16171616
inputs.append(out)
16181617
elif isinstance(obj, np.ndarray):
16191618
inputs.append(obj[offset : offset + dims[0]])
16201619
elif isinstance(obj, (int, float, bool, complex)):
1621-
inputs.append(np.full(udata.blockshape[0], obj, dtype=dtype))
1620+
inputs.append(np.full(udata.array.blockshape[0], obj, dtype=dtype))
16221621
else:
16231622
raise ValueError("Unsupported operand")
16241623
else:
@@ -1652,10 +1651,10 @@ cdef int general_numba(blosc2_prefilter_params *params):
16521651
for i in range(nd):
16531652
start[i] = 0
16541653
slice_shape[i] = blockshape[i]
1655-
blockshape_int64[i] = udata.blockshape[i]
1654+
blockshape_int64[i] = udata.array.blockshape[i]
16561655
buf = <Py_buffer *> malloc(sizeof(Py_buffer))
16571656
PyObject_GetBuffer(output, buf, PyBUF_SIMPLE)
1658-
b2nd_copy_buffer(udata.ndim, params.output_typesize,
1657+
b2nd_copy_buffer(udata.array.ndim, params.output_typesize,
16591658
buf.buf, slice_shape, start, slice_shape,
16601659
params.output, blockshape_int64, start)
16611660
PyBuffer_Release(buf)

tests/ndarray/test_numba_expr.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#######################################################################
2+
# Copyright (c) 2019-present, Blosc Development Team <[email protected]>
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under a BSD-style license (found in the
6+
# LICENSE file in the root directory of this source tree)
7+
#######################################################################
8+
9+
import numpy as np
10+
import pytest
11+
import numba as nb
12+
13+
import blosc2
14+
15+
@pytest.mark.parametrize(
16+
"shape, chunks, blocks",
17+
[
18+
((10, 10), (10, 10), (10, 10),),
19+
((20, 20), (10, 10), (10, 10),),
20+
((20, 20), (10, 10), (5, 5),),
21+
((13, 13), (10, 10), (10, 10),),
22+
((13, 13), (10, 10), (5, 5),),
23+
((10, 10), (10, 10), (4, 4),),
24+
((13, 13), (10, 10), (4, 4),),
25+
],
26+
)
27+
def test_numba_expr(shape, chunks, blocks): #, dtype, urlpath, contiguous
28+
@nb.jit(nopython=True, parallel=True)
29+
def func_numba(inputs_tuple, output, offset):
30+
x = inputs_tuple[0]
31+
output[:] = x + 1
32+
33+
# Create a NDArray from a NumPy array
34+
npa = np.linspace(0, 1, np.prod(shape)).reshape(shape)
35+
npc = npa + 1
36+
37+
# a = blosc2.asarray(npa)
38+
expr = blosc2.expr_from_udf(func_numba, ((npa, npa.dtype), ), npa.dtype, chunks=chunks, blocks=blocks)
39+
res = expr.eval()
40+
tol = 1e-5 if res.dtype is np.float32 else 1e-14
41+
if res.dtype in (np.float32, np.float64):
42+
np.testing.assert_allclose(res[...], npc, rtol=tol, atol=tol)
43+

0 commit comments

Comments
 (0)