Как работает режим копирования-записи-записи в memmap? - PullRequest
0 голосов
/ 03 января 2019

Я смущен тем, как numpy's memmap обрабатывает изменения данных при использовании копирования при записи (mmap_mode=c).Поскольку в исходный массив на диске ничего не записано, я ожидаю, что он должен хранить все изменения в памяти и, следовательно, может исчерпать память, если вы измените каждый отдельный элемент.К моему удивлению, этого не произошло.

Я пытаюсь сократить использование памяти для своих сценариев машинного обучения, которые я запускаю в общем кластере (чем меньше памяти занимает каждый экземпляр, тем больше экземпляров я могу запуститьв то же время).У меня очень большие массивы данных (каждый> 8 Гб).Я надеюсь использовать np.memmap для работы с этими массивами с малой памятью (доступно <4 ГБ). </p>

Однако каждый экземпляр может по-разному изменять данные (например, может каждый раз по-разному нормализовать входные данные),Это имеет значение для места для хранения.Если я использую режим r+, то нормализация массива в моем сценарии навсегда изменит сохраненный массив.

Поскольку я не хочу избыточных копий данных, а просто хочу сохранить исходные данные вдиск, я думал, что я должен использовать режим 'c' (копирование при записи), чтобы открыть массивы.Но тогда куда делись твои изменения?Сохраняются ли изменения только в памяти?Если это так, если я изменю весь массив, не будет ли у меня нехватка памяти в системе с малой памятью?

Вот пример теста, который я ожидал провалить:

Набольшая система памяти, создайте массив:

import numpy as np
GB = 1000**3
GiB = 1024**3
a = np.zeros((50000, 20000), dtype='float32')
bytes = a.size * a.itemsize
print('{} GB'.format(bytes / GB))
print('{} GiB'.format(bytes / GiB))
np.save('a.npy', a)
# Output:
# 4.0 GB
# 3.725290298461914 GiB

Теперь на машине с объемом памяти всего 2 ГБ происходит сбой, как и ожидалось:

a = np.load('a.npy')

Но эти два удастся, так какожидается:

a = np.load('a.npy', mmap_mode='r+')
a = np.load('a.npy', mmap_mode='c')

Проблема 1: Недостаточно памяти для запуска этого кода, пытаюсь изменить массив memmapped (не удается независимо от режима r + / c):

for i in range(a.shape[0]):
    print('row {}'.format(i))
    a[i,:] = i*np.arange(a.shape[1])

Почему происходит сбой (особенно, почему он не работает даже в режиме r+, где он может записывать на диск)?Я думал, memmap будет загружать только части массива в память?

Проблема 2: Когда я заставляю numpy сбрасывать изменения время от времени, оба r +Режим / C успешно завершить цикл. Но как режим c может это сделать? Я не думал, что flush() что-нибудь сделает для режима c?Изменения не записываются на диск, поэтому они хранятся в памяти, и все же каким-то образом все изменения, которые должны превышать 3 ГБ, не вызывают ошибок нехватки памяти?

for i in range(a.shape[0]):
    if i % 100 == 0:
        print('row {}'.format(i))
        a.flush()
    a[i,:] = i*np.arange(a.shape[1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...