Como passar números inteiros longos e / ou não assinados para argumentos MPI?

Suponha que eu tenha uma matriz muito grande que desejo enviar ou receber com o MPI (v1). Para indexar essa matriz, eu uso um número inteiro longo sem sinal.

Agora, todas as chamadas de função MPI que eu vi usam tipos int para seus argumentos "count", como neste exemplo:

MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

Mas e se, na minha implementação, eu exigir a capacidade de enviar / receber uma matriz maior que o número máximo que um int pode conter? O compilador, naturalmente, me fornece um erro de "conversão inválida", quando tento alimentar um número inteiro não assinado para o argumento "count". Pensei em fazer um elenco, mas estou preocupado que isso diminua minha variável, então estou meio que sem saber o que fazer.

 slugonamission21 de abr de 2014 18:37
Talvez você precise dividir o pacote em vários pacotes menores.

questionAnswers(2)

reinterpret_cast<int>() do seu contador não assinado no remetente e faça a inversão no receptor. No entanto, acho que uma solução melhor é fazer uma estrutura que contenha o ponteiro e a contagem com os tipos corretos e siga os conselhos deesta resposta para criar seu próprio tipo de dados personalizado para transmitir usando MPI_Type_create_struct.

 Mark Anderson21 de abr de 2014 19:24
@ maxywb que eu conheço. Mas, ao criar a estrutura em si, você deve fornecer a contagem de elementos dentro da estrutura. Portanto, isso apenas empurra o problema um passo atrás. O problema não é o tamanho do tipo de dados, o problema é precisamente o número de elementos contidos no buffer, já que meu buffer é destinado a conter um grande número de elementos.
 Mark Anderson21 de abr de 2014 19:00
Obrigado pela sua resposta, mas também não vejo como fazer isso com uma estrutura. O principal problema é que, a estrutura também requer uma variável "count". Então, sim, eu poderia empacotar todo o intervalo da matriz necessário em uma estrutura e enviar apenas essa estrutura "uma". Mas, ao criar a estrutura, enfrento o mesmo problema: o MPI não aceita argumentos inteiros. Você poderia me ajudar um pouco a entender o que tinha em mente?
 maxywb21 de abr de 2014 19:11
@MarkAnderson Quando você envia a estrutura, a contagem é o número dessas estruturas que você envia. No seu caso, seria uma estrutura única, portanto a contagem é 1.
 Ben Voigt21 de abr de 2014 18:58
Não vejo como suas idéias resultarão na transferência correta da quantidade de dados. Tamanho da mensagem não é um valor opaco.
 maxywb21 de abr de 2014 19:13
@BenVoigt Thecount O parâmetro não especifica a quantidade de dados enviados diretamente, é o número de elementos contidos no buffer. Vejompich.org/static/docs/v3.1/www3/MPI_Recv.html, o tamanho do tipo de dados que está sendo enviado é um parâmetro separado.
QuestionSolution

pois simplesmente truncará a contagem longa. Existem dois obstáculos a serem superados aqui - um fácil e um difícil.

O obstáculo fácil é oint digite para o argumento count. Você pode superar isso simplesmente criando um tipo contíguo de tamanho menor e enviando os dados como múltiplos do novo tipo de dados. Um código de exemplo a seguir:

// Data to send
int data[1000];

// Create a contiguous datatype of 100 ints
MPI_Datatype dt100;
MPI_Type_contiguous(100, MPI_INT, &dt100);
MPI_Type_commit(&dt100);

// Send the data as 10 elements of the new type
MPI_Send(data, 10, dt100, ...);

Desde o argumento count deMPI_Type_contiguous éint, com esta técnica, você pode enviar até (231-1)2 = (262 - 232. + 1) elementos. Se isso não for suficiente, você pode criar um novo tipo de dados contíguo a partir dodt100 tipo de dados, por exemplo:

// Create a contiguous datatype of 100 dt100's (effectively 100x100 elements)
MPI_Datatype dt10000;
MPI_Type_contiguous(100, dt100, &dt10000);
MPI_Type_commit(&dt10000);

Se o tamanho original dos dados não for múltiplo do tamanho do novo tipo de dados, você poderá criar um tipo de dados de estrutura cujo primeiro elemento seja uma matriz deint(data_size / cont_type_length) elementos do tipo de dados contíguo e cujo segundo elemento é uma matriz dedatasize % cont_type_length elementos do tipo de dados primitivo. Exemplo a seguir:

// Data to send
int data[260];

// Create a structure type
MPI_Datatype dt260;

int blklens[2];
MPI_Datatype oldtypes[2];
MPI_Aint offsets[2];

blklens[0] = 2; // That's int(260 / 100)
offsets[0] = 0;
oldtypes[0] = dt100;

blklens[1] = 60; // That's 260 % 100
offsets[1] = blklens[0] * 100L * sizeof(int); // Offsets are in BYTES!
oldtypes[1] = MPI_INT;

MPI_Type_create_struct(2, blklens, offsets, oldtypes, &dt260);
MPI_Type_commit(&dt260);

// Send the data
MPI_Send(data, 1, dt260, ...);

MPI_Aint é um número inteiro grande o suficiente que pode conter compensações maiores do queint pode representar em sistemas LP64. Observe que o receptor deve construir o mesmo tipo de dados e usá-lo de maneira semelhante noMPI_Recv ligar. O recebimento de uma quantidade arbitrária não inteira do tipo de dados contíguo é um pouco problemático.

Esse é o obstáculo fácil. Não é tão fácil assim quando sua implementação MPI não usa contagens internamente longas. Nesse caso, o MPI geralmente trava ou envia apenas parte dos dados ou algo estranho pode acontecer. Essa implementação MPI pode ser travada mesmo sem a construção de um tipo de dados especial, simplesmente enviandoINT_MAX elementos do tipoMPI_INT como o tamanho total da mensagem seria (231 - 1) * 4 = 233 - 4. Se for esse o caso, sua única saída é dividir manualmente a mensagem e enviá-la / recebê-la em um loop.

 steabert22 de abr de 2014 16:30
apenas para comentar sobre "é 2014", com o Intel MPI, por exemplo, os tamanhos das mensagens ainda são limitados a 2 GB, mesmo que o número de elementos caiba em um int de 4 bytes (software.intel.com/en-us/forums/topic/361060 esoftware.intel.com/en-us/forums/topic/505683) Não conheço outras implementações.
 Hristo Iliev22 de abr de 2014 20:25
Esse é apenas o efeito da escrita automatizada à noite. Recentemente, tivemos problemas com alguns softwares em nosso cluster que começaram a ter problemas quando o usuário mudou do Open MPI para o Intel MPI e o tamanho da mensagem foi o culpado.

yourAnswerToTheQuestion