16 struct matrix
*mat1
= NULL
;
17 struct matrix
*mat2
= NULL
;
18 struct matrix
*mat3
= NULL
;
26 /* function prototypes */
27 mm_error
allocmat(struct matrix
**mat
, unsigned int rows
, unsigned int cols
);
28 void freemat(struct matrix
**mat
);
29 mm_error
readmat(const char *path
, struct matrix
**mat
);
30 void printmat(const struct matrix
*mat
);
31 void *mulvect(void *arg
);
32 void diep(const char *s
);
34 int main(int argc
, char *argv
[])
37 struct matrix_index
*v
;
38 unsigned int i
, j
, k
, numthreads
;
40 /* check argument count */
42 fprintf(stderr
, "Usage: %s matfile1 matfile2\n", argv
[0]);
46 /* read matrix data from files */
47 readmat(argv
[1], &mat1
);
48 readmat(argv
[2], &mat2
);
50 /* is the multiplication feasible by definition? */
51 if (mat1
->cols
!= mat2
->rows
) {
52 fprintf(stderr
, "Matrices' dimensions size must satisfy (NxM)(MxK)=(NxK)\n");
56 /* allocate memory for the result */
57 allocmat(&mat3
, mat1
->rows
, mat2
->cols
);
59 /* how many threads do we need ?*/
60 numthreads
= mat1
->rows
* mat2
->cols
;
62 /* v[k] holds the (i, j) pair in the k-th computation */
63 if ((v
= malloc(numthreads
* sizeof(struct matrix_index
))) == NULL
)
66 /* allocate memory for the threads' ids */
67 tid
= malloc(numthreads
* sizeof(pthread_t
));
69 fprintf(stderr
, "Error allocating memory\n");
73 /* create the threads */
74 for (i
= 0; i
< mat1
->rows
; i
++) {
75 for (j
= 0; j
< mat2
->cols
; j
++) {
79 if (pthread_create(&tid
[k
], NULL
, mulvect
, (void *)&v
[k
])) {
80 fprintf(stderr
, "pthtrad_create() error\n");
86 /* make sure all threads are done */
87 for (i
= 0; i
< numthreads
; i
++)
88 if (pthread_join(tid
[i
], NULL
)) {
89 fprintf(stderr
, "pthread_join() error\n");
93 /* print the result */
104 mm_error
allocmat(struct matrix
**mat
, unsigned int rows
, unsigned int cols
)
106 unsigned int i
, j
, mdepth
= 0;
108 *mat
= malloc(sizeof **mat
);
111 goto CLEANUP_AND_RETURN
;
118 (*mat
)->data
= malloc(rows
* sizeof(int *));
119 if ((*mat
)->data
== NULL
) {
121 goto CLEANUP_AND_RETURN
;
125 for (i
= 0; i
< rows
; i
++) {
126 (*mat
)->data
[i
] = malloc(cols
* sizeof(int));
127 if ((*mat
)->data
[i
] == NULL
) {
131 goto CLEANUP_AND_RETURN
;
134 return mm_error_none
;
139 for (j
= 0; j
< i
; j
++)
140 free((*mat
)->data
[j
]);
149 return mm_error_no_memory
;
152 void freemat(struct matrix
**mat
)
156 for (i
= 0; i
< (*mat
)->rows
; i
++) {
157 if ((*mat
)->data
[i
] != NULL
)
158 free((*mat
)->data
[i
]);
167 mm_error
readmat(const char *path
, struct matrix
**mat
)
170 unsigned int i
, j
, rows
, cols
;
173 if ((fp
= fopen(path
, "r")) == NULL
) {
174 fprintf(stderr
, "Error opening file: %s\n", path
);
178 /* read matrix dimensions */
179 fscanf(fp
, "%u%u", &rows
, &cols
);
181 /* allocate memory for matrix */
182 allocmat(mat
, rows
, cols
);
184 /* read matrix elements */
185 for (i
= 0; i
< (*mat
)->rows
; i
++) {
186 for (j
= 0; j
< (*mat
)->cols
; j
++) {
187 fscanf(fp
, "%d", &(*mat
)->data
[i
][j
]);
194 return mm_error_none
;
198 void printmat(const struct matrix
*mat
)
202 for (i
= 0; i
< mat
->rows
; i
++) {
203 for (j
= 0; j
< mat
->cols
; j
++) {
204 printf("%d ", mat
->data
[i
][j
]);
211 void *mulvect(void *arg
) {
212 unsigned int i
, row
, col
;
214 row
= *((int *)arg
+ 0);
215 col
= *((int *)arg
+ 1);
217 mat3
->data
[row
][col
] = 0;
218 for (i
=0; i
<mat1
->cols
; i
++)
219 mat3
->data
[row
][col
] += mat1
->data
[row
][i
] * mat2
->data
[i
][col
];
224 void diep(const char *s
)