Come affrontare la non associatività numerica per la riduzione parallela?


17

Una riduzione parallela presuppone che l'operazione corrispondente sia associativa. Questa ipotesi viene violata per l'aggiunta di numeri in virgola mobile. Potresti chiederti perché ci tengo a questo. Bene, rende i risultati meno riproducibili. E peggiora quando si utilizza la ricottura simulata per ottimizzare (o adattare i parametri) su subroutine producendo tali risultati non riproducibili.

Quali sono i modi comuni per affrontare questo problema? Cosa si può dire delle seguenti strategie?

  • Non preoccuparti della non riproducibilità.
  • Non utilizzare la riduzione parallela con numeri e aggiunte in virgola mobile.
  • Crea pacchetti di lavoro di dimensioni adeguate in modo riproducibile e esegui la riduzione finale a mano.
  • Utilizzare una precisione maggiore per l'aggiunta (ma non tutti i compilatori offrono tipi a virgola mobile di precisione più elevata).

Sei preoccupato per la riproducibilità sullo stesso numero di processi o la riproducibilità su un numero diverso di processori? Quanto di un colpo di performance sei disposto a prendere per la riproducibilità bit a bit? Sei interessato solo alla ricottura simulata?
Jed Brown,

@JedBrown Sono preoccupato per la possibilità di ottenere risultati riproducibili, ad esempio per il debug di potenziali problemi. Va bene per me se esiste un modo per riprodurre i risultati, ad esempio utilizzando lo stesso numero di processori (o semplicemente "conoscendo" il numero di processori utilizzati originariamente). Sarei disposto a prendere il colpo di prestazione associato all'uso di tipi a virgola mobile di precisione più elevata per l'aggiunta stessa. I miei problemi concreti erano principalmente legati alla ricottura simulata e alle differenze inaspettate, ma tutti si sono rivelati veri e propri bug.
Thomas Klimpel,

Risposte:


15

Una riduzione implementata usando MPI_Allreduce()è riproducibile se si utilizza lo stesso numero di processori, a condizione che l'implementazione osservi la seguente nota che appare nella Sezione 5.9.1 della norma MPI-2.2.

Consigli per gli implementatori . Si consiglia vivamente di MPI_REDUCEessere implementato in modo da ottenere lo stesso risultato ogni volta che la funzione viene applicata sugli stessi argomenti, che appaiono nello stesso ordine. Si noti che ciò può impedire ottimizzazioni che sfruttano la posizione fisica dei processori. ( Fine della consulenza agli implementatori .)

Se è necessario garantire la riproducibilità a tutti i costi, è possibile seguire le linee guida nel paragrafo successivo:

Consigli agli utenti . Alcune applicazioni potrebbero non essere in grado di ignorare la natura non associativa delle operazioni in virgola mobile o potrebbero utilizzare operazioni definite dall'utente (vedere la Sezione 5.9.5) che richiedono un ordine di riduzione speciale e non possono essere trattate come associative. Tali domande dovrebbero far rispettare esplicitamente l'ordine di valutazione. Ad esempio, nel caso di operazioni che richiedono un rigoroso ordine di valutazione da sinistra a destra (o da destra a sinistra), ciò potrebbe essere fatto raccogliendo tutti gli operandi in un unico processo (ad esempio, con MPI_GATHER), applicando l'operazione di riduzione nell'ordine desiderato (ad es. con MPI_REDUCE_LOCAL) e, se necessario, trasmettere o diffondere il risultato ad altri processi (ad es. con MPI_BCAST). ( Fine del consiglio per gli utenti .)

Nel più ampio schema di cose, algoritmi efficienti per la maggior parte delle applicazioni sfruttano la località. Poiché l'algoritmo è davvero diverso quando eseguito su un numero diverso di processi, non è pratico riprodurre esattamente i risultati quando eseguito su un numero diverso di processi. Una possibile eccezione è il multigrid con smorzatori Jacobi smorzati o polinomiali (ad es. Chebyshev), dove è possibile che questo semplice metodo funzioni molto bene.

Con lo stesso numero di processi, è spesso vantaggioso per le prestazioni elaborare i messaggi nell'ordine in cui sono ricevuti (ad es. Utilizzando MPI_Waitany()), che introduce il non determinismo. In tali casi, è possibile implementare due varianti, quella veloce che riceve in qualsiasi ordine e una "debug" che riceve in un ordine statico. Ciò richiede che anche tutte le librerie sottostanti siano scritte per offrire questo comportamento.

Per il debug in alcuni casi, è possibile isolare parte di un calcolo che non offre questo comportamento riproducibile ed eseguirlo in modo ridondante. A seconda di come sono stati progettati i componenti, tale modifica può essere una piccola quantità di codice o molto invadente.


6

Per la maggior parte ho idem la risposta di Jed. Tuttavia, esiste una via d'uscita diversa: date le dimensioni dei normali numeri in virgola mobile, è possibile memorizzare ogni numero in un numero a virgola fissa di circa 4000 bit. Quindi, se si fa una riduzione sui numeri in virgola mobile così incorporati, si ottiene un calcolo esatto, indipendentemente dall'associatività. (Mi dispiace, non ho il riferimento a chi ha avuto questa idea.)


1
Non credo che sia stato il primo, ma il tuo collega Dr. Bandwidth ha sicuramente un bel commento su questo argomento: sites.utexas.edu/jdm4372/2012/02/15/…
Jeff

5

È possibile implementare un algoritmo di riduzione numericamente stabile in MPI come in seriale. Potrebbe esserci un colpo di scena, ovviamente. Se puoi permetterti di replicare il vettore, usa semplicemente MPI_Gather e fai la riduzione numericamente stabile del seriale sul root. In alcuni casi, potresti riscontrare che l'hit performance non è un grosso problema.

Un'altra soluzione è utilizzare accumulatori larghi come descritto qui . Puoi farlo con MPI come riduzione definita dall'utente, sebbene utilizzi molta più larghezza di banda.

Un compromesso per quanto sopra è l'uso della somma compensata. Vedere i riferimenti "Sommario di Kahan" per i dettagli. " Precisione e stabilità degli algoritmi numerici " di Higham è una risorsa eccellente su questo argomento.



2

Vorrei sottolineare che invece di utilizzare un'aritmetica di precisione più elevata per l'aggiunta, esiste la possibilità di utilizzare la somma compensata (vedere [1]). Ciò potrebbe aumentare l'accuratezza della somma senza la necessità di ricorrere a tipi di dati più grandi.

[1] Higham, NJ La precisione della sommatoria in virgola mobile. SIAM Journal on Scientific Computing 14, 783–799 (1993).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.