-2

I'm trying to divide the string str_data1 and send it to the slave processors in MPI_COMM_WORLD, but I am getting an error on the slaves.

The error looks something like this:

2

2

3
�E0� �E0�� �E0O�

#include <stdio.h>
#include <string.h>
#include "mpi.h"

int main(int argc, char* argv[]) {
int rank;
int p;
MPI_Status status;
int msg_size = 0;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

MPI_Comm_size(MPI_COMM_WORLD, &p);

char *str_data1 = "Samsung Galaxy Tab S 10.5 Wi-Fi, Tablet PC Android";

int len1 = strlen(str_data1), i;
char *str1[len1];
char *a[len1];

if (rank == 0) {

    char *ds = strdup(str_data1);
    int n = 0;
    a[n] = strtok(ds, " ,");
    while (a[n] && n < len1) {
        a[++n] = strtok(NULL, " ,");
    }

    int chunk = n / p;
    int str_size = chunk;
    for (i = 1; i < p; i++) {
        if (i == p - 1) {
            str_size = n - chunk * i;
        }
        MPI_Send(&str_size, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
        MPI_Send(&a, str_size + 1, MPI_CHAR, i, 0, MPI_COMM_WORLD);
    }

} else {

    MPI_Recv(&msg_size, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
    char messagsg_size];
    printf(" \n  %d ", msg_size);
    MPI_Recv(&message, msg_size + 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD,
            &status);
    printf(" \n  %s ", message);
}
MPI_Finalize();

return 0;
}

does anyone have any clues what im doing wrong? Thanks.

Wesley Bland
  • 8,816
  • 3
  • 44
  • 59

2 Answers2

0

Some newer compilers will give you nice warning about these sorts of things. It's been very nice ever since Clang added this. If you were to use that compiler, you'd see this:

$ mpic++ asdf.c
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
asdf.c:17:23: warning: conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings]
    char *str_data1 = "Samsung Galaxy Tab S 10.5 Wi-Fi, Tablet PC Android";
                      ^
asdf.c:39:22: warning: argument type 'char *(*)[len1]' doesn't match specified 'MPI' type tag that requires 'char *' [-Wtype-safety]
            MPI_Send(&a, str_size + 1, MPI_CHAR, i, 0, MPI_COMM_WORLD);
                     ^~                ~~~~~~~~
asdf.c:47:18: warning: argument type 'char (*)[msg_size]' doesn't match specified 'MPI' type tag that requires 'char *' [-Wtype-safety]
        MPI_Recv(&message, msg_size + 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD,
                 ^~~~~~~~                ~~~~~~~~
3 warnings generated.

That shows you that you're using the wrong types for your character arrays. You should be using either just character arrays:

char a[len1];

or character pointers:

char *a;

Either way, you need to do some code rework to make that work correctly. Specifically, this section:

char *ds = strdup(str_data1);
int n = 0;
a[n] = strtok(ds, " ,");
while (a[n] && n < len1) {
    a[++n] = strtok(NULL, " ,");
}

I don't think that string tokenizer is doing what you think it is since it would just be overwriting itself over and over.

Wesley Bland
  • 8,816
  • 3
  • 44
  • 59
0

Thanks Wesly.. i tired with structure.. looks like its working..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<mpi.h>

struct tokan {
char buff[30];
} t[50];

int main(int argc, char* argv[]) {
int rank;
int p;
MPI_Status status;
int msg_size = 0, i = 0, j = 0, msg_size1 = 0;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

MPI_Comm_size(MPI_COMM_WORLD, &p);
int n = 0, m = 0, k = 0, N = 0, M = 0;
char *str1, *str2, *str_data2, *str_data1;

if (rank == 0) {

    str_data1 =
            "processes in this communicator will now abort, and potentially your MPI job";

    str_data2 =
            "The behavior is undefined if lhs or rhs are not pointers to null-terminated byte strings";

    str1 = (char *) malloc(strlen(str_data1) * sizeof(char));
    str2 = (char *) malloc(strlen(str_data2) * sizeof(char));

    strcpy(str1, str_data1);
    strcpy(str2, str_data2);

    int len;
    M = strlen(str2);
    N = strlen(str1);

    char *ptr;
    k = 0;
    char *ds = strdup(str_data1);
    ptr = strtok(ds, " ,");
    while (ptr != NULL) {
        ++n;
        len = strlen(ptr);
        for (j = 0; j < len; j++) {
            t[k].buff[j] = *(ptr + j);
        }
        //printf(" %s ", t[k].buff);
        k++;
        ptr = strtok(NULL, " ,");
    }
    int chunk = n / p;
    int str_size = chunk, cnt = 0;
    j = chunk;
    for (i = 1; i < p; i++) {
        if (i == p - 1) {
            str_size = n - chunk * i;
        }
        MPI_Send(&str_size, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
        for (cnt = 0; cnt < str_size; cnt++) {
            /*printf("process 0: %c %d %d %d %d %d %d\n", t[j].buff, str_size, n,
             chunk, cnt, j, l);*/
            MPI_Send(t[j].buff, 100, MPI_CHAR, i, 0, MPI_COMM_WORLD);
            j++;
        }
    }

    str_size = chunk;
    for (i = 1; i < p; i++) {
        MPI_Send(&M, 1, MPI_INT, i, 0, MPI_COMM_WORLD);
        //printf("process 0: %s %d %d %d %d\n", str2, n, chunk, cnt, j);
        MPI_Send(str2, M, MPI_CHAR, i, 0, MPI_COMM_WORLD);
    }

} else {

    MPI_Recv(&msg_size, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
    int k;
    for (k = 0; k < msg_size; k++) {
        MPI_Recv(t[k].buff, 100, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
        printf(" \nstr1:  %s %d %d  %d\n", t[k].buff, rank, msg_size, k);
    }

    printf("***************");
    MPI_Recv(&M, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
    str2 = (char *) malloc((M + 1) * sizeof(char));
    MPI_Recv(str2, M, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
    str2[M] = '\0';
    printf(" \nstr2:  %s %d %d %d \n", str2, rank, k, M);
}
if (rank == 0)
    free(str1);
free(str2);
MPI_Finalize();

return 0;
}