Имейте некоторый опыт работы с MPI, но не с некоторыми более продвинутыми аспектами, такими как производные типы, с чем связан мой вопрос.Как использовать MPI для отправки правильного количества объектов производного типа?
Код, над которым я работаю, имеет несколько массивов размером (-1:nx+2,-1:ny+2,-1:nz+2)
. Чтобы было ясно, каждый процесс имеет свои значения nx
, ny
и nz
. Между массивами существует перекрытие. Например, x(:,:,-1:2)
по одному проку будет представлять ту же самую информацию, что и x(:,:,nz-1:nz+2)
, на proc, только «ниже».
Производная 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, это отправляет только два горизонтальных среза, хотя вместо аргумента count вместо «1» я использую «2». Я могу это исправить, сделав два вызова 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) ячейками памяти, используемыми вашим типом. Aka, размер вашего типа не является действительно «nx * ny * nz'. – NoseKnowsAll
Чтобы выполнить то, что вы хотите сделать, вам придется указать свой производный тип данных в различной степени. Обратите внимание, что размер типа данных будет таким же, но «объем» (или объем последовательных версий памяти этого типа будет охватывать) не будет. Я считаю, что вы можете выполнить это с помощью [MPI_Type_create_resized] (http://www.mpich.org/static/docs/v3.1/www3/MPI_Type_create_resized.html). – NoseKnowsAll