MPI-3 中大的計數及相關函式
在上一篇中我們介紹了非執行緒安全的 Probe 和 MPI-3 中執行緒安全的 Mprobe,下面將介紹 MPI-3 中大的計數及相關函式。
在 MPI-1 和 MPI-2 標準中,所有的通訊和 I/O 函式/方法中的計數引數都使用的是 C 語言 int 或者 Fortran INTEGER 型別,在大多數系統中,它們都是用 32 位來表示的。一個 32 位的 C int 數所能表示的最大整數是 2147483647,超過該值就會發生溢位,此即一些通訊和 I/O 函式中能夠傳送/接收的最大資料型別個數,如果使用 MPI 中預定義的資料型別,如 MPI.INT 或 MPI.FLOAT,則單次能夠傳送/接收的資料量的上限大概是 2 GB。這對一些資料量比較大的應用是一個比較嚴重的限制。
MPI 論壇也意識到這個問題,一種可行的解決方案是為這些函式都定義一個新的版本,在這些新版本中使用 64 位或更大的整數型別,不過這樣會使得 MPI 標準中的函式數量大為增加。MPI 論壇採用了另外一種解決方案,那就是利用 MPI 對派生資料型別的支援,再額外定義一個 MPI_Count 資料型別及若干使用該資料型別的查詢函式。通過此種方法,如果要傳送/接收計數超過 32 位最大整數的某種型別資料,則可以首先由該資料型別作為基本型別建立派生資料型別,只要所傳送/接收的資料按照派生資料型別計數不超過 32 位最大整數,通訊操作就能成功執行,並且可以用這些新定義的查詢函式來得到大的訊息及資料型別的相關資訊,而不至於發生溢位。
MPI-3 新定義的 MPI_COUNT 資料型別被定義為足夠大的整數以使其足以表示 MPI 支援的記憶體地址和檔案偏移。新定義的查詢函式與已經存在的對應函式完成相同的功能,不過在名稱後面加了 _x 字尾,並且 size,lb,extent 等引數都使用了 MPI_Count 資料型別,其 C 語言介面如下:
MPI_Type_size_x(MPI_Datatype datatype, MPI_Count *size)
MPI_Type_get_extent_x(MPI_Datatype datatype, MPI_Count *lb, MPI_Count *extent)
MPI_Type_get_true_extent_x(MPI_Datatype datatype, MPI_Count *lb, MPI_Count *extent)
另外,新增 status 狀態中設定和獲取大的計數, 其 C 語言介面如下:
MPI_Get_elements_x(const MPI_Status *status, MPI_Datatype datatype, MPI_Count *count)
MPI_Status_set_elements_x(MPI_Status *status, MPI_Datatype datatype, MPI_Count count)
mpi4py 3.0.0 支援 MPI-3 標準,因此以上介紹的新特性也可用,不過因為 Python 並不用宣告資料型別,所以我們不用特別地關心 MPI.COUNT 資料型別,另外由於 Python 中的整型數預設就是 64 位的,因此也與大的計數相容。雖然已經存在的無 _x 字尾版本的函式在 MPI-3 中依然可用,但是卻並不推薦使用,應該儘量使用 MPI-3 所新引進的支援大的計數的相應函式。基於這一思想,且為了簡潔,mpi4py 3.0.0 直接包裝和呼叫了新的帶有 _x 字尾的相關函式。因此在支援 MPI-3 的環境下,以下方法及屬性都支援大的計數;但是在不支援 MPI-3 的環境下,它們會呼叫無 _x 字尾的函式版本。
方法介面
MPI.Datatype.Get_size(self)
MPI.Datatype.Get_extent(self)
MPI.Datatype.Get_true_extent(self)
MPI.Status.Get_elements(self, Datatype datatype)
MPI.Status.Set_elements(self, Datatype datatype, Count count)
屬性
MPI.Datatype.size
MPI.Datatype.extent
MPI.Datatype.lb
MPI.Datatype.ub
MPI.Datatype.true_extent
MPI.Datatype.true_lb
MPI.Datatype.true_ub
以上方法和屬性獲取資料型別的型別圖的相關資訊,型別圖及其相關資訊在前面已經介紹過,此處不再贅述。
限制
以上方案雖然能夠解決很大一部分涉及大的訊息和大的計數的問題,但也有若干限制。
集合規約操作
以上解決方案的一個限制是執行大量資料的規約操作,如 MPI.Comm.Reduce 和 MPI.Comm.Allreduce。MPI 預定義的規約算符 只能使用在預定義資料型別上,不能使用在派生資料型別上。因此對大量資料的規約操作,如果使用派生資料型別,則必須自己定義對派生資料型別的規約操作算符(可以通過 MPI.Op.Create 來定義)。
不規則集合操作
另一個限制是在對大量資料的不規則集合操作上,如 MPI.Comm.Gatherv,MPI.Comm.Alltoallv,MPI.Comm.Alltoallw。對 MPI.Comm.Gatherv 和 MPI.Comm.Alltoallv,每個程式可以傳送不同數量但是相同型別的資料。在一些情況下,可能沒法定義一個能滿足所有程式的派生資料型別,比如說各個程式所傳送的資料量不存在一個公約數時。在此種情況下,對大量資料的 MPI.Comm.Gatherv,MPI.Comm.Alltoallv 操作將無法進行。MPI.Comm.Alltoallw 雖然可以使用多個資料型別,但是它的以位元組為單位的偏移引數卻用的是 C 語言 int 型別,這就限制了最大可用的偏移範圍。
對這些不規則的集合操作,如果要對大量的資料操作,一種方法是採用一系列的點到點操作來替換,雖然這樣可能達不到最好的執行效能。另一種方法是使用 MPI-3 新引進的近鄰集合操作,如 MPI.Topocomm.Neighbor_alltoallw,該方法不同於 MPI.Comm.Alltoallw 的地方在於其偏移引數使用的是 MPI_Aint 而不是 C 語言 int,MPI_Aint 可以表示的數值範圍比 C 語言 int 型別更大。
例程
下面給出使用例程。
# large_count.py
"""
Demonstrates the large counts in MPI-3.
Run this with 2 processes like:
$ mpiexec -n 2 python large_count.py
"""
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.rank
MAX_INT32 = np.iinfo(np.int32).max
print 'Max value of a 32 bits int: %d' % MAX_INT32
# create a derived datatype conposed of MAX_INT32 MPI.INT
LARGE_TYPE = MPI.INT.Create_contiguous(MAX_INT32)
print 'LARGE_TYPE:', LARGE_TYPE.lb, LARGE_TYPE.ub, LARGE_TYPE.size, LARGE_TYPE.extent
# create a derived datatype conposed of 2*MAX_INT32 MPI.INT
LARGE_TYPE2 = LARGE_TYPE.Create_contiguous(2)
print 'LARGE_TYPE2:', LARGE_TYPE2.lb, LARGE_TYPE2.ub, LARGE_TYPE2.size, LARGE_TYPE2.extent
# commit the derived datatypes
LARGE_TYPE.Commit()
LARGE_TYPE2.Commit()
if rank == 0:
large_array = np.ones(2*MAX_INT32, dtype=np.int32)
print 'rank 0 sends a large message of', 1.0 * large_array.nbytes / 2**32, 'GB'
# comm.Send([large_array, 1, LARGE_TYPE2], dest=1, tag=11)
# or
comm.Send([large_array, 2, LARGE_TYPE], dest=1, tag=11)
else:
recv_buf = np.empty(2*MAX_INT32, dtype=np.int32)
comm.Recv([recv_buf, 1, LARGE_TYPE2], source=0, tag=11)
# or
# comm.Recv([recv_buf, 2, LARGE_TYPE], source=0, tag=11)
print 'rank 1 successfully received the large message.'
執行結果如下:
$ mpiexec -n 2 python large_count.py
Max value of a 32 bits int: 2147483647
LARGE_TYPE: 0 8589934588 8589934588 8589934588
LARGE_TYPE2: 0 17179869176 17179869176 17179869176
Max value of a 32 bits int: 2147483647
LARGE_TYPE: 0 8589934588 8589934588 8589934588
LARGE_TYPE2: 0 17179869176 17179869176 17179869176
rank 0 sends a large message of 3.99999999814 GB
rank 1 successfully received the large message.
以上介紹了 MPI-3 中大的計數及相關函式,在下一篇中我們將介紹 MPI 3.1 新增的若干功能。
相關文章
- 物件及函式相關物件函式
- 【C語言】常用的字串函式及相關函式的自我實現C語言字串函式
- 字串的相關函式字串函式
- 也談箭頭函式的 this 指向問題及相關函式
- 關於javascript中變數及函式的提升JavaScript變數函式
- SAP PP相關函式函式
- 字串相關函式的實現字串函式
- python 的數值和字串和相關內建函式Python字串函式
- Python之函式的相關介紹Python函式
- ES6 函式相關函式
- 函式的動態引數 及函式巢狀函式巢狀
- python3 堆相關函式的使用Python函式
- CodeIgniter框架之url相關函式框架函式
- 學習PHP中的URL相關操作函式PHP函式
- C語言相關的基礎字串函式C語言字串函式
- 函式的關鍵字引數函式
- interrupt結構體和相關函式結構體函式
- PG wal日誌LSN相關函式函式
- FreeRTOS-01-任務相關函式函式
- tensorflow相關函式學習總結函式
- 統計學三大相關係數之Pearson相關係數、Spearman相關係數
- Win32 API CreateCompatibleDC 函式的相關應用Win32API函式
- 執行緒中的幾個退出相關函式執行緒函式
- MySQL 字串擷取相關函式總結MySql字串函式
- [BUG反饋]get_cover函式相關函式
- FreeRTOS-03-其它任務相關函式函式
- MySQL全面瓦解13:系統函式相關MySql函式
- Python資料分析--Numpy常用函式介紹(5)--Numpy中的相關性函式Python函式
- 全面瞭解Vue3的 ref 和相關函式和計算屬性Vue函式
- Processing中PImage類和loadImage()、createImage()函式的相關解析函式
- 全面瞭解Vue3的 reactive 和相關函式VueReact函式
- 偏相關係數計算
- OC常用數學函式及常量函式
- 函式引數傳遞及返回函式
- 熵、交叉熵及似然函式的關係熵函式
- 時間函式:與時間相關那些事。。。函式
- 偶函式在零點的泰勒展開式相關知識點函式
- 解讀數倉中的資料物件及相關關係物件