Skip to content

Instantly share code, notes, and snippets.

@ahmetilgin
Last active January 13, 2018 19:42
Show Gist options
  • Save ahmetilgin/0708ff7483f35df7f39d556e5f02d1be to your computer and use it in GitHub Desktop.
Save ahmetilgin/0708ff7483f35df7f39d556e5f02d1be to your computer and use it in GitHub Desktop.
Cuda Matrix Product Vector
#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