W MPI wykonuję operację zmniejszenia (minimalną) na wartości. To działa dobrze, ale w jaki sposób mogę pobrać numer procesora, z którego pochodzi minimum i poprosić tego procesora o więcej informacji (lub wysłać dodatkowe dane za pomocą operacji zmniejszania)?MPI Pobierz procesor z wartością minimalną
Odpowiedz
Jeśli nie masz nic przeciwko parowaniu każdej wartości lokalnie z indeksem całkowitym (wypełnionym w tym przypadku wartością lokalnego rankingu), możesz użyć wbudowanych operacji MPI_MINLOC or MPI_MAXLOC dla zmniejszenia; czy jest to dość łatwe do napisania własnego operatora redukcji MPI na takie rzeczy jak wielu indeksów, ETCC
Updated dodać: Z wbudowanego operatorów MINLOC lub MAXLOC zamiast przechodzącą w pojedynczej wartości, aby znaleźć minimum , przekazujesz w tym plus indeks liczby całkowitej. Indeks może mieć dowolną wartość, ale "podąża" za drugą wartością. MPI ma wbudowane typy danych "pair" - MPI_DOUBLE_INT dla double + an int lub MPI_2INT dla dwóch int, z których możesz korzystać.
Powiedzmy, że chcesz znaleźć minimum tablicy całkowitej i na którym zadaniu MPI było ono zlokalizowane. W normalny sposób określasz swoje lokalne minimum dla każdego zadania i redukujesz je; ale tym razem także powiązać go z liczby całkowitej, w tym przypadku swoją rangę:
#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;
}
i działa otrzymasz:
$ 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
Jeżeli wartość jesteś zmniejszenie nie jest liczbą całkowitą, (powiedzmy, podwójne), tworzysz strukturę zawierającą wartość redukcji i indeks liczby całkowitej, i używasz odpowiedniego typu danych pary MPI. (np. MPI_DOUBLE_INT).
Zaktualizowane dalsze: Ok, tylko dla zabawy, robi to z własnej pracy redukcji i naszego własnego rodzaju wdrożyć dwa wskaźniki:
#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;
}
Bieg daje
$ 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. Swift i ObjectMapper: NSDate z wartością minimalną
- 2. Atrybuty Perl Moose z minimalną, maksymalną i domyślną wartością
- 3. Pobierz obiekt z wartością atrybutu max na liście obiektów
- 4. Program hybrydowy OpenMP i MPI
- 5. MPI + GPU: jak miksować obie techniki
- 6. Jak używać LINQ do wybierania obiektu z minimalną lub maksymalną wartością właściwości
- 7. Jak grupować według jednej kolumny i pobrać wiersz z minimalną wartością innej kolumny w T/SQL?
- 8. Ładowanie udostępnionej biblioteki w open-mpi/mpi-run
- 9. Microsoft MPI nie działa
- 10. MPI Liczba procesorów?
- 11. Testy jednostkowe Programy MPI z gtestem
- 12. Procesor adnotacji: pobierz wszystkie wartości wyliczeniowe z obiektu TypeMirror lub TypeElement
- 13. Dopasuj linię z wartością LOESS w R
- 14. Obliczyć minimalną parę wektorów.
- 15. NSDictionary z wartością pustą
- 16. Jak ustawić minimalną szerokość z rozmiarem tła
- 17. Debugowanie MPI za pomocą VS2012
- 18. Jakiej biblioteki Pythona mpi użyć?
- 19. MPI i D: Opcje Linkera
- 20. Wykorzystanie wektorów w MPI (C++)
- 21. MPI - Błąd ładowania biblioteki współdzielone
- 22. Definiowanie zmiennych globalnych w MPI
- 23. Procesor zrzutu GCC definiuje
- 24. Procesor asynchroniczny Django
- 25. Ustawienie Explict procesor adnotacji
- 26. Python - procesor wielkoformatowy z 2 okienkami gtk
- 27. Django-sass-procesor TypeError
- 28. Procesor XSLT2.0 dla Perla?
- 29. Jak uruchamiać aplikacje kompatybilne z MPI z notebooków Jupyter?
- 30. vector.assign() z wartością w sekwencji
można opracować lub przykład tego? –
Dzięki, to bardzo pomogło! Czy można zdefiniować coś takiego jak MPI_DOUBLE_2INT, abym mógł wysłać więcej niż jeden klucz na podwójne? –
Myślę, że dla czegoś innego niż typy wbudowane, musiałbyś napisać własną operację, ale nie byłoby to takie trudne. –