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?
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.
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With