2

I am running into a numpy error numpy.core._exceptions.MemoryError in my code. I have plenty of available memory in my machine so this shouldn't be a problem. (This is on a raspberry pi armv7l, 4GB)

$ free
              total        used        free      shared  buff/cache   available
Mem:        3748172       87636     3384520        8620      276016     3528836
Swap:       1048572           0     1048572

I have found this post which suggested that I should allow overcommit_memory in the kernel, and so I did:

$ cat /proc/sys/vm/overcommit_memory
1

Now when I try to run this example:

import numpy as np
arrays = [np.empty((18, 602, 640), dtype=np.float32) for i in range(200)]

I get the same error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
numpy.core._exceptions.MemoryError: Unable to allocate 26.5 MiB for an array with shape (18, 602, 640) and data type float32

Why is python (or numpy) behaving in that way and how can I get it to work?

EDIT: Answers to questions in replies:

This is a 32bit system (armv7l)

>>> sys.maxsize
2147483647

I printed the approximate size (according to the error message each iteration should be 26.5MiB) at which the example fails:

 def allocate_arr(i):
     print(i, i * 26.5)
     return np.empty((18, 602, 640), dtype=np.float32)

 arrays = [allocate_arr(i) for i in range(0, 200)]

The output shows that this fails below at around 3GB of RAM allocated:

1 26.5
2 53.0
3 79.5
...
111 2941.5
112 2968.0
113 2994.5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <listcomp>
  File "<stdin>", line 3, in allocate_arr
numpy.core._exceptions.MemoryError: Unable to allocate 26.5 MiB for an array with shape (18, 602, 640) and data type float32

Is 3GB the limit? Is there a way to increase that? Also isn't this the point of overcommitting?

Almog-at-Nailo
  • 1,152
  • 1
  • 4
  • 20
  • Is this a 32-bit build or a 64-bit build of Python? What's the value of `sys.maxsize`? – Mark Dickinson May 29 '23 at 11:17
  • Note that you're trying to allocate around 5.5Gb in total, which won't work on a 32-bit machine. – Mark Dickinson May 29 '23 at 11:19
  • 1
    Both questions answered in edit (@MarkDickinson) – Almog-at-Nailo May 29 '23 at 11:50
  • 1
    Then you have max 4Gb of addressable memory for any given process. Overcommit doesn't change that. (My guess is that the RPi OS is reserving 1Gb of the address space for the kernel, which is why you're hitting the limit at 3Gb. But that's just a guess; with luck someone better informed will be along to write a proper answer.) – Mark Dickinson May 29 '23 at 12:29

2 Answers2

2

By default 32-bit Linux has a 3:1 user/kernel split. That is, of the 4 GB one can address with a 32-bit unsigned integer, 3 GB is reserved for the user space but 1 GB is reserved for kernel space. Thus, any single process can use at most 3 GB memory. The vm.overcommit setting is not related to this, that is about using more virtual memory than there is actual physical memory backing the virtual memory.

There used to be so-called 4G/4G support in the Linux kernel (not sure if these patches were ever mainlined?), allowing the full 4 GB to be used by the user space process and another 4 GB address space by the kernel, at the cost of worse performance (TLB flush at every syscall?). But AFAIU these features have bitrotted as everyone who's interested in using lots of memory has moved to 64-bit systems a long time ago.

janneb
  • 36,249
  • 2
  • 81
  • 97
0

Others have exp similar issues in the past. Does the issue persist even on a 64 bit OS ? It's possible that the issue is related to the fact that you are using a 32-bit system. On a 32-bit system, the maximum amount of addressable memory for any given process is 4GB. It is possible that the OS is reserving some of the address space for the kernel ( 1GB) , which could explain why you are hitting the limit at around 3GB.

given as per your comments below that you are constrained in using 32 bit OS there are some additional things you may want to try I have not given 'em in comments since I just cannot format things easily over there the type space is pretty crunched

  • Increase swap space: On a 32-bit system, increasing the swap space can provide additional virtual memory. You can adjust the swap space size by modifying the configuration file /etc/dphys-swapfile on Raspberry Pi and then restarting the swap service. there is no guarantee this will work but given the short solutions give it a try

  • Split computations: If your computations involve large datasets or memory-intensive operations, consider splitting the task into smaller, manageable parts. Process data in smaller chunks or batches, perform computations incrementally, or use techniques like streaming or memory-mapped files to reduce the memory requirements at any given time.

  • Consider alternative libraries: If NumPy is too memory-intensive for your 32-bit system, you might explore alternative libraries that offer similar functionality but with lower memory requirements. For example, you could look into using Pandas with smaller datasets or exploring specialized libraries for specific tasks.

  • raspberry Pi kernel is open source and can be recompiled where you would need to make changes to the kernel configuration file (/usr/src/linux/.config) and then recompile the kernel. Specifically, you would modify the value of the CONFIG_OVERCOMMIT_MEMORY option to the desired setting. Setting it to CONFIG_OVERCOMMIT_MEMORY=2 would allow unlimited memory overcommitment.

user1874594
  • 2,277
  • 1
  • 25
  • 49
  • Theoretical limit for 32bit systems is 4GB. If the kernel is reserving 1GB of RAM, the question is now how do I change this ratio of kernel/user space so I can use all (or most) of that 4GB limit? – Almog-at-Nailo Jun 04 '23 at 08:35
  • On some systems, it may be possible to change the ratio of `kernel/user space` memory by adjusting the kernel configuration. However, I couldn’t find any specific information on how to do this on a `Raspberry Pi`...so only viable op is go for 64 bit OS that removes this restriction – user1874594 Jun 04 '23 at 08:50
  • Thnaks. Due to some system restrictions I can't move to a 64 bit system at the moment, so I'm looking for a solution on a 32bit OS – Almog-at-Nailo Jun 04 '23 at 10:39
  • I have added other things you can try to my answer hopefully one or more could work and you can use your current setup good luck – user1874594 Jun 05 '23 at 02:31