Действительно ли xarray или dask поддерживают отображение памяти?

В своих экспериментах я пробовал:

  • xr.open_dataset с chunks аргументом, и он загружает данные в память.
  • Настройте NetCDF4DataStore и вызовите ds['field'].values, и он загрузит данные в память.
  • Установите ScipyDataStore с mmap='r', и ds['field'].values загружает данные в память.

Из того, что я видел, дизайн, похоже, сосредоточен не на фактическом применении функций numpy к массивам с отображением памяти, а скорее на загрузке небольших фрагментов в память (иногда с использованием отображения памяти для этого). Например, этот комментарий. И несколько связанный комментарий здесь о том, что xarray не может определить, является ли массив numpy mmapped или нет.

Я хотел бы иметь возможность представлять и нарезать данные как xarray.Dataset, а также иметь возможность вызывать .values (или .data), чтобы получить ndarray, но чтобы он оставался mmapped (для целей совместно используемой памяти и т. Д.).

Также было бы неплохо, если бы операции dask с фрагментами могли, по крайней мере, работать с отображенным в память массивом до тех пор, пока ему действительно не нужно что-то видоизменить, что кажется возможным, поскольку dask, похоже, спроектирован вокруг неизменяемых массивов.

Тем не менее, я нашел трюк с xarray, который должен сделать так:

data=np.load('file.npy', mmap_mode='r')
ds=xr.Dataset({'foo': (['dim1', 'dim2'], data)})

На этом этапе такие вещи, как следующие, работают без загрузки в память:

np.sum(ds['foo'].values)
np.sum(ds['foo'][::2,:].values)

... xarray, по-видимому, не знает, что массив является mmapped, и не может позволить наложить np.copy для таких случаев.

Есть ли «поддерживаемый» способ сделать memmapping только для чтения (или копирующую запись, если на то пошло) в xarray или dask?


person chrisbarber    schedule 24.06.2017    source источник


Ответы (1)


xr.open_dataset с chunks= не должен сразу загружать данные в память, он должен создавать dask.array, который выполняет ленивую оценку.

testfile = '/Users/mdurant/data/smith_sandwell_topo_v8_2.nc'
arr = xr.open_dataset(testfile, chunks={'latitude': 6336//11, 'longitude': 10800//15}).ROSE
arr 

<xarray.DataArray 'ROSE' (latitude: 6336, longitude: 10800)> dask.array</Users/mdurant/data/smith_sandwell_topo_v8_2.nc:/ROSE, shape=(6336, 10800), dtype=float64, chunksize=(576, 720)> Coordinates: * longitude (longitude) float32 0.0166667 0.05 0.0833333 0.116667 0.15 ... * latitude (latitude) float32 -72.0009 -71.9905 -71.9802 -71.9699 ... Attributes: long_name: Topography and Bathymetry ( 8123m -> -10799m) units: meters valid_range: [-32766 32767] unpacked_missing_value: -32767.0 (обратите внимание на dask.array выше)

Многие операции xarray могут быть ленивыми и работать по частям (и если вы разрежете, будут загружены только необходимые фрагменты)

arr.sum()

<xarray.DataArray 'ROSE' ()> dask.array<sum-aggregate, shape=(), dtype=float64, chunksize=()>

arr.sum().values    # evaluates

Однако это не то же самое, что отображение памяти, поэтому я признателен, если это не ответит на ваш вопрос.

В многопоточном планировщике dask значения в памяти доступны другим рабочим, поэтому совместное использование будет весьма эффективным. И наоборот, распределенный планировщик неплохо распознает, когда результаты можно повторно использовать в графе вычислений или между графами.

person mdurant    schedule 26.06.2017
comment
Я подумал, что было бы круто, если бы xarray / dask поддерживали сквозное отображение памяти. Но с другой стороны, отложенная загрузка фрагментов почти функционально эквивалентна. Я предполагаю, что xarray по умолчанию использует планировщик dask.threaded. Я создаю сервер на основе модели данных в стиле xarray / CF (для приложений веб-визуализации для доступа и запросов через веб-сокет), и я пытаюсь решить, стоит ли полагаться на хакерский метод memmapping, который я описал выше, вместе с моим собственным распараллеливанием, или полностью на dask. - person chrisbarber; 26.06.2017
comment
Сами данные доступны только для чтения, но для некоторых запросов может быть полезно вычислить динамический массив масок на основе некоторых параметров / фильтров. Здесь может пригодиться изменяемый массив sharedmem. Хотя использование dask для вычисления маски с каждым запросом тоже может подойти. Мне нужно больше расследовать самостоятельно. Я, вероятно, приму ваш ответ, хотя, кстати, поскольку мой вопрос, похоже, касается неподдерживаемых / недокументированных аспектов xarray, что является сложной задачей. - person chrisbarber; 26.06.2017
comment
Да, dask по умолчанию использует многопоточный планировщик и, следовательно, xarray, если вы не создали распределенный клиент. Для файлов HDF это желательно, поскольку в противном случае могут возникнуть проблемы с межпроцессной блокировкой файлов. Для интерактивной визуализации больших наборов данных с помощью xarray / dask вы можете изучить примеры даташадера < / а>. - person mdurant; 27.06.2017
comment
Я был обеспокоен тем, что граф задач, такой как ((arr>0.75)*arr).sum(), съел бы много памяти, поскольку промежуточное вычисление (arr>0.75) - это размер полного массива. Но теперь мне кажется очевидным, что размер отпечатка будет просто chunksize * Nthreads. Я думаю, что это отлично подойдет для моего приложения без необходимости отображения памяти. Я выполняю статистические запросы на стороне сервера, используя такие функции, как da.einsum, а компонент визуализации на данный момент довольно прост. Datashader выглядит потрясающе, спасибо за фиксатор HDF. - person chrisbarber; 27.06.2017