Basecode.c 4.37 KB
Newer Older
Iker Martín Álvarez's avatar
Iker Martín Álvarez committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mpi.h>

#define USE_DERIVED_DATATYPE 1

void PrintMPIError(int err, int my_rank) {
	int eclass, len;
	char estring[MPI_MAX_ERROR_STRING];

	MPI_Error_class(err, &eclass);
	MPI_Error_string(err, estring, &len);
	printf("P%d Error %d: %s\n", my_rank, eclass, estring);fflush(stdout);
}

void MakePacket(int *buffer1, double *buffer2, int elems, int my_rank, MPI_Datatype *new_type) {
	int k, err, lblq[2];
	MPI_Aint dspl[2];
	MPI_Datatype type[2];
		
	type[0] = MPI_INT   ; lblq[0] = elems ; MPI_Get_address(buffer1, &dspl[0]);
	type[1] = MPI_DOUBLE; lblq[1] = elems ; MPI_Get_address(buffer2, &dspl[1]);
	for (k=1; k>=0; k--) dspl[k] -= dspl[0]; 
	// Creation of the packet
	err = MPI_Type_create_struct (2, lblq, dspl, type, new_type);
	if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	err = MPI_Type_commit(new_type);
	if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
}

int main(int argc, char* argv[])
{
    MPI_Init(&argc, &argv);

    // Size of the default communicator
    int size, my_rank;
    int tag, elems, use_derived, err;
    MPI_Datatype new_type;
    tag = 210;
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int name_len;
    MPI_Get_processor_name(processor_name, &name_len);

    use_derived = USE_DERIVED_DATATYPE;
    // Get my rank and do the corresponding job
    switch(my_rank)
    {
        case 0:
        { 
	    printf("P%d at node %s\n", my_rank, processor_name);
	    elems = 752;
            int *buffer1 = (int*) malloc(elems * sizeof(int));
            double *buffer2 = (double*) malloc(elems * sizeof(double));

	    if(use_derived)
	    {
              MakePacket(buffer1, buffer2, elems, my_rank, &new_type);
              err = MPI_Send(buffer1, 1, new_type, 2, tag, MPI_COMM_WORLD);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	      sleep(1);
              err = MPI_Send(buffer1, 1, new_type, 1, tag, MPI_COMM_WORLD);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	      err = MPI_Type_free(&new_type);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	    } else 
	    {
              MPI_Send(buffer1, elems, MPI_INT, 2, tag, MPI_COMM_WORLD);
	      sleep(1);
              MPI_Send(buffer1, elems, MPI_INT, 1, tag, MPI_COMM_WORLD);
	    }
            break;
        }
        case 1: // This rank is in a different machine than rank 0
	    sleep(2);
        case 2: // This rank is in the same machine than rank 0
        {
            printf("P%d at node %s\n", my_rank, processor_name);

            // Retrieve information about the incoming message
            MPI_Status status;
            err = MPI_Probe(0, tag, MPI_COMM_WORLD, &status);
	    if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);

            // Get the number of elements in the message probed
            int count, tam_int, tam_double;
	    if(use_derived)
	    {
	      err = MPI_Get_count(&status, MPI_BYTE, &count);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	      err = MPI_Type_size(MPI_INT, &tam_int);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	      err = MPI_Type_size(MPI_DOUBLE, &tam_double);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	      elems = count / (tam_int + tam_double);
//	      elems = 752;
	    }
	    else
	    {
	      MPI_Get_count(&status, MPI_INT, &count);
	      elems=count;
	    }

	    printf("P%d: Total expected counts=%d elems=%d\n", my_rank, count, elems);
            // Allocate the buffer now that we know how many elements there are
            int* buffer1 = (int*) malloc(elems * sizeof(int));
            double *buffer2 = (double*) malloc(elems * sizeof(double));

	    // Receive the message
	    if(use_derived)
	    {
              MakePacket(buffer1, buffer2, elems, my_rank, &new_type);
              err = MPI_Recv(buffer1, 1, new_type, 0, tag, MPI_COMM_WORLD, &status);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	      err = MPI_Type_free(&new_type);
	      if (err != MPI_SUCCESS) PrintMPIError(err, my_rank);
	    }
	    else
	    { 
              MPI_Recv(buffer1, elems, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
	    }
            printf("P%d: received message with %d elements\n", my_rank, elems);
            break;
        }
	default:
	{
	    break;
	}
    }

    MPI_Finalize();
    return EXIT_SUCCESS;
}