sparse matrix multiplied to a vector using multicore programming.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kayjay66
    New Member
    • Mar 2010
    • 5

    sparse matrix multiplied to a vector using multicore programming.

    hello!

    MY CODE IS RUNNING AND IT'S ALL FINE, I ONLY NEED TO KNOW HOW TO MODIFY IT AND MAKE IT RUN ON A CORE 2 DUO INTEL CENTRINO.

    i have written 2 programs,
    the first one is only for creating a sparse matrix and i don't need to parallelize it. i have explained how it works in case u need to use it or something... the second code is the one that needs to be parallelized. here's what the each of the 2 programs does:

    1-the first program generates a 2d array, where most of its elements are zeros and the others are randoms between 0 and 99. the program will transform this 2d array into an equivalent sparse matrix in the CSR Format (values-columns-row index). after the transformation is complete, the program will write this sparse matrix into a file named "sparse 100". the first line written in the file will be the number of rows, then columns, then nonzero elements. (EX: if G[10][4] has 3 nonzero elements, the first line in the file "sparse 100" will be: 10 4 3.
    i have made ALL the arrays to be dynamically varied, so that if i want to change the number of rows and colums in the array, all what i have to do is go to line 13 and change i and j (i=number of rows, j=number of columns)

    2-the second program reads the output file of the first program. it will first read the first line of the file "sparse 100", and store the data read in an array (info[]) info[0]=i=number of rows, info[1]=j=number of columns, info[2]=nnz=number of nonzero elemnts. then 3 arrays will be dunamically allocated:
    B[]: is the vextor which will be multiplied to the sparse matrix. its size is the same as the number of rows of the initial 2d array (from which we have created our sparse matrix). its elements start from 1 at the index 0, and increment 1 by 1 accrording to the index (EX: B[0]=1 B[1]=2 B[2]=3...)
    A[]: its size is the same as the nonzero elements. its elements are the nonzeroelements of the original 2d array.
    J[]: its size is the same as the nonzero elements. its elements are the row index of the nonzero elements of the original 2d array.
    I[]: its size is the size of the number of rows of the original 2d array+1. it represents how many nonzero elements is there in every row.
    then, i've written a loop that will multiply the sparse matrix by the vextor B[]. it's from the line 68 till 78. it will take each elements in A[] (nonzero elements of the original 2d array) check its column index, and multiply it to the simular index in the vector.

    program1:

    Code:
    #include <iomanip>
    #include<fstream>
    #include <cstdlib>
    #include <ctime>
    #include<iostream>
    #include <new>
    using namespace std;
    int main()
    {
    
    
    	ofstream myfile ("sparse 100.txt");
    	const int i=600, j=400;   //number of rows and columns
    	int AF[i][j],nnz=0;
    		
    	unsigned cte;
        srand( time( 0 ) );
    
        for ( int a = 0; a < i; a++ )
        {
    	   for ( int b = 0; b <j; b++ )
    	   {
    		   cte=rand() %220;
    		   if(cte>100)
    			   cte=0;
    		   AF[a][b]=cte;
    		   
    		   if(cte!=0)
    		   nnz++;
    	   }
       }
    
       if (myfile.is_open())
       {
    
    
    
    		int * A, * J,I[i+1],counter=0;
    		A= new (nothrow) int[nnz];
    		J= new (nothrow) int[nnz];
    		I[0]=0;
    		for (int a = 0; a <i; a++ )
    		{
    			for ( int b = 0; b <j; b++ )
    			{
    				if(AF[a][b]!=0)
    				{
    					A[counter]=AF[a][b];
    					J[counter]=b;
    					counter++;
    				}
    			}
    			I[a+1]=counter;
    		}
    		
    		myfile <<i<<" "<<j<<" "<<nnz<<endl;
    
    		for(int a=0;a<nnz;a++)
    		{
    			myfile << A[a]<<" ";
    		}
    
    
    		myfile <<endl;
    
    		for(int a=0;a<nnz;a++)
    		{
    			myfile << J[a]<<" ";
    		}
    		myfile <<endl;
    
    		for(int a=0;a<=i;a++)
    		{
    			myfile << I[a]<<" ";
    		}
    		
       
    		myfile.close();
    	}
    
    	return 0;  
    }




    program2:

    Code:
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main() 
    {
    	ofstream myfile ("matrix multiplication.txt");
    
    	int z=1;
        int x,info[3];
        ifstream inFile;
        
        inFile.open("sparse 100.txt");
        if (!inFile) 
    	{
            cout << "Unable to open file";
            exit(1); // terminate with error
        }
    
    	for(int i=0;i<=2;i++)
    	{
    		inFile>>info[i];
    
    		
    	}
    	
    	cout<<endl;
    	
    	int i=info[0],j=info[1],nnz=info[2];
    	int *B;
    	B = new int [j] ;
    
    	for(int i=0; i<j; i++)
    		B[i]=z++;
    
    
    
    	int* A = NULL, * J = NULL, * I = NULL;
    	
    	A = new int[nnz];
    	J = new int[nnz];
    	I = new int[i+1];
    
    	for(int i=0;i<nnz;i++)
    	{
    		inFile>>A[i];
    	}
    
    	for(int i=0;i<nnz;i++)
    	{
    		inFile>>J[i];
    	}
    	
    	for(int k=0;k<=i;k++)
    	{
    		inFile>>I[k];
    	}
    	int index=0, k=0, e, count=0;
    	
    	unsigned **solution = 0;
    	solution = new unsigned *[i] ;
    
    	for( int a = 0 ; a < i ; a++ )
    		solution[a] = new unsigned[1];
    
    	for(int a=0; a<i; a++)
    	{
    		count=I[a+1]-I[a]+count;
    		while(index!=count)
    		{
    			k=k+A[index]*B[J[index]];
    			index++;
    		}
    		solution[a][0]=k;
    		k=0;
    	}
    
    	if (myfile.is_open())
    	{
    	
    
    		for(int a=0; a<i; a++)
    			myfile<<solution[a][0]<<endl;
    
    		myfile.close();
    	}
    
    
    
        inFile.close();     
        return 0;
    	system("pause");
    }


    now concerning the parallel thing, i'm writing the commands such as (/Od , /O1 , /Ob0...) in the "property pages" but nothing is changing, the needed time is still the same. i also don't know where to add the #pragma omp ... and all these stuff...
    one other problem, i've done something wrong in the "properties page", this is what i'm getting:
    /Od /D "_MBCS" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.p db" /W3 /nologo /c /ZI /TP /errorReport:pro mpt
    how can i delete this errorReport:pro mpt and replace it by the right commands?

    i wish some1 helps me! i worked hard for writing these 2 programs, and it's kinda disappointing to not know how to parallelize it all all the reading that i've been through :(
    sorry for all the reading!
    thank you in advance!
  • RedSon
    Recognized Expert Expert
    • Jan 2007
    • 4980

    #2
    MY CODE IS RUNNING AND IT'S ALL FINE, I ONLY NEED TO KNOW HOW TO MODIFY IT AND MAKE IT RUN ON A CORE 2 DUO INTEL CENTRINO.
    It shouldn't matter what CPU you are using. If your compiler supports the cpu architecture than just compile it for that architecture.

    Comment

    • kayjay66
      New Member
      • Mar 2010
      • 5

      #3
      Originally posted by RedSon
      It shouldn't matter what CPU you are using. If your compiler supports the cpu architecture than just compile it for that architecture.
      thank's for the reply, but i didn't understand what u mean... how should i know if my compiler supports the CPU architecture? and how should i compile it for that architecture?
      can u plz be more specific?
      thank you in advance :)

      Comment

      • Frinavale
        Recognized Expert Expert
        • Oct 2006
        • 9749

        #4
        The CPU contains a bunch of instructions that can be called in order to make your program work. Each CPU has a different set of instructions that can be called in order to perform your task. These instructions differ from chip to chip...for example if you have an Intel chip, the instructions available will be very different from an AMD chip. The instructions even differ from chip version to chip version.

        Your compiler will take your high level C code and transform it into machine code. (It may compile it into assembler first).

        In other words, the machine code generated by the compiler is code that is able to call the instructions that are part of the CPU.

        So, the answer to your question (how do I make my code work on a computer with Duo Intel Centrino chip?) is that the compiler does this for you!

        -Frinny

        Comment

        • kayjay66
          New Member
          • Mar 2010
          • 5

          #5
          i've been searching about how does my compiler do it, it's a very interesting subject which i didn't know about earlier.

          i'm using Microsoft Visual Studio 2008. this is a reading from my parallel amplifier:
          Elapsed Time: 40.990s
          CPU Time: 34.750s
          Unused CPU Time: 47.229s
          Core Count: 2
          Threads Created: 1

          so the compiler isn't parallelizing my code, some commands have to be added to the code... how to do it? that's what i didn't find during my search :(

          Comment

          Working...