2010-02-13 2 views
5

Мне нужно MPI_Gatherv() несколько пар int/string. Предположим, каждая пара выглядит так:Передача структур переменной длины между процессами MPI

struct Pair { 
    int x; 
    unsigned s_len; 
    char s[1]; // variable-length string of s_len chars 
}; 

Как определить подходящий тип данных MPI для пары?

+0

Используйте 'char s [0];' для массива переменной длины, а не 'char s [1];'. – kennytm

+0

@KennyTM, s [0] дает «предупреждение C4200: используется нестандартное расширение: массив нулевого размера в struct/union». – Constantin

+0

Ах MSVC. C99 поддерживается gcc, но не MSVC. – kennytm

ответ

4

Короче говоря, теоретически невозможно отправить одно сообщение переменного размера и получить его в буфер идеального размера. Вам придется либо отправить первое сообщение с размерами каждой строки, а затем второе сообщение с самими строками или закодировать этот метаинфо в полезную нагрузку и использовать статический буфер приема.

Если вы должны отправить только одно сообщение, я бы отказался от определения типа данных для пары: вместо этого я бы создал тип данных для всей полезной нагрузки и дал все данные в один непрерывный, нетипизированный пакет. Затем на приемном конце вы можете перебирать его, выделяя точное количество места, необходимое для каждой строки, и заполняете его. Позвольте мне взломать диаграмму ASCII для иллюстрации. Это будет ваша полезная нагрузка:

| ..x1 .. | ..s_len1 .. | .... строка1 .... | ..x2 .. | ..s_len2 .. | .string2. |. .x3 .. | ..s_len3 .. | ....... string3 ....... | ...

Вы отправляете все это как единое целое (например, массив MPI_BYTE), то приемник будет распаковать его что-то вроде этого:

while (buffer is not empty) 
{ 
    read x; 
    read s_len; 
    allocate s_len characters; 
    move s_len characters from buffer to allocated space; 
} 

Заметим, однако, что это решение работает только, если представление данных целых чисел и символов одинакова на передающей и приемной систем.

+0

Упаковывая все в смежный буфер, я наконец решил. Следует отметить, что мне пришлось использовать дополнительный MPI_Gather() для сбора размеров полезной нагрузки из каждого процесса. Эти размеры полезной нагрузки были использованы для расчета размера буфера recv и вектора перемещения (http://www.mpi-forum.org/docs/mpi-11-html/node70.html). – Constantin

2

Я не думаю, что вы можете делать то, что хотите, с MPI. Я программист Фортран, так что медведь со мной, если мое понимание С немного шаткое. Кажется, вы хотите передать структуру данных, состоящую из 1 int и 1 строки (которую вы передаете, передавая местоположение первого символа в строке) из одного процесса в другой? Я думаю, что вам нужно будет пройти строку с фиксированной длиной, которая, следовательно, должна быть такой же, как любая строка, которую вы действительно хотите передать. Зона приема для сбора этих строк должна быть достаточно большой, чтобы получать все строки вместе с их длиной.

Возможно, вам захочется объявить новый тип данных MPI для ваших структур; вы можете их собрать и, поскольку собранные данные включают длину строки, извлеките полезные части строки в приемнике.

Я не уверен в этом, но я никогда не сталкивался с действительно переменными длинами сообщений, которые, как вам кажется, хотят использовать, и он сортирует себя как не-MPI-подобный. Но это может быть что-то реализовано в последней версии MPI, которую я просто никогда не спотыкался, хотя, глядя на документацию в режиме онлайн, это не похоже.

+0

Я надеялся избежать траты пространства с буферами фиксированной длины. Другой возможный вариант, который следует избегать, представляет собой массив пар len/chars с двумя отдельными массивами: один из объектива и один из символов. Спасибо, в любом случае. – Constantin

+0

Марк, прошло некоторое время с тех пор, как я играл с MPI, но я уверен, что вы здесь точны. По крайней мере, около 2005 года MPI. –

1

Реализации MPI не проверяют и не интерпретируют фактическое содержимое сообщения. При условии, что вы знаете размер структуры данных, вы можете представить этот размер в некотором количестве символов char или int. Реализация MPI не будет знать и не учитывать фактические внутренние данные.

Существует несколько предостережений ... как отправителю, так и получателю необходимо согласовать интерпретацию содержимого сообщения, а буфер, который вы предоставляете на отправляющей и принимающей стороне, должен вписаться в определенное число символов или ИНТ-х.