FIFO in While loop stucks and waits for read - c

Server sends its PID to client, client gets and sends SIGUSR1 signal in a loop, so i have handler for that in server code. In theory it needs to get signal and create some random matrix to client back.Client receives Server PID but it never sends matrix to client for some reason. It waits and insert blinking forever.I assume somehow they dont connect to each other but why? I tried to sending a matrix and it did just fine.
client.c
int main()
{
int n=2;
pid_t pid=1;
int i,j;
double matrix[20][20];
char *myfifo2 = "/tmp/kek_fifo";
int server_to_client;
char *myfifo3 = "/tmp/fifor_fifo";
int fifor;
int forke=1;
char str[BUFSIZ];
fifor = open(myfifo3, O_RDONLY);
read(fifor,&pid,sizeof(pid));
printf("pid %d\n",pid);
close(fifor);
unlink(myfifo3);
while(1){
printf("no\n");
server_to_client = open(myfifo2, O_RDONLY);
read(server_to_client,matrix,sizeof(matrix));
close(server_to_client);
printf("yes\n");
forke=fork();
if(forke){
printf("forke buyuktur >= parent olmali %d \n",forke);
for(i = 0; i < 2*n; i++){
for(j = 0; j < 2*n; j++){
printf("%2f ",matrix[i][j]);
}
printf("\n");
}
wait(0); //parent child bekliyo
}
else{
printf("forke =0 yani child %d \n",forke);
exit(0);
}
//sleep(5);
kill(pid,SIGUSR1);
}
return 0;
}
server.c
void actionHandler(int signum);
void matrix_init(double m[20][20],int n);
void randome(double myPointer[20][20],int n);
static int signalcheck=0;
int main()
{
int i,j;
int n=2; //argv olacak
pid_t pide=getpid();
printf("pide is %d \n",pide);
struct sigaction action;
action.sa_handler=actionHandler;
action.sa_flags = 0;
int client_to_server;
char *myfifo = "/tmp/client_to_server_fifo";
int forke;
int server_to_client;
char *myfifo2 = "/tmp/kek_fifo";
char *myfifo3 = "/tmp/fifor_fifo";
int fifor;
char buf[BUFSIZ];
double M[20][20];
matrix_init(M,n);
/* create the FIFO (named pipe) */
// mkfifo(myfifo, 0666);
mkfifo(myfifo2, 0666);
mkfifo(myfifo3,0666);
fifor =open(myfifo3,O_WRONLY);
write(fifor,&pide,sizeof(pide));
close(fifor);
unlink(myfifo3);
if ((sigemptyset(&action.sa_mask) == -1) ||
(sigaction(SIGUSR1, &action, NULL) == -1))
perror("Failed to install SIGURS1 signal handler");
/* open, read, and display the message from the FIFO */
// client_to_server = open(myfifo, O_RDONLY);
printf("Server ON.\n");
while (1)
{
if(signalcheck==1){
forke=fork();
if(forke==0){
while(1){
randome(M,n);
server_to_client = open(myfifo2, O_WRONLY);
write(server_to_client,M,sizeof(M));
close(server_to_client);
unlink(myfifo2);
printf("matrix yarat\n");
//sleep(5);
//create matrix send to fifo
}
}
/*
read(client_to_server, buf, BUFSIZ);
if (strcmp("exit",buf)==0)
{
printf("Server OFF.\n");
break;
}
else if (strcmp("",buf)!=0)
{
printf("Received: %s\n", buf);
printf("Sending back...\n");
write(server_to_client,buf,BUFSIZ);
}
clean buf from any data
memset(buf, 0, sizeof(buf)); */
//sleep(5);
}
signalcheck=0;
}
// close(client_to_server);
// close(server_to_client);
// unlink(myfifo);
// unlink(myfifo2);
return 0;
}
void actionHandler(int signum)
{
signalcheck=1;
if(signum==SIGUSR1)
printf("i catched signal code from client i guess \n");
/* Signal handler code goes here. */
}
void matrix_init(double m[20][20],int z){
/*
this function purpose to create
2Nx2N int matrix n being int z
then initing this matrix to 0 before random numbers take in part
it has error checks .
blah!*/
int i, j,n=z;
double **k = (double **) malloc(n * sizeof(double*));
if(m == NULL){
printf("Error full matrix not created");
exit(-1);
}
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
m[i][j] = 0;
}
}
}
void randome(double myPointer[20][20],int n){
int i,j;
int r;
srand ( time(NULL) );
for(i=0;i<n*2;i++)
for(j=0;j<n*2;j++)
myPointer[i][j]=rand()%10;
}

I think one reason your question got ignored for so long is that the code is that there's quite a lot of code and a fair amount of comments that are irrelevant bits of code, and the layout isn't all tidy. These add up to "it is hard work to read the code", which puts people off actually reading it.
This code seems to work OK on a MacBook Pro running macOS Sierra 10.12.4 using GCC 6.3.0 to compile.
Client code
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
int n = 2;
pid_t pid = 1;
int i, j;
double matrix[20][20];
char *myfifo2 = "/tmp/kek_fifo";
int server_to_client;
char *myfifo3 = "/tmp/fifor_fifo";
int fifor;
int forke = 1;
fifor = open(myfifo3, O_RDONLY);
read(fifor, &pid, sizeof(pid));
printf("pid %d\n", pid);
close(fifor);
unlink(myfifo3);
for (int loopnum = 0; loopnum < 20; loopnum++)
{
printf("begin loop %d\n", loopnum);
kill(pid, SIGUSR1);
printf("signal sent\n");
server_to_client = open(myfifo2, O_RDONLY);
printf("Open done\n");
read(server_to_client, matrix, sizeof(matrix));
printf("read done\n");
close(server_to_client);
printf("close done\n");
forke = fork();
if (forke)
{
printf("forke buyuktur >= parent olmali %d\n", forke);
for (i = 0; i < 2 * n; i++)
{
for (j = 0; j < 2 * n; j++)
{
printf("%2f ", matrix[i][j]);
}
printf("\n");
}
wait(0); // parent child bekliyo
}
else
{
printf("forke = 0 yani child %d\n", forke);
exit(loopnum);
}
}
return 0;
}
Server code
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
void actionHandler(int signum);
void matrix_init(double m[20][20], int n);
void randome(double myPointer[20][20], int n);
static volatile sig_atomic_t signalcheck = 0;
int main(void)
{
int n = 2; // argv olacak
pid_t pide = getpid();
printf("pide is %d\n", pide);
struct sigaction action;
action.sa_handler = actionHandler;
action.sa_flags = 0;
int forke;
int server_to_client;
char *myfifo2 = "/tmp/kek_fifo";
char *myfifo3 = "/tmp/fifor_fifo";
int fifor;
double M[20][20];
matrix_init(M, n);
srand(time(NULL));
if ((sigemptyset(&action.sa_mask) == -1) ||
(sigaction(SIGUSR1, &action, NULL) == -1))
{
perror("Failed to install SIGURS1 signal handler");
return 1;
}
/* create the FIFO (named pipe) */
mkfifo(myfifo2, 0666);
mkfifo(myfifo3, 0666);
fifor = open(myfifo3, O_WRONLY);
write(fifor, &pide, sizeof(pide));
close(fifor);
unlink(myfifo3);
printf("Server ON (%d).\n", signalcheck);
while (1)
{
if (signalcheck == 1)
{
printf("Signal received:\n");
signalcheck = 0;
randome(M, n);
forke = fork();
if (forke == 0)
{
server_to_client = open(myfifo2, O_WRONLY);
write(server_to_client, M, sizeof(M));
close(server_to_client);
printf("matrix yarat %d\n", (int)getpid());
exit(0);
}
else
{
int corpse;
int status;
while ((corpse = wait(&status)) != -1)
printf("PID %d exited with status 0x%.4x\n", corpse, status);
}
}
}
return 0;
}
void actionHandler(int signum)
{
static char msg[] = "I caught a signal from the client\n";
signalcheck = 1;
if (signum == SIGUSR1)
{
int nb = write(1, msg, sizeof(msg)-1);
assert(nb == sizeof(msg)-1);
}
}
void matrix_init(double m[20][20], int z)
{
for (int i = 0; i < z; i++)
{
for (int j = 0; j < z; j++)
m[i][j] = 0;
}
}
void randome(double myPointer[20][20], int n)
{
int i, j;
for (i = 0; i < n * 2; i++)
{
for (j = 0; j < n * 2; j++)
myPointer[i][j] = rand() % 10;
}
}
Server output
pide is 474
Server ON (0).
I caught a signal from the client
Signal received:
matrix yarat 476
PID 476 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 478
PID 478 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 481
PID 481 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 483
PID 483 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 485
PID 485 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 488
PID 488 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 491
PID 491 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 493
PID 493 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 496
PID 496 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 499
PID 499 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 501
PID 501 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 503
PID 503 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 506
PID 506 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 512
PID 512 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 514
PID 514 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 516
PID 516 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 518
PID 518 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 521
PID 521 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 523
PID 523 exited with status 0x0000
I caught a signal from the client
Signal received:
matrix yarat 525
PID 525 exited with status 0x0000
^C
The ^C is where I interrupted the server in its terminal window. The program was spinning in a busy loop, using 99.5% of a CPU.
Client output
pid 474
begin loop 0
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 477
5.000000 6.000000 0.000000 9.000000
2.000000 1.000000 4.000000 7.000000
0.000000 8.000000 2.000000 5.000000
7.000000 8.000000 3.000000 2.000000
forke = 0 yani child 0
begin loop 1
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 480
0.000000 7.000000 0.000000 3.000000
0.000000 7.000000 2.000000 9.000000
2.000000 4.000000 5.000000 5.000000
9.000000 7.000000 3.000000 4.000000
forke = 0 yani child 0
begin loop 2
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 482
8.000000 6.000000 1.000000 4.000000
9.000000 2.000000 3.000000 9.000000
2.000000 3.000000 8.000000 0.000000
7.000000 8.000000 9.000000 8.000000
forke = 0 yani child 0
begin loop 3
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 484
1.000000 4.000000 2.000000 9.000000
5.000000 3.000000 5.000000 0.000000
5.000000 9.000000 7.000000 5.000000
3.000000 1.000000 7.000000 3.000000
forke = 0 yani child 0
begin loop 4
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 487
2.000000 3.000000 0.000000 4.000000
0.000000 2.000000 6.000000 8.000000
1.000000 8.000000 8.000000 7.000000
7.000000 4.000000 1.000000 4.000000
forke = 0 yani child 0
begin loop 5
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 489
6.000000 3.000000 4.000000 0.000000
5.000000 9.000000 2.000000 3.000000
9.000000 7.000000 5.000000 4.000000
5.000000 9.000000 1.000000 8.000000
forke = 0 yani child 0
begin loop 6
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 492
7.000000 1.000000 4.000000 6.000000
7.000000 1.000000 2.000000 4.000000
5.000000 1.000000 8.000000 6.000000
1.000000 9.000000 8.000000 6.000000
forke = 0 yani child 0
begin loop 7
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 495
0.000000 0.000000 5.000000 1.000000
6.000000 8.000000 3.000000 1.000000
8.000000 1.000000 6.000000 9.000000
7.000000 3.000000 1.000000 5.000000
forke = 0 yani child 0
begin loop 8
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 497
3.000000 0.000000 1.000000 8.000000
4.000000 4.000000 2.000000 3.000000
8.000000 9.000000 6.000000 3.000000
1.000000 3.000000 6.000000 3.000000
forke = 0 yani child 0
begin loop 9
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 500
4.000000 0.000000 9.000000 3.000000
1.000000 5.000000 1.000000 2.000000
3.000000 0.000000 5.000000 6.000000
4.000000 5.000000 9.000000 7.000000
forke = 0 yani child 0
begin loop 10
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 502
4.000000 9.000000 7.000000 6.000000
6.000000 4.000000 7.000000 1.000000
3.000000 5.000000 9.000000 0.000000
7.000000 9.000000 7.000000 9.000000
forke = 0 yani child 0
begin loop 11
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 504
3.000000 3.000000 0.000000 3.000000
7.000000 5.000000 8.000000 5.000000
6.000000 1.000000 3.000000 6.000000
8.000000 3.000000 3.000000 0.000000
forke = 0 yani child 0
begin loop 12
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 507
6.000000 5.000000 1.000000 8.000000
7.000000 3.000000 9.000000 7.000000
9.000000 4.000000 0.000000 5.000000
1.000000 6.000000 9.000000 3.000000
forke = 0 yani child 0
begin loop 13
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 513
6.000000 4.000000 6.000000 3.000000
5.000000 6.000000 6.000000 0.000000
2.000000 1.000000 5.000000 2.000000
7.000000 3.000000 9.000000 8.000000
forke = 0 yani child 0
begin loop 14
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 515
0.000000 3.000000 7.000000 8.000000
9.000000 1.000000 2.000000 4.000000
5.000000 7.000000 4.000000 8.000000
3.000000 1.000000 1.000000 6.000000
forke = 0 yani child 0
begin loop 15
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 517
0.000000 8.000000 9.000000 7.000000
7.000000 3.000000 3.000000 0.000000
4.000000 0.000000 8.000000 1.000000
5.000000 8.000000 4.000000 4.000000
forke = 0 yani child 0
begin loop 16
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 520
8.000000 3.000000 8.000000 8.000000
1.000000 7.000000 0.000000 3.000000
4.000000 2.000000 0.000000 3.000000
8.000000 4.000000 4.000000 8.000000
forke = 0 yani child 0
begin loop 17
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 522
9.000000 3.000000 9.000000 3.000000
3.000000 3.000000 2.000000 9.000000
9.000000 3.000000 6.000000 0.000000
8.000000 0.000000 8.000000 1.000000
forke = 0 yani child 0
begin loop 18
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 524
9.000000 1.000000 4.000000 3.000000
4.000000 8.000000 9.000000 2.000000
2.000000 5.000000 0.000000 6.000000
9.000000 0.000000 5.000000 7.000000
forke = 0 yani child 0
begin loop 19
signal sent
Open done
read done
close done
forke buyuktur >= parent olmali 526
2.000000 0.000000 5.000000 3.000000
1.000000 2.000000 1.000000 3.000000
3.000000 6.000000 5.000000 8.000000
7.000000 3.000000 2.000000 5.000000
forke = 0 yani child 0
Note that the client exited tidily after 20 loops; it should probably have been smaller.
Some of the changes
The code only calls srand() once
The code sets up the servers signal handler before messing with the FIFOs.
The code no longer deletes the FIFO in a loop.
The code no longer sets signalcheck to zero unless it was one. One problem seemed to be that the 'signalcheck` variable was zero whenever checked.
The code uses static volatile sig_atomic_t signalcheck.
The random matrix is generated before the fork() so that different results are seen.
The server cleans up dead children (zombies).
It really isn't clear why either the server or the child forks, but that was left more or less as found.
The signal handler doesn't use printf().
Improvements still needed
The code is far from perfect. There are multiple things that should be addressed, including:
Handling errors correctly (e.g. after fork() in server).
Mechanism to terminate server other than interrupt.
Detecting when client has stopped.
Not using signals to tell the server there is work.
Removing client forking.
Decide whether server really needs to fork.
Use configurable FIFO names.
Sort out matrix initialization better.
Etc.

Related

Two different outputs of the same array

I have a question about some odd behaviour with my program.
I have two arrays data and ind_array. Both arrays are initialized in main function. ind_array is filled with some values and data is filled with values using function loadData().
But output of the program depends on where I print values of data array. Before inputting values to ind_array or after.
Look at the first tree numbers of output.
Thanks in advance.
Code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define FILE_NAME "DataValues.csv"
#define NUM_ROWS 40
#define NUM_COLUMS 2
#define COMA " ,"
void loadData(double (*data)[2]){
//double data[NUM_ROWS][NUM_COLUMS];
FILE* data_file = fopen(FILE_NAME, "r");
char line[NUM_ROWS];
int i = 0;
while(fgets(line, sizeof(line), data_file)){
char* tok = strtok(line, COMA);
int j = 0;
while(tok != NULL){
char *ptr;
data[i][j] = atof(tok); //const char to double
tok = strtok(NULL, COMA);
j++;
}
i++;
}
}
int main(){
double data[NUM_ROWS][NUM_COLUMS];
double ind_array[0][5];
loadData(data);
for(int j = 0; j < NUM_ROWS; j++){
printf(" %f\n", data[j][0]);
}
printf("\n");
ind_array[0][0] = 2;
ind_array[0][1] = 5;
ind_array[0][2] = 0;
ind_array[0][3] = 3;
ind_array[0][4] = 0;
for(int j = 0; j < NUM_ROWS; j++){
printf(" %f\n", data[j][0]);
}
return 0;
}
Output
1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000
9.000000 10.000000 11.000000 12.000000 13.000000 14.000000 15.000000
16.000000 17.000000 18.000000 19.000000 20.000000 21.000000 22.000000
23.000000 24.00000025.000000 26.000000 27.000000 28.000000 29.000000
30.000000 31.000000 32.000000 33.000000 34.000000 35.000000 36.000000
37.000000 38.000000 39.000000 40.000000
2.000000 0.000000 0.000000 4.000000 5.000000 6.000000 7.000000
8.000000 9.000000 10.000000 11.000000 12.000000 13.000000 14.000000
15.000000 16.000000 17.000000 18.000000 19.000000 20.000000 21.000000
22.000000 23.000000 24.000000 25.000000 26.000000 27.000000 28.000000
29.000000 30.000000 31.000000 32.000000 33.000000 34.000000 35.000000
36.000000 37.000000 38.000000 39.000000 40.000000
Well you are declaring a 0 X 5 array on this line:
double ind_array[0][5];
The total amount of cells in that array is 0 x 5 = 0. You are printing uninitialized memory which is undefined behaviour, switch the 0 for 1.

Getting column data from file stream in C

I have a file which is written with a column of data (For example, "250\n 249\n...". Actually, there are 250 rows data with at most 15 digits in a row). I wish to get data from the different files and average them. However, I have no idea how could I get such a large amount of data with single column. I tried the following:
char str[80];\newline
FILE * abc;
abc=fopen("bromo.dat", "r");
fgets(str, 80, msd);
atof(str);
What I got was only the data from the first row. How could get the rest of the data?
You can use strtok to split the number in each line by space character. Then use the atof funcition as you used in your code to convert string to float number.
You should use 2D array to store all numbers in the file, and use another array to store the number in each line:
float number[250][15]; // maximum 250 line with at most 15 digits in each line
int number_each_line[250] = {0}; // the number of digits in each line
The complete program for test:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char str[80];
float number[250][15];
int number_each_line[250] = {0};
FILE * fp;
fp =fopen("bromo.dat", "r");
if (!fp) {
return -1;
}
int i = 0;
while(fgets(str, 80, fp) && i < 250) {
int j = 0;
char *token = strtok(str, " ");
while(token != NULL) {
number[i][j] = atof(token);
j++;
token = strtok(NULL, " ");
}
number_each_line[i] = j;
i++;
}
// print first 10 lines in file
for(int k = 0; k < 10; k++) {
for(int j = 0; j < number_each_line[k]; j++) {
printf("%f ", number[k][j]);
}
printf("\n");
}
fclose(fp);
}
The output of test:
bromo.dat:
1.2 1 4 5
2.1 2 6 7 8
3.5 3 2 3 5.3
2.1 4 6 7 8
2.1 5 6 7 8
2.1 6 6 7 8
2.1 8 6 7 8
2.1 9 6 7 8
2.1 10 6 7 8
./test
1.200000 1.000000 4.000000 5.000000
2.100000 2.000000 6.000000 7.000000 8.000000
3.500000 3.000000 2.000000 3.000000 5.300000
2.100000 4.000000 6.000000 7.000000 8.000000
2.100000 5.000000 6.000000 7.000000 8.000000
2.100000 6.000000 6.000000 7.000000 8.000000
2.100000 8.000000 6.000000 7.000000 8.000000
2.100000 9.000000 6.000000 7.000000 8.000000
2.100000 10.000000 6.000000 7.000000 8.000000

SSE Matrix Multiplication NxN. Why is this error

I am beginner using SSE instructions, and I try to implement MMM. So, I implemented MMM using matriz 2by2, now I want to implement MMM using matrix NXN
#include <emmintrin.h>
#include <stdio.h>
#include <stdlib.h>
void simd_2x2(int lda, double *A, double *B, double *C)
{
__m128d a, b1, c1;
for (int k = 0; k < lda; k++) {
//printf("%f\n",C[k * lda]);
c1 = _mm_loadu_pd(C + k * lda); //load unaligned block in C
//c2 = _mm_loadu_pd(C + 1 * lda);
for (int i = 0; i < lda; ++i) {
a = _mm_load_pd(A + i * lda);//load aligned i-th column of A
b1 = _mm_load1_pd(B + i + k * lda); //load i-th row of B
//b2 = _mm_load1_pd(B + i + 1 * lda);
c1 = _mm_add_pd(c1, _mm_mul_pd(a, b1)); //rank-1 update
//c2 = _mm_add_pd(c2, _mm_mul_pd(a, b2));
}
_mm_storeu_pd(C + k * lda, c1); //store unaligned block in C
//_mm_storeu_pd(C + 1 * lda, c2);
}
}
int main() {
int n = 2;
double *buf = NULL;
buf = (double *)malloc(3 * n * n * sizeof(double));
double *A = buf + 0;
double *B = A + n * n;
double *C = B + n * n;
simd_2x2(n, A, B, C);
return 0;
}
When n=2 everything work fine:
A = 4.000000 3.000000
2.000000 4.000000
B = 1.000000 3.000000
2.000000 4.000000
C = 0.000000 0.000000
0.000000 0.000000
C = C + A * B = 10.000000 24.000000
10.000000 22.000000
but if n=4 I get the next:
A = 4.000000 0.000000 1.000000 4.000000
2.000000 1.000000 4.000000 0.000000
3.000000 1.000000 2.000000 1.000000
4.000000 1.000000 3.000000 1.000000
B = 1.000000 5.000000 9.000000 13.000000
2.000000 6.000000 10.000000 14.000000
3.000000 7.000000 11.000000 15.000000
4.000000 8.000000 12.000000 16.000000
C = 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
C = C + A * B = 23.000000 59.000000 95.000000 131.000000
16.000000 44.000000 72.000000 100.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
The last two rows are not calculated, why is this? Can someone help me?
I have almost 5 days reading about SSE but I can not fully understand and neither solve this problem.

How to use MPI_Scatterv and displacement in C

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
int size;
typedef struct process_struct
{
int start;
int end;
} process_tag;
int main(int argc, char **argv)
{ //array size
size=11;
int rc, myrank, world_size;
rc = MPI_Init(&argc, &argv);
if (rc != MPI_SUCCESS) {
printf ("Error starting MPI program\n");
MPI_Abort(MPI_COMM_WORLD, rc);
}
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int i, j;
int process_num=4;
int processs_i;
int start, end;
double **a = malloc(size*sizeof(double*));
if (a == NULL) { printf("malloc failed\n"); return 1; }
for (i = 0; i < size; i++) {
a[i] = malloc(size*sizeof(double));
if (a[i] == NULL) { printf("malloc failed\n"); return 1; }
}
//initialize array "a"
a=ini(a);
if(myrank == 0 ) {
printarray(a,size);
}
// store starting row and ending row for each process
process_tag process[process_num];
int chunk_size = (size - 2 ) / process_num ;
int remain = (size - 2) - chunk_size * process_num ;
start = 1;
end = 1;
int process_i =0;
while(start < size) {
start = end;
end = start + chunk_size;
if (remain > 0) {
end++;
remain--;
}
process[process_i].start = start;
process[process_i].end = end;
process_i++;
}
int send_count[process_num];
for (process_i = 0; process_i < process_num; process_i++) {
send_count[process_i] = process[process_i].end - process[process_i].start;
}
int receive_count = send_count[myrank];
int *displs = malloc(sizeof(int)*size);
int sum =1;
for (i = 0; i < process_num; i++) {
displs[i] = sum;
sum += send_count[i];
}
double **blocal;
blocal = malloc(receive_count*sizeof(double*));
if (blocal == NULL)
{ printf("malloc failed\n"); return 1; }
for (i = 0; i < size; i++) {
blocal[i] = malloc(size*sizeof(double));
if (blocal[i] == NULL)
{ printf("malloc failed\n"); return 1; }
}
MPI_Scatterv(a, send_count, displs, MPI_DOUBLE, blocal,
receive_count, MPI_DOUBLE, 0, MPI_COMM_WORLD);
printarray(blocal,receive_count);
printf("from rank %d \n", myrank);
}
output is:
array a is
1.000000 3.700000 2.000000 6.000000 5.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 8.200000 3.000000 7.000000 3.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 6.000000 9.000000 1.000000 6.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 5.000000 1.000000 3.000000 4.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 4.500000 6.000000 4.000000 7.600000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
1.000000 1.000000 1.000000 1.000000 1.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000
blocal from rank 0
1.000000 8.200000 3.000000 7.000000 3.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 6.000000 9.000000 1.000000 6.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
1.000000 5.000000 1.000000 3.000000 4.300000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000
blocal from rank 1
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
blocal from rank 2
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
blocal from rank 3
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
I want to scatter the elements of 11*11 sendbuf array "a" to arrays "blocal" (receivebuf).
What I want to achieve is that blocal at process 0 get row 1 to 3, process 1 get row 4 to 5, process 2 get row 6 to 7, and process 3 get row 8 to 9. Row 0 and row 10 are ignored.
However in my output only process 0 got the sub-array from array "a".
Could anybody spot any error in my code? I think the problem might be the displacement.

Merge sorting a struct

#include<stdio.h>
#include<stdlib.h>
typedef struct points{
float axis[2];
int id;
}Points;
typedef enum{
SortById,
SortByXAxis
}SortType;
Points* fill_Array(char* filename, int* length);
void Print_set(Points* set, int number_of_points);
void mergesort(Points* set, int low, int high, int number_of_points,SortType sort);
void merge(Points* set, int low, int middle, int high, int number_of_points,SortType sort);
int main(int argc, char* argv[])
{
int length;
Points *array;
array=fill_Array(argv[1],&length);
Print_set(array,length);
printf("\n\n");
mergesort(array,0,length,length,SortById);
Print_set(array,length);
return 0;
}
Points* fill_Array(char* filename,int* length)
{
int i;
Points* array;
FILE* file=fopen(filename,"r");
if(file == NULL)
{
return NULL;
}
fscanf(file,"%d",length);
array=malloc(sizeof(Points)* *length);
for(i = 0; i < *length; i++)
{
fscanf(file,"%d %f %f", &(array+i)->id,&(array+i)->axis[0],&(array+i)->axis[1]);
}
fclose(file);
return array;
}
void Print_set(Points *set, int number_of_points)
{
int i;
for(i = 0; i < number_of_points; i++)
{
printf("%d %f %f\n",(set+i)->id,(set+i)->axis[0],(set+i)->axis[1]);
}
}
void mergesort(Points* set,int low,int high,int number_of_points, SortType sort)
{
int mid1;
if((high-low)>=1)
{
mid1 = (low+high)/2;
mergesort(set, low, mid1, number_of_points, sort);
mergesort(set, mid1+1, high, number_of_points, sort);
merge(set, low, mid1, high, number_of_points, sort);
}
}
void merge(Points* set, int low, int middle, int high, int number_of_points, SortType sort)
{
int leftIndex=low;
int rightIndex=middle;
int combinedIndex = low;
Points tempArray[number_of_points];
int i;
while(leftIndex <= middle && rightIndex<= high)
{
if(set[leftIndex].id <= set[rightIndex].id)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
else
tempArray[combinedIndex++] = set[rightIndex++];
}
if(leftIndex == middle+1)
{
while(rightIndex <= high)
{
tempArray[combinedIndex++] = set[rightIndex++];
}
}
else
{
while(leftIndex <= middle)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
}
for( i = low; i < high; i++)
{
set[i] = tempArray[i];
}
}
I am trying to perform a merge sort on an input file using a custom merge sort function. The merge sort functions however are not working and print out down below, the first block being the actual input file printed out to make sure fscanf is reading in everything correctly and the second being the printing after the merge functions are run. The functions are duplicating some of the values and are not sorting them either and I cannot find the mistake in the code. Note that the enum will be used to sort either the ids or the first float values I am just trying to get the merge sort to work before I use it to sort either the ids or those values.
1 13.000000 7.000000
13 14.000000 6.000000
95 7.000000 13.000000
39 0.000000 20.000000
78 10.000000 10.000000
68 3.000000 17.000000
32 6.000000 14.000000
10 19.000000 1.000000
0 18.000000 2.000000
45 17.000000 3.000000
92 4.000000 16.000000
29 5.000000 15.000000
85 8.000000 12.000000
79 15.000000 5.000000
12 16.000000 4.000000
32 1.000000 19.000000
77 9.000000 11.000000
52 12.000000 8.000000
80 11.000000 9.000000
31 2.000000 18.000000
1 13.000000 7.000000
13 14.000000 6.000000
68 3.000000 17.000000
0 18.000000 2.000000
10 19.000000 1.000000
0 18.000000 2.000000
0 18.000000 2.000000
92 4.000000 16.000000
92 4.000000 16.000000
29 5.000000 15.000000
32 1.000000 19.000000
52 12.000000 8.000000
77 9.000000 11.000000
79 15.000000 5.000000
12 16.000000 4.000000
32 1.000000 19.000000
32 1.000000 19.000000
80 11.000000 9.000000
95 7.000000 13.000000
95 7.000000 13.000000
You appear to have gotten confused about the meaning of your boundary indices. Consider the initial call to function mergesort():
mergesort(array,0,length,length,SortById);
You pass the same value for arguments high and number_of_points, which is fine, but it implies that high represents an exclusive upper bound on the indices of the sort range. The mergesort() implementation, however, seems geared for argument high to represent an inclusive bound.
The confusion continues with your merge() function, which is probably the main culprit here. By taking the passed midpoint value as the start index of the right sub-array, it seems to be expecting the midpoint as an exclusive upper bound of the left sub-array, but the current mergesort() implementation passes an inclusive upper bound. On the other hand, some of the index comparisons performed by merge() are appropriate only if middle is an inclusive upper bound of the subarray.
In short, you have a muddle. The basic outline of the algorithm looks fine, but you need to decide (and document for yourself) what your function parameters represent, and reconcile your implementation details with that. Were I you, I would adopt half-open representation for all intervals, so that lower bounds are always inclusive, and upper bounds always exclusive. Among other things, that has the advantage that each midpoint value can be interpreted equally correctly as the (exclusive) upper bound of the left half of its subarray or as the (inclusive) lower bound of the right half.
void mergesort(Points* set,int low,int high,int number_of_points, SortType sort)
{
int mid1;
if((high-low)>1)
{
mid1 = (low+high)/2;
mergesort(set, low, mid1, number_of_points, sort);
mergesort(set, mid1, high, number_of_points, sort);
merge(set, low, mid1, high, number_of_points, sort);
}
}
void merge(Points* set, int low, int middle, int high, int number_of_points, SortType sort)
{
int leftIndex=low;
int rightIndex=middle;
int combinedIndex = low;
Points tempArray[number_of_points];
int i;
while(leftIndex <= middle && rightIndex < high)
{
if(set[leftIndex].id <= set[rightIndex].id)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
else
tempArray[combinedIndex++] = set[rightIndex++];
}
if(leftIndex == middle+1)
{
while(rightIndex < high)
{
tempArray[combinedIndex++] = set[rightIndex++];
}
}
else
{
while(leftIndex < middle)
{
tempArray[combinedIndex++] = set[leftIndex++];
}
}
for( i = low; i < high; i++)
{
set[i] = tempArray[i];
}
}
0 18.000000 2.000000
1 13.000000 7.000000
10 19.000000 1.000000
0 18.000000 2.000000
12 16.000000 4.000000
13 14.000000 6.000000
29 5.000000 15.000000
31 2.000000 18.000000
32 6.000000 14.000000
32 1.000000 19.000000
39 0.000000 20.000000
39 0.000000 20.000000
52 12.000000 8.000000
31 2.000000 18.000000
68 3.000000 17.000000
77 9.000000 11.000000
78 10.000000 10.000000
12 16.000000 4.000000
79 15.000000 5.000000
85 8.000000 12.000000

Resources