Structs manipulation via MPI_Send and MPI_recv in CWhat's the difference between struct and class in .NET?When should you use a class vs a struct in C++?Why isn't sizeof for a struct equal to the sum of sizeof of each member?How to initialize a struct in accordance with C programming language standardsWhy are mutable structs “evil”?When to use struct?Difference between 'struct' and 'typedef struct' in C++?typedef struct vs struct definitionsMPI_Send and MPI_RecvWhy Choose Struct Over Class?

Can an old DSLR be upgraded to match modern smartphone image quality

The term for the person/group a political party aligns themselves with to appear concerned about the general public

Can a magnetic field of a large body be stronger than its gravity?

Can you keep a readied action even through incapacitation?

Setting extra bits in a bool makes it true and false at the same time

Accidentally cashed a check twice

How is it possible for Mordenkainen to be alive during the Curse of Strahd adventure?

Singlequote and backslash

How to detach yourself from a character you're going to kill?

Is there a way to save this session?

How can I offer a test ride while selling a bike?

If a problem only occurs randomly once in every N times on average, how many tests do I have to perform to be certain that it's now fixed?

If Sweden was to magically float away, at what altitude would it be visible from the southern hemisphere?

Comma Code - Ch. 4 Automate the Boring Stuff

Hygienic footwear for prehensile feet?

How should I push back against my job assigning "homework"?

Filling region bounded by multiple paths

What is a simple, physical situation where complex numbers emerge naturally?

Is this cancel button needed?

Asking bank to reduce APR instead of increasing credit limit

When to clean out old bird boxes?

What's the most polite way to tell a manager "shut up and let me work"?

Have powerful mythological heroes ever run away or been deeply afraid?

Is it possible to kill all life on Earth?



Structs manipulation via MPI_Send and MPI_recv in C


What's the difference between struct and class in .NET?When should you use a class vs a struct in C++?Why isn't sizeof for a struct equal to the sum of sizeof of each member?How to initialize a struct in accordance with C programming language standardsWhy are mutable structs “evil”?When to use struct?Difference between 'struct' and 'typedef struct' in C++?typedef struct vs struct definitionsMPI_Send and MPI_RecvWhy Choose Struct Over Class?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I am still a newcomer when it comes to MPI and I am trying to define and MPI type to match a custom structure I wrote. The idea behind this is having a list of students sent to multiple processes, each using it to search, let's say for a particular one. I have custom initialized the first element in the list so I can check if the program works. The search functionality has been implemented, but not used.



The problems:



  • I wanted to ensure that my data is correctly passed to the processes, thus I wanted to print their local list (local). I have discovered that after the first few entries, everything gets messed up and I cannot seem to figure out why.

  • Is there a way to have pointers instead of arrays of chars in side the struct? As far as I have read, there is no possible way to do this, because the memory space is not shared. is that correct?

  • Is there a better way to initialize a char array from a pointer? I think this is using a lot of memory.

Some portions of the code have been commented, such as the receive part of the processes, for debugging purposes. I have compiled the source using mpicc students.c -Wall -Wextra -g and I have executed it using mpiexec -n 4 ./a.out.



Code:



#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NELEM 25
#define MAX_STR_LENGTH 30
#define MAX_FNAME_LENGTH 10
#define MAX_LNAME_LENGTH 10
#define MAX_YEAR_ID_LENTGH 3
#define MAX_CNP_LENGTH 13
#define MAX_YEARS 6
#define TAG 1
#define MASTER 0
#define TRUE 1
#define FALSE 0

#define FNAME_LABEL "First name"
#define LNAME_LABEL "Last name"
#define CNP_LABEL "CNP"
#define STUDIES_LABEL "Studies"
#define YEAR_LABEL "Year"

typedef struct

char firstName[MAX_FNAME_LENGTH];
char lastName[MAX_LNAME_LENGTH];
char cnp[MAX_CNP_LENGTH];
char studies[MAX_YEAR_ID_LENTGH];
int year;
Student;

void receive(MPI_Datatype type, int rank);
void send_data(Student data[], MPI_Datatype type, int num_procs);
void initialize(Student data[]);
char *rand_string(char *str, size_t size);
char *rand_string_alloc(size_t size);
int rand_year();
void initialize_student(Student *stud);
void fill_field(char data[], char *fill, int size, int max_size);
void print_field(char data[], int size, char *field_label);
void print_stud(Student stud);
int is_a_match(char lvalue[], char *rvalue);
Student *search_stud(char *cnp, Student students[], int list_size);
void initialize_custom_student(Student *stud);
void print_list(Student students[], int size, int rank);

int main(int argc, char **argv)

srand(time(NULL));
int num_procs, rank;

Student to_send[NELEM];
MPI_Datatype studentType, oldtypes[2];
int blockcounts[2];

/* MPI_Aint type used to be consistent with syntax of */
/* MPI_Type_extent routine */
MPI_Aint offsets[2], extent;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

/* Setup description of the 4 MPI_FLOAT fields x, y, z, velocity */
offsets[0] = 0;
oldtypes[0] = MPI_CHAR;
blockcounts[0] = 4;
/* Setup description of the 2 MPI_INT fields n, type */
/* Need to first figure offset by getting size of MPI_FLOAT */
MPI_Type_extent(MPI_CHAR, &extent);

offsets[1] = 4 * extent;
oldtypes[1] = MPI_INT;
blockcounts[1] = 1;

/* Now define structured type and commit it */
MPI_Type_struct(2, blockcounts, offsets, oldtypes, &studentType);
MPI_Type_commit(&studentType);

/* Initialize the particle array and then to_send it to each task */
if (rank == MASTER)

initialize(to_send);
send_data(to_send, studentType, num_procs);
// print_list(to_send, NELEM, rank);

else

// receive(studentType, rank);


//sanity-check printing
if (rank == num_procs - 1)

receive(studentType, rank);


MPI_Type_free(&studentType);
MPI_Finalize();


void receive(MPI_Datatype type, int rank)

// printf("Process %d is awaiting data....!n", rank);
Student local[NELEM];
MPI_Status status;
MPI_Recv(local, NELEM, type, MASTER, TAG, MPI_COMM_WORLD, &status);
print_list(local, NELEM, rank);

// printf("[OK]:Proccess %d has finished receiving all the data!n", rank);


void send_data(Student data[], MPI_Datatype type, int num_procs)

// printf("Sending data....!n");
for (int i = 1; i < num_procs; i++)

MPI_Send(data, NELEM, type, i, TAG, MPI_COMM_WORLD);

// printf("[OK]:All data was sent!n");


void initialize(Student data[])

initialize_custom_student(&data[0]);

printf("Initializing data....!n");
for (int i = 1; i < NELEM; i++)

initialize_student(&data[i]);


printf("[OK]:Data initialized!n");


void initialize_custom_student(Student *stud)

char *fName = "Some";
int fNameSize = 5;

char *lName = "Name";
int lNameSize = 7;

char *cnp = "1234";
int cnpSize = 4;

char *studies = "CS";
int studiesSize = 2;

fill_field(stud->firstName, fName, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, cnp, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = 4;


void initialize_student(Student *stud)

int fNameSize = rand() % MAX_FNAME_LENGTH;
char *firstname = rand_string_alloc(fNameSize);

int lNameSize = rand() % MAX_LNAME_LENGTH;
char *lastName = rand_string_alloc(MAX_LNAME_LENGTH);

int cnpSize = rand() % MAX_CNP_LENGTH;
char *CNP = rand_string_alloc(MAX_CNP_LENGTH);

int studiesSize = rand() % MAX_YEAR_ID_LENTGH;
char *studies = rand_string_alloc(MAX_YEAR_ID_LENTGH);

fill_field(stud->firstName, firstname, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lastName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, CNP, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = rand_year();

free(firstname);
free(lastName);
free(CNP);
free(studies);


void fill_field(char data[], char *fill, int size, int max_size)

for (int i = 0; i < size; i++)

data[i] = fill[i];


for (int i = size; i < max_size; i++)

data[i] = '*';



void print_field(char data[], int size, char *field_label)

printf(" %s: ", field_label);
for (int i = 0; i < size; i++)

char character = data[i];
if (character == '*')

break;


printf("%c", character);

printf("n");


char *rand_string(char *str, size_t size)

const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK";
if (size)

--size;
for (size_t n = 0; n < size; n++)

int key = rand() % (int)(sizeof charset - 1);
str[n] = charset[key];

str[size] = '';

return str;


char *rand_string_alloc(size_t size)

char *s = malloc(size + 1);
if (s)

rand_string(s, size);

return s;


int rand_year()

return rand() % MAX_YEARS;


void print_stud(Student stud)

print_field(stud.firstName, MAX_FNAME_LENGTH, FNAME_LABEL);
print_field(stud.lastName, MAX_LNAME_LENGTH, LNAME_LABEL);
print_field(stud.cnp, MAX_CNP_LENGTH, CNP_LABEL);
print_field(stud.studies, MAX_YEAR_ID_LENTGH, STUDIES_LABEL);


Student *search_stud(char *cnp, Student students[], int list_size)

Student *current = NULL;

for (int i = 0; i < list_size; i++)

*current = students[i];
if (is_a_match(current->cnp, cnp))

return current;



return NULL;


int is_a_match(char lvalue[], char *rvalue)

for (int i = 0; i < MAX_CNP_LENGTH; i++)


return TRUE;


void print_list(Student students[], int size, int rank)

for (int i = 0; i < size; i++)

print_stud(students[i]);
printf("n");




Thanks!










share|improve this question

















  • 1





    if (left == '0' || right == '0' || left != right) You want 0 as a filler, instead of * ? [also: the condition looks wrong, you probably want to allow both sides to be 0]

    – wildplasser
    Mar 17 at 14:57












  • You are right, sir. What about the loss of data after transferring ?

    – CyberFox
    Mar 17 at 18:56

















0















I am still a newcomer when it comes to MPI and I am trying to define and MPI type to match a custom structure I wrote. The idea behind this is having a list of students sent to multiple processes, each using it to search, let's say for a particular one. I have custom initialized the first element in the list so I can check if the program works. The search functionality has been implemented, but not used.



The problems:



  • I wanted to ensure that my data is correctly passed to the processes, thus I wanted to print their local list (local). I have discovered that after the first few entries, everything gets messed up and I cannot seem to figure out why.

  • Is there a way to have pointers instead of arrays of chars in side the struct? As far as I have read, there is no possible way to do this, because the memory space is not shared. is that correct?

  • Is there a better way to initialize a char array from a pointer? I think this is using a lot of memory.

Some portions of the code have been commented, such as the receive part of the processes, for debugging purposes. I have compiled the source using mpicc students.c -Wall -Wextra -g and I have executed it using mpiexec -n 4 ./a.out.



Code:



#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NELEM 25
#define MAX_STR_LENGTH 30
#define MAX_FNAME_LENGTH 10
#define MAX_LNAME_LENGTH 10
#define MAX_YEAR_ID_LENTGH 3
#define MAX_CNP_LENGTH 13
#define MAX_YEARS 6
#define TAG 1
#define MASTER 0
#define TRUE 1
#define FALSE 0

#define FNAME_LABEL "First name"
#define LNAME_LABEL "Last name"
#define CNP_LABEL "CNP"
#define STUDIES_LABEL "Studies"
#define YEAR_LABEL "Year"

typedef struct

char firstName[MAX_FNAME_LENGTH];
char lastName[MAX_LNAME_LENGTH];
char cnp[MAX_CNP_LENGTH];
char studies[MAX_YEAR_ID_LENTGH];
int year;
Student;

void receive(MPI_Datatype type, int rank);
void send_data(Student data[], MPI_Datatype type, int num_procs);
void initialize(Student data[]);
char *rand_string(char *str, size_t size);
char *rand_string_alloc(size_t size);
int rand_year();
void initialize_student(Student *stud);
void fill_field(char data[], char *fill, int size, int max_size);
void print_field(char data[], int size, char *field_label);
void print_stud(Student stud);
int is_a_match(char lvalue[], char *rvalue);
Student *search_stud(char *cnp, Student students[], int list_size);
void initialize_custom_student(Student *stud);
void print_list(Student students[], int size, int rank);

int main(int argc, char **argv)

srand(time(NULL));
int num_procs, rank;

Student to_send[NELEM];
MPI_Datatype studentType, oldtypes[2];
int blockcounts[2];

/* MPI_Aint type used to be consistent with syntax of */
/* MPI_Type_extent routine */
MPI_Aint offsets[2], extent;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

/* Setup description of the 4 MPI_FLOAT fields x, y, z, velocity */
offsets[0] = 0;
oldtypes[0] = MPI_CHAR;
blockcounts[0] = 4;
/* Setup description of the 2 MPI_INT fields n, type */
/* Need to first figure offset by getting size of MPI_FLOAT */
MPI_Type_extent(MPI_CHAR, &extent);

offsets[1] = 4 * extent;
oldtypes[1] = MPI_INT;
blockcounts[1] = 1;

/* Now define structured type and commit it */
MPI_Type_struct(2, blockcounts, offsets, oldtypes, &studentType);
MPI_Type_commit(&studentType);

/* Initialize the particle array and then to_send it to each task */
if (rank == MASTER)

initialize(to_send);
send_data(to_send, studentType, num_procs);
// print_list(to_send, NELEM, rank);

else

// receive(studentType, rank);


//sanity-check printing
if (rank == num_procs - 1)

receive(studentType, rank);


MPI_Type_free(&studentType);
MPI_Finalize();


void receive(MPI_Datatype type, int rank)

// printf("Process %d is awaiting data....!n", rank);
Student local[NELEM];
MPI_Status status;
MPI_Recv(local, NELEM, type, MASTER, TAG, MPI_COMM_WORLD, &status);
print_list(local, NELEM, rank);

// printf("[OK]:Proccess %d has finished receiving all the data!n", rank);


void send_data(Student data[], MPI_Datatype type, int num_procs)

// printf("Sending data....!n");
for (int i = 1; i < num_procs; i++)

MPI_Send(data, NELEM, type, i, TAG, MPI_COMM_WORLD);

// printf("[OK]:All data was sent!n");


void initialize(Student data[])

initialize_custom_student(&data[0]);

printf("Initializing data....!n");
for (int i = 1; i < NELEM; i++)

initialize_student(&data[i]);


printf("[OK]:Data initialized!n");


void initialize_custom_student(Student *stud)

char *fName = "Some";
int fNameSize = 5;

char *lName = "Name";
int lNameSize = 7;

char *cnp = "1234";
int cnpSize = 4;

char *studies = "CS";
int studiesSize = 2;

fill_field(stud->firstName, fName, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, cnp, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = 4;


void initialize_student(Student *stud)

int fNameSize = rand() % MAX_FNAME_LENGTH;
char *firstname = rand_string_alloc(fNameSize);

int lNameSize = rand() % MAX_LNAME_LENGTH;
char *lastName = rand_string_alloc(MAX_LNAME_LENGTH);

int cnpSize = rand() % MAX_CNP_LENGTH;
char *CNP = rand_string_alloc(MAX_CNP_LENGTH);

int studiesSize = rand() % MAX_YEAR_ID_LENTGH;
char *studies = rand_string_alloc(MAX_YEAR_ID_LENTGH);

fill_field(stud->firstName, firstname, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lastName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, CNP, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = rand_year();

free(firstname);
free(lastName);
free(CNP);
free(studies);


void fill_field(char data[], char *fill, int size, int max_size)

for (int i = 0; i < size; i++)

data[i] = fill[i];


for (int i = size; i < max_size; i++)

data[i] = '*';



void print_field(char data[], int size, char *field_label)

printf(" %s: ", field_label);
for (int i = 0; i < size; i++)

char character = data[i];
if (character == '*')

break;


printf("%c", character);

printf("n");


char *rand_string(char *str, size_t size)

const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK";
if (size)

--size;
for (size_t n = 0; n < size; n++)

int key = rand() % (int)(sizeof charset - 1);
str[n] = charset[key];

str[size] = '';

return str;


char *rand_string_alloc(size_t size)

char *s = malloc(size + 1);
if (s)

rand_string(s, size);

return s;


int rand_year()

return rand() % MAX_YEARS;


void print_stud(Student stud)

print_field(stud.firstName, MAX_FNAME_LENGTH, FNAME_LABEL);
print_field(stud.lastName, MAX_LNAME_LENGTH, LNAME_LABEL);
print_field(stud.cnp, MAX_CNP_LENGTH, CNP_LABEL);
print_field(stud.studies, MAX_YEAR_ID_LENTGH, STUDIES_LABEL);


Student *search_stud(char *cnp, Student students[], int list_size)

Student *current = NULL;

for (int i = 0; i < list_size; i++)

*current = students[i];
if (is_a_match(current->cnp, cnp))

return current;



return NULL;


int is_a_match(char lvalue[], char *rvalue)

for (int i = 0; i < MAX_CNP_LENGTH; i++)


return TRUE;


void print_list(Student students[], int size, int rank)

for (int i = 0; i < size; i++)

print_stud(students[i]);
printf("n");




Thanks!










share|improve this question

















  • 1





    if (left == '0' || right == '0' || left != right) You want 0 as a filler, instead of * ? [also: the condition looks wrong, you probably want to allow both sides to be 0]

    – wildplasser
    Mar 17 at 14:57












  • You are right, sir. What about the loss of data after transferring ?

    – CyberFox
    Mar 17 at 18:56













0












0








0


1






I am still a newcomer when it comes to MPI and I am trying to define and MPI type to match a custom structure I wrote. The idea behind this is having a list of students sent to multiple processes, each using it to search, let's say for a particular one. I have custom initialized the first element in the list so I can check if the program works. The search functionality has been implemented, but not used.



The problems:



  • I wanted to ensure that my data is correctly passed to the processes, thus I wanted to print their local list (local). I have discovered that after the first few entries, everything gets messed up and I cannot seem to figure out why.

  • Is there a way to have pointers instead of arrays of chars in side the struct? As far as I have read, there is no possible way to do this, because the memory space is not shared. is that correct?

  • Is there a better way to initialize a char array from a pointer? I think this is using a lot of memory.

Some portions of the code have been commented, such as the receive part of the processes, for debugging purposes. I have compiled the source using mpicc students.c -Wall -Wextra -g and I have executed it using mpiexec -n 4 ./a.out.



Code:



#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NELEM 25
#define MAX_STR_LENGTH 30
#define MAX_FNAME_LENGTH 10
#define MAX_LNAME_LENGTH 10
#define MAX_YEAR_ID_LENTGH 3
#define MAX_CNP_LENGTH 13
#define MAX_YEARS 6
#define TAG 1
#define MASTER 0
#define TRUE 1
#define FALSE 0

#define FNAME_LABEL "First name"
#define LNAME_LABEL "Last name"
#define CNP_LABEL "CNP"
#define STUDIES_LABEL "Studies"
#define YEAR_LABEL "Year"

typedef struct

char firstName[MAX_FNAME_LENGTH];
char lastName[MAX_LNAME_LENGTH];
char cnp[MAX_CNP_LENGTH];
char studies[MAX_YEAR_ID_LENTGH];
int year;
Student;

void receive(MPI_Datatype type, int rank);
void send_data(Student data[], MPI_Datatype type, int num_procs);
void initialize(Student data[]);
char *rand_string(char *str, size_t size);
char *rand_string_alloc(size_t size);
int rand_year();
void initialize_student(Student *stud);
void fill_field(char data[], char *fill, int size, int max_size);
void print_field(char data[], int size, char *field_label);
void print_stud(Student stud);
int is_a_match(char lvalue[], char *rvalue);
Student *search_stud(char *cnp, Student students[], int list_size);
void initialize_custom_student(Student *stud);
void print_list(Student students[], int size, int rank);

int main(int argc, char **argv)

srand(time(NULL));
int num_procs, rank;

Student to_send[NELEM];
MPI_Datatype studentType, oldtypes[2];
int blockcounts[2];

/* MPI_Aint type used to be consistent with syntax of */
/* MPI_Type_extent routine */
MPI_Aint offsets[2], extent;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

/* Setup description of the 4 MPI_FLOAT fields x, y, z, velocity */
offsets[0] = 0;
oldtypes[0] = MPI_CHAR;
blockcounts[0] = 4;
/* Setup description of the 2 MPI_INT fields n, type */
/* Need to first figure offset by getting size of MPI_FLOAT */
MPI_Type_extent(MPI_CHAR, &extent);

offsets[1] = 4 * extent;
oldtypes[1] = MPI_INT;
blockcounts[1] = 1;

/* Now define structured type and commit it */
MPI_Type_struct(2, blockcounts, offsets, oldtypes, &studentType);
MPI_Type_commit(&studentType);

/* Initialize the particle array and then to_send it to each task */
if (rank == MASTER)

initialize(to_send);
send_data(to_send, studentType, num_procs);
// print_list(to_send, NELEM, rank);

else

// receive(studentType, rank);


//sanity-check printing
if (rank == num_procs - 1)

receive(studentType, rank);


MPI_Type_free(&studentType);
MPI_Finalize();


void receive(MPI_Datatype type, int rank)

// printf("Process %d is awaiting data....!n", rank);
Student local[NELEM];
MPI_Status status;
MPI_Recv(local, NELEM, type, MASTER, TAG, MPI_COMM_WORLD, &status);
print_list(local, NELEM, rank);

// printf("[OK]:Proccess %d has finished receiving all the data!n", rank);


void send_data(Student data[], MPI_Datatype type, int num_procs)

// printf("Sending data....!n");
for (int i = 1; i < num_procs; i++)

MPI_Send(data, NELEM, type, i, TAG, MPI_COMM_WORLD);

// printf("[OK]:All data was sent!n");


void initialize(Student data[])

initialize_custom_student(&data[0]);

printf("Initializing data....!n");
for (int i = 1; i < NELEM; i++)

initialize_student(&data[i]);


printf("[OK]:Data initialized!n");


void initialize_custom_student(Student *stud)

char *fName = "Some";
int fNameSize = 5;

char *lName = "Name";
int lNameSize = 7;

char *cnp = "1234";
int cnpSize = 4;

char *studies = "CS";
int studiesSize = 2;

fill_field(stud->firstName, fName, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, cnp, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = 4;


void initialize_student(Student *stud)

int fNameSize = rand() % MAX_FNAME_LENGTH;
char *firstname = rand_string_alloc(fNameSize);

int lNameSize = rand() % MAX_LNAME_LENGTH;
char *lastName = rand_string_alloc(MAX_LNAME_LENGTH);

int cnpSize = rand() % MAX_CNP_LENGTH;
char *CNP = rand_string_alloc(MAX_CNP_LENGTH);

int studiesSize = rand() % MAX_YEAR_ID_LENTGH;
char *studies = rand_string_alloc(MAX_YEAR_ID_LENTGH);

fill_field(stud->firstName, firstname, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lastName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, CNP, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = rand_year();

free(firstname);
free(lastName);
free(CNP);
free(studies);


void fill_field(char data[], char *fill, int size, int max_size)

for (int i = 0; i < size; i++)

data[i] = fill[i];


for (int i = size; i < max_size; i++)

data[i] = '*';



void print_field(char data[], int size, char *field_label)

printf(" %s: ", field_label);
for (int i = 0; i < size; i++)

char character = data[i];
if (character == '*')

break;


printf("%c", character);

printf("n");


char *rand_string(char *str, size_t size)

const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK";
if (size)

--size;
for (size_t n = 0; n < size; n++)

int key = rand() % (int)(sizeof charset - 1);
str[n] = charset[key];

str[size] = '';

return str;


char *rand_string_alloc(size_t size)

char *s = malloc(size + 1);
if (s)

rand_string(s, size);

return s;


int rand_year()

return rand() % MAX_YEARS;


void print_stud(Student stud)

print_field(stud.firstName, MAX_FNAME_LENGTH, FNAME_LABEL);
print_field(stud.lastName, MAX_LNAME_LENGTH, LNAME_LABEL);
print_field(stud.cnp, MAX_CNP_LENGTH, CNP_LABEL);
print_field(stud.studies, MAX_YEAR_ID_LENTGH, STUDIES_LABEL);


Student *search_stud(char *cnp, Student students[], int list_size)

Student *current = NULL;

for (int i = 0; i < list_size; i++)

*current = students[i];
if (is_a_match(current->cnp, cnp))

return current;



return NULL;


int is_a_match(char lvalue[], char *rvalue)

for (int i = 0; i < MAX_CNP_LENGTH; i++)


return TRUE;


void print_list(Student students[], int size, int rank)

for (int i = 0; i < size; i++)

print_stud(students[i]);
printf("n");




Thanks!










share|improve this question














I am still a newcomer when it comes to MPI and I am trying to define and MPI type to match a custom structure I wrote. The idea behind this is having a list of students sent to multiple processes, each using it to search, let's say for a particular one. I have custom initialized the first element in the list so I can check if the program works. The search functionality has been implemented, but not used.



The problems:



  • I wanted to ensure that my data is correctly passed to the processes, thus I wanted to print their local list (local). I have discovered that after the first few entries, everything gets messed up and I cannot seem to figure out why.

  • Is there a way to have pointers instead of arrays of chars in side the struct? As far as I have read, there is no possible way to do this, because the memory space is not shared. is that correct?

  • Is there a better way to initialize a char array from a pointer? I think this is using a lot of memory.

Some portions of the code have been commented, such as the receive part of the processes, for debugging purposes. I have compiled the source using mpicc students.c -Wall -Wextra -g and I have executed it using mpiexec -n 4 ./a.out.



Code:



#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NELEM 25
#define MAX_STR_LENGTH 30
#define MAX_FNAME_LENGTH 10
#define MAX_LNAME_LENGTH 10
#define MAX_YEAR_ID_LENTGH 3
#define MAX_CNP_LENGTH 13
#define MAX_YEARS 6
#define TAG 1
#define MASTER 0
#define TRUE 1
#define FALSE 0

#define FNAME_LABEL "First name"
#define LNAME_LABEL "Last name"
#define CNP_LABEL "CNP"
#define STUDIES_LABEL "Studies"
#define YEAR_LABEL "Year"

typedef struct

char firstName[MAX_FNAME_LENGTH];
char lastName[MAX_LNAME_LENGTH];
char cnp[MAX_CNP_LENGTH];
char studies[MAX_YEAR_ID_LENTGH];
int year;
Student;

void receive(MPI_Datatype type, int rank);
void send_data(Student data[], MPI_Datatype type, int num_procs);
void initialize(Student data[]);
char *rand_string(char *str, size_t size);
char *rand_string_alloc(size_t size);
int rand_year();
void initialize_student(Student *stud);
void fill_field(char data[], char *fill, int size, int max_size);
void print_field(char data[], int size, char *field_label);
void print_stud(Student stud);
int is_a_match(char lvalue[], char *rvalue);
Student *search_stud(char *cnp, Student students[], int list_size);
void initialize_custom_student(Student *stud);
void print_list(Student students[], int size, int rank);

int main(int argc, char **argv)

srand(time(NULL));
int num_procs, rank;

Student to_send[NELEM];
MPI_Datatype studentType, oldtypes[2];
int blockcounts[2];

/* MPI_Aint type used to be consistent with syntax of */
/* MPI_Type_extent routine */
MPI_Aint offsets[2], extent;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);

/* Setup description of the 4 MPI_FLOAT fields x, y, z, velocity */
offsets[0] = 0;
oldtypes[0] = MPI_CHAR;
blockcounts[0] = 4;
/* Setup description of the 2 MPI_INT fields n, type */
/* Need to first figure offset by getting size of MPI_FLOAT */
MPI_Type_extent(MPI_CHAR, &extent);

offsets[1] = 4 * extent;
oldtypes[1] = MPI_INT;
blockcounts[1] = 1;

/* Now define structured type and commit it */
MPI_Type_struct(2, blockcounts, offsets, oldtypes, &studentType);
MPI_Type_commit(&studentType);

/* Initialize the particle array and then to_send it to each task */
if (rank == MASTER)

initialize(to_send);
send_data(to_send, studentType, num_procs);
// print_list(to_send, NELEM, rank);

else

// receive(studentType, rank);


//sanity-check printing
if (rank == num_procs - 1)

receive(studentType, rank);


MPI_Type_free(&studentType);
MPI_Finalize();


void receive(MPI_Datatype type, int rank)

// printf("Process %d is awaiting data....!n", rank);
Student local[NELEM];
MPI_Status status;
MPI_Recv(local, NELEM, type, MASTER, TAG, MPI_COMM_WORLD, &status);
print_list(local, NELEM, rank);

// printf("[OK]:Proccess %d has finished receiving all the data!n", rank);


void send_data(Student data[], MPI_Datatype type, int num_procs)

// printf("Sending data....!n");
for (int i = 1; i < num_procs; i++)

MPI_Send(data, NELEM, type, i, TAG, MPI_COMM_WORLD);

// printf("[OK]:All data was sent!n");


void initialize(Student data[])

initialize_custom_student(&data[0]);

printf("Initializing data....!n");
for (int i = 1; i < NELEM; i++)

initialize_student(&data[i]);


printf("[OK]:Data initialized!n");


void initialize_custom_student(Student *stud)

char *fName = "Some";
int fNameSize = 5;

char *lName = "Name";
int lNameSize = 7;

char *cnp = "1234";
int cnpSize = 4;

char *studies = "CS";
int studiesSize = 2;

fill_field(stud->firstName, fName, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, cnp, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = 4;


void initialize_student(Student *stud)

int fNameSize = rand() % MAX_FNAME_LENGTH;
char *firstname = rand_string_alloc(fNameSize);

int lNameSize = rand() % MAX_LNAME_LENGTH;
char *lastName = rand_string_alloc(MAX_LNAME_LENGTH);

int cnpSize = rand() % MAX_CNP_LENGTH;
char *CNP = rand_string_alloc(MAX_CNP_LENGTH);

int studiesSize = rand() % MAX_YEAR_ID_LENTGH;
char *studies = rand_string_alloc(MAX_YEAR_ID_LENTGH);

fill_field(stud->firstName, firstname, fNameSize, MAX_FNAME_LENGTH);
fill_field(stud->lastName, lastName, lNameSize, MAX_LNAME_LENGTH);
fill_field(stud->cnp, CNP, cnpSize, MAX_CNP_LENGTH);
fill_field(stud->studies, studies, studiesSize, MAX_YEAR_ID_LENTGH);
stud->year = rand_year();

free(firstname);
free(lastName);
free(CNP);
free(studies);


void fill_field(char data[], char *fill, int size, int max_size)

for (int i = 0; i < size; i++)

data[i] = fill[i];


for (int i = size; i < max_size; i++)

data[i] = '*';



void print_field(char data[], int size, char *field_label)

printf(" %s: ", field_label);
for (int i = 0; i < size; i++)

char character = data[i];
if (character == '*')

break;


printf("%c", character);

printf("n");


char *rand_string(char *str, size_t size)

const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJK";
if (size)

--size;
for (size_t n = 0; n < size; n++)

int key = rand() % (int)(sizeof charset - 1);
str[n] = charset[key];

str[size] = '';

return str;


char *rand_string_alloc(size_t size)

char *s = malloc(size + 1);
if (s)

rand_string(s, size);

return s;


int rand_year()

return rand() % MAX_YEARS;


void print_stud(Student stud)

print_field(stud.firstName, MAX_FNAME_LENGTH, FNAME_LABEL);
print_field(stud.lastName, MAX_LNAME_LENGTH, LNAME_LABEL);
print_field(stud.cnp, MAX_CNP_LENGTH, CNP_LABEL);
print_field(stud.studies, MAX_YEAR_ID_LENTGH, STUDIES_LABEL);


Student *search_stud(char *cnp, Student students[], int list_size)

Student *current = NULL;

for (int i = 0; i < list_size; i++)

*current = students[i];
if (is_a_match(current->cnp, cnp))

return current;



return NULL;


int is_a_match(char lvalue[], char *rvalue)

for (int i = 0; i < MAX_CNP_LENGTH; i++)


return TRUE;


void print_list(Student students[], int size, int rank)

for (int i = 0; i < size; i++)

print_stud(students[i]);
printf("n");




Thanks!







c struct mpich






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 17 at 13:23









CyberFoxCyberFox

879




879







  • 1





    if (left == '0' || right == '0' || left != right) You want 0 as a filler, instead of * ? [also: the condition looks wrong, you probably want to allow both sides to be 0]

    – wildplasser
    Mar 17 at 14:57












  • You are right, sir. What about the loss of data after transferring ?

    – CyberFox
    Mar 17 at 18:56












  • 1





    if (left == '0' || right == '0' || left != right) You want 0 as a filler, instead of * ? [also: the condition looks wrong, you probably want to allow both sides to be 0]

    – wildplasser
    Mar 17 at 14:57












  • You are right, sir. What about the loss of data after transferring ?

    – CyberFox
    Mar 17 at 18:56







1




1





if (left == '0' || right == '0' || left != right) You want 0 as a filler, instead of * ? [also: the condition looks wrong, you probably want to allow both sides to be 0]

– wildplasser
Mar 17 at 14:57






if (left == '0' || right == '0' || left != right) You want 0 as a filler, instead of * ? [also: the condition looks wrong, you probably want to allow both sides to be 0]

– wildplasser
Mar 17 at 14:57














You are right, sir. What about the loss of data after transferring ?

– CyberFox
Mar 17 at 18:56





You are right, sir. What about the loss of data after transferring ?

– CyberFox
Mar 17 at 18:56












1 Answer
1






active

oldest

votes


















0














I have found the problem. It was an allocation error, effectively allocating memory for a string of size + 1 although it was indented for only for size size in rand_string_alloc. Also, the entire method fill_field can be replaced with strncpy(data, fill, max_size)






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55207538%2fstructs-manipulation-via-mpi-send-and-mpi-recv-in-c%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    I have found the problem. It was an allocation error, effectively allocating memory for a string of size + 1 although it was indented for only for size size in rand_string_alloc. Also, the entire method fill_field can be replaced with strncpy(data, fill, max_size)






    share|improve this answer



























      0














      I have found the problem. It was an allocation error, effectively allocating memory for a string of size + 1 although it was indented for only for size size in rand_string_alloc. Also, the entire method fill_field can be replaced with strncpy(data, fill, max_size)






      share|improve this answer

























        0












        0








        0







        I have found the problem. It was an allocation error, effectively allocating memory for a string of size + 1 although it was indented for only for size size in rand_string_alloc. Also, the entire method fill_field can be replaced with strncpy(data, fill, max_size)






        share|improve this answer













        I have found the problem. It was an allocation error, effectively allocating memory for a string of size + 1 although it was indented for only for size size in rand_string_alloc. Also, the entire method fill_field can be replaced with strncpy(data, fill, max_size)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 24 at 12:01









        CyberFoxCyberFox

        879




        879





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55207538%2fstructs-manipulation-via-mpi-send-and-mpi-recv-in-c%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Obelisk of Theodosius Contents History Description Notes Bibliography Further reading External links Navigation menuAge of spirituality : late antique and early Christian art, third to seventh centuryOver 60 picturesObelisks of the World41°00′21.24″N 28°58′31.43″E / 41.0059000°N 28.9753972°E / 41.0059000; 28.97539727724550-7235741376235741376

            밀양 대씨 역사 각주 함께 보기 둘러보기 메뉴밀양 대씨

            1973년 목차 사건 문화 탄생 사망 노벨상 달력 둘러보기 메뉴