2014-04-04 47 views
1

我對使用MPI例程相對來說比較新,我對以下代碼中的原因感到困惑,根據我使用的節點數有多少,我將得到不同的結果。MPI4PY:不同數量的節點返回不同的結果

的代碼:

import numpy as np 
from mpi4py import MPI 

def MPI_sum(comm,x): 
    xsum = np.sum(x) 
    vals = comm.gather(xsum,root=0) 

    if rank == 0: 
     s = np.sum(vals) 

    s = comm.bcast(s,root=0) 

    return s 

comm = MPI.COMM_WORLD 
size = comm.Get_size() 

datalen = 80000/size 
x = np.zeros(datalen) + 1. + 1e-5 

xsum = MPI_sum(comm,x) 
if rank == 0: 
    print xsum - np.floor(xsum) 

我跑這個代碼與1個節點,並用2個節點。 我從1個節點得到的答案是:0.800000153016 我從2個節點得到的答案是:0.800000035219

是什麼導致了這種差異? (作爲補充說明,我嘗試將MPI_sum中的所有x數組數據都傳遞給root = 0,然後求和root = 0,這給了我正確的答案;不管節點的數量如何,都是相同的輸出。但是,將所有數據傳遞到一個節點對於我將要實現的代碼而言並不實際。)

感謝您的幫助!

回答

3

觀察到的效果是由浮點操作的非關聯性引起的,並不是MPI應用程序特有的,儘管由於問題域的分區,後者往往會更頻繁地暴露它。注意下列情況從而得到一個想法發生了什麼:

>>> import numpy as np 
>>> datalen = 80000 
>>> x = np.zeros(datalen) + 1. + 1e-5 
>>> xsum = np.sum(x) 
>>> xsum - np.floor(xsum) 
0.80000015301629901 
>>> xsum = np.sum(x[:datalen/2]) + np.sum(x[datalen/2:]) 
>>> xsum - np.floor(xsum) 
0.80000003521854524 

換句話說,給定一個有限精度計算機,總結整個數組是不一樣的第一陣列的兩半分別相加,然後總結兩總和,不管你是使用MPI(如你的代碼)還是連續使用(如我的例子)。

原因是任何時候發生的最後一位四捨五入將兩個浮點數相加。及時學會處理浮點算術的特性。有特殊的求和算法可以防止類似的效應,例如Kahan summation algorithm

注意,10 -5不是因爲log任何有限精度二進制計算機上精確表示(10 -5)= -5×登錄(10)和的二進制數10是一個不合理的數字。

+0

我不太明白這一點,雖然我使用64位浮點數的精度應該不是2^64(10^19)有效數字的順序,而不是10^10? – Bremsstrahlung

+0

整數部分有5位數字,小數部分在第7位數字中有所不同。這是12位數的精度。其餘的由於四捨五入誤差而總計80000(〜10^6)數字而丟失。與Kahan算法的結果進行比較。 –