Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Divide by zero encountered in matmul on MacOS M4 with numpy v2.0.0

I'm encountering a strange RuntimeWarning: divide by zero encountered in matmul when performing a simple matrix multiplication on my new Apple M4 machine.

The most peculiar part is that this warning appears specifically when the identity matrix dimension is n=15, but it does not occur for n=14 or other smaller values I've tested. The calculation itself appears to complete correctly.

Environment

Hardware: MacBook Pro (M4 Chip)

  • OS: macOS Sonoma

  • Python: 3.12

  • NumPy Version: 2.0.0 (or the latest version installed via pip)

Minimal Reproducible Example

Here is the simple code that reproduces the issue:

import numpy as np

print(f"NumPy version: {np.__version__}")

# This line produces the RuntimeWarning
print("Testing with n=15:")
try:
    result_15 = np.identity(n=15) @ np.identity(n=15)
    print(result_15)
except Exception as e:
    print(e)

print("\n" + "="*30 + "\n")

# This line runs without any warning
print("Testing with n=14:")
try:
    result_14 = np.identity(n=14) @ np.identity(n=14)
    print(result_14)
except Exception as e:
    print(e)

Output:

(.venv) mursalatulpallob@Mac ml_codes % python del.py 
NumPy version: 2.0.0
Testing with n=15:
/Users/mursalatulpallob/programming/research/ml_codes/del.py:8: RuntimeWarning: divide by zero encountered in matmul
  result_15 = np.identity(n=15) @ np.identity(n=15)
/Users/mursalatulpallob/programming/research/ml_codes/del.py:8: RuntimeWarning: overflow encountered in matmul
  result_15 = np.identity(n=15) @ np.identity(n=15)
/Users/mursalatulpallob/programming/research/ml_codes/del.py:8: RuntimeWarning: invalid value encountered in matmul
  result_15 = np.identity(n=15) @ np.identity(n=15)
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

==============================

Testing with n=14:
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

BLAS Configuration of numpy:

{
  "Compilers": {
    "c": {
      "name": "clang",
      "linker": "ld64",
      "version": "15.0.0",
      "commands": "cc"
    },
    "cython": {
      "name": "cython",
      "linker": "cython",
      "version": "3.0.10",
      "commands": "cython"
    },
    "c++": {
      "name": "clang",
      "linker": "ld64",
      "version": "15.0.0",
      "commands": "c++"
    }
  },
  "Machine Information": {
    "host": {
      "cpu": "aarch64",
      "family": "aarch64",
      "endian": "little",
      "system": "darwin"
    },
    "build": {
      "cpu": "aarch64",
      "family": "aarch64",
      "endian": "little",
      "system": "darwin"
    }
  },
  "Build Dependencies": {
    "blas": {
      "name": "accelerate",
      "found": true,
      "version": "unknown",
      "detection method": "system",
      "include directory": "unknown",
      "lib directory": "unknown",
      "openblas configuration": "unknown",
      "pc file directory": "unknown"
    },
    "lapack": {
      "name": "accelerate",
      "found": true,
      "version": "unknown",
      "detection method": "system",
      "include directory": "unknown",
      "lib directory": "unknown",
      "openblas configuration": "unknown",
      "pc file directory": "unknown"
    }
  },
  "Python Information": {
    "path": "/private/var/folders/dm/88b38gj92jj53dgxdsm12qf00000gn/T/build-env-j0ydyct6/bin/python",
    "version": "3.9"
  },
  "SIMD Extensions": {
    "baseline": [
      "NEON",
      "NEON_FP16",
      "NEON_VFPV4",
      "ASIMD"
    ],
    "found": [
      "ASIMDHP"
    ],
    "not found": [
      "ASIMDFHM"
    ]
  }
}

This problem doesn't occur on Windows or Linux. Is there any way to fix this without downgrading NumPy, since the latest Python packages require an up-to-date version?

like image 960
Md. Mursalatul Islam Pallob Avatar asked Oct 27 '25 19:10

Md. Mursalatul Islam Pallob


1 Answers

Is there any way to fix this without downgrading NumPy, since the latest Python packages require an up-to-date version?

I have two possible suggestions for how you could work around this: suppress errors locally, or suppress errors globally.

  1. You could use np.errstate() to selectively suppress warnings on the specific lines. This can be done by placing a with np.errstate(): context manager around each matrix multiply.

    import numpy as np
    
    with np.errstate(divide='ignore', over='ignore', invalid='ignore'):
        A = B @ C
    

    Note that this will also suppress warnings that are not caused by this bug. For example, this will also suppress errors due to overflows (e.g. a matmul of 1e200 * 1e200 will not fit in a floating point number) and invalid values (e.g. a matmul containing NaN.)

  2. You could use np.seterr() to supress these kinds of errors everywhere in your program. You can do this by placing the following code at the beginning of your program.

    import numpy as np
    
    np.seterr(divide='ignore', over='ignore', invalid='ignore')
    

    Note that this will also suppress warnings that are not caused by this bug.

like image 65
Nick ODell Avatar answered Oct 30 '25 10:10

Nick ODell