Last active
January 13, 2018 19:42
-
-
Save ahmetilgin/0708ff7483f35df7f39d556e5f02d1be to your computer and use it in GitHub Desktop.
Cuda Matrix Product Vector
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <cstdlib> | |
#include <time.h> | |
#include "boost/lexical_cast.hpp" | |
using namespace std; | |
//Fonksiyon Prototipleri | |
void readMatrix(string, double *&, int &); | |
void vectorInit(double *x , int boyut); | |
void print_array(double *a, const int N); | |
void serialMultiply(double *vec, double *mat, double *out, const int N, const int M); | |
//GPU da calisan kernel fonksiyonu parametre olarak vecktor matris,sonuc kolon sayısı satır sayısı alıyor | |
__global__ void kernel(double *vec, double *mat, double *out, const int N, const int M){ | |
// indise erişim için hangi block hangi thread hangi indis | |
int tid=threadIdx.x+blockIdx.x*blockDim.x; | |
double sum=0; | |
if(tid<M){ | |
// Matris vektor carpimi | |
for(int i=0; i<N; i++) | |
{ | |
sum += vec[i]*mat[N*tid+i]; //matris vektör | |
//sum += vec[i]*mat[(i*M)+tid]; // vektor matris | |
} | |
// Outa yazılıyor | |
out[tid]=sum; | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
// device a kopyalanacak matris vektör ve sonuc vektörleri | |
double *dev_matris, *dev_vec, *dev_sonuc; | |
double *sonuc; | |
// süre tanımlaması | |
time_t start,finish; | |
double *carpimVectoru; | |
double *data,*row,*column; | |
int rowSize,columnSize,dataSize; | |
//Dosyadan okuma işlemleri | |
readMatrix("Rp.txt",row,rowSize); | |
readMatrix("C.txt",column,columnSize); | |
readMatrix("D.txt",data,dataSize); | |
int kolonSize = 0; | |
// En büyük kolon tespiti matris sınırı için | |
for(int a= 0 ;a < columnSize;a++){ | |
if(column[a] > kolonSize){ | |
kolonSize = column[a]; | |
} | |
} | |
// tüm elemanları sıfırla matrixin | |
rowSize--; | |
cout<<"Enbuyuk kolonSize "<<kolonSize<<endl<<"Satir:"<<rowSize<<endl; | |
double * matrix = (double*)malloc(sizeof(double)*(rowSize)*kolonSize); | |
// tüm elemanları sıfırla matrixin | |
for(int i = 0; i < rowSize;i++){ | |
for(int j = 0; j < kolonSize;j++){ | |
matrix[i*kolonSize+j] = 0; | |
} | |
} | |
// hangi satırda kaç eleman olduğunu anlamak için | |
int satirdakiElemanlar[rowSize]; | |
for(int i = 0 ; i < rowSize;i++){ | |
satirdakiElemanlar[i] = row[i+1] - row[i]; | |
} | |
// carpacagimiz 1.0 lardan oluşan vektör tanımlaması ve hepsine 1.0 atanıyor | |
carpimVectoru=(double*)malloc(sizeof(double)*kolonSize); | |
vectorInit(carpimVectoru,kolonSize); | |
int a = 0; | |
int sinir = 0; | |
int sutun =0; | |
// sparse vektörlerinden matrix oluşturulması | |
for(int i = 0; i < rowSize;i++){ | |
for(a = 0 ;a < satirdakiElemanlar[i];a++){ | |
sutun = column[sinir]-1; | |
matrix[ i*kolonSize + sutun] = data[sinir]; | |
sinir++; | |
} | |
} | |
// test için | |
// for(int i = 0; i < rowSize;i++){ | |
// for(int j = 0 ; j < kolonSize;j++){ | |
// cout<<matrix[i*kolonSize+j]<<" "; | |
// } | |
// cout<<endl; | |
// } | |
// sonuc için kolon kadar yer ayırtılıyor | |
sonuc=(double*)malloc(sizeof(double)*kolonSize); | |
vectorInit(sonuc,kolonSize); | |
// cuda da bellek bölgeleri ayırtılıyor device üzerinde ki bellekte | |
cudaMalloc((void**)&dev_vec, sizeof(double)*kolonSize); | |
cudaMalloc((void**)&dev_matris, sizeof(double)*(rowSize)*kolonSize); | |
cudaMalloc((void**)&dev_sonuc, sizeof(double)*(rowSize)); | |
// hostun raminden device ın ramine kopyalama işlemi | |
cudaMemcpy(dev_vec, carpimVectoru, sizeof(double)*kolonSize, cudaMemcpyHostToDevice); | |
cudaMemcpy(dev_matris, matrix, sizeof(double)*(rowSize)*kolonSize, cudaMemcpyHostToDevice); | |
// süreyi başlat | |
start=clock(); | |
serialMultiply(carpimVectoru, matrix, sonuc, rowSize, kolonSize); | |
double second=(double)(finish-start)/CLOCKS_PER_SEC; | |
cout<<"Seride geçen süre: "<<second<<"."<<endl; | |
start=clock(); | |
// device çalıştır çarpma işlemini yap | |
kernel<<<1, 10>>>(dev_vec, dev_matris, dev_sonuc, rowSize, kolonSize); | |
//kernel<<<kolonSize/256+1, 256>>>(dev_vec, dev_matris, dev_sonuc, rowSize, kolonSize); | |
// bitir süreyi ve geçen süreyi bul | |
second=(double)(finish-start)/CLOCKS_PER_SEC; | |
cudaMemcpy(sonuc, dev_sonuc, sizeof(double)*kolonSize, cudaMemcpyDeviceToHost); | |
cudaFree(dev_vec); | |
cudaFree(dev_matris); | |
cudaFree(dev_sonuc); | |
//print_array(sonuc, kolonSize); | |
cout<<"Cuda Da geçen Süre: "<<second<<"."<<endl; | |
cout<<"Row Size: "<<rowSize<<endl<<"Column Size: "<<columnSize<<endl<<"Data Size: "<<dataSize<<endl; | |
//print_array(sonuc, kolonSize); | |
return 0; | |
} | |
void readMatrix(string fileName,double *&array, int &size){ | |
ifstream matrixFile(fileName.c_str(),ios::in); | |
if(!matrixFile){ | |
cout<<"Failed to Open File!.. ("<<fileName<<")"<<endl; | |
exit(EXIT_FAILURE); | |
} | |
char ch; | |
unsigned long int counter=1; | |
while(!matrixFile.eof()){ | |
matrixFile.get(ch); | |
if(ch==' ') | |
counter++; | |
} | |
matrixFile.close(); | |
size=counter; | |
cout<<"There are "<<counter<< " elements in "<<"'"<<fileName<<"'"<< "file."<<endl; | |
array=new double[counter]; | |
matrixFile.open(fileName.c_str(),ios::in); | |
string s; | |
for(unsigned long int i=0;i<counter;i++){ | |
matrixFile>>s; | |
array[i]=boost::lexical_cast<double>(s); | |
} | |
matrixFile.close(); | |
cout<<counter<< " elements readed."<<endl; | |
} | |
void vectorInit(double *x , int boyut){ | |
for(int i = 0 ; i < boyut;i++){ | |
x[i] = 1.0; | |
} | |
} | |
void print_array(double *a, int N) { | |
int i; | |
cout<<"Sonuc:"; | |
for(i=0; i<N; i++) | |
cout<<a[i]<<" "; | |
cout<<endl; | |
} | |
void serialMultiply(double *vec, double *mat, double *out, const int N, const int M){ | |
double sum=0; | |
for(int i = 0 ; i <N;i++){ | |
sum = 0; | |
for(int j=0; j<M; j++) | |
{ | |
sum += mat[i*N+j]*vec[j]; | |
} | |
out[i] = sum; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment