Как я могу предсказать ошибку памяти, зная размер используемых массивов? - PullRequest
0 голосов
/ 25 февраля 2019

Для обработки больших файлов моделирования (> 6 ГБ) я создал графический интерфейс, который ведет пользователя через каждый шаг.Используя API программного обеспечения для моделирования, я создал рабочий скрипт для извлечения соответствующих данных в пакетном режиме.В то время как программа в основном используется для извлечения небольших временных интервалов или только нескольких переменных, пользователь может также создать вывод, который приводит к MemoryError.

Поскольку я извлекаю данные в пакетах, результат будетбыть MemoryError в одном из последних шагов кода.Это не удобно для пользователя.Поэтому я хочу знать (с некоторой уверенностью), что вывод выдаст MemoryError и предупредить пользователя об этом перед выполнением сценария.Поскольку пользователь может установить размер общего пакета 1, я должен учитывать наихудший случай.Я уже думал о том, чтобы сохранить выходные данные API на моем жестком диске и затем объединить их.

Я знаю, что это предсказание каким-то образом возможно, потому что, например, numpy, вызывает ошибку MemoryError непосредственно после выполнения следующей команды (с 8 ГБ ОЗУ):

>>> e = np.random.rand(2000000,1000000000)
Traceback (most recent call last):
  File "D:\Continuum\anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2961, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-62-b74d848e009e>", line 1, in <module>
    e = np.random.rand(2000000,1000000000)
  File "mtrand.pyx", line 1363, in mtrand.RandomState.rand
  File "mtrand.pyx", line 861, in mtrand.RandomState.random_sample
  File "mtrand.pyx", line 167, in mtrand.cont0_array
MemoryError

Мне не удалось найти код, где возникает эта ошибка.

Что я пробовал до сих пор:

Используя psutil.virtual_memory() и базовое умножение измерений, я сравниваю доступную память и предполагаемый размер выходного массива:

import psutil

def checkForMemoryError(num_rows, num_cols):
    sizeInMemory = 1  # Factor to multiple the array dimension to convert to memory size.
    crit_size = psutil.virtual_memory().available  # Get available ram and provide threshold
    trajOutSize = num_cols * num_rows  # Size of trajOut in last interation
    if trajOutSize * sizeInMemory > crit_size:
        raise MemoryError

Я думаю, что этот подход несколько плох, так как psutil.virtual_memory() возвращаемые значения, которые не совпадают с выводом sys.getsizeof ():

In[59]: e = np.random.rand(2000,1000000)
In[60]: sys.getsizeof(e)
Out[60]: 16000000112
In[61]: psutil.virtual_memory().total
Out[61]: 8278392832

В этом примере размер массива np.array равен удвоенному размеру общей доступной памяти.Я думаю, что это связано с тем, что NumPy хранит и обрабатывает данные.Если он вас интересует / помогает, вывод API прост: list.Позже я преобразую этот 2D-список в фрейм данных, чтобы сохранить его в формате .hdf или .csv.

...