Hi!

So, I made this code

    #include<iostream>
    #include<cstdlib>
    #include<pthread.h>
    using namespace std;

    const int m=6;
    const int n=5;
    const int s=5;
    const int r=8;
    const int num_thrd=3;

    class data{
    public:
      int* A;
      int* B;
      int* C;
      int start;
    };

    void* multiply(void* pod)
    {
      data* P=(data*)pod;

      for(int i=P->start;i<m;i+=num_thrd)
      {
        for(int j=0;j<r;j++)
        {
          float sum=0;
          for(int k=0;k<n;k++)
            sum+=P->A[i*n+k]*P->B[k*r+j];
          P->C[i*r+j]=sum;
        }
      }
    }

    int main()
    {
      int* A=new int[m*n];
      int* B=new int[s*r];

      for(int i=0;i<m*n;i++)
        A[i]=rand()%10+1;

      for(int i=0;i<s*r;i++)
        B[i]=rand()%10+1;

      if(n==s)
      {
        int* AB=new int[m*r];
        pthread_t tID[num_thrd];
        data* P=new data;

        P->A=A;
        P->B=B;
        P->C=AB;
        P->start=0;

        for(int i=0;i<num_thrd;i++)
        {
          pthread_create(&tID[i],NULL,multiply,(void*)P);
          P->start++;
        }

        for(int i=0;i<num_thrd;i++)
          pthread_join(tID[i],NULL);

        cout << "A [" << m << "*" << n << "]=" << endl;
        for(int i=0;i<m*n;i++)
        {
          cout << A[i] << "\t";
          if((i+1)%n==0) cout << endl;
        }

        cout << endl << "B [" << s << "*" << r << "]=" << endl;
        for(int i=0;i<s*r;i++)
        {
          cout << B[i] << "\t";
          if((i+1)%r==0) cout << endl;
        }

        cout << endl << "AB [" << m << "*" << r << "]=" << endl;
        for(int i=0;i<m*r;i++)
        {
          cout << AB[i] << "\t";
          if((i+1)%r==0) cout << endl;
        }
        delete[] AB;
      }else
        cout << "Matrices cant be multiplied!" << endl;

      delete[] A;
      delete[] B;

      return 1;
    }

It works fine, but the task was to make it using threads on both loops in thread function. First for-loop is for rows of matrix, and I made it using threads, but we should do it so that both rows and columns are calculated with threads. Do you have any idea on how to do it?
Thanks a lot

DeanMSands3 commented: This is probably one of the best requests for help I've seen. +5

Recommended Answers

All 2 Replies

Here's the code rewritten in a readable format. The main task is still incomplete.

#include<iostream>
#include<cstdlib>
#include<pthread.h>
using namespace std;

const int m=6;
const int n=5;
const int s=5;
const int r=8;
const int number_of_outer_threads=3;

class Matrix{
    int *dataArray;
    int rows;
    int columns;
public:
    Matrix(int new_rows, int new_columns){
        rows=new_rows;
        columns=new_columns;
        dataArray=new int[rows*columns];
    }
    void fill_array(){
        for(int i=0;i<rows*columns;i++){
            dataArray[i]=rand()%10+1;
        }
    }
    void display(){ //Yes, this would have been better as an ostream. Bite me.
        cout << "[" << rows << "*" << columns << "]="<<endl;
        for(int i=0;i<rows;i++)
        {
            for(int j=0;j<columns;j++)
            {
                cout << this->get(i,j) << "\t";
            }
            cout<<endl;
        }
    }
    int get(int i, int j){return dataArray[i*columns+j];}
    void set(int i, int j, int d){dataArray[i*columns+j]=d;}
    int get_rows(){return rows;}
    int get_columns(){return columns;}
    bool can_multiply(Matrix *that){return this->columns==that->rows;}
};

typedef struct {
    Matrix* A;
    Matrix* B;
    Matrix* C;
}DataSet;

typedef struct{
    DataSet *pDataSet;
    int startRow;
}
ThreadOuterPackage;

typedef struct{
    DataSet *pDataSet;
    int currentRow;
    int column;
}ThreadInnerPackage;


void* multiply(void* pod)
{
    ThreadOuterPackage *top=(ThreadOuterPackage*)pod;
    DataSet* P=top->pDataSet;

    for(int i=top->startRow;i<m;i+=number_of_outer_threads)
    {
        ////////////////////////////////////////////////////
        // VV      This block needs to be threaded     VV //
        ////////////////////////////////////////////////////
        for(int j=0;j<r;j++)
        {
            float sum=0;
            for(int k=0;k<n;k++)
                sum+=P->A->get(i, k) * P->B->get(k,j);
            P->C->set(i, j, sum);
        }
        ////////////////////////////////////////////////////
        // ^^      This block needs to be threaded     ^^ //
        ////////////////////////////////////////////////////
    }
    return NULL;
}

int main()
{
    Matrix *A=new Matrix(m,n);
    A->fill_array();
    Matrix *B=new Matrix(s,r);
    B->fill_array();
    ThreadOuterPackage **threadOuterPackages=new ThreadOuterPackage* [m];
    DataSet* mainDataSet=new DataSet;

    if(A->can_multiply(B))
    {
        Matrix* AB=new Matrix(m,r);
        pthread_t tID[number_of_outer_threads];
        mainDataSet->A=A;
        mainDataSet->B=B;
        mainDataSet->C=AB;

        ////////////////////////////////////////////////////
        // VV    Use this block as a reference point   VV //
        ////////////////////////////////////////////////////

        for(int i=0;i<number_of_outer_threads;i++)
        {
            threadOuterPackages[i]=new ThreadOuterPackage;
            threadOuterPackages[i]->pDataSet=mainDataSet;
            threadOuterPackages[i]->startRow=i;
            pthread_create(&tID[i],NULL,multiply,(void*)threadOuterPackages[i]);
        }

        for(int i=0;i<number_of_outer_threads;i++)
        {
            pthread_join(tID[i],NULL);
            delete threadOuterPackages[i];
        }
        ////////////////////////////////////////////////////
        // ^^    Use this block as a reference point   ^^ //
        ////////////////////////////////////////////////////

        A->display();
        B->display();
        AB->display();

        delete[] AB;
    }else
        cout << "Matrices can't be multiplied!" << endl;

    delete mainDataSet;
    delete A;
    delete B;
    delete threadOuterPackages;
    return 1;
}

So, something like this, but still not made, I still need help

#include<iostream>
#include<cstdlib>
#include<pthread.h>
using namespace std;

const int m=6;
const int n=5;
const int s=5;
const int r=8;

const int br_thrd_red=2;
const int br_thrd_stup=3;

pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mtx2=PTHREAD_MUTEX_INITIALIZER;

class podaci{
public:
  int* A;
  int* B;
  int* C;
  int br_red;
  int start;
};

int brojac=0;

void* p_stupci(void* pod)
{
  pthread_mutex_lock(&mtx);

  podaci* P=(podaci*)pod;
  int i=P->br_red;

  for(int j=brojac;j<r;j+=br_thrd_stup)
  {
    float suma=0;
    cout << i << " "<<j << endl;
    for(int k=0;k<n;k++)
      suma+=P->A[i*n+k]*P->B[k*r+j];
    P->C[i*r+j]=suma;
  }
  brojac++;
  pthread_mutex_unlock(&mtx);
}
void* p_retci(void* pod)
{
  pthread_mutex_lock(&mtx2);

  podaci* P=(podaci*)pod;
  podaci* novi=new podaci;
  pthread_t tID2[m*br_thrd_stup];

  novi->A=P->A;
  novi->B=P->B;
  novi->C=P->C;

  int i=P->start;
  novi->br_red=i;

  for(int j=0;j<br_thrd_stup;j++)
    pthread_create(&tID2[i*br_thrd_stup+j],NULL,p_stupci,(void*)novi);

  for(int j=0;j<br_thrd_stup;j++)
    pthread_join(tID2[i*br_thrd_stup+j],NULL);

  pthread_mutex_unlock(&mtx2);
}

int main()
{
  int* A=new int[m*n];
  int* B=new int[s*r];

  for(int i=0;i<m*n;i++)
    A[i]=rand()%10+1;

  for(int i=0;i<s*r;i++)
    B[i]=rand()%10+1;

  if(n==s)
  {
    int* AB=new int[m*r];
    pthread_t tID[br_thrd_red];
    podaci* P=new podaci;

    P->A=A;
    P->B=B;
    P->C=AB;
    P->start=0;

    for(int i=0;i<br_thrd_red;i++)
    {
      pthread_create(&tID[i],NULL,p_retci,(void*)P);
      P->start++;
    }

    for(int i=0;i<br_thrd_red;i++)
      pthread_join(tID[i],NULL);

    cout << "A [" << m << "*" << n << "]=" << endl;
    for(int i=0;i<m*n;i++)
    {
      cout << A[i] << "\t";
      if((i+1)%n==0) cout << endl;
    }

    cout << endl << "B [" << s << "*" << r << "]=" << endl;
    for(int i=0;i<s*r;i++)
    {
      cout << B[i] << "\t";
      if((i+1)%r==0) cout << endl;
    }

    cout << endl << "AB [" << m << "*" << r << "]=" << endl;
    for(int i=0;i<m*r;i++)
    {
      cout << AB[i] << "\t";
      if((i+1)%r==0) cout << endl;
    }
    delete[] AB;
  }else
    cout << "Matrice nisu ulancane!" << endl;

  delete[] A;
  delete[] B;

  return 1;
}

I used mutex just for checking what happens. I hope someone can do it now

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.