Matrix Multiplication Using win32 threads - c++

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.

Related

C++ Array swapping and find smallest element

I am trying to find first smallest array but my code does not display any output. There are no errors or warnings. Actually, I am trying to check an algorithm that I got as an assignment from my university.
#include <iostream>
using namespace std;
int main(){
int arr[7]= {8,4,6,9,2,3,1};
int n = sizeof(arr)/sizeof(arr[0]);
int smallest = 0;
for(int j = 1; j = (n-1); j = (j + 1) )
{
smallest= j ;
for(int i = (j+1); i = n ; i = (i + 1))
{
if (arr[i]<arr[smallest])
{
smallest = i;
int swaper = arr[j];
arr[j] = arr[smallest];
arr[smallest] = swaper;
}
}
}
for(int a = 1; a = n; a = (a + 1))
{
cout<<arr[a];
}
return 0;
}
There are three errors with this code:
for(int a = 1; a = n; a = (a + 1))
{
cout<<arr[a];
}
Firstly, arrays start from zero, not one. So the first part of the for statement should be int a = 0;.
Secondly, you are not comparing a and n, you are assigning n to a, (and the value is non-zero, so you always keep going). The equality test is ==, but you don't want that anyway!
Thirdly, the loop condition is for when to keep going, not when to stop. So you need either < or != (either will work, people have long arguments about which is preferable).
The normal way to write a loop over a range of integers in C++ is:
for (int a = 0; a < n; a++)
You are at least consistent, and have made the same mistake in every loop. You will need to fix it in every loop.
# include <iostream>
using namespace std;
int main ()
{
int a[100][100],n,k,i,j,aux,mi=0;
cin>>n>>k;
for(i=1;i<=n;i++)
for(j=1;j<=k;j++)
cin>>a[i][j];
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++)
if(a[i][k]>a[j][k])
{aux=a[i][k];
a[i][k]=a[j][k];
a[j][k]=aux;
} //until here you are sorting the 2D array
for(i=1;i<=n;i++) {
for(j=1;j<=k;j++) {
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
mi=a[1][1];
for (i=1; i<=n; i++)
{
for (j=1; j<=n; j++)
if (mi<a[i][j])
mi=a[i][j];
} //here you're finding the smallest element
cout<<mi;
return 0;
}
The Code doesn't compile, but the idea should solve 90%, you just have to write the code.

How to construct a compound for loop in C++?

Is another for loop allowed in the counter section (third part) of a for loop? In my attempt to get elegant in writing code to produce a right triangle, I wrote this but it wouldn't compile:
#include <stdio.h>
int main()
{
int i, j, N = 5;
for (i = 1;
i <= N;
(for (j = 1; j <= i; j++, printf("%c", '0'));), i++)
printf("\n");
}
return 0;
}
No there are allowed only expressions or declarations.
EDIT: I am sorry. I thought you are speaking about the condition part of the loop. In the expression part of the loop there are allowed only expressions.
You could use a lambda expression that would contain this for loop. For example
for ( i = 1;
i <= N;
[]( int i ) { for ( j = 1; j <= i; j++, printf("%c", '0' ) ); }( i ), i++)
Here is a demonstrative example
#include <iostream>
int main()
{
int N = 10;
for ( int i = 1;
i < N;
[]( int i )
{
for ( int j = 1; j < i; j++, ( std::cout << '*' ) );
}( i ), i++ )
{
std::cout << std::endl;
}
return 0;
}
The output is
*
**
***
****
*****
******
*******
********
Or your could define the lambda expression outside the outer loop that to make the program more readable. For example
#include <iostream>
int main()
{
int N = 10;
auto inner_loop = []( int i )
{
for ( int j = 1; j < i; j++, ( std::cout << '*' ) );
};
for ( int i = 1; i < N; inner_loop( i ), i++ )
{
std::cout << std::endl;
}
return 0;
}
Take into account that in general case the nested loops showed in other posts are unable to substitute the loop with the lambda-expression. For example the outer loop can contain continue statements that will skip the inner loop. So if you need that the inner loop will be executed in any case independing on the continue statements then this construction with the lambda expression will be helpful.:)
There is no need to do so. Because for loop can be easily replaced with while loop, every part of for loop can be placed in another place, where it's possible to use complex constructions. In your case, you can just change loop to the following:
for (i = 1; i <= N; i++) {
printf("\n");
for (j = 1; j <= i; j++) {
printf("%c", '0');
}
}
However, if you really have to place complex action, you may use gcc extension (compound statement):
for (i = 1;
i <= N;
({for (j = 1; j <= i; j++) putchar('0'); }), i++) {
printf("\n");
}
In the counter section of a for() loop, expressions are allowed, but statements are not.
And every for() line in C/C++ forms a new statement (it's not an expression).
However, you can nest several for() loops if you want.
For example, since you want a new loop in the counter sections, that means that you need to perform a loop at the end of the main for() loop.
This is the scheme:
for (int i = 0; i < i_max; i++) {
// stuff...
for (int j = 0; j < j_max; j++) {
// stuff..
}
}
You can't do that because condition and increment parts of a for can only contain expressions. A for loop is an iteration statement, though.
Simply nest the loops like sane programers do:
#include <stdio.h>
int main()
{
int N = 5;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= i; j++)
printf("0");
printf("\n");
}
}
If you're not feeling well, though, you could use a lambda:
#include <stdio.h>
int main()
{
int N = 5;
for (
int i = 1;
i <= N;
[=](){ for (int j = 1; j <= i; j++) printf("0"); }(), printf("\n"), i++
) ;
}
Shortest-possible solution:
main(i){for(i=1;i<11;printf("%0*d\n",i++,0));}
Output:
0
00
000
0000
00000
000000
0000000
00000000
000000000
0000000000
LIVE DEMO
Elegance comes with clarity.
When I want to create a string of characters, I construct a C++ object called std::string.
#include <iostream>
#include <string>
int main()
{
char c = '0';
const int n = 5;
for (int i = 1; i <= n; ++i)
{
std::cout << std::string(i, c) << '\n';
}
}
So there is no need for a nested for-loop in this particular case.
Otherwise put a for-statement in the body of the outer loop as other answers suggested.
Hat tip to Michael Burr for the suggestion to use lambda. And thanks to the commentators requesting me to use putchar().
#include <stdio.h>
int main() {
int N;
scanf("%d", &N);
for (int i = 0; i < N; i++, [i] {
for (int j = 1; j <= i; j++, putchar('0'))
;
}(), printf("\n"))
;
return 0;
}
LIVE DEMO
I think we should avoid obfuscated code unless we get paid for making the code complex.

Array comparison for integer

Here I am comparing two array element , If array element are equal SETPASSWORD=1; else SETPASSWORD=0;
But Here It is always printing password set status 1 even array are not equal
#include <stdio.h>
#define ARY_SIZE 4
int password_set;
int main (void)
{
//Local Declarations
int numbersA[ARY_SIZE];
int numbersB[ARY_SIZE];
int i;
int j;
//Statements
printf("Please Enter 10 Integers For Array A\n");
for (int i = 0; i < ARY_SIZE; i++)
scanf("%d", &numbersA[i]);
printf("\nPlease Enter 10 Integers For Array B\n");
for (int j = 0; j < ARY_SIZE; j++)
scanf("%d", &numbersB[j]);
for (int i = 0; i < ARY_SIZE; i++)
{
for (int j = 0; j < ARY_SIZE; j++)
{
if (numbersA[i] == numbersB[j])
password_set=1;
else
password_set=0;
}
}
printf(" password setstaus =%d",password_set);
return 0;
}
Your logic is wrong. You must exit the loop as soon as one pair of numbers is non equal.
And you also need only one loop :
password_set = 1 ;
for (int j = 0; j < ARY_SIZE; j++)
{
if (numbersA[j] != numbersB[j])
{
password_set = 0;
break ;
}
}
Your compare each value of the array in your for (if (numbersA[i] == numbersB[j])
It resets the value of password_set at each iterations. It means that the result printed will be the last index of your array.
And btw you need only one loop
Actually, you comparison is wrong. Because you want to test two arrays is equal or not, you just test each number of these two arrays.
like this:
password_set = 1;
for (int i = 0; i < ARY_SIZE; i++) {
if (numbersA[i] != numbersB[i]) {
password_set=0;
break;
}
}

How can I properly add and access items to a multidimensional vector using loops?

I have this program that is trying to determine how many unique items are within some intersecting sets. The amount of input entirely depends on the the first value n, and then the amount of sets entered afterward. For example, if I start with entering n = 2, I am expected to enter 2 integers. The program then determines how many intersections there are between n items (this is like choosing 2 items from n items). This goes on as k increments. But that's kind of beyond the point. Just some background info.
My program adapts correctly and accepts the proper amount of input, but it stops working properly before the first for loop that is outside of the while loop. What I have tried to do is make a vector of integer vectors and then add every other row (when index starts at 0 AND index starts at 1). But I am guessing I have constructed my vectors incorrectly. Does anybody see an error in my vector logic?
#include <iostream>
#include <vector>
using namespace std;
int fact (int m) {
if (m <= 1)
return 1;
return m * fact(m - 1);
}
int comb (int n, int k) {
return fact(n)/(fact(n-k)*fact(k));
}
int main() {
int n = 0;
int k = 2;
int sum = 0;
int diff = 0;
int final = 0;
vector <vector <int> > arr;
cin >> n;
while (n > 0) {
vector <int> row;
int u;
for (int i = 0; i < n ; ++i) {
cin >> u;
row.push_back(u);
}
arr.push_back(row);
n = comb(row.size(), k);
k++;
}
for (int i = 0; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
sum += arr[i][j];
for (int i = 1; i < arr.size(); i+2)
for (int j = 0; j < arr[i].size(); ++j)
diff += arr[i][j];
final = sum - diff;
cout << final;
return 0;
}
for (int i = 0; i < arr.size(); i+=2)
^
You want to do i+=2 or i=i+2, else the value of i is never changed, leading to an infinite loop.

Matrix Multiplication Using win32 threads

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.