Skip to content

Instantly share code, notes, and snippets.

@mmajewsk
Last active December 8, 2015 15:54
Show Gist options
  • Save mmajewsk/c2704ee3a5629753bdf8 to your computer and use it in GitHub Desktop.
Save mmajewsk/c2704ee3a5629753bdf8 to your computer and use it in GitHub Desktop.
cuda mini-project
#include "logger.hpp"
Logger::Logger(double *x,
double *y,
double *total_distance,
int n,
std::string datapath):x(x),y(y),total_distance(total_distance),size(n),datapath(datapath){
file.open(datapath);
file<<"i"<<" "<<"x"<<" "<<"y"<<" "<<"d"<<"\n";
}
void Logger::log_histograms(){
for(int i =0 ;i < size; ++i){
file<<i<<" "<<x[i]<<" "<<y[i]<<" "<<total_distance[i]<<"\n";
}
}
void Logger::stop(){
file.close();
//a
}
#include <fstream>
#include <iostream>
#include <cstdio>
#include <cstdlib>
class Logger{
public:
double *x;
double *y;
double * total_distance;
int size;
std::ofstream file;
std::string datapath;
Logger(double *x, double *y, double *total_distance, int n, std::string datapath);
void log_histograms();
void stop();
};
#include "processor.hpp"
#include "logger.hpp"
#include <string>
int main(int args, char **vargs){
std::string cuda(vargs[1]);
std::string datapath(vargs[2]);
std::string s_steps(vargs[3]);
std::string s_size(vargs[4]);
bool processing_on_gpu = cuda=="gpu"?true:false;
int number_of_particles = std::stoi(s_size);
int startx = 0;
int starty = 0;
int _time = 0;
int dt = 1;
double *vx_d;
auto vx_h = new double[number_of_particles];
auto vy_h = new double[number_of_particles];
auto X = new double[number_of_particles];
auto Y = new double[number_of_particles];
auto total_distance = new double[number_of_particles];
auto steps = std::stoi(s_steps);
Processor * processor;
if (processing_on_gpu){
processor = (Processor *)(new GPU(number_of_particles));
}
else{
processor = (Processor *)(new CPU(number_of_particles));
}
processor->setIinitialPosition(X,Y);
processor->setInitialVelocity(vx_h,vy_h);
Logger logger(X,Y,total_distance,number_of_particles,datapath);
//std::ofstream fs(datapath);
for(int i = 0; i<steps; ++i ){
//std::cout<<"petla"<<std::endl;
_time = processor->evolveSystem(X,Y,vx_h,vy_h,total_distance,number_of_particles,_time,dt);
//print_to_file(X, Y, number_of_particles, step, fs);
}
logger.log_histograms();
logger.stop();
}
#include "processor.hpp"
Processor::Processor(int size){
this->size = size;
}
void Processor::setInitialVelocity(double *vx_h, double *vy_h){
std::default_random_engine generator;
std::normal_distribution<double> distribution(1.0,2.5);
for(auto i = 0; i<size; ++i) {
vx_h[i] = distribution(generator);
vy_h[i] = distribution(generator);
}
}
void Processor::setIinitialPosition(double *x, double *y ){
for(int i=0;i<size;++i){
x[i] = 0.0;
y[i] = 0.0;
}
}
void Processor::randomizeVelocity(double * vx_h, double * vy_h){
std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0,1.0);
for(auto i = 0; i<size; ++i) {
if(distribution(generator) > 0.5){
vx_h[i] = -vx_h[i];
vy_h[i] = -vy_h[i];
}
}
}
void Processor::countTotalDistance(double * vx_h, double * vy_h, double * total_distance){
this->euclidianDistance(vx_h,vy_h,tmpa);
this->addVectors(tmpa,total_distance,total_distance);
}
int Processor::evolveSystem(double *x,
double *y,
double *vx_h,
double *vy_h,
double *total_distance,
int l,
int t,
int dt ){
t += dt;
this->countTotalDistance(vx_h, vy_h, total_distance);
this->addVectors(x, vx_h, tmpa);
this->addVectors(y, vy_h, tmpb);
this->addVectors(x, tmpa, x);
this->addVectors(y, tmpb, y);
this->multiplyVector(x, tmpa, 0.025);
this->multiplyVector(y, tmpb, 0.025);
this->addVectors(x, tmpa, vx_h);
this->addVectors(y, tmpb, vy_h);
this->randomizeVelocity(vx_h,vy_h);
return t;
}
CPU::CPU(int size): Processor(size){
size = size;
tmpa = new double[size];
tmpb = new double[size];
}
void CPU::addVectors(double * a, double * b, double * result){
for(auto i = 0; i<size; ++i) result[i] = a[i] + b[i];
}
void CPU::addToVector(double * a, double* result, double value){
for(auto i = 0; i<size; ++i) result[i] = a[i] + value;
}
void CPU::multiplyVector(double * a, double * result, double value){
for(auto i = 0; i<size; ++i) result[i] = a[i] * value;
}
void CPU::euclidianDistance(double *a, double *b, double *result){
for(auto i = 0; i<size; ++i) result[i] = sqrt(pow(a[i],2)+pow(b[i],2));
}
__global__ void _AddVectors(double* a, double* b, double * c, int size){
int blockId = blockIdx.y * gridDim.x + blockIdx.x;
int threadId = blockId * (blockDim.x * blockDim.y) + (threadIdx.y * blockDim.x) + threadIdx.x;
//if(threadId<size){
c[threadId] = a[threadId] + b[threadId];
//}
}
__global__ void _AddToVector(double* a, double* result, int size, double value){
int blockId = blockIdx.y * gridDim.x + blockIdx.x;
int threadId = blockId * (blockDim.x * blockDim.y) + (threadIdx.y * blockDim.x) + threadIdx.x;
if(threadId<size){
result[threadId] = a[threadId] + value;
}
}
__global__ void _MultiplyVector(double* a, double * result, int size, double value){
int blockId = blockIdx.y * gridDim.x + blockIdx.x;
int threadId = blockId * (blockDim.x * blockDim.y) + (threadIdx.y * blockDim.x) + threadIdx.x;
if(threadId<size){
result[threadId] = a[threadId] * value;
}
}
__global__ void _EuclideanDistanceVectors(double* a, double* b, double * result, int size){
int blockId = blockIdx.y * gridDim.x + blockIdx.x;
int threadId = blockId * (blockDim.x * blockDim.y) + (threadIdx.y * blockDim.x) + threadIdx.x;
if(threadId<size){
result[threadId] = sqrt(pow(a[threadId],2)+pow(b[threadId],2));
}
}
GPU::GPU(int size): Processor(size){
cudaMalloc(&a, size*sizeof(double));
cudaMalloc(&b, size*sizeof(double));
cudaMalloc(&c, size*sizeof(double));
}
void GPU::addVectors(double * a, double * b, double * result){
cudaMemcpy(this->a, a, size*sizeof(double), cudaMemcpyHostToDevice);
cudaMemcpy(this->b, b, size*sizeof(double), cudaMemcpyHostToDevice);
dim3 gridSize(16,16);
dim3 blockSize(8,8);
_AddVectors<<<gridSize, blockSize>>>(this->a,this->b,this->c,this->size);
cudaMemcpy( result, this->c, size*sizeof(double), cudaMemcpyDeviceToHost);
}
void GPU::addToVector(double * a, double* result, double value){
cudaMemcpy(this->a, a, size*sizeof(double), cudaMemcpyHostToDevice);
dim3 gridSize(16,16);
dim3 blockSize(8,8);
_AddToVector<<<gridSize, blockSize>>>(this->a, this->c, this->size, value);
cudaMemcpy( result, this->c, size*sizeof(double), cudaMemcpyDeviceToHost);
}
void GPU::multiplyVector(double * a, double * result, double value){
cudaMemcpy(this->a, a, size*sizeof(double), cudaMemcpyHostToDevice);
dim3 gridSize(16,16);
dim3 blockSize(8,8);
_MultiplyVector<<<gridSize, blockSize>>>(this->a, this->c, this->size, value);
cudaMemcpy( result, this->c, size*sizeof(double), cudaMemcpyDeviceToHost);
}
void GPU::euclidianDistance(double *a, double *b, double *result){
cudaMemcpy(this->a, a, size*sizeof(double), cudaMemcpyHostToDevice);
cudaMemcpy(this->b, b, size*sizeof(double), cudaMemcpyHostToDevice);
dim3 gridSize(16,16);
dim3 blockSize(8,8);
_EuclideanDistanceVectors<<<gridSize, blockSize>>>(this->a,this->b,this->c,this->size);
cudaMemcpy( result, this->c, size*sizeof(double), cudaMemcpyDeviceToHost);
}
#include <time.h>
#include <cuda_runtime_api.h>
#include <cuda.h>
#include <cmath>
#include <random>
class Processor{
public:
double *tmpa, *tmpb;
int size;
Processor(int size);
virtual void addVectors(double * a, double * b, double * result) = 0;
virtual void addToVector(double * a, double * result, double value) = 0;
virtual void multiplyVector(double * a, double * result, double value) = 0;
virtual void euclidianDistance(double *a, double *b, double *result) = 0;
void countTotalDistance(double * vx_h, double * vy_h, double * total_distance);
void setInitialVelocity(double *vx_h, double *vy_h);
void setIinitialPosition(double *x, double *y );
void randomizeVelocity(double * vx_h, double * vy_h);
int evolveSystem(double *x,
double *y,
double *vx_h,
double *vy_h,
double* total_distance,
int l,
int t,
int dt);
};
class CPU: public Processor
{
public:
CPU(int size);
void addVectors(double * a, double * b, double * result);
void addToVector(double * a, double * result, double value);
void multiplyVector(double * a, double * result, double value);
void euclidianDistance(double *a, double *b, double *result);
void countTotalDistance(double * vx_h, double * vy_h, double * total_distance);
};
class GPU: public Processor
{
public:
double *a, *b, *c;
GPU(int size);
void addVectors(double * a, double * b, double * result);
void addToVector(double * a, double* result, double value);
void multiplyVector(double * a, double * result, double value);
void euclidianDistance(double *a, double *b, double *result);
void countTotalDistance(double * vx_h, double * vy_h, double * total_distance);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment