diff --git a/Doxyfile b/Doxyfile index 22a1c04..bb91ae9 100644 --- a/Doxyfile +++ b/Doxyfile @@ -68,7 +68,7 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = G:/Dev/Exponential/docs +OUTPUT_DIRECTORY = G:/repos/Exponential/docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 # sub-directories (in 2 levels) under the output directory of each output format diff --git a/Exponential.sln b/Exponential.sln index 781745c..e248e59 100644 --- a/Exponential.sln +++ b/Exponential.sln @@ -1,31 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.3.32929.385 +VisualStudioVersion = 17.13.35919.96 d17.13 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Exponential", "Exponential\Exponential.vcxproj", "{74C04891-9509-4EA4-BC52-6D86492B203A}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Exponential", "Exponential\Exponential.vcxproj", "{2830B1BE-546C-E378-6C77-93E4E7132BE8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {74C04891-9509-4EA4-BC52-6D86492B203A}.Debug|x64.ActiveCfg = Debug|x64 - {74C04891-9509-4EA4-BC52-6D86492B203A}.Debug|x64.Build.0 = Debug|x64 - {74C04891-9509-4EA4-BC52-6D86492B203A}.Debug|x86.ActiveCfg = Debug|Win32 - {74C04891-9509-4EA4-BC52-6D86492B203A}.Debug|x86.Build.0 = Debug|Win32 - {74C04891-9509-4EA4-BC52-6D86492B203A}.Release|x64.ActiveCfg = Release|x64 - {74C04891-9509-4EA4-BC52-6D86492B203A}.Release|x64.Build.0 = Release|x64 - {74C04891-9509-4EA4-BC52-6D86492B203A}.Release|x86.ActiveCfg = Release|Win32 - {74C04891-9509-4EA4-BC52-6D86492B203A}.Release|x86.Build.0 = Release|Win32 + {2830B1BE-546C-E378-6C77-93E4E7132BE8}.Debug|x64.ActiveCfg = Debug|x64 + {2830B1BE-546C-E378-6C77-93E4E7132BE8}.Debug|x64.Build.0 = Debug|x64 + {2830B1BE-546C-E378-6C77-93E4E7132BE8}.Release|x64.ActiveCfg = Release|x64 + {2830B1BE-546C-E378-6C77-93E4E7132BE8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {C33279A4-898B-46DE-9C0E-87EE72B702AF} + SolutionGuid = {7D6F270A-75F4-460B-A7D5-E224EBA791ED} EndGlobalSection EndGlobal diff --git a/Exponential/Exponential.h b/Exponential/Exponential.cuh similarity index 83% rename from Exponential/Exponential.h rename to Exponential/Exponential.cuh index e56ae95..6ed9b19 100644 --- a/Exponential/Exponential.h +++ b/Exponential/Exponential.cuh @@ -11,6 +11,33 @@ #include #include +#ifdef USE_CUDA_ACCELERATION +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +__global__ void Fitness(int lrgst_expo, int64_t* constants, int sizeOfCons, double* x_vals, double* ranks, int sizeOfSols, double y_val) +{ + int idx = threadIdx.x + blockIdx.x * blockDim.x; + if (idx < sizeOfSols) + { + double ans = 0; + for (int i = lrgst_expo; i >= 0; i--) + ans += constants[i] * pow(x_vals[idx], (lrgst_expo - i)); + + ans -= y_val; + ranks[idx] = (ans == 0) ? DBL_MAX : fabs(1 / ans); + } +} +#endif + namespace JRAMPERSAD { namespace EXPONENTIAL @@ -66,6 +93,8 @@ namespace JRAMPERSAD return res; } + +#ifndef USE_CUDA_ACCELERATION // Genetic Algorithm helper struct struct GA_Solution { @@ -86,6 +115,7 @@ namespace JRAMPERSAD rank = (ans == 0) ? DBL_MAX : ABS(1 / ans); } }; +#endif } using namespace detail; @@ -114,8 +144,8 @@ namespace JRAMPERSAD Function(const unsigned short& Lrgst_expo) : lrgst_expo(Lrgst_expo), bInitialized(false) { if (lrgst_expo < 0) - throw std::logic_error("Function template argument must not be less than 0"); - constants.reserve(Lrgst_expo); + throw std::logic_error("Function template argument must not be less than 0"); + constants.reserve(Lrgst_expo); } /** \brief Destructor */ virtual ~Function(); @@ -140,7 +170,7 @@ namespace JRAMPERSAD void SetConstants(std::vector&& constnts); friend std::ostream& operator<<(std::ostream& os, const Function func); - + friend Function operator+(const Function& f1, const Function& f2); friend Function operator-(const Function& f1, const Function& f2); @@ -214,7 +244,7 @@ namespace JRAMPERSAD res.push_back(((NEGATE(b) - sqrt(sqr_val)) / 2 * a)); return res; } - + Function::~Function() { constants.clear(); @@ -346,7 +376,7 @@ namespace JRAMPERSAD f.SetConstants(res); return f; } - + /** Operator to subtract two functions */ Function operator-(const Function& f1, const Function& f2) { @@ -444,7 +474,7 @@ namespace JRAMPERSAD return *this; } - + Function Function::differential() const { try @@ -504,6 +534,7 @@ namespace JRAMPERSAD return ans; } +#ifndef USE_CUDA_ACCELERATION inline std::vector Function::solve_x(const double& y_val, const GA_Options& options) const { try @@ -522,12 +553,12 @@ namespace JRAMPERSAD solutions.resize(options.data_size); for (unsigned int i = 0; i < options.sample_size; i++) - solutions[i] = (GA_Solution{lrgst_expo, 0, unif(device), y_val}); + solutions[i] = (GA_Solution{ lrgst_expo, 0, unif(device), y_val }); for (unsigned int count = 0; count < options.num_of_generations; count++) { std::generate(std::execution::par, solutions.begin() + options.sample_size, solutions.end(), [this, &unif, &device, &y_val]() { - return GA_Solution{lrgst_expo, 0, unif(device), y_val}; + return GA_Solution{ lrgst_expo, 0, unif(device), y_val }; }); @@ -589,6 +620,67 @@ namespace JRAMPERSAD } return ans; } +#else + std::vector Function::solve_x(const double& y_val, const GA_Options& options) const + { + // Create initial random solutions + std::random_device device; + std::uniform_real_distribution unif(options.min_range, options.max_range); + + int64_t* cons = new int64_t[constants.size()]; + int64_t* d_cons; + for (int i = 0; i < constants.size(); i++) + cons[i] = constants[i]; + + cudaMalloc(&d_cons, sizeof(int64_t) * constants.size()); + cudaMemcpy(d_cons, cons, sizeof(int64_t) * constants.size(), cudaMemcpyHostToDevice); + + thrust::host_vector xVals(options.data_size); + thrust::device_vector d_xVals(options.data_size); + thrust::device_vector d_ranks(options.data_size); + + + for (unsigned int i = 0; i < options.sample_size; i++) + { + xVals[i] = unif(device); + } + + for (unsigned int count = 0; count < options.num_of_generations; count++) + { + for (unsigned int i = options.sample_size; i < options.data_size; i++) + { + xVals[i] = unif(device); + } + + d_xVals = xVals; + Fitness << <(options.data_size / 8192) + 1, 512 >> > (lrgst_expo, d_cons, (int)(constants.size()), d_xVals, d_ranks, options.data_size, y_val); + thrust::sort_by_key(thrust::device, d_ranks.begin(), d_ranks.end(), d_xVals.begin()); + thrust::reverse(d_xVals.begin(), d_xVals.end()); + xVals = d_xVals; + + if (count + 1 == options.num_of_generations) + { + break; + } + + std::uniform_real_distribution m((1 - options.mutation_percentage), (1 + options.mutation_percentage)); + auto x_begin = &xVals[0]; + auto x_end = &xVals[options.sample_size - 1]; + std::for_each(x_begin, x_end, [&m, &device](auto& v) { + v *= m(device); + }); + } + + std::vector ans; + for (unsigned int i = 0; i < options.sample_size; i++) + ans.push_back(xVals[i]); + + delete[] cons; + cudaFree(d_cons); + + return ans; + } +#endif } } diff --git a/Exponential/Exponential.vcxproj b/Exponential/Exponential.vcxproj index a144d23..b715f5a 100644 --- a/Exponential/Exponential.vcxproj +++ b/Exponential/Exponential.vcxproj @@ -1,14 +1,6 @@ - + - - Debug - Win32 - - - Release - Win32 - Debug x64 @@ -18,50 +10,31 @@ x64 + + + - 16.0 - Win32Proj - {74c04891-9509-4ea4-bc52-6d86492b203a} + {2830B1BE-546C-E378-6C77-93E4E7132BE8} Exponential 10.0 - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - Application true + MultiByte v143 - Unicode Application false - v143 true - Unicode + MultiByte + v143 - - - - - - - - + @@ -70,78 +43,47 @@ - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - + + true + Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpp20 - false - $(SolutionDir) - NoListing + Disabled + WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - Console true + Console + cudart_static.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + 64 + Level3 + MaxSpeed true true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpp20 - false - $(SolutionDir) - NoListing + WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + stdcpp17 - Console + true true true - true + Console + cudart_static.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + 64 + compute_89,sm_89 + - - - - - - - + \ No newline at end of file diff --git a/Exponential/Exponential.vcxproj.filters b/Exponential/Exponential.vcxproj.filters deleted file mode 100644 index 1fc27ed..0000000 --- a/Exponential/Exponential.vcxproj.filters +++ /dev/null @@ -1,30 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - - - Source Files - - - \ No newline at end of file diff --git a/Exponential/Source.cpp b/Exponential/Source.cpp deleted file mode 100644 index e90c98e..0000000 --- a/Exponential/Source.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -#include -#include "Exponential.h" -#include "Timer.h" - -using namespace JRAMPERSAD; - -using EXPONENTIAL::Function; - -typedef TIMER::Timer timer; - -void CalcRoots(std::mutex& m, const Function& func, EXPONENTIAL::GA_Options options) -{ - m.lock(); - std::cout << "Starting calculation...\n"; - m.unlock(); - - timer t; - auto gr = func.get_real_roots(options); - t.SetEnd(); - - m.lock(); - std::cout << "Time took to calculate approx root values: " << t.GetTimeInS() << "s\n"; - std::cout << "Approximate values of x where y = 0 are: \n"; - std::for_each(gr.begin(), gr.end(), - [](const auto& val) { - std::cout << "x:" << val << '\n'; - }); - m.unlock(); -} - -void SolveX(std::mutex& m, const Function& func, EXPONENTIAL::GA_Options options, const double& y) -{ - timer t; - auto res = func.solve_x(y, options); - t.SetEnd(); - - m.lock(); - std::cout << "Time took to calculate approx x values: " << t.GetTimeInS() << "s\n"; - std::cout << "Approximate values of x where y = " << y << " are: \n"; - std::for_each(res.begin(), res.end(), - [](const auto& val) { - std::cout << "x:" << val << '\n'; - }); - m.unlock(); -} - -int main() -{ - std::vector vec{ 1, 5, 4 }; - Function f{2}; - INITIALIZE_EXPO_FUNCTION(f, vec); - Function g{3}; - INITIALIZE_EXPO_FUNCTION(g, { 1, -6, 11, -6 }); - - EXPONENTIAL::GA_Options options; - options.mutation_percentage = 0.005; - options.num_of_generations = 1; - options.sample_size = 1; - options.data_size = 2; - options.min_range = 0.13; - options.max_range = 0.14; - - auto res = (f + g).get_real_roots(options); - std::for_each(res.begin(), res.end(), - [](const auto& val) { - std::cout << "x:" << val << '\n'; - }); - - std::cout << (f + g) << " when x = 0.13056\n" << (f + g).solve_y(0.13056); - - std::mutex m; - //std::thread th(CalcRoots, std::ref(m), std::cref(g), options); - //std::thread th1(SolveX, std::ref(m), std::cref(g), options, 5); - //std::thread th2(SolveX, std::ref(m), std::cref(g), options, 23); - - //CalcRoots(m, g); - - m.lock(); - //std::cout << g << " when x = 4.961015\n" << "y = " << g.solve_y(4.961015) << "\n\n"; - //std::cout << g << " when x = 4.30891\n" << "y = " << g.solve_y(4.30891) << "\n\n"; - //std::cout << g << " when x = 2\n" << "y = " << g.solve_y(2) << "\n\n"; - //std::cout << g << " when x = 3\n" << "y = " << g.solve_y(3) << "\n\n"; - - //std::cout << "Median: " << MATH::MEDIAN(gr) << '\n'; - //std::cout << "Mean: " << MATH::MEAN(gr) << '\n'; - - //std::cout << "Calculating Roots for function f(x) = " << g << '\n'; - //std::cout << "The y-intercept of the function f(x) is " << g.solve_y(0) << '\n'; - //std::cout << "dy/dx of f(x) is " << g.differential() << '\n'; - //std::cout << "f(x) = " << f << std::endl; - //std::cout << "g(x) = " << g << std::endl; - //std::cout << "f(x) + g(x) = " << f + g << std::endl; - m.unlock(); - - //th.join(); - //th1.join(); - //th2.join(); - return 0; -} \ No newline at end of file diff --git a/Exponential/Timer.h b/Exponential/Timer.h deleted file mode 100644 index 1ec849e..0000000 --- a/Exponential/Timer.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include -#include - -namespace TIMER{ - struct Timer - { - std::chrono::time_point start, end; - std::chrono::duration duration; - - Timer() - { - Reset(); - } - - ~Timer() - { - - } - - inline void Reset() noexcept - { - start = std::chrono::high_resolution_clock::now(); - } - - void SetEnd() noexcept - { - end = std::chrono::high_resolution_clock::now(); - duration = end - start; - } - - inline float GetTimeInMS() const noexcept - { - return float(duration.count() * 1000.f); - } - - inline float GetTimeInS() const noexcept - { - return float(duration.count()); - } - }; -} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e04da38 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Exponential Support Library + +## use #define USE_CUDA_ACCELERATION when importing the .cuh file to use CUDA Acceleration for Genetic Algorithm diff --git a/commit.bat b/commit.bat deleted file mode 100644 index a530b12..0000000 --- a/commit.bat +++ /dev/null @@ -1,5 +0,0 @@ -git add . -git commit -m %1 -git push - -pause \ No newline at end of file diff --git a/test.txt b/test.txt deleted file mode 100644 index e69de29..0000000