Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Пушкарев Д.С. ЛР№3 Умножение разреженных матриц. Элементы типа double. Формат хранения матрицы – столбцовый (CCS). TBB #170

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Done
  • Loading branch information
Gus96 committed May 28, 2020
commit ad803f086631256bad7432f5528ce64ba36bdb33
280 changes: 252 additions & 28 deletions 1706-4/Pushkarev_DS/CCS_TBB/CCS_TBB/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
#include <vector>
#include <algorithm>
#include <iostream>
#include <list>
#include <fstream>
#include <string>
#include <omp.h>
#include "tbb\tbb.h"

using namespace std;
typedef double type;

typedef double type;

struct Task
{
Expand All @@ -35,7 +35,7 @@ class Matrix
{
this->row = row;
this->col = col;
vv = vector<type>(row * col);
vv = vector<type>(row * col);//�� ��������
}
Matrix(int col, int row, type val)
{
Expand Down Expand Up @@ -78,6 +78,62 @@ class Matrix
if (vv[i] != m.vv[i]) return false;
return true;
}

static void readMatrix(Matrix& A, Matrix& B, int N, string name)//��� ������ �������(������ ������� �� �����)
{
ifstream input(name);
input >> A.vv[0];//��������� ������, �� ��� �������� �����
for (int i = 0; i < A.vv.size() + B.vv.size(); i++)
{
if (i < A.vv.size())
input >> A.vv[i];
else
{
for (int j = 0; j < B.vv.size(); j++)
input >> B.vv[j];
}
}
input.close();
A.transposition();
B.transposition();
}

static void writeMatrix(Matrix& A, int N)//���������� ������� � ����
{
A.transposition();
ofstream input("resMatrix.txt");
for (int i = 0; i < A.vv.size(); i++)
{
if (i < A.vv.size())
input << A.vv[i] << "\t ";
if ((i + 1) % N == 0)
input << endl;
}
input.close();
}

static void randMatrixdata(Matrix& A, Matrix& B, int N)//���������� ������� ��� ������ � ����
{
for (int i = 0; i < N * N; i++)
{
int prob;//�����������
prob = rand() % 100;
if (prob < 10)
A.vv[i] = (rand() % 10) + (double)(rand() % 10) / 10;//���������� ����� � ������� �����
else
A.vv[i] = 0;
}

for (int i = 0; i < N * N; i++)
{
int prob;//�����������
prob = rand() % 100;
if (prob < 10)
B.vv[i] = (rand() % 10) + (double)(rand() % 10) / 10;
else
B.vv[i] = 0;
}
}
};

class MatrixCCS
Expand All @@ -88,8 +144,8 @@ class MatrixCCS
vector<int> pointer;
int N;
public:
friend class FunctorTBB;

friend class FunctorTBB;
MatrixCCS() {}
MatrixCCS(int n) :N(n)
{
pointer.push_back(0);
Expand Down Expand Up @@ -127,7 +183,7 @@ class MatrixCCS
for (int i = 0; i < values.size(); i += numElementsInCol)
{
numElementsInCol = pointer[pCount + 1] - pointer[pCount];//���������� ���������� ��������� � �������
for (int z = i; z < i + numElementsInCol; z++)
for (int z = i; z < i + numElementsInCol; z++)//���� ��� ��������� ������ �������
{
int row = rows[z];//� ����� ������ ���������
int col = pCount;
Expand Down Expand Up @@ -161,22 +217,20 @@ class MatrixCCS

}
}
void uniteMatrix(const MatrixCCS& m)
void uniteMatrix(const MatrixCCS& m)//����������� ������ � ���� �������
{
int numCol = pointer.size();
for (int i = 0; i < m.values.size(); i++)
for (int i = 0; i < m.values.size(); i++)//���������� values � rows
{
values.push_back(m.values[i]);
rows.push_back(m.rows[i]);
}
for (int i = 1; i < m.pointer.size(); i++)
for (int i = 1; i < m.pointer.size(); i++)//���������� pointer
{
int start = pointer[pointer.size() - 1];
int start = pointer[pointer.size() - 1];//����� pointer ��� ���������
pointer.push_back(m.pointer[i] - m.pointer[i - 1] + start);
}
}


MatrixCCS parallelMult(MatrixCCS& m, const int numThreads)
{
class FunctorTBB
Expand All @@ -196,10 +250,10 @@ class MatrixCCS
tmp = nullptr;
elCountM = nullptr;
}
FunctorTBB(MatrixCCS* matrix1_, MatrixCCS* matrix2_, vector<Task>* tasks_, vector<MatrixCCS>* tmp_, vector<int>* elCountM_)
{
m1 = matrix1_;
m2 = matrix2_;
FunctorTBB(MatrixCCS* m1_, MatrixCCS* m2_, vector<Task>* tasks_, vector<MatrixCCS>* tmp_, vector<int>* elCountM_)
{//��������� ������
m1 = m1_;
m2 = m2_;
tasks = tasks_;
tmp = tmp_;
elCountM = elCountM_;
Expand All @@ -214,35 +268,205 @@ class MatrixCCS
}
void operator()(const tbb::blocked_range<size_t>& range) const
{
//
int N = m1->N;
vector<int>* cols = &(m1->rows);
for (size_t itask = range.begin(); itask < range.end(); itask++)
for (int j = (*tasks)[itask].pointerStart; j < (*tasks)[itask].pointerEnd; j++)
{
int numElInResCol = 0;//���������� ��������� � �������������� �������
const int numElementInCol = m2->pointer[j + 1] - m2->pointer[j];//���������� ��������� � �������
if (numElementInCol == 0)//���� ������� ������ � ������
{
int size = (*tmp)[itask].pointer.size();
(*tmp)[itask].pointer.push_back((*tmp)[itask].pointer[size - 1]);
continue;
}
int elCountThis = 0;
for (int i = 0; i < N; i++)
{
const int numElementInRow = m1->pointer[i + 1] - m1->pointer[i];
if (numElementInRow == 0)
{
continue;
}
int tmpNumElRow = numElementInRow;//��� A
int tmpNumElCol = numElementInCol;//��� B

type sum = 0;
int tmpElCountM = (*elCountM)[itask];
for (int z = 0; z < min(tmpNumElCol, tmpNumElRow);)//�������� �� ������� � ��������
{
int colThis = (*cols)[elCountThis];//cols==rows(�� A)
int rowM = m2->rows[tmpElCountM];//������ rows � �������� ����� �������� task(�������� �������� rows � B)
if (colThis == rowM)
{
sum += m1->values[elCountThis] * m2->values[tmpElCountM];
tmpNumElCol--;
tmpNumElRow--;
tmpElCountM++;
elCountThis++;
}
else if (colThis < rowM)
{
tmpNumElRow--;//��������� ���������� ���������
elCountThis++;//����������� ������
}
else
{
tmpNumElCol--;
tmpElCountM++;
}
}
for (int z = 0; z < tmpNumElRow; z++)//������� ������ � rows, ���� � ����� ������� � ������� ������ �����
elCountThis++;

if (sum != 0)//���������� � �������������� �������(�� ��������)
{
(*tmp)[itask].values.push_back(sum);
(*tmp)[itask].rows.push_back(i);
numElInResCol++;
}
}
const int size = (*tmp)[itask].pointer.size();
(*tmp)[itask].pointer.push_back((*tmp)[itask].pointer[size - 1] + numElInResCol);//���������� ���������� + ���������� ���������, ������� � �������
(*elCountM)[itask] += numElementInCol;
}
}
~FunctorTBB()
{

}
};
int numTask = numThreads;
if (numTask > N)
numTask = N;
vector<MatrixCCS> tmpMatrix(numTask, MatrixCCS(N));
vector<int> elCountM(numTask);
vector<int>* cols = &rows;
vector<Task> task(numTask);//�������� ������, � ������� numTask �����
//�������� ����� �������
{
int sizeTask = m.N / numTask + (bool)(m.N % numTask);//���� �������, �� + 0, ����� + 1 (������������ ������� �������)
for (int i = 0; i < numTask; i++)
task[i] = Task(i * sizeTask, min((i + 1) * sizeTask, m.N), i % numTask);//(������, �����, ������)
int lastPointerM = 0;
for (int i = 0; i < numTask; i++)
{
elCountM[i] = lastPointerM;
int jstart = task[i].pointerStart;
const int jend = task[i].pointerEnd;
for (jstart; jstart < jend; jstart++)
{
lastPointerM += m.pointer[jstart + 1] - m.pointer[jstart];//������� ���������� ��������� ���������
}
}
}


FunctorTBB fctor(this, &m, &task, &tmpMatrix, &elCountM);
tbb::parallel_for(tbb::blocked_range<size_t>((size_t)0, task.size(), (size_t)4), fctor);

for (int i = 1; i < tmpMatrix.size(); i++)
{
tmpMatrix[0].uniteMatrix(tmpMatrix[i]);//�������� ��������� ����� �������, ���������� ��� ����� � �������
}
if (tmpMatrix[0].pointer.size() < N + 1)
tmpMatrix[0].pointer.push_back(tmpMatrix[0].values.size());
return tmpMatrix[0];
}

Matrix CCStoMatrix()
{
Matrix res(N, N);

int Elem = 0;
int count = 0;
int resCount = 0;

for (int i = 0; i < N; i++)
{
int numOfElem = pointer[i + 1] - pointer[i];

if (numOfElem != 0)
for (int j = 0; j < N; j++)
{
if (numOfElem != 0 && rows[resCount] == j)
{
res.vv[count] = values[Elem];
Elem++;
resCount++;
numOfElem--;
}
else
res.vv[count] = 0;
count++;
}
else
for (int j = 0; j < N; j++)
{
res.vv[count] = 0;
count++;
}
}

return res;
}
};


int main()
{
int numThreads = 1;
int numThreads;
int mSize;
cout << "NumThreads = ";
cin >> numThreads;

tbb::task_scheduler_init init(numThreads);

cout << "1.Rand" << endl;
cout << "2.From file" << endl;
int choice;
cin >> choice;

if (choice == 1)
{
cout << "Size of Matrix = ";
cin >> mSize;
Matrix a(mSize, mSize), b(mSize, mSize), c(mSize, mSize);//������� �������
Matrix::randMatrixdata(a, b, mSize);//������������� �������
MatrixCCS a1(a), b1(b), c1(c);//������������� ������� � CCS �������

int N = 5;
Matrix a(N, N), b(N, N), c(N, N);

MatrixCCS a1(a), b1(b);
a1.transposition();

double time = omp_get_wtime();//������� �������
c1 = a1.parallelMult(b1, numThreads);
time = omp_get_wtime() - time;
cout << time << endl;//���������� �������� ������� � �����
c = c1.CCStoMatrix();

tbb::task_scheduler_init init(numThreads);
Matrix::writeMatrix(c, mSize);//������ ���������� � ����

}
else if (choice == 2)
{
ifstream input("matrix.txt");//������ �� ����� ����������� �������
input >> mSize;
input.close();

Matrix a(mSize, mSize), b(mSize, mSize), c(mSize, mSize);//������� �������
Matrix::readMatrix(a, b, mSize, "matrix.txt");
MatrixCCS a1(a), b1(b), c1(c);
a1.transposition();

double time = omp_get_wtime();//������� �������
c1 = a1.parallelMult(b1, numThreads);
time = omp_get_wtime() - time;
cout << time << endl;//���������� �������� ������� � �����
c = c1.CCStoMatrix();

Matrix::writeMatrix(c, mSize);//������ ���������� � ����
}
else
cout << "Error" << endl;

double time = omp_get_wtime();
a1.parallelMult(b1, numThreads);
time = omp_get_wtime() - time;
return 0;
}
}
10 changes: 10 additions & 0 deletions 1706-4/Pushkarev_DS/CCS_TBB/CCS_TBB/matrix.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
4
1 0 0 5
0 0 0 2
0 4 0 1
2.5 0 0 0

0 0 0 0
7 0 1 4.2
0 2 0 8
3 0 0 0
10 changes: 10 additions & 0 deletions 1706-4/Pushkarev_DS/CCS_TBB/CCS_TBB/resMatrix.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
0 0 93.65 0 0 0 50.49 86.48 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 4.32 7.2 0
0 0 0 0 0 0 0 0 0 0
0 0 0.21 0 0 0 6.93 0 0 0
0 0 0 0 0 0 0 0 0 0