-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatrix.c
130 lines (124 loc) · 3.31 KB
/
matrix.c
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
#include <stdlib.h>
#include <string.h>
#include "matrix.h"
matrix_p matrix_construct(int width, int depth){
matrix_p matrix = malloc(sizeof(matrix_t)+sizeof(Real*)*width + sizeof(Real)*depth);
for ( int i = 0 ; i < matrix -> width ; ++i){
matrix -> vals [i] = (Real*)&(matrix->vals) + 1 +i*width*sizeof(Real);
}
return matrix;
}
void matrix_delete(matrix_p old){
free( old );
return;
}
Real * matrix_sort(matrix_p old){
Real * sorted = malloc( sizeof(Real)*old -> depth * old-> width);
Real * ptr = sorted;
int stride;
int offset = 0;
for ( int j = 0 ; j < old -> depth ; ++j){
stride = old -> depth/nprocs;
stride += (j < old->depth / nprocs ) ? 1 : 0 ;
for ( int i = 0 ; i < old -> width ; ++i ){
memcpy( ptr , &(old -> vals[i][0])+offset, stride*sizeof(Real));
ptr += stride;
}
offset+=stride;
}
return sorted;
}
matrix_p matrix_unsort(Real * data){
int width = problemsize / nprocs + ((problemsize %nprocs < myrank)?1: 0);
matrix_p matrix = matrix_construct( width , problemsize);
for ( int i = 0 ; i < width ; ++i){
for ( int j = 0 ; j < problemsize ; ++j){
matrix -> vals[i][j] = data[i*width + j];
}
}
free(data);
return matrix;
}
int* create_senddispl() {
int * sizes = malloc( sizeof( Real ) * nprocs );
sizes[0] = 0;
{
int i;
int block;
block = problemsize / nprocs +1;
for (i = 1 ; i < problemsize %nprocs ; i++) {
sizes[i] = sizes[i-1]+block;
}
block = problemsize / nprocs;
for ( ; i < nprocs ; ++i) {
sizes[i] = sizes[i-1]+block;
}
}
return sizes;
}
int* c_sendcounts() {
int * sizes = malloc( sizeof( Real ) * nprocs );
{
int i;
int block;
block = problemsize / nprocs +1;
for (i = 0 ; i < problemsize %nprocs ; i++) {
sizes[i] = block;
}
block = problemsize / nprocs;
for ( ; i < nprocs ; ++i) {
sizes[i] = block;
}
}
return sizes;
}
comm_helper_p create_comm_list(matrix_p data){
comm_helper_p comms = malloc(sizeof(comm_helper_t));
comms -> sendcounts = c_sendcounts();
comms -> data= matrix_sort(data);
comms -> senddispl= create_senddispl();
comms -> recvdispl = c_recvdispl();
comms -> recvcounts = c_receivecounts();
return comms;
}
void free_comm_list(comm_helper_p a){
free( a ->sendcounts);
free( a ->senddispl);
free( a ->recvcounts);
free( a ->recvdispl);
free( a ->data);
free(a);
return;
}
Real *sendarr( comm_helper_p a){
int width = problemsize / nprocs + ((problemsize %nprocs < myrank)?1: 0);
int depth = problemsize;
int recvsize = width * depth;
Real *recvbuf = malloc(sizeof(Real)*recvsize);
MPI_Alltoallv( a -> data ,a -> senddispl, a -> senddispl, MPI_DOUBLE, recvbuf, a->recvcounts, a->recvdispl , MPI_DOUBLE, world_com);
return recvbuf;
}
int * c_receivecounts(){
int * recv = malloc(sizeof(int)*nprocs);
int recvsize = problemsize / nprocs +( ( problemsize % nprocs) >= myrank) ? 1:0;
for (int *i = recv ; i < recv + nprocs ; ++i){
*i = recvsize;
}
return recv;
}
int *c_recvdispl(){
int * recv = malloc(sizeof(int)*nprocs);
int recvsize = problemsize / nprocs +( ( problemsize % nprocs) >= myrank) ? 1:0;
for (int i = 0 ; i < nprocs ; ++i){
recv[i] = i*recvsize;
}
return recv;
}
matrix_p transpose(matrix_p old){
comm_helper_p com = create_comm_list(old);
Real * received = sendarr(com);
matrix_p new = matrix_unsort(received);
free(received);
free_comm_list(com);
return new;
}