Matrix Multiplication Using win32 threads - c++

I have a running code with 9 threads to operate on a 3*3 matrix .. I want to make the number of threads an input from the user .but I can't divide the matrix on for example 4 threads only. Any help would be appreciated. thanks :)
#include<iostream>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include<windows.h>
using namespace std;
int nGlobalCount = 0;
int thread_index = 0;
int num_of_thr=9;
int a[3][3] , b[3][3] , c[3][3];
int i , j , k;
struct v {
int i; /*row*/
int j; /*column*/
};
DWORD ThreadProc (LPVOID lpdwThreadParam ) {
struct v *input = (struct v *)lpdwThreadParam ;
int avg=4*4/9;
for(int n=0; n<avg; n++) {
int sum=0;
for ( k = 0 ; k < 3; k++) {
sum=sum+((a[input->i][k])*(b[k][input->j]));
c[input->i][input->j]=sum;
if(j<3 && avg!=1)
j=j+1;
else if (j==3 && avg!=1 && (avg-n)!=1)
i=i+1;
}
}
cout<<"the number of the thread "<<thread_index<<endl;
return 0;
}
int main() {
DWORD ThreadIds[9];
HANDLE ThreadHandles[9];
struct v data[9];
for ( int i = 0 ; i < 3; i++) {
for (int j = 0 ; j < 3 ; j++) {
a[i][j] = rand() % 10;
b[i][j] = rand() % 10;
c[i][j] = 0;
}
}
for ( int i=0 ; i < 3; i++) {
for(int j=0 ; j <3; j++) {
data[thread_index].i = i;
data[thread_index].j = j;
ThreadHandles[thread_index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, &data[thread_index], 0,&ThreadIds[thread_index]);
thread_index++;
}
}
WaitForMultipleObjects(num_of_thr, ThreadHandles, TRUE, INFINITE);
cout<<"The matrix A is "<<endl;
for ( i = 0 ; i < 3; i++) {
for ( j = 0 ; j < 3 ; j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<"The matrix B is "<<endl;
for ( i = 0 ; i < 3; i++) {
for ( j = 0 ; j < 3 ; j++)
cout<<b[i][j]<<" ";
cout<<endl;
}
cout<<"The resultant matrix is "<<endl;
for ( i = 0 ; i < 3; i++) {
for ( j = 0 ; j < 3 ; j++)
cout<<c[i][j]<<" ";
cout<<endl;
}
for (int i=0; i<9; i++) CloseHandle(ThreadHandles[i]);
return 0;
}

As some of the comments point out, you won't see any performance boot on a 3x3 matrix. The cost of spawning new threads is too high.
In general though, you might try a thread-safe queue of tasks. Essentially, just an ordinary queue with semaphores in the right places. Put all the indexes which still need to be computed into the queue. Each thread grabs the next index from the front of the queue (removing it), and then computes and fills in the appropriate cell of the solution matrix before fetching another job from the queue. Seems to me that thread-safe queue implementations are fairly common, so it shouldn't be hard to find one for your purpose.
This has the added benefit that you can add more threads in real-time, or take some away if you wanted to. Its a more general purpose way of parallelizing things.

I suspect a part of the problem may lie in this line inside your threadproc:
int avg=4*4/9;
This is going to be a constant of 1 which may not be what you want (16/9 as an int is 1 (reminder 7)). And that in turn means that your outer loop (n) will only execute once.

Related

Finding largest value in every array's column

Currently I have a 2D array and I need to find largest value of every array's column and find their sum.
My code seems to not work properly because I'm getting largest values of every row, not column, also the program sometimes prints the same value two times.
I wrote this code based on a tutorial and I don't know where I made a mistake. There should be basic C++ functions (cycles, if statements, arrays).
My code:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, m, a[10][10], sum = 0, max;
cin >> n >> m;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> a[j][i];
}
}
for (int i = 0; i < m; i++) {
max = a[0][i];
for (int j = 0; j < n; j = j + 1) {
if (a[j][i] >= max) {
max = a[j][i];
sum = sum + a[j][i];
cout << max << endl; //control printing to see the values
}
}
}
cout << sum;
}
Input:
3 3
3 2 3
7 5 1
6 3 5
Output I need to get is 17 but I am getting 19 right now.
Assuming your array has m columns and n rows.
int sum = 0, max = 0;
for( int i = 0 ; i < m ; ++i )
{
max = 0;
for( int j = 0 ; j < n ; ++j )
{
if(max < a [j][i])
{
max = a[j][i];
}
}
sum += max;
}

How to convert List of Edges to Adjacency Matrix in C++ with the number of edges connected to a vertex instead of ones?

I am struggling to convert a list of Edges to Adjacency Matrix in a certain required way.
Problem:
The Adjacency matrix should have number of edges connected to a vertex, so it should not have only 1s where two vertexes are connected. For better explanation here is sample input.
Input
4 7
1 2
2 3
3 2
2 4
4 1
4 2
3 2
Where 4 is number of vertexes and 7 is the number of edges and each line represents edges.
Output:
4
0 1 0 1
1 0 3 2
0 3 0 0
1 2 0 0
Where 4 is number of vertexes and each line represents how many times a vertex is connected.
In my code I only managed to convert to normal Adjacency matrix with 1s, but I cannot understand if I can solve this task only with arrays and how?
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int adjMatrix[100][100] = { };
int edgeList[100][100];
int row, col;
int N, M;
cin >> N;
cin >> M;
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
adjMatrix[i][j] = 0;
}
}
for (int i = 1; i < 8; i++)
{
for (int j = 1; j <= 2; j++)
{
cin >> row;
cin >> col;
adjMatrix[row][col] = 1;
adjMatrix[col][row] = 1;
}
}
for (int i = 1; i < 8; i++)
{
for (int j = 1; j <= 2; j++)
{
if (adjMatrix[i][j] == adjMatrix[j][i])
{
adjMatrix[i][j]++;
}
}
}
cout << N << endl;
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
cout << adjMatrix[i][j] << " ";
}
cout << endl;
}
return 0;
}
Problem: Want count of connections, not simply that connection exists.
Solution: Use ++
adjMatrix[row][col]++;
adjMatrix[col][row]++;
It is worth noting that
This loop
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
adjMatrix[i][j] = 0;
}
}
Is rendered redundant by
int adjMatrix[100][100] = { };
because the = {} default initializes the array, setting all elements to 0.
In addition, what if N is greater than the 100 used to define the array dimensions? adjMatrix needs to be dynamic. Read up on and use a std::vector
The following loop conditions are incorrect
for (int i = 1; i < 8; i++)
{
for (int j = 1; j <= 2; j++)
{
cin >> row;
cin >> col;
adjMatrix[row][col] = 1;
adjMatrix[col][row] = 1;
}
}
14 lines will ALWAYS be read from the file regardless of the size of the file. The outer loop will always run 7 times (1..7) and the inner loop always twice (1..2).
M defines the number of rows in the file. Use that to control your loop.
This fixed number of lines is particularly bad if there are less than 14 lines in the file because the cin >> are not being tested for validity. The code could be loading the matrix with garbage and you would never know. Instead use something like
if (cin >> row >> col)
{
do stuff
}
else
{
handle error
}
A program must validate all input because you can't trust those slimy users. One minute they're making typos and the next trying to hack into the Pentagon.
This loop accomplishes nothing useful, but you knew that already. No thought went into this at all. It is exceptionally hard to write code without thinking. This is why I held off on answering the question so long. Not thinking is also a disincentive to others offering assistance.
for (int i = 1; i < 8; i++)
{
for (int j = 1; j <= 2; j++)
{
if (adjMatrix[i][j] == adjMatrix[j][i])
{
adjMatrix[i][j]++;
}
}
}

Sort entered number - difference between FOR and WHILE

I have to write a code which sort digits in one entered number.
For example: input: 4713239
output: 1233479
It doesn't work properly when I enter repeating digits(like 33) when I have the last loop as FOR:
for(int j = 0; j < arr[i]; j++) // in this loop my output is: 123479.
When I change this loop from FOR to WHILE it works properly.
It means:
while(arr[i]) // and the number is sorted correctly (1233479)
True be told, I don't know what is the difference between these operations in this code.
Why FOR loop doesn't work properly? Could somebody explain me this?
I wrote a code:
int sort(int arg)
{
int var, score = 0;
int arr[10] = {0};
for(int i = 0; i < 10; i++)
{
var = arg % 10;
arr[var]++;
arg = arg / 10;
}
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < arr[i]; j++) //while(arr[i]) --> works correctly
{
score = score * 10 + i;
arr[i]--;
}
}
return score;
}
You modify both arr[i] and j, therefore the loop will end too fast when both are part of the comparison.
for(int j = 0; j < arr[i]; j++) // increase j, compare with arr[i]
{
score = score * 10 + i;
arr[i]--; // decrease arr[i]
}

Selection sort ascending

That is my function:
int main() {
double data[100];
int num;
cout<<"num= ";
cin>>num;
for(int i = 1; i <= num; i++) {
cout<<i<<" element = ";
cin>>data[i];
}
Sort(data, num);
for (int i = 1; i <= num; i++) {
cout<<data[i]<<endl;
}
return 0;
}
void Sort(double data[], int n) {
int i,j,k;
double min;
for(i = 0; i < n-1; i++) {
k = i;
min = data[k];
for(j = i+1; j < n; j++)
if(data[j] < min) {
k = j;
min = data[k];
}
data[k] = data[i];
data[i] = min;
}
}
if I write for exp. three elements: 8,9,1 again cout 8,9,1?
for(int i = 1; i <= num; i++) { // WRONG
I think you mean:
for(int i = 0; i < num; i++) { // RIGHT
Arrays in C are 0-indexed remember.
Your sorting function is fine. The only problem is that you enter elements at positions 1 through n, inclusive, while you should use 0 through n-1, inclusive, in both loops of the main() function.
If you need to print numbers 1 through n, use
cout<<(i+1)<<" element = ";
You should get used of the 0 index begin in the for loop
for(int i = 0; i < N; ++i)
so fixing these two index errors will make your code run properly.
the reason is:
if you write data to data[] using 1 as the begining, your data array's first item will be a random number:
if you insert 3 elements, the array will be like this:
data[0] = ??? // maybe a very very big number
data[1] = 8
data[2] = 9
data[3] = 1
and in your Sort function, your index begins at 0 and ends before num, that means your code would only sort data[0], data[1], data[2].
if you use: num = 3, 3 2 1 as your input data for the origin code you could see that 3 and 2 is sorted
I guess your Sort code is googled from somewhere, please try to understand it.
Good online algorithm course: https://www.coursera.org/course/algs4partI
a very good algorithm online book: http://algs4.cs.princeton.edu/home/
btw, for(j = i+1; j < n; j++) in the Sort function would be better if it has { } braces.

Matrix Multiplication Using win32 threads

I have no idea what's wrong with my code ... It always return zeros in all the elements. A hint of where is the problem would be great :)
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include <windows.h>
using namespace std;
int nGlobalCount = 0;
int thread_index = 0;
int num_of_thr=5;
int a[4][4], b[4][4], c[4][4];
int i, j, k;
struct v {
int i; /*row*/
int j; /*column*/
};
DWORD ThreadProc (LPVOID lpdwThreadParam ) {
//
struct v *input = (struct v *)lpdwThreadParam;
int avg=4*4/num_of_thr;
int count=0;
for(int i = 0; i <= 3 ; i++) {
for(int j = 0; j <= 3; j++) {
int sum=0;
for ( k = 0 ; k <= 3; k++) {
sum=sum+((a[input->i][k])*(b[k][input->j]));
c[input->i][input->j]=sum;
count++;
}
}
}
//Print Thread Number
//printf ("Thread #: %d\n", *((int*)lpdwThreadParam));
//Reduce the count
return 0;
}
int main() {
// int x=0;
cout<<"enter no of threads : ";
cin>>num_of_thr;
DWORD ThreadIds[num_of_thr];
HANDLE ThreadHandles[num_of_thr];
//struct v {
// int i; /*row*/
// int j; /*column*/
//};
struct v data[num_of_thr];
int i , j , k;
for ( int i = 0 ; i <= 3; i++) {
for (int j = 0 ; j <= 3 ; j++) {
a[i][j] = rand() % 10;
b[i][j] = rand() % 10;
c[i][j] = 0;
}
}
for(int i = 0; i < num_of_thr/2; i++) {
for(int j = 0; j < num_of_thr/2; j++) {
data[thread_index].i = i;
data[thread_index].j = j;
ThreadHandles[thread_index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, &data[thread_index], 0,&ThreadIds[thread_index]);
thread_index++;
}
}
WaitForMultipleObjects(num_of_thr, ThreadHandles, TRUE, INFINITE);
cout<<"The resultant matrix is "<<endl;
for ( i = 0 ; i < 4; i++) {
for ( j = 0 ; j < 4 ; j++)
cout<<c[i][j]<<" ";
cout<<endl;
}
for (int i=0; i<num_of_thr; i++)
CloseHandle(ThreadHandles[i]);
return 0;
}
At a GLANCE, your sum declaration in the loop looks sketchy.
for(int i = 0; i <= 3 ; i++) {
for(int j = 0; j <= 3; j++) {
for ( k = 0 ; k <= 3; k++)
{
int sum=sum+((a[input->i][k])*(b[k][input->j])); // this declaration seems wrong
c[input->i][input->j]=sum;
count++;
}
}
}
Each inner loop you redeclare sum, effectively making it 0. You might want to move the declaration up one or two loops from the assignment depending on what you are trying to achieve.
Do you realise that you have two separate sets of variables named a, b and c? One is local to the function main, and the other is a static for the whole program. I suspect that this is not what you intended. Try deleting the one that is local to main.
Martyn
A few things I found while poking about in addition to the other issues noted previously:
What are you compiling this with? With VC++ 2010 it "works", as in it outputs non-zeroes, although it complains about the DWORD ThreadIds[num_of_thr]; array declaration with a non-constant array size (I just made num_of_thr a constant and commented out the cin to test it quickly).
Are you sure you are inputting a valid number of threads with cin >> num_of_thr; For example, if num_of_thr was 0 this would explain the zeroes output. A simple cout here for num_of_thr would be useful.
In your data initialization loop starting with for(int i = 0; i < num_of_thr/2; i++) { you are not correctly counting threads which will result in an array underflow or overflow. For example, if num_of_thr is 5 then num_of_thr/2 is 2 which results in initializing only the elements 0..3 leaving the last element uninitialized. An array underflow is technically ok although the later CloseHandle() call will fail when it tries to free an essentially random handle. If you enter a larger number of threads you will overflow all your arrays (try it with num_of_thr=10 for example).
If it still doesn't work try removing the threading to see if the threading or code itself is the source of the problem. For example, you can call the ThreadProc() function manually in a loop instead of from within threads. Either trace through the program with a debugger or output logs to stdout/file (which would also work in the threading model).
Instead of a random source matrix I would use a few fixed values at first with a known result. This will make it easier to determine if the code is actually computing the correct result.