對MPI有一定的經驗,但是對於衍生類型等更高級的方面,這與我的問題有關。如何使用MPI發送正確數量的派生類型對象?
我正在使用的代碼有幾個數組,尺寸爲(-1:nx+2,-1:ny+2,-1:nz+2)
。爲了清楚起見,每個過程都有自己的值nx
,ny
和nz
。數組之間有重疊。例如,一個proc上的x(:,:,-1:2)
將代表與「僅位於其下」的proc上的x(:,:,nz-1:nz+2)
相同的信息。
派生cell_zface
類型被定義爲:
idir = 3
sizes = (/nx_glb, ny_glb, nz_glb/) !These nums are the same for all procs.
subsizes = (/nx, ny, 2/)
mpitype = MPI_DATATYPE_NULL
CALL MPI_TYPE_CREATE_SUBARRAY(3, sizes, subsizes, starts, &
MPI_ORDER_FORTRAN, mpireal, mpitype, errcode)
CALL MPI_TYPE_COMMIT(mpitype, errcode)
cell_zface = mpitype
現在,這種派生類型被使用,成功地在幾個MPI_SENDRECV
電話。例如
CALL MPI_SENDRECV(&
x(-1,-1, 1), 1, cell_zface, proc_z_min, tag, &
x(-1,-1,nz+1), 1, cell_zface, proc_z_max, tag, &
comm, status, errcode)
據我所知,這個呼叫被髮送和接收兩個「水平」切片特效之間的陣列(即X-Y切片)。
我想做一點不同的事情,即發送四個「水平」切片。所以我嘗試
call mpi_send(x(-1,-1,nz-1), 2, cell_zface, &
proc_z_max, rank, comm, mpierr)
隨附的接收。
最後,我的問題:代碼運行,但錯誤。 AFAICT,這隻發送兩個水平分片,即使我使用「2」而不是「1」作爲計數參數。我可以做兩個調用mpi_send
解決這個問題:
call mpi_send(x(-1,-1,nz-1), 1, cell_zface, &
proc_z_max, rank, comm, mpierr)
call mpi_send(x(-1,-1,nz+1), 1, cell_zface, &
proc_z_max, rank, comm, mpierr)
伴隨接收,但是這肯定是不漂亮。
那麼,爲什麼mpi_send
只發送兩個水平切片,即使我將count參數設置爲「2」?有沒有一種乾淨的方式來做我想在這裏做的事情?
你必須明白,即使你有自己的「類型」,你真正擁有的東西都是一個巨大的連續的記憶塊。因此,雖然可以發送兩個'cell_zface'類型,但類型本身在內存中的大小與您類型使用的第一個和最後一個(在1D)內存位置之間的距離一樣大。也就是說,你的類型的大小並不是真正的'nx * ny * nz'。 – NoseKnowsAll
要完成您正在尋找的任務,您必須在不同的範圍內給出您的派生數據類型。請注意,數據類型的大小將是相同的,但「範圍」(或此數據類型的內存連續版本數量將包含)將不會。我相信您可以通過[MPI_Type_create_resized](http://www.mpich.org/static/docs/v3.1/www3/MPI_Type_create_resized.html)完成此操作。 – NoseKnowsAll