mpi4py 中的不連續(xù)讀/寫和集合 I/O 操作

上一篇中我們介紹了 mpi4py 中的簡單并行 I/O 操作,下面我們將介紹 mpi4py 中的不連續(xù)讀/寫和集合 I/O 操作。

在前面的介紹中,我們沒有設(shè)定文件視圖,或者說使用了默認(rèn)的文件視圖。MPI 中的文件視圖定義文件中對(duì)一個(gè)進(jìn)程可見的部分,一個(gè) MPI 讀/寫操作方法只能操作文件中其可見的部分,而會(huì)跳過其不可見的部分。當(dāng)一個(gè)文件剛被打開時(shí),默認(rèn)情況下,整個(gè)文件的內(nèi)容對(duì)打開該文件的進(jìn)程組中的所有進(jìn)程都是可見的,MPI 把這個(gè)文件當(dāng)成由連續(xù)的二進(jìn)制字節(jié)構(gòu)成(而不是任何有類型的數(shù)據(jù))。文件剛打開時(shí),每個(gè)進(jìn)程的獨(dú)立文件指針和共享文件指針都被設(shè)置成了文件起始位置(即偏移為 0 的位置)。

采用默認(rèn)文件視圖,并且使用上一篇中介紹的 Read/Write 或 Read_at/Write_at 文件讀/寫方法,每個(gè)進(jìn)程每次只能讀/寫文件中的一段連續(xù)數(shù)據(jù)。其實(shí)這種文件操作功能用普通的 Unix/Linux I/O 讀/寫函數(shù)也能實(shí)現(xiàn),因此并不能體現(xiàn)出 MPI 并行 I/O 操作的優(yōu)勢。在實(shí)際的并行科學(xué)計(jì)算應(yīng)用中,每個(gè)進(jìn)程通常需要讀/寫很多處于文件中不同位置的很多小的連續(xù)數(shù)據(jù)塊。當(dāng)然可以使用前面介紹的讀/寫方法每次讀/寫一個(gè)這種小的數(shù)據(jù)塊,但是由于 I/O 操作本身高的時(shí)延,這種操作是非常低效和費(fèi)時(shí)的。MPI 提供了更高效的操作方法,允許使用一次函數(shù)調(diào)用讀/寫不連續(xù)的數(shù)據(jù)塊。如果將這種操作方式和集合 I/O 結(jié)合起來,則能進(jìn)一步提高 I/O 操作性能。因?yàn)檫@種組合可以給 MPI 實(shí)現(xiàn)提供足夠的信息使其知道有哪些進(jìn)程在同時(shí)讀/寫文件及文件中所有會(huì)被同時(shí)讀/寫到的數(shù)據(jù)。MPI 實(shí)現(xiàn)可以利用這些信息對(duì)該 I/O 操作實(shí)施一些優(yōu)化,比如說將各個(gè)進(jìn)程的小的數(shù)據(jù)塊合并成若干大的連續(xù)數(shù)據(jù)塊一次性進(jìn)行操作等,以顯著地提高程序的 I/O 性能。

MPI 的不連續(xù)讀/寫功能是使用文件視圖結(jié)合相應(yīng)的讀/寫函數(shù)實(shí)現(xiàn)的,下面我們首先介紹文件視圖相關(guān)方法。

文件視圖和不連續(xù)讀/寫

MPI.File.Set_view(self, Offset disp=0, Datatype etype=None, Datatype filetype=None, datarep=None, Info info=INFO_NULL)

MPI.File.Get_view(self)

上面兩個(gè)方法在前面已經(jīng)作過介紹,這里不再贅述。這里只強(qiáng)調(diào)幾點(diǎn):設(shè)置文件視圖的操作是一個(gè)集合操作,必須打開文件的進(jìn)程組中的所有進(jìn)程一起參與。當(dāng)使用獨(dú)立文件指針或顯式偏移地址方法時(shí),每個(gè)進(jìn)程可以根據(jù)需要設(shè)置一個(gè)不同的文件視圖;但是當(dāng)使用共享文件指針時(shí),所有的進(jìn)程必須設(shè)置一個(gè)同樣的視圖。在程序中文件視圖可以多次重新設(shè)置。當(dāng)一個(gè)文件被打開后,如果不設(shè)置其文件視圖,則會(huì)使用默認(rèn)的文件視圖:即初始偏移 disp 為 0,etypefiletype 都為 MPI.BYTE。

下面這張圖給出了文件視圖的一個(gè)例子:disp 為 5 × 4 字節(jié),etype 為 MPI.INT,filetype 為 2 個(gè)整數(shù)加 4 個(gè)整數(shù)大小的一段空隙。如果某個(gè)進(jìn)程設(shè)置了以上文件視圖,則該進(jìn)程只能讀/寫到文件中如上圖陰影部分的數(shù)據(jù),其它位置的數(shù)據(jù)會(huì)被跳過。在下面的例程中,我們將展示如何設(shè)置這樣的文件視圖,及如果利用此文件視圖結(jié)合上一篇中介紹的文件讀/寫方法一次性向文件寫入或者從文件讀取大量不連續(xù)的數(shù)據(jù)。

文件視圖舉例

下面是上一篇中介紹的文件讀/寫方法的集合操作版本。

集合操作

獨(dú)立文件指針

MPI.File.Read_all(self, buf, Status status=None)

MPI.File.Read 的集合操作版本,參數(shù)也相同,不同之處在于該方法必須被打開該文件的進(jìn)程組中的進(jìn)程一起調(diào)用,而 MPI.File.Read 則可以被某個(gè)或某幾個(gè)進(jìn)程調(diào)用而無需其它進(jìn)程一起參與。該方法也是使用獨(dú)立文件指針的阻塞調(diào)用。

MPI.File.Write_all(self, buf, Status status=None)

MPI.File.Write 的集合操作版本,參數(shù)也相同,不同之處在于該方法必須被打開該文件的進(jìn)程組中的進(jìn)程一起調(diào)用,而 MPI.File.Write 則可以被某個(gè)或某幾個(gè)進(jìn)程調(diào)用而無需其它進(jìn)程一起參與。該方法也是使用獨(dú)立文件指針的阻塞調(diào)用。

顯式偏移地址

MPI.File.Read_at_all(self, Offset offset, buf, Status status=None)

MPI.File.Read_at 的集合操作版本,參數(shù)也相同,不同之處在于該方法必須被打開該文件的進(jìn)程組中的進(jìn)程一起調(diào)用,而 MPI.File.Read_at 則可以被某個(gè)或某幾個(gè)進(jìn)程調(diào)用而無需其它進(jìn)程一起參與。該方法也是使用顯式偏移地址的阻塞調(diào)用。

MPI.File.Write_at_all(self, Offset offset, buf, Status status=None)

MPI.File.Write_at 的集合操作版本,參數(shù)也相同,不同之處在于該方法必須被打開該文件的進(jìn)程組中的進(jìn)程一起調(diào)用,而 MPI.File.Write_at 則可以被某個(gè)或某幾個(gè)進(jìn)程調(diào)用而無需其它進(jìn)程一起參與。該方法也是使用顯式偏移地址的阻塞調(diào)用。

例程

下面給出使用例程。

# noncontig_io.py

"""
Demonstrates the usage of noncontiguous accesses and collective I/O.

Run this with 3 processes like:
$ mpiexec -n 3 python noncontig_io.py
"""

import numpy as np
from mpi4py import MPI


comm = MPI.COMM_WORLD
rank = comm.Get_rank()

buf1 = np.arange(10, dtype='i')
buf2 = np.zeros(10, dtype='i') # initialize to all zeros

filename = 'temp.txt'

# open the file for read and write, create it if it does not exist,
# and delete it on close
fh = MPI.File.Open(comm, filename, amode= MPI.MODE_CREATE | MPI.MODE_RDWR | MPI.MODE_DELETE_ON_CLOSE)

# displacement in bytes of each process
disp = (5 + rank * 2) * MPI.INT.Get_size()
# the etype
etype = MPI.INT

# construct filetype, which consists of 2 ints and a gap of 4 ints
INT2 = MPI.INT.Create_contiguous(2)
filetype = INT2.Create_resized(0, 6*MPI.INT.Get_size())
filetype.Commit()

# set the file view, which is a collective operation
fh.Set_view(disp, etype, filetype)

if rank == 0:
    # rank 0 writes buf1 to the file
    # the 10 interges will be writen into noncontiguous positions
    # in the file with a single write call
    fh.Write(buf1)
    # rank 0 reads data from file to buf2
    # 10 interges in noncontiguous positions of the file will be read
    # with a single read call
    fh.Read_at(0, buf2)
    print 'buf2:', buf2

# use collective I/O method
# first reset the individual file pointer to the beginning of the file
fh.Seek(0, whence=MPI.SEEK_SET)

# collectively write the data to file
fh.Write_all(buf1)

# reset the file view for read, which is a collective operation
fh.Set_view(disp, etype, etype)

# check what's in the file
if rank == 0:
    buf3 = np.zeros(30, dtype='i') # initialize to all zeros
    fh.Seek(0, whence=MPI.SEEK_SET)
    fh.Read(buf3)
    print 'buf3:', buf3
    # buf3: [0 1 0 1 0 1 2 3 2 3 2 3 4 5 4 5 4 5 6 7 6 7 6 7 8 9 8 9 8 9]
    # rank 0 ---         ---         ---         ---         ---
    # rank 1     ---         ---         ---         ---         ---
    # rank 2         ---         ---         ---         ---         ---

# close the file
fh.Close()

運(yùn)行結(jié)果如下:

$ mpiexec -n 3 python noncontig_io.py
buf2: [0 1 2 3 4 5 6 7 8 9]
buf3: [0 1 0 1 0 1 2 3 2 3 2 3 4 5 4 5 4 5 6 7 6 7 6 7 8 9 8 9 8 9]

以上介紹了 mpi4py 中的不連續(xù)讀/寫和集合 I/O 操作,在下一篇中我們將介紹 mpi4py 中讀/寫文件中數(shù)組的方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在上一篇中我們介紹了 mpi4py 中的 memory 對(duì)象及內(nèi)存操作,下面我們將介紹 mpi4py 中的簡單并行...
    自可樂閱讀 1,909評(píng)論 0 2
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,868評(píng)論 25 709
  • 窗前獨(dú)悵,苦酒獨(dú)醉灌。 不覺傍晚至,雨淅瀝。 夜涼,添幾許,惆悵。 夜深人靜獨(dú)月下,聞?dòng)曷?,忽驚醒。 細(xì)聞小雨淅瀝...
    紅塵z閱讀 235評(píng)論 10 5
  • 從前有一種叫做寒號(hào)鳥的珍稀動(dòng)物,在夏天全身披著美麗的羽毛,唱著歌,冬天到了,就會(huì)說“哆哆哆,寒風(fēng)凍死我,明天就筑窩...
    洞庭府君閱讀 275評(píng)論 0 2

友情鏈接更多精彩內(nèi)容