Имейте некоторый опыт работы с MPI, но не с некоторыми более сложными аспектами, такими как производные типы, с чем связан мой вопрос.
Код, над которым я работаю, имеет несколько массивов с размерами (-1:nx+2,-1:ny+2,-1:nz+2)
. Чтобы было понятно, каждый процесс имеет свои значения nx
, ny
и nz
. Существует перекрытие между массивами. Например, x(:,:,-1:2)
для одного процесса будет представлять ту же информацию, что и 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
. - person NoseKnowsAll   schedule 05.11.2015