16 struct matrix
*mat1
= NULL
;
17 struct matrix
*mat2
= NULL
;
18 struct matrix
*mat3
= NULL
;
20 /* function prototypes */
21 void allocmat(struct matrix
**mat
, int rows
, int cols
);
22 void freemat(struct matrix
**mat
);
23 void readmat(const char *path
, struct matrix
**mat
);
24 void printmat(const struct matrix
*mat
);
25 void *mulvect(void *arg
);
27 int main(int argc
, char *argv
[]) {
29 struct matrix_index
*v
;
30 unsigned int i
, j
, k
, numthreads
;
32 /* arguments validations */
34 fprintf(stderr
, "Incorrect num of args.\nUsage: ./matrixmul matfile1 matfile2\n");
38 /* read matrix data from files */
39 readmat(argv
[1], &mat1
);
40 readmat(argv
[2], &mat2
);
42 /* Is the multiplication feasible by definition? */
43 if (mat1
->cols
!= mat2
->rows
) {
44 fprintf(stderr
, "Matrices' dimensions size must satisfy (NxM)(MxK)=(NxK)\n");
48 /* allocate memory for the result */
49 allocmat(&mat3
, mat1
->rows
, mat2
->cols
);
51 /* How many threads do we need ?*/
52 numthreads
= mat1
->rows
* mat2
->cols
;
54 /* v[k] holds the (i, j) pair in the k-th computation */
55 v
= malloc(numthreads
* sizeof(struct matrix_index
));
57 /* allocate memory for the threads' ids */
58 tid
= malloc(numthreads
* sizeof(pthread_t
));
60 fprintf(stderr
, "Error allocating memory\n");
64 /* create the threads */
65 for (i
=0; i
<mat1
->rows
; i
++) {
66 for (j
=0; j
<mat2
->cols
; j
++) {
70 if (pthread_create(&tid
[k
], NULL
, mulvect
, (void *)&v
[k
])) {
71 fprintf(stderr
, "pthtrad_create() error\n");
77 /* make sure all threads are done */
78 for (i
=0; i
<numthreads
; i
++)
79 if (pthread_join(tid
[i
], NULL
)) {
80 fprintf(stderr
, "pthread_join() error\n");
84 /* print the result */
95 void allocmat(struct matrix
**mat
, int rows
, int cols
) {
98 *mat
= malloc(sizeof(struct matrix
));
100 fprintf(stderr
, "Error allocating memory\n");
107 (*mat
)->data
= malloc(rows
* sizeof(int *));
109 fprintf(stderr
, "Error allocating memory\n");
113 for (i
=0; i
<rows
; i
++) {
114 (*mat
)->data
[i
] = malloc(cols
* sizeof(int));
115 if (!(*mat
)->data
[i
]) {
116 fprintf(stderr
, "Error allocating memory\n");
122 void freemat(struct matrix
**mat
) {
125 for (i
=0; i
<(*mat
)->rows
; i
++) {
126 free((*mat
)->data
[i
]);
132 void readmat(const char *path
, struct matrix
**mat
) {
134 unsigned int i
, j
, rows
, cols
;
137 if (!(fp
= fopen(path
, "r"))) {
138 fprintf(stderr
, "Error opening file: %s\n", path
);
142 /* read matrix dimensions */
143 fscanf(fp
, "%u%u", &rows
, &cols
);
145 /* allocate memory for matrix */
146 allocmat(mat
, rows
, cols
);
148 /* read matrix elements */
149 for (i
=0; i
<(*mat
)->rows
; i
++) {
150 for (j
=0; j
<(*mat
)->cols
; j
++) {
151 fscanf(fp
, "%d", &(*mat
)->data
[i
][j
]);
160 void printmat(const struct matrix
*mat
) {
163 for (i
=0; i
<mat
->rows
; i
++) {
164 for (j
=0; j
<mat
->cols
; j
++) {
165 printf("%d ", mat
->data
[i
][j
]);
172 void *mulvect(void *arg
) {
173 unsigned int i
, row
, col
;
175 row
= *((int *)arg
+ 0);
176 col
= *((int *)arg
+ 1);
178 mat3
->data
[row
][col
] = 0;
179 for (i
=0; i
<mat1
->cols
; i
++)
180 mat3
->data
[row
][col
] += mat1
->data
[row
][i
] * mat2
->data
[i
][col
];