Skip to content

Commit 77ab92e

Browse files
committed
Merge branch 'main' of github.com:Blosc/python-blosc2
2 parents 1796a60 + 5382b58 commit 77ab92e

4 files changed

Lines changed: 32 additions & 3 deletions

File tree

src/blosc2/lazyexpr.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,7 @@ def _new_expr(cls, expression, operands, guess, out=None, where=None, ne_args=No
31093109
# Validate the expression
31103110
validate_expr(expression)
31113111
expression = convert_to_slice(expression)
3112+
chunks, blocks = None, None
31123113
if guess:
31133114
# The expression has been validated, so we can evaluate it
31143115
# in guessing mode to avoid computing reductions
@@ -3139,6 +3140,11 @@ def _new_expr(cls, expression, operands, guess, out=None, where=None, ne_args=No
31393140
# (e.g. all operands are numpy arrays or constructors)
31403141
# or passed "a", "a[:10]", 'sum(a)'
31413142
expression_, operands_ = conserve_functions(_expression, _operands, local_vars)
3143+
if hasattr(new_expr, "chunks") and new_expr.chunks != (1,) * len(_shape):
3144+
# for constructors with chunks in kwargs, chunks will be specified
3145+
# for general expression new_expr is just with dummy scalar variables (so ignore)
3146+
chunks = new_expr.chunks
3147+
blocks = new_expr.blocks
31423148
new_expr = cls(None)
31433149
new_expr.expression = f"({expression_})" # force parenthesis
31443150
new_expr.operands = operands_
@@ -3147,6 +3153,8 @@ def _new_expr(cls, expression, operands, guess, out=None, where=None, ne_args=No
31473153
# Cache the dtype and shape (should be immutable)
31483154
new_expr._dtype = _dtype
31493155
new_expr._shape = _shape
3156+
if chunks is not None and blocks is not None:
3157+
new_expr._chunks, new_expr._blocks = chunks, blocks
31503158
else:
31513159
# Create a new LazyExpr object
31523160
new_expr = cls(None)

src/blosc2/ndarray.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5208,7 +5208,7 @@ def arange_fill(inputs, output, offset):
52085208

52095209
if is_inside_new_expr() or NUM < 0:
52105210
# We already have the dtype and shape, so return immediately
5211-
return blosc2.zeros(shape, dtype=dtype)
5211+
return blosc2.zeros(shape, dtype=dtype, **kwargs)
52125212

52135213
lshape = (math.prod(shape),)
52145214
lazyarr = blosc2.lazyudf(arange_fill, (start, stop, step), dtype=dtype, shape=lshape)
@@ -5309,7 +5309,7 @@ def linspace_fill(inputs, output, offset):
53095309

53105310
if is_inside_new_expr() or num == 0:
53115311
# We already have the dtype and shape, so return immediately
5312-
return blosc2.zeros(shape, dtype=dtype) # will return empty array for num == 0
5312+
return blosc2.zeros(shape, dtype=dtype, **kwargs) # will return empty array for num == 0
53135313

53145314
inputs = (start, stop, num, endpoint)
53155315
lazyarr = blosc2.lazyudf(linspace_fill, inputs, dtype=dtype, shape=(num,))

src/blosc2/shape_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,9 @@ def visit_Constant(self, node):
521521
def visit_Tuple(self, node):
522522
return tuple(self.visit(arg) for arg in node.elts)
523523

524+
def visit_List(self, node):
525+
return self.visit_Tuple(node)
526+
524527
def visit_BinOp(self, node):
525528
left = self.visit(node.left)
526529
right = self.visit(node.right)

tests/ndarray/test_lazyexpr.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,7 @@ def test_sort():
13451345

13461346
def test_listargs():
13471347
# lazyexpr tries to convert [] to slice, but could
1348-
# have problems for argumetns which are lists
1348+
# have problems for arguments which are lists
13491349
shape = (20,)
13501350
na = np.arange(shape[0])
13511351
a = blosc2.asarray(na)
@@ -1354,6 +1354,18 @@ def test_listargs():
13541354
np.testing.assert_array_equal(expr[:], np.stack([a[:], b[:]]))
13551355

13561356

1357+
def test_str_constructors():
1358+
shape = (1000, 1)
1359+
chunks = (100, 1)
1360+
a = blosc2.lazyexpr(f"linspace(0, 100, {np.prod(shape)}, shape={shape}, chunks={chunks})")
1361+
assert a.chunks == chunks
1362+
b = blosc2.lazyexpr("a.T") # this fails unless chunkshape is assigned to a on creation
1363+
1364+
b = blosc2.ones((1000, 10))
1365+
a = blosc2.lazyexpr(f"b + linspace(0, 100, {np.prod(shape)}, shape={shape}, chunks={chunks})")
1366+
assert a.shape == np.broadcast_shapes(shape, b.shape)
1367+
1368+
13571369
@pytest.mark.parametrize(
13581370
"obj",
13591371
[
@@ -1735,6 +1747,12 @@ def test_lazylinalg():
17351747
npres = np.stack((npx, npy), axis=0)
17361748
assert out.shape == npres.shape
17371749
np.testing.assert_array_almost_equal(out[()], npres)
1750+
# --- stack ---
1751+
# repeat with list arg instead of tuple
1752+
out = blosc2.lazyexpr("stack([x, y], axis=0)")
1753+
npres = np.stack((npx, npy), axis=0)
1754+
assert out.shape == npres.shape
1755+
np.testing.assert_array_almost_equal(out[()], npres)
17381756

17391757
# --- tensordot ---
17401758
out = blosc2.lazyexpr("tensordot(A, B, axes=1)") # test with int axes

0 commit comments

Comments
 (0)