镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

In-place operators on NDArray (a *= 2) return a LazyExpr and leave the array unchanged #760

Open

Description

@FabianIsensee

Hi Francesc,

NDArray.__imul__ and the other in-place operators (__iadd__, __isub__, __itruediv__, __ifloordiv__, __imod__, __ipow__, __iand__, __ior__, __ixor__, __ilshift__, __irshift__) return the out-of-place LazyExpr. So a *= 2 rebinds the name a to a lazy expression, and the array itself, which other names may still refer to, does not change:

import blosc2
import numpy as np

a = blosc2.ones(4, dtype=np.float32)
b = a        # e.g. the caller's reference to the same array
a *= 2
type(a)      # blosc2.lazyexpr.LazyExpr
b[:]         # array([1., 1., 1., 1.], dtype=float32): the array did not change

This is blosc2 4.14.1; the methods are the same on main (a712c65).

With NumPy, a *= 2 updates the array in place, and code written for NumPy arrays relies on that, e.g. a function that rescales an array it is given. Given an NDArray, such code silently does nothing to the caller's data, and nothing raises. I noticed it while looking at nnInteractive, which rescales stored blosc2 channels with interactions[ch] *= scale: that works because it goes through __getitem__ (a NumPy array) and __setitem__, while interactions *= scale would have replaced the attribute with a LazyExpr and left the stored channels as they were.

Would you take a PR that makes these operators work in place? (a * 2).compute(out=a) already gives the right values in place in the cases I tried (float16, float32 and int32, with several chunks), so they could evaluate the expression into self and return self. Two points I have not checked yet: whether compute(out=) is safe when the other operand overlaps self (e.g. a shifted view), and keeping self's dtype (NumPy raises for int_array *= 2.5 under its default same_kind casting). If the lazy result is intended instead, documenting it, and perhaps a warning, would already help.

AI disclosure: I used Claude Code (Anthropic) to look into this and to draft this issue, and Claude Code opened it on my behalf. I checked the examples.

Best,
Fabian

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions