Tengo dos archivos HDF5 que tienen una estructura idéntica, cada uno almacena una matriz de la misma forma. Necesito crear un tercer archivo HDF5 con una matriz que represente la suma de elementos de las dos matrices mencionadas anteriormente. Dado que los tamaños de las matrices son extremadamente grandes (en el rango Gb-Tb), ¿cuál sería la mejor manera de hacerlo, preferiblemente en forma paralela? Estoy usando la interfaz h5py para la biblioteca HDF5. ¿Hay bibliotecas capaces de hacerlo?

0
freude 20 ene. 2021 a las 06:39

1 respuesta

La mejor respuesta

Si, esto es posible. La clave es acceder a porciones de datos de file1 & file2, hacer su suma de elementos y luego escribir esa porción de datos nuevos en file3. Puede hacer esto con h5py o PyTables (también conocido como tablas). No se requieren otras bibliotecas. Solo tengo un conocimiento pasajero de computación paralela. Sé que h5py admite una interfaz mpi a través del paquete mpi4py Python. Detalles aquí: h5py docs: Parallel HDF5

He aquí un ejemplo sencillo. Crea 2 archivos con un conjunto de datos de flotantes aleatorios, shape=(10,10,10). Luego crea un nuevo archivo con un conjunto de datos vacío de la misma forma. El bucle lee un segmento de datos de file1 y file2, los suma y luego escribe en el mismo segmento en file3. Para probar con datos grandes, puede modificar las formas para que coincidan con su archivo.
Actualización del 21 de enero de 2021:
Agregué código para obtener las formas del conjunto de datos de file1 y file2, y compararlas (para asegurarme de que sean iguales). Si las formas no son iguales, salgo. Si coinciden, creo el nuevo archivo y luego creo un conjunto de datos de forma coincidente. (Si realmente quiere ser robusto, puede hacer lo mismo con el dtype). También utilizo el valor de shape[2] como iterador de corte sobre el conjunto de datos.

import h5py
import numpy as np
import random
import sys

arr = np.random.random(10**3).reshape(10,10,10)
with h5py.File('file1.h5','w') as h5fw :
    h5fw.create_dataset('data_1',data=arr)

arr = np.random.random(10**3).reshape(10,10,10)
with h5py.File('file2.h5','w') as h5fw :
    h5fw.create_dataset('data_2',data=arr)

h5fr1 = h5py.File('file1.h5','r')
f1shape = h5fr1['data_1'].shape
h5fr2 = h5py.File('file2.h5','r')
f2shape = h5fr2['data_2'].shape

if (f1shape!=f2shape):
    print ('Datasets shapes do not match')
    h5fr1.close()
    h5fr2.close()
    sys.exit('Exiting due to error.') 
         
else:
    with h5py.File('file3.h5','w') as h5fw :
        ds3 = h5fw.create_dataset('data_3', shape=f1shape, dtype='f')
    
        for i in range(f1shape[2]):
            arr1_slice = h5fr1['data_1'][:,:,i]
            arr2_slice = h5fr2['data_2'][:,:,i]
            arr3_slice = arr1_slice + arr2_slice
            ds3[:,:,i] = arr3_slice
        
        #     alternately, you can slice and sum in 1 line
        #     ds3[:,:,i] = h5fr1['data_1'][:,:,i] + \
        #                  h5fr2['data_2'][:,:,i]    
            
    print ('Done.')

h5fr1.close()
h5fr2.close()
1
kcw78 21 ene. 2021 a las 20:16