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;
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
add a comment |
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
1
if (left == '0' || right == '0' || left != right)You want0as a filler, instead of*? [also: the condition looks wrong, you probably want to allow both sides to be0]
– wildplasser
Mar 17 at 14:57
You are right, sir. What about the loss of data after transferring ?
– CyberFox
Mar 17 at 18:56
add a comment |
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
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
c struct mpich
asked Mar 17 at 13:23
CyberFoxCyberFox
879
879
1
if (left == '0' || right == '0' || left != right)You want0as a filler, instead of*? [also: the condition looks wrong, you probably want to allow both sides to be0]
– wildplasser
Mar 17 at 14:57
You are right, sir. What about the loss of data after transferring ?
– CyberFox
Mar 17 at 18:56
add a comment |
1
if (left == '0' || right == '0' || left != right)You want0as a filler, instead of*? [also: the condition looks wrong, you probably want to allow both sides to be0]
– 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
add a comment |
1 Answer
1
active
oldest
votes
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)
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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)
add a comment |
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)
add a comment |
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)
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)
answered Mar 24 at 12:01
CyberFoxCyberFox
879
879
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
if (left == '0' || right == '0' || left != right)You want0as a filler, instead of*? [also: the condition looks wrong, you probably want to allow both sides to be0]– wildplasser
Mar 17 at 14:57
You are right, sir. What about the loss of data after transferring ?
– CyberFox
Mar 17 at 18:56