1

Send an array larger than 250 using send / recv the MPI. How should I proceed? With this kind of attribute it gives buffer error.

My arrays are text1, text2, Text3. Thanks =D

#include <stdio.h>
#include <mpi.h>
#include <time.h>
#include <math.h>
#include <string.h>
#define maxn 12000 //AoLéo
#include <stdlib.h>

int max(int a,int b);
int LongestCommonSubsequence(char text[]);


static char search[] = "ab"; //array que irá ser buscado nos arrays
static const char alphanum[]               ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(alphanum) - 1;



int max(int a,int b)
{
    return a>b?a:b;
}

   int LongestCommonSubsequence(char text[]){



    int Slength = strlen(search); //Procurado
    int Tlength = strlen(text); //Procura
    int iter,jter=0;


   int common[Slength+1][Tlength+1];


    for(iter=0; iter<=Slength; iter++){
            for(jter=0; jter<=Tlength; jter++){

                    if(iter == 0 || jter == 0){
                        common[iter][jter] = 0;
                    }

                    else if(search[iter-1] == text[jter-1] ){
                            common[iter][jter] = common[iter-1][jter-1] + 1;
                    }
                    else{
                            common[iter][jter]= max(common[iter][jter-1],common[iter-1][jter]);


                    }

            }
    }


 return common[Slength][Tlength];

}



 main(int argc, char **argv)
{   
double startwtime = 0.0, endwtime; //var de tempo de execução
int id;//id : Rank de um processo
int p;//p : Numero de Processos


char texto1[maxn];
char texto2[maxn];
char texto3[maxn];



    //Inicializa os processos.
MPI_Init(&argc,&argv);
//determina o rank de um processo
MPI_Comm_rank(MPI_COMM_WORLD,&id);
//determina o numero de processos executando
MPI_Comm_size(MPI_COMM_WORLD,&p);
MPI_Status status;
    //mostra dados
 printf("Processo iniciado do id: %d\n ",id);
     printf("Numeros de processos p: %d \n",p);
if(id==0)
{
startwtime = MPI_Wtime();//iniciando o contador de tempo

strcpy(texto1,"auhauhsushauhs");
strcpy(texto2, "oplpadasdasdasdasdafadvalk");
strcpy(texto3, "cbfgrwtgjyunyhs");

int lengthText1 = strlen(texto1);//Atribuindo o tamanho do vetor
int lengthText2 = strlen(texto2);//Atribuindo o tamanho do vetor        
int lengthText3 = strlen(texto3);//Atribuindo o tamanho do vetor
printf("TAMANHO DO VETOR 1 >>>%d<<<", lengthText1);

printf("Enviando o tamanho dos vetores para os %d processadores....\n", p);
MPI_Send(&lengthText1, 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);  
MPI_Send(&lengthText2, 1, MPI_CHAR, 2, 0, MPI_COMM_WORLD);
MPI_Send(&lengthText3, 1, MPI_CHAR, 3, 0, MPI_COMM_WORLD);


printf("Enviando os dados para os %d processadores....\n", p);
MPI_Send(texto1, lengthText1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);  
MPI_Send(texto2, lengthText2, MPI_CHAR, 2, 0, MPI_COMM_WORLD);
MPI_Send(texto3, lengthText3, MPI_CHAR, 3, 0, MPI_COMM_WORLD);
printf("Dados enviados com sucesso!\n");


}

if(id == 1){
int answer; 
int lengthText1;
MPI_Recv(&lengthText1, 1, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);//Recebendo o tamanho do vetor
MPI_Recv(texto1, lengthText1, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);//Recebendo o vetor
printf("Dados recebidos com sucesso no processador: %d \n", id);

answer = LongestCommonSubsequence(texto1);
printf("Resposta do processador %d eh de %d incidencias\n", id, answer);
MPI_Send(&answer, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}

if(id == 2){
int answer;
int lengthText2;
MPI_Recv(&lengthText2, 1, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);//Recebendo o tamanho do vetor
MPI_Recv(texto2, lengthText2, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);//Recebendo o vetor
printf("Dados recebidos com sucesso no processador: %d \n", id);

answer = LongestCommonSubsequence(texto2);
printf("Resposta do processador %d eh de %d incidencias\n", id, answer);
MPI_Send(&answer, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}

if(id == 3){
int answer; 
int lengthText3;
MPI_Recv(&lengthText3, 1, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);//Recebendo o tamanho do vetor
MPI_Recv(texto3, lengthText3, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);//Recebendo o vetor
printf("Dados recebidos com sucesso no processador: %d \n", id);

answer = LongestCommonSubsequence(texto3);
printf("Resposta do processador %d eh de %d incidencias\n", id, answer);
MPI_Send(&answer, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
}




//Retorno do Jedi
if(id == 0 ){
int answer=0;
int i;
int respostas[2];
endwtime = MPI_Wtime();

printf("Recebendo dados dos processadores\n");
for(i=1; i<4; i++){
MPI_Recv(&answer, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
respostas[i] = answer;
answer=0;
}
printf("Dados recebidos com sucesso no servidor!\n");
for(i=1; i<4; i++){
printf("Incidencias no noh %d foi de: %d\n", i, respostas[i]);



}
printf("\n\n************ Tempo de execucao foi de %.4f segundos ***********\n", endwtime-startwtime);
  }


MPI_Finalize(); //Finalizar MPI
}

I'm using dynamic programming and I'm 3 knots + server.

2 Answers 2

2

This is no surprise. You are using the MPI datatype MPI_CHAR for sending and receiving the string lengths. This sends only 1 byte. Use MPI_INT as the MPI datatype instead to send the full 4 byte integer:

// what you are doing:
MPI_Send(&lengthText1, 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
// ... and
MPI_Recv(&lengthText1, 1, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

// what you should be doing:
MPI_Send(&lengthText1, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
// ... and
MPI_Recv(&lengthText1, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
Sign up to request clarification or add additional context in comments.

4 Comments

I am frightened by such inattention. : / Thank you so much for looking so silly .
if you compile with clang, there are type annotations to catch this sort of mistake
I am sending two character sizes with 12k and 1k , When I put 15k + it explodes . Any Suggestion? I am suspicious of LongestCommonSub function, but it makes no sense . 500 and 15k comparisons are valid, but 15k to 15k not.
What do you mean by 'explode'? Your LongestCommonSub function is quadratic in time and memory complexity. It will require much more time and memory for the 15k*15k case (~1GB Ram) than for the 500*15k case.
0

It should be noted that there is MPI_Probe to obtain the size of an array before sending. There do not have to be two MPI_Send calls. Furthermore, you can use arrays of dynamic size conforming to the C++ standard, and simply use std::string.

For example:

template<typename T>
struct ManagedArray { // for RAII on dynamic arrays
    T* data;
    ManagedArray() : data(nullptr) { }
    ManagedArray(size_t size) : data(new T[size]) { }
    ~ManagedArray() { delete data; }
};

string mpi_recvString(int rank, int source) {
    MPI_Status status_recv;
    MPI_Probe(source, 0, MPI_COMM_WORLD, &status_recv);
    int size;
    MPI_Get_count(&status_recv, MPI_CHAR, &size);
    cout << rank << ": Will receive " << size << " chars." << endl;
    ManagedArray<char> arr(size);
    MPI_Recv(arr.data, size, MPI_CHAR, source, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    cout << rank << ": Received: " << arr.data << ". (length " << string(arr.data).length() << ")" << endl;
    return arr.data;
}

In case anyone would like to see the mpi_sendString as well:

void mpi_sendString(int rank, const string& s, int dest) {
    cout << rank << ": Sending " << s << ". (length " << s.length() << ")" << endl;
    // Actually send s.size() + 1 chars, since s.c_str() is null-terminated.
    MPI_Send(s.c_str(), s.size() + 1, MPI_CHAR, dest, 0, MPI_COMM_WORLD);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.