En MPI, estoy haciendo una operación de reducción (mínimo) en un valor. Esto funciona bien, pero ¿cómo tomo el número de procesador del que proviene el mínimo y solicito más información al procesador (o envío de datos adicionales con la operación de reducción)?MPI Obtener procesador con valor mínimo
Respuesta
Si no le importa emparejar cada valor localmente con un índice entero (rellenado en este caso con el valor del rango local), puede usar las operaciones integradas MPI_MINLOC or MPI_MAXLOC para reducir; o que es bastante fácil de escribir su propio operador de reducción de MPI para incluir cosas como varios índices, ETCC
actualizado para añadir: Con la MINLOC operadores orden interna o MAXLOC, en lugar de pasar en un solo valor para encontrar el mínimo de , pasas eso más un índice entero. Ese índice puede tener cualquier valor que desee, pero "sigue" el otro valor a lo largo. MPI ha incorporado tipos de datos "pares" - MPI_DOUBLE_INT para un doble + un int, o MPI_2INT para dos entradas, que puede usar.
Supongamos que quiere encontrar el mínimo de una matriz de enteros y en qué tarea de MPI se encuentra. Como es normal, usted encuentra su mínimo local en cada tarea, y realiza la reducción; pero esta vez también sincronizarlo con un entero, en este caso su rango:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char **argv) {
int rank, size;
const int locn=5;
int localarr[locn];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
srand(rank);
for (int i=0; i<locn; i++)
localarr[i] = rand() % 100;
for (int proc=0; proc<size; proc++) {
if (rank == proc) {
printf("Rank %2d has values: ",rank);
for (int i=0; i<locn; i++)
printf(" %d ", localarr[i]);
printf("\n");
}
MPI_Barrier(MPI_COMM_WORLD);
}
int localres[2];
int globalres[2];
localres[0] = localarr[0];
for (int i=1; i<locn; i++)
if (localarr[i] < localres[0]) localres[0] = localarr[i];
localres[1] = rank;
MPI_Allreduce(localres, globalres, 1, MPI_2INT, MPI_MINLOC, MPI_COMM_WORLD);
if (rank == 0) {
printf("Rank %d has lowest value of %d\n", globalres[1], globalres[0]);
}
MPI_Finalize();
return 0;
}
Y corriendo que se obtiene:
$ mpirun -np 5 ./minloc
Rank 0 has values: 83 86 77 15 93
Rank 1 has values: 83 86 77 15 93
Rank 2 has values: 90 19 88 75 61
Rank 3 has values: 46 85 68 40 25
Rank 4 has values: 1 83 74 26 63
Rank 4 has lowest value of 1
Si el valor que está reduciendo no es un entero, (digamos, un doble), crea una estructura que contiene el valor de reducción y el índice entero, y usa el tipo de datos de par MPI apropiado. (por ejemplo, MPI_DOUBLE_INT).
más actualizada: Ok, sólo por diversión, haciéndolo con nuestra propia operación de reducción y nuestro propio tipo de implementar dos índices:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
typedef struct dbl_twoindex_struct {
double val;
int rank;
int posn;
} dbl_twoindex;
void minloc_dbl_twoindex(void *in, void *inout, int *len, MPI_Datatype *type){
/* ignore type, just trust that it's our dbl_twoindex type */
dbl_twoindex *invals = in;
dbl_twoindex *inoutvals = inout;
for (int i=0; i<*len; i++) {
if (invals[i].val < inoutvals[i].val) {
inoutvals[i].val = invals[i].val;
inoutvals[i].rank = invals[i].rank;
inoutvals[i].posn = invals[i].posn;
}
}
return;
}
int main(int argc, char **argv) {
int rank, size;
const int locn=5;
double localarr[locn];
dbl_twoindex local, global;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* create our new data type */
MPI_Datatype mpi_dbl_twoindex;
MPI_Datatype types[3] = { MPI_DOUBLE, MPI_INT, MPI_INT };
MPI_Aint disps[3] = { offsetof(dbl_twoindex, val),
offsetof(dbl_twoindex, rank),
offsetof(dbl_twoindex, posn), };
int lens[3] = {1,1,1};
MPI_Type_create_struct(3, lens, disps, types, &mpi_dbl_twoindex);
MPI_Type_commit(&mpi_dbl_twoindex);
/* create our operator */
MPI_Op mpi_minloc_dbl_twoindex;
MPI_Op_create(minloc_dbl_twoindex, 1, &mpi_minloc_dbl_twoindex);
srand(rank);
for (int i=0; i<locn; i++)
localarr[i] = 1.*rand()/RAND_MAX;
for (int proc=0; proc<size; proc++) {
if (rank == proc) {
printf("Rank %2d has values: ",rank);
for (int i=0; i<locn; i++)
printf(" %8.4lf ", localarr[i]);
printf("\n");
}
MPI_Barrier(MPI_COMM_WORLD);
}
local.val = localarr[0];
local.posn = 0;
for (int i=1; i<locn; i++)
if (localarr[i] < local.val) {
local.val = localarr[i];
local.posn = i;
}
local.rank = rank;
MPI_Allreduce(&local, &global, 1, mpi_dbl_twoindex, mpi_minloc_dbl_twoindex, MPI_COMM_WORLD);
if (rank == 0) {
printf("Rank %d has lowest value of %8.4lf in position %d.\n", global.rank, global.val, global.posn);
}
MPI_Op_free(&mpi_minloc_dbl_twoindex);
MPI_Type_free(&mpi_dbl_twoindex);
MPI_Finalize();
return 0;
}
funcionar, se
$ mpirun -np 5 ./minloc2
Rank 0 has values: 0.8402 0.3944 0.7831 0.7984 0.9116
Rank 1 has values: 0.8402 0.3944 0.7831 0.7984 0.9116
Rank 2 has values: 0.7010 0.8097 0.0888 0.1215 0.3483
Rank 3 has values: 0.5614 0.2250 0.3931 0.4439 0.2850
Rank 4 has values: 0.9165 0.1340 0.1912 0.2601 0.2143
Rank 2 has lowest value of 0.0888 in position 2.
- 1. Obtener el valor mínimo entre varias columnas
- 2. fila con valor mínimo de una columna
- 3. Android SeekBar Valor mínimo
- 4. Obtener el valor mínimo de un mapa (clave, doble)
- 5. MPI: ¿núcleos o procesadores?
- 6. Obtener el valor mínimo flotante NEGATIVO en C++
- 7. Valor mínimo de la pila
- 8. Encuentre el valor positivo mínimo
- 9. MPI ¿Número de procesadores?
- 10. Buscar valor mínimo en una columna
- 11. ¿Cómo compilar MPI con gcc?
- 12. Encontrar el valor mínimo en un mapa
- 13. encontrar el valor mínimo en int matriz con C#
- 14. ¿Cómo encontrar el índice del elemento con un valor mínimo?
- 15. Obtener información del procesador en Python
- 16. ¿Encontrando el valor mínimo del grupo máximo?
- 17. Bash: Valor mínimo de la variable global
- 18. ¿MPI o zócalos?
- 19. Cómo obtener el número de procesador en android
- 20. Obtener casilla con valor específico
- 21. ¿Necesito tener un MPI :: Irecv correspondiente para un MPI :: Isend?
- 22. Obtener la clave correspondiente al valor mínimo dentro de un diccionario
- 23. Cargando biblioteca compartida en open-mpi/mpi-run
- 24. MPI y C construye
- 25. Variables globales y MPI
- 26. OBJ-C: obteniendo el valor mínimo/máximo en un NSMutableArray
- 27. MPI - Transmisión asíncrona/Reúna
- 28. Sección crítica en MPI?
- 29. Servidor web Java mínimo con soporte JSP
- 30. ASP.NET MVC 2 y ComponentModel.DataAnnotations Validación: atributo de valor mínimo
¿Puede explicar o ejemplificar esto? –
¡Gracias, eso ayudó tanto! ¿Se puede definir algo así como MPI_DOUBLE_2INT para poder enviar más de una clave por doble? –
Creo que para cualquier cosa que no sean los tipos integrados, tendría que escribir su propia operación, pero no sería tan difícil. –