J'ai l'MWE suivant à l'aide comm.Scatterv
et comm.Gatherv
de distribuer un tableau 4D à travers un certain nombre de noyaux (size
)Le long de quel axe la fonction Scatterv de mpi4py scinde-t-elle un tableau numpy?
import numpy as np
from mpi4py import MPI
import matplotlib.pyplot as plt
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
test = np.random.rand(411,48,52,40) #Create array of random numbers
outputData = np.zeros(np.shape(test))
split = np.array_split(test,size,axis = 0) #Split input array by the number of available cores
split_sizes = []
for i in range(0,len(split),1):
split_sizes = np.append(split_sizes, len(split[i]))
displacements = np.insert(np.cumsum(split_sizes),0,0)[0:-1]
plt.imshow(test[0,0,:,:])
plt.show()
else:
#Create variables on other cores
split_sizes = None
displacements = None
split = None
test = None
outputData = None
#Broadcast variables to other cores
test = comm.bcast(test, root = 0)
split = comm.bcast(split, root=0)
split_sizes = comm.bcast(split_sizes, root = 0)
displacements = comm.bcast(displacements, root = 0)
output_chunk = np.zeros(np.shape(split[rank])) #Create array to receive subset of data on each core, where rank specifies the core
print("Rank %d with output_chunk shape %s" %(rank,output_chunk.shape))
comm.Scatterv([test,split_sizes, displacements,MPI.DOUBLE],output_chunk,root=0) #Scatter data from test across cores and receive in output_chunk
output = output_chunk
plt.imshow(output_chunk[0,0,:,:])
plt.show()
print("Output shape %s for rank %d" %(output.shape,rank))
comm.Barrier()
comm.Gatherv(output,[outputData,split_sizes,displacements,MPI.DOUBLE], root=0) #Gather output data together
if rank == 0:
print("Final data shape %s" %(outputData.shape,))
plt.imshow(outputData[0,0,:,:])
plt.show()
Cela crée un tableau 4D de nombres aléatoires et, en principe, devrait diviser entre size
noyaux avant recombinant. Je m'attendais à Scatterv
à diviser le long de l'axe 0 (longueur 411) en fonction des entiers de départ et des déplacements dans les vecteurs split_sizes
et displacements
. Cependant, j'obtiens une erreur lors de la recombinaison avec Gatherv
(mpi4py.MPI.Exception: MPI_ERR_TRUNCATE: message truncated
) et le tracé de output_chunk sur chaque core montre que la plupart des données d'entrée ont été perdues, il semble donc que la scission ne s'est pas produite le long du premier axe. Mes questions sont les suivantes: Pourquoi le fractionnement ne se produit-il pas le long du premier axe, comment puis-je savoir dans quel axe se produit la division, et est-il possible de changer/spécifier quel axe cela se produit?
'comm.Scatterv' ne sait probablement rien sur le tableau, la forme, les dimensions ou les pas de' numpy'. Au mieux, il peut traiter 'test' comme un bloc de mémoire. En fait, il se peut que ce soit uniquement le pointeur de l'objet tableau, et non son tampon de données. Est-ce que ce code fonctionne avec un tableau 1d? Ou 'test.flatten()'? – hpaulj