Skip to content

Commit

Permalink
Add Mersene Twister random engine, correct indexing in kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
gprabowski committed Nov 16, 2020
1 parent 66bfaa1 commit d42be31
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 34 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ CC_LIBS=
## NVCC COMPILER OPTIONS ##

NVCC=nvcc
NVCC_FLAGS=--std c++17 -lineinfo
NVCC_FLAGS=--std c++17 -lineinfo -g -G
NVCC_LIBS=

# CUDA library directory:
Expand Down Expand Up @@ -73,4 +73,4 @@ $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cu $(INC_DIR)/%.cuh

# Clean objects in object directory.
clean:
$(RM) bin/* *.o $(EXE)
$(RM) bin/* *.o $(EXE)
3 changes: 1 addition & 2 deletions include/Chromosome.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class Chromosome {

Chromosome();

static auto random(int size) -> Chromosome;
static auto fromWeights(std::vector<float> genes) -> Chromosome;
};
#endif
#endif
9 changes: 6 additions & 3 deletions include/TimeSeriesPredictor.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define TIME_SERIES_PREDICTOR_CUH

#include <iostream>
#include <random>
#include <vector>
#include <random>
#include <cuda.h>
Expand Down Expand Up @@ -37,11 +38,12 @@ private:
float *mapInputGpu;
int numberOfNodes;
int populationSize;
int windowSize;
std::default_random_engine generator;
int windowSize;
std::mt19937 mt;
std::uniform_real_distribution<float> distribution;

auto maxFitness(std::vector<Chromosome> population) -> Chromosome;
auto printPopulation() -> void;
auto crossover(Chromosome chr1, Chromosome chr2) -> std::vector<Chromosome>;
auto mutate(Chromosome chr) -> Chromosome;

Expand All @@ -50,5 +52,6 @@ private:
auto randomSampleFromPopulation(int size) -> std::vector<Chromosome>;
auto launchCudaKernel() -> void;
auto prepareGpuMemory() -> void;
auto randomGenes(int size) -> Chromosome;
};
#endif
#endif
13 changes: 1 addition & 12 deletions src/Chromosome.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,8 @@ Chromosome::Chromosome() {
cumulativeProbability = 0.0;
}

auto Chromosome::random(int size) -> Chromosome {
std::default_random_engine generator;
std::uniform_real_distribution<float> distribution(-1.0, 1.0);
Chromosome chromosome;

for(int i = 0; i < size; ++i) {
chromosome.genes.push_back(distribution(generator));
}
return chromosome;
}

auto Chromosome::fromWeights(std::vector<float> genes) -> Chromosome {
Chromosome chromosome;
chromosome.genes = genes;
return chromosome;
}
}
8 changes: 4 additions & 4 deletions src/FitnessFunctionKernel.cu
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ __global__ void calculate_fitness(

for(int j = 0; j < window_size * node_number; ++j) {
// map_input[j % node_number] += data_weights[j] * input_data[j];
mapInput[j % node_number] += dataWeights[j] * data[i + j];
mapInput[j % node_number + index * node_number] += dataWeights[j + window_size * node_number * index] * data[i + j];
}

for(int j = 0; j < node_number; ++j) {
mapInput[j] = 1.0 / (1.0 + expf(-5 * mapInput[j]));
mapInput[j + index * node_number] = 1.0 / (1.0 + expf(-5 * mapInput[j + index * node_number]));
}

for(int j = 0; j < node_number; ++j) {
Expand All @@ -36,7 +36,7 @@ __global__ void calculate_fitness(

float x = 0.0f;
for(int k = 0; k < node_number; ++k) {
x += mapWeights[j * node_number + k] * mapInput[k];
x += mapWeights[j * node_number + k + node_number * node_number * index] * mapInput[k];
}

float y = 1.0 / (1.0 + expf(-5 * x));
Expand All @@ -52,4 +52,4 @@ __global__ void calculate_fitness(
fitness[index] = 1.0 / (1.0 + epsilon);

printf("Fitness: %f, index: %d\n", fitness[index], index);
}
}
43 changes: 32 additions & 11 deletions src/TimeSeriesPredictor.cu
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "../include/TimeSeriesPredictor.cuh"

TimeSeriesPredictor::TimeSeriesPredictor(std::vector<float> data, int numberOfNodes, int populationSize, int windowSize) : distribution(0.0, 1.0) {
#include <chrono>
TimeSeriesPredictor::TimeSeriesPredictor(std::vector<float> data, int numberOfNodes, int populationSize, int windowSize) : distribution(0.0, 1.0) {
this->data = data;
std::random_device rd;
mt = std::mt19937(rd());
this->numberOfNodes = numberOfNodes;
this->populationSize = populationSize;
this->windowSize = windowSize;
Expand All @@ -22,7 +24,7 @@ auto TimeSeriesPredictor::prepareGpuMemory() -> void {
gpuErrchk(cudaMalloc((void**)&this->fitnessGpu, this->populationSize * sizeof(float)));
gpuErrchk(cudaMalloc((void**)&this->dataWeightsGpu, this->populationSize * this->windowSize * this->numberOfNodes * sizeof(float)));
gpuErrchk(cudaMalloc((void**)&this->mapWeightsGpu, this->populationSize * this->numberOfNodes * this->numberOfNodes * sizeof(float)));
gpuErrchk(cudaMalloc((void**)&this->mapInputGpu, this->numberOfNodes * sizeof(float)));
gpuErrchk(cudaMalloc((void**)&this->mapInputGpu, this->populationSize * this->numberOfNodes * sizeof(float)));

if((this->fitnessHost = (float *)malloc(this->populationSize * sizeof(float))) == NULL) {
std::cerr << "malloc\n";
Expand All @@ -32,14 +34,13 @@ auto TimeSeriesPredictor::prepareGpuMemory() -> void {

auto TimeSeriesPredictor::train() -> std::vector<float> {
this->generatePopulation();
this->prepareGpuMemory();
this->prepareGpuMemory();
int generation = 0;

while(true) {
std::vector<Chromosome> nextGen;
this->launchCudaKernel();
Chromosome bestCandidate = this->maxFitness(this->population);

if(generation == 500 || abs(1.0 - bestCandidate.fitness) < 1e-5) break;

std::cout << "-----GEN {generation}-------" << std::endl;
Expand All @@ -48,7 +49,7 @@ auto TimeSeriesPredictor::train() -> std::vector<float> {
while(nextGen.size() < this->populationSize) {
auto parents = this->tournamentSelection();

if(this->distribution(this->generator) < 0.5) {
if(this->distribution(mt) < 0.5) {
auto children = this->crossover(parents[0], parents[1]);
for(auto child: children) {
nextGen.push_back(this->mutate(child));
Expand All @@ -63,12 +64,23 @@ auto TimeSeriesPredictor::train() -> std::vector<float> {
return this->maxFitness(this->population).genes;
}

auto TimeSeriesPredictor::printPopulation() -> void {
for(auto& chr : this->population) {
printf("singular fitness: %f \n", chr.fitness);
printf("Genes: \n");
for(auto& gene : chr.genes) {
printf(" %f ", gene);
}
printf("\n");

}
}
auto TimeSeriesPredictor::maxFitness(std::vector<Chromosome> population) -> Chromosome {
float maxFitness = -1.0;
Chromosome max;

for(auto chr: this->population) {
if(chr.fitness > maxFitness) {
if(chr.fitness > maxFitness) {
maxFitness = chr.fitness;
max = chr;
}
Expand All @@ -89,18 +101,27 @@ auto TimeSeriesPredictor::crossover(Chromosome chr1, Chromosome chr2) -> std::ve

auto TimeSeriesPredictor::mutate(Chromosome chr) -> Chromosome {
for(int i = 0; i < chr.genes.size(); ++i) {
if(this->distribution(this->generator) < 0.05) {
chr.genes[i] *= -1.0;
if(this->distribution(mt) < 0.08) {
chr.genes[i] = distribution(mt) * 2 - 1;
}
}
return chr;
}

auto TimeSeriesPredictor::randomGenes(int size) -> Chromosome::Chromosome {
Chromosome chr;
for(auto i = 0; i < size; ++i){
chr.genes.push_back(this->distribution(mt) * 2 - 1);
}

return chr;
}

auto TimeSeriesPredictor::generatePopulation() -> void {
int n = this->numberOfNodes;

for(int i = 0; i < this->populationSize; ++i) {
this->population.push_back(Chromosome::random(pow(n, 2) + n * this->windowSize));
this->population.push_back(randomGenes(pow(n, 2) + n * this->windowSize));
}
}

Expand Down Expand Up @@ -146,4 +167,4 @@ auto TimeSeriesPredictor::launchCudaKernel() -> void {
for(int i = 0; i < this->populationSize; ++i) {
this->population[i].fitness = fitnessHost[i];
}
}
}

0 comments on commit d42be31

Please sign in to comment.