Addition of a matrix using thread in c - c

The question is to add two matrix using thread,where a loop takes row element of 2 matrix and that thread creates thread to add the individual elements. Below is the code --
#include<stdio.h>
#include<pthread.h>
#include<error.h>
#include<stdlib.h>
#define r 2
#define c 3
struct mat{
int (*a)[r][c];
int (*b)[r][c];
int (*d)[r][c];
int m, n;
};
struct element{
int *a;
int *b;
int *d;
};
void* add_element(void* pelement){
struct element* e1 = pelement;
(*e1).d = (*e1).a + (*e1).b;
pthread_exit(NULL);
}
void* add_row(void* pmat){
struct mat *mat1 = pmat;
int i = 0, m = mat1->m, n = mat1->n;
for(i = 0; i < n; ++i){
pthread_t add_e;
struct element e1;
e1.a = (*mat1->a)[m][i];
e1.b = (*mat1->b)[m][i];
e1.d = (*mat1->d)[m][i];
if(pthread_create(&add_e, NULL, add_element, &e1) != 0){
perror("Unable to create thread\n");
exit(0);
}
(*mat1->d)[m][i] = e1.d;
pthread_join(add_e, NULL);
//(*(*mat1).d)[m][i] = (*(*mat1).a)[m][i] + (*(*mat1).b)[m][i];
}
pthread_exit(0);
}
int main()
{
int a[r][c] = {1, 2, 3, 4, 5, 6};
int b[r][c] = {1, 2, 3, 4, 5, 6};
int d[r][c] = {0, 0, 0, 0, 0, 0};
pthread_t add_mat[r];
struct mat mat1;
mat1.a = &a;
mat1.b = &b;
mat1.d = &d;
int i = 0;
for(i = 0; i < r; ++i){
mat1.m = i;
mat1.n = c;
if(pthread_create(&add_mat[i], NULL, add_row, &mat1) != 0){
perror("Unable to create thread\n");
exit(1);
}
pthread_join(add_mat[i], NULL);
}
for(i = 0; i < r; ++i){
int j = 0;
for(j = 0; j < c; ++j)
printf("%d ", d[i][j]);
printf("\n");
}
pthread_exit(NULL);
}
While executing, I am doing something wrong with the pointer. The error is like --
add_matrix.c: In function ‘add_element’:
add_matrix.c:20:20: error: invalid operands to binary + (have ‘int *’ and ‘int *’)
(*e1).d = (*e1).a + (*e1).b;
How can I handle the pointer in order to get the result?
Edit
I have solved it. Please ignore it.

Related

Multiple C threads not returning correct values

I am trying to multiply two matrices using a different thread for each member of the resultant matrix. I have this code:
struct data{
int p;
int linie[20];
int coloana[20];
};
void *func(void *args){
struct data *st = (struct data *) args;
int c = 0;
for(int k = 0; k < st->p; k++){
c += st->linie[k] * st->coloana[k];
}
char *rez = (char*) malloc(5);
sprintf(rez, "%d", c);
return rez;
}
int main(int argc, char *argv[]){
int n = 2;
int m = 2;
int A[2][2] = {{1, 2},
{4, 5}};
int B[2][2] = {{7, 3},
{7, 5}};
int C[n][m];
char *res[n * m];
char *rez[n * m];
pthread_t threads[n * m];
int count = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
struct data st;
st.p = 2;
for(int x = 0; x < st.p; x++){
st.linie[x] = A[i][x];
st.coloana[x] = B[x][j];
}
pthread_create(&threads[count], NULL, func, &st);
count++;
}
}
for(int i = 0; i < n * m; i++){
pthread_join(threads[i], (void**) &rez[i]);
printf("%d ", atoi(rez[i]));
}
return 0;
}
But the correct result is never put into rez[i]. For example I get output "63 37 37 37".
The code works perfectly if I don't choose to wait for every thread to finish, i.e. I put that pthread_join right after pthread_create in the nested for loop. What should I do?
Thanks for reading!
Your first threading problem is here:
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
struct data st;
st.p = 2;
for(int x = 0; x < st.p; x++){
st.linie[x] = A[i][x];
st.coloana[x] = B[x][j];
}
pthread_create(&threads[count], NULL, func, &st);
count++;
}
}
All the threads get passed a pointer to the same variable, &st, which goes out of scope after each call to pthread_create(). You need to ensure that each thread gets its own variable, and that the variable lasts until the thread exits.
To fix this, for example, you could try:
struct data st[n * m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
st[count].p = 2;
for (int x = 0; x < st[count].p; x++)
{
st[count].linie[x] = A[i][x];
st[count].coloana[x] = B[x][j];
}
int rc = pthread_create(&threads[count], NULL, func, &st[count]);
if (rc != 0)
…report pthread creation error…
count++;
}
}
This gives each thread its own struct data to work on, and the structure outlasts the pthread_join() loop.
I'm not completely that it is a good scheme to make one copy of the relevant parts of the two arrays for each thread. It's not too painful at size 2x2, but at 20x20, it begins to be painful. The threads should be told which row and column to process, and should be given pointers to the source matrices, and so on. As long as no thread modifies the source matrices, there isn't a problem reading the data.
Updated answer which replaces the previous invalid code related to pthread_join() (as noted by oftigus in a comment) with this working code. There's a reason I normally test before I post!
On the whole, casts like (void **) should be avoided in the pthread_join() loop. One correct working way to handle this is:
for (int i = 0; i < n * m; i++)
{
void *vp;
int rc = pthread_join(threads[i], &vp);
if (rc == 0 && vp != NULL)
{
rez[i] = vp;
printf("(%s) %d ", rez[i], atoi(rez[i]));
free(rez[i]);
}
}
putchar('\n');
This passes a pointer to a void * variable to pthread_join(). If it finds the information for the requested thread, then pthread_join() makes that void * variable hold the value returned by the thread function. This can then be used as shown — note the error handling (though I note that the example in the POSIX specification for pthread_join()ignores the return value from pthread_join() with a (void) cast on the result).
I don't see where you use res or C.
The result I get is:
(21) 21 (13) 13 (63) 63 (37) 37
where the value in parentheses is a string and the value outside is converted by atoi(). That looks like the correct answer for multiplying A by B (in that order).
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
struct data
{
int p;
int linie[20];
int coloana[20];
};
static void *func(void *args)
{
struct data *st = (struct data *)args;
int c = 0;
for (int k = 0; k < st->p; k++)
{
c += st->linie[k] * st->coloana[k];
}
char *rez = (char *)malloc(5);
sprintf(rez, "%d", c);
return rez;
}
int main(void)
{
int n = 2;
int m = 2;
int A[2][2] = {{1, 2}, {4, 5}};
int B[2][2] = {{7, 3}, {7, 5}};
char *rez[n * m];
pthread_t threads[n * m];
int count = 0;
struct data st[n * m];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
st[count].p = 2;
for (int x = 0; x < st[count].p; x++)
{
st[count].linie[x] = A[i][x];
st[count].coloana[x] = B[x][j];
}
int rc = pthread_create(&threads[count], NULL, func, &st[count]);
if (rc != 0)
{
fprintf(stderr, "Failed to create thread %d for cell C[%d][%d]\n", count, i, j);
exit(1);
}
count++;
}
}
for (int i = 0; i < n * m; i++)
{
void *vp;
int rc = pthread_join(threads[i], &vp);
if (rc == 0 && vp != NULL)
{
rez[i] = vp;
printf("(%s) %d ", rez[i], atoi(rez[i]));
free(rez[i]);
}
}
putchar('\n');
return 0;
}

How do I assign values to a matrix inside a struct?

I have a header file with this type definition:
typedef struct {
int rows;
int columns;
int **values;
} bidimensional_matrix;
As an example, If I instantiate the matrix from a main function I'd just do:
int matrix[][] = {{1, 2, 3}, {1, 1, 1}, {5, 5, 5}};
How would you generate the same matrix but with the typedef provided previously? (I mean, with pointers and malloc)
Is the approach correct? Maybe I'm a little object oriented biased and in c it's not convenient to handle it that way. I've defined the struct that way so I can just pass two bidimensional_matrix by parameter and do a multiplication.
I propose you to use flexible member array, exemple:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
size_t n;
size_t m;
int matrix[];
} bidimensional_matrix;
bidimensional_matrix *new_bidimensional_matrix(size_t n, size_t m) {
bidimensional_matrix *bm = malloc(sizeof *bm + sizeof *bm->matrix * n * m);
if (!bm) {
return NULL;
}
*bm = (bidimensional_matrix){ .n = n, .m = m };
return bm;
}
int get_bidimensional_matrix(bidimensional_matrix *bm, size_t i, size_t j) {
return bm->matrix[i * bm->m + j];
}
int set_bidimensional_matrix(bidimensional_matrix *bm, size_t i, size_t j, int x) {
return bm->matrix[i * bm->m + j] = x;
}
int main(void) {
bidimensional_matrix *bm = new_bidimensional_matrix(5, 10);
if (!bm) {
return EXIT_FAILURE;
}
for (size_t i = 0; i < bm->n * bm->m; i++) {
bm->matrix[i] = i;
}
printf("sample value %d\n", get_bidimensional_matrix(bm, 4, 5));
set_bidimensional_matrix(bm, 4, 5, 42);
printf("sample value %d\n", get_bidimensional_matrix(bm, 4, 5));
free(bm);
}
But you could use this too, that have other avantage but generally is more slow:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
size_t n;
size_t m;
int **matrix;
} bidimensional_matrix;
int main(void) {
bidimensional_matrix bm = { .n = 5, .m = 10, .matrix = malloc(sizeof *bm.matrix * bm.n) };
if (!bm.matrix) {
return EXIT_FAILURE;
}
for (size_t i = 0; i < bm.n; i++) {
bm.matrix[i] = malloc(sizeof *bm.matrix[i] * bm.m);
if (!bm.matrix[i]) {
return EXIT_FAILURE;
}
for (size_t j = 0; j < bm.m; j++) {
bm.matrix[i][j] = i * bm.m + j;
}
}
printf("sample value %d\n", bm.matrix[4][5]);
for (size_t i = 0; i < bm.n; i++) {
free(bm.matrix[i]);
}
free(bm.matrix);
}
If you need to swap rows the second could be a little faster cause swap row are O(1). But like you see the first one has only one malloc(), in practice with the cache of the processor it should be a lot more faster than the second implementation.

Search in array of char* in c

I am trying to work out what is wrong with the process of scanning the char* star value.
struct Property {
unsigned int shift;
int mask;
char * str[4];
}
human [] = {
{0, 1, {"fe", "ma"}},
{1, 1, {"du", "cl"}},
{2, 1, {"nh", "ha"}},
{3, 1, {"sk", "tr"}},
{4, 3, {"bn", "rd", "bw", "bk"}},
{6, 3, {"bu", "ge", "gy", "da"}},
};
int find(char* w){
int i;
int j;
for (i = 0; i < (sizeof(human)/ sizeof(struct Property)); i++){
for (j = 0; j < 4 ; j++){
if (human[i].str[j] == w)
return i;
}
}
}
int main(){
char* w ;
scanf("%s", w);
int k = find(w);
printf("k is %d", k);
return 0;
}
Clion compiler says that 'pointer parameter w can be pointer to const'. So in my main() I tried to use my function scanning w as array or char*.
Upd with suggestions.
struct Property {
unsigned int shift;
int mask;
char * st[4];
} human [] = {
{0, 1, {"fe", "ma"}},
{1, 1, {"du", "cl"}},
{2, 1, {"nh", "ha"}},
{3, 1, {"sk", "tr"}},
{4, 3, {"bn", "rd", "bw", "bk"}},
{6, 3, {"bu", "ge", "gy", "da"}},
};
int find(char* w)
{
int i;
int j;
for (i = 0; i < (sizeof(human)/ sizeof(struct Property)); i++)
{
for (j = 0; j < 4 ; j++)
{
if ((strcmp(human[i].st[j], w)) == 0)
return i;
else
continue;
}
}
return -1;
}
int main()
{
char* w = malloc(sizeof(char*));
scanf("%99s", w);
int k = find(w);
if (k != -1 )
printf("k is %d", k);
if (k == -1) { printf("%s","Error");}
return 0;
}
Still no output.I truly believe, that something is still wrong
There are couple of problems -
Allocate memory to w. Other wise passing an uninitialized pointer to scanf is Undefined behavior. (You can allocate the memory dynamically too)
char w[100];
if( scanf("%99s",w) != 1 ){
/* Handle error */
}
Comparing two strings can be done using strcmp. Using == operator is not the correct way.
if ( strcmp(human[i].str[j], w) == 0 )
Also you should always return something from the function. It is supposed to return something even if nothing matches. But you didn't follow that contract. Compiler complained.
for(..){
...
}
return -1; /* denoting invalid index - search failed*/
You can easily make the argument passed as const char * because you are not changing it's value (the content of the string).

fwrite incorrect value assignment writing matrixes in a binary file

I am trying to make a program that writes matrixes in a binary file. The 1st two items are the rows and columns of the matrix, and then the rest of the values.
The data of matrix are floats (when it was all in ints, it worked, but when I changed the values to floats it stopped working).
The next piece of code is the method to write the matrix in a binary file. It is the part where everything crashes.
The Matrix definition is the next one:
#include <stdio.h>
#include <stdlib.h>
typedef struct Matriz_t {
int numFilas;
int numColumnas;
float** datos;
}Matriz_t;
//create matrix
Matriz_t* crearMatriz(int numFilas, int numColumnas)
{
Matriz_t* nMatriz = NULL;
int i = 0;
nMatriz = (Matriz_t*)malloc(sizeof(Matriz_t));
nMatriz->numColumnas = numColumnas;
nMatriz->numFilas = numFilas;
nMatriz->datos = (float**)malloc(sizeof(float*)*numFilas);
for (i = 0; i < numColumnas; i++) {
nMatriz->datos[i] = (float*)malloc(sizeof(float)*numColumnas);
}
return nMatriz;
}
//read matrix
void leerMatriz(char * nomFichero, Matriz_t ** m1, int traspuesta)
{
FILE* f1 = NULL;
int i, j;
int numFilas = 0, numColumnas = 0;
f1 = fopen(nomFichero, "r");
fread(&(numFilas), sizeof(int), 1, f1); .
fread(&(numColumnas), sizeof(int), 1, f1);
(*m1) = crearMatriz(numFilas, numColumnas);
if (traspuesta) {
for (i = 0; i < (*m1)->numFilas; i++)
for (j = 0; j<(*m1)->numColumnas; j++)
fread(&((*m1)->datos[j][i]), sizeof(float), 1, f1);
}
else {
for (i = 0; i < (*m1)->numFilas; i++)
fread((*m1)->datos[i], sizeof(float), (*m1)->numColumnas, f1);
}
fclose(f1);
}
//write matrix
void escribirMatriz(char * nomFichero, Matriz_t * m1, int traspuesta)
{
FILE* f1 = NULL;
int i, j;
f1 = fopen(nomFichero, "w");
fwrite(&(m1->numFilas), sizeof(int), 1, f1);
fwrite(&(m1->numColumnas), sizeof(int), 1, f1);
if (traspuesta) {
for (i = 0; i < m1->numFilas; i++)
for (j = 0; j < m1->numColumnas; j++)
fwrite(&(m1->datos[j][i]), sizeof(float), 1, f1);
}
else {
for (i = 0; i < m1->numFilas; i++)
fwrite(m1->datos[i], sizeof(float), m1->numColumnas, f1);
}
fclose(f1);
}
//main
int main()
{
int i = 0, j = 0;
Matriz_t *m1, *m2, *mres;
m1 = crearMatriz(4, 4);
m2 = crearMatriz(4, 4);
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++) {
m1->datos[i][j] = j;
m2->datos[i][j] = i;
}
printf("\n Matriz 1: \n");
printf("%d y %d ", m1->numFilas, m1->numColumnas);
for (i = 0; i < 4; i++) {
printf("\n");
for (j = 0; j < 4; j++) {
printf("%f ", m1->datos[i][j]);
}
}
printf("\n Matriz 2: \n");
for (i = 0; i < 4; i++) {
printf("\n");
for (j = 0; j < 4; j++) {
printf("%f ", m2->datos[i][j]);
}
}
escribirMatriz("matriz3.bin", &m1, 1);
escribirMatriz("matriz4.bin", &m2, 1);
//leer matriz
leerMatriz("matriz3.bin", &m1, 0);
leerMatriz("matriz4.bin", &m2, 0);
Changing the last number "traspuesta" (turn cols and rows) to all 1 1 may work but as the number of cols and rows are not correct, it cannot multiply (And that method is correct, but anyways, it should be alright to have 0's in everything).
Then I do a simple if to check if I can multiply those matrixes (M1 nxm and M2 ixj, can be multiplied if m==i, but as the writing method is not working, it never multiplies.
escribirMatriz("matriz3.bin", &m1, 1);
This is incorrect and any compiler made in this millennium should have at lest warned you about it.
mtrx.c:102:39: warning: passing argument 2 of ‘escribirMatriz’ from incompatible pointer type [-Wincompatible-pointer-types]
escribirMatriz("matriz3.bin", &m1, 1);
^
mtrx.c:53:6: note: expected ‘Matriz_t * {aka struct Matriz_t *}’ but argument is of type ‘Matriz_t ** {aka struct Matriz_t **}’
void escribirMatriz(char * nomFichero, Matriz_t * m1, int traspuesta)
^~~~~~~~~~~~~~
mtrx.c:103:39: warning: passing argument 2 of ‘escribirMatriz’ from incompatible pointer type [-Wincompatible-pointer-types]
escribirMatriz("matriz4.bin", &m2, 1);
^
mtrx.c:53:6: note: expected ‘Matriz_t * {aka struct Matriz_t *}’ but argument is of type ‘Matriz_t ** {aka struct Matriz_t **}’
void escribirMatriz(char * nomFichero, Matriz_t * m1, int traspuesta)
^~~~~~~~~~~~~~

Using a structure in a recursive function (referenced structure)

I'm having problems understanding how to write code that solves the following problem: I have a structure containing a 2D-array. Then I have a recursive function that take a pointer to the structure as an argument and I want the recursive function to be able to manipulate the structure sent, not a local copy.
The struct is initialized in the function initStruct, where memory for the 2D-array is allocated. The recursive function builds up an array and at a specific point calls a function to insert it into the structure's array.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int** spBasis(int);
void mpBasis(int**, int, int, int, int, int, int, int*, struct mpBasis *, int, int);
void initMpBasis(struct mpBasis *, int, int);
void insertMpState(struct mpBasis *, int *);
struct mpBasis {
int** basis;
int size;
int capacity;
};
int main() {
int a, b, c, d;
char maxE[256];
char noParticles[256];
char P[256];
char M[256];
FILE *fp;
int **spStates;
struct mpBasis *mp;
int mpState[6] = {0, 0, 0, 0, 0, 0};
printf("Input max e for sp states, no of particles, parity (1 for odd and 0 for even) and magnetic projection: ");
gets(maxE);
gets(noParticles);
gets(P);
gets(M);
spStates = spBasis(atoi(maxE));
fp = fopen("spStates.txt", "a+");
fprintf(fp, "E\tj\tl\tm\n");
for (a = 0; a < 330; a++) {
fprintf(fp, "State %d: ", a+1);
for (b = 0; b < 4; b++) {
fprintf(fp, "%d\t", spStates[a][b]);
}
fprintf(fp, "\n");
}
mp = malloc(sizeof(struct mpBasis));
initMpBasis(mp, 5449, 6);
for (c = 0; c < 5449; c++) {
for (d = 0; d < 6; d++) {
fprintf(fp, "%d: %d\t", c, mp->basis[c][d]);
}
fprintf(fp, "\n");
}
printf("%p\n", (void*) mp);
printf("hello 3");
mpBasis(spStates, 0, atoi(maxE), 0, atoi(M), 0, atoi(P), mpState, mp, 0, 0);
fclose(fp);
return 0;
}
int** spBasis(int maxE) {
int c;
int i, j, k, l;
int q = 0;
int** spStates;
spStates = (int**)malloc(330 * sizeof(int *));
for (c = 0; c < 330; c++) {
spStates[c] = malloc(4 * sizeof(int));
}
for (i = 0; i <= maxE; i++) {
for (j = i % 2; j <= i; j += 2) {
for (k = -(2 * j + 1); k <= (2 * j + 1); k += 2) {
spStates[q][0] = i;
spStates[q][1] = j;
spStates[q][2] = 2 * j + 1;
spStates[q][3] = k;
q += 1;
}
for (l = -(2 * j - 1); l <= (2 * j - 1); l += 2) {
spStates[q][0] = i;
spStates[q][1] = j;
spStates[q][2] = 2 * j - 1;
spStates[q][3] = l;
q += 1;
}
}
}
return spStates;
}
void mpBasis(int** spStates, int e, int maxE, int m, int M, int l,
int P, int * mpState, struct mpBasis *mpB, int position, int lastSpState) {
int i;
for (i = lastSpState; i < 330; i++) {
if (e > maxE) {
break;
} else if (position == 5) {
if (m == M && l % 2 == P) {
insertMpState(mpB, mpState);
break;
}
} else {
// add spState to mpState and make the recursive call for the next position
mpState[position] = i;
mpBasis(spStates, e + spStates[i][0], maxE, m + spStates[i][3], M,
l + spStates[i][1], P, mpState, mpB, position+1, i);
}
}
}
void initMpBasis(struct mpBasis *a, int initialSize, int sizeY) {
int c;
a->basis = (int **)malloc(initialSize * sizeof(int*));
for (c = 0; c < initialSize; c++) {
a->basis[c] = (int *) malloc(sizeY * sizeof(int));
}
a->size = 0;
a->capacity = initialSize;
}
void insertMpState(struct mpBasis *a, int* mpState) {
/*if (a->size == a->capacity) {
a->size *= 2;
a->basis = (int **)realloc(a->basis, a->size * sizeof(int));
}*/
a->basis[a->size++] = mpState;
}
Added all the code.
The problem is that after the recursive function has been called, the "basis" array in structure mpBasis still only contains random values, i.e. the mpBasis function hasn't done anything with it. Am I passing the mp argument by value here?
Thanks for your help!
The first step is to compile with warnings enabled. Eg if you are using GCC you can use option -Wall -Wextra.
EDIT:
(previous listing of >20 errors removed)
Ok, since you are using Visual Studio, enable warnings like this:
Open the project's Property Pages dialog box.
Select C/C++.
On the General property page, modify the Warning Level to /W4

Resources