From c24671e1552fc20451bdf12445fdf069b29aeac8 Mon Sep 17 00:00:00 2001 From: Simon Stelter Date: Wed, 11 Sep 2019 15:37:34 +0200 Subject: [PATCH 1/2] added benchmark that turns big expressions into llvm functions --- benchmarks/CMakeLists.txt | 6 ++ benchmarks/llvm_diff_cache.cpp | 149 +++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 benchmarks/llvm_diff_cache.cpp diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index 2cd26dc3a2..a5a49828fc 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -85,3 +85,9 @@ target_link_libraries(parsing symengine) add_executable(diff_cache diff_cache.cpp) target_link_libraries(diff_cache symengine) + +if (WITH_LLVM) + add_executable(llvm_diff_cache llvm_diff_cache.cpp) + target_link_libraries(llvm_diff_cache symengine) +endif() + diff --git a/benchmarks/llvm_diff_cache.cpp b/benchmarks/llvm_diff_cache.cpp new file mode 100644 index 0000000000..10c4ce5b7d --- /dev/null +++ b/benchmarks/llvm_diff_cache.cpp @@ -0,0 +1,149 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +using SymEngine::LLVMDoubleVisitor; + +using SymEngine::Basic; +using SymEngine::RCP; +using SymEngine::add; +using SymEngine::symbol; +using SymEngine::integer; +using SymEngine::log; +using SymEngine::sin; +using SymEngine::pow; +using SymEngine::sqrt; +using SymEngine::Symbol; +using SymEngine::rcp_static_cast; +using SymEngine::free_symbols; +using SymEngine::DenseMatrix; + +double CommonSubexprLLVM() +{ + RCP e; + + std::string tmp_str = "a"; + std::vector> v; + for (int i = 0; i < 1000; ++i) { + v.push_back(symbol(tmp_str)); + tmp_str += "a"; + } + + e = integer(23); + for (unsigned int i = 0; i < v.size(); ++i) { + RCP z = symbol(tmp_str); + e = pow(e, add(cos(sqrt(log(sin(pow(v[v.size() - i - 1], v[i]))))), e)); + } + e = expand(e); + + DenseMatrix M, J, S; + M = DenseMatrix(1, 1, {e}); + S = DenseMatrix(10, 1, v); + J = DenseMatrix(1, 10); + + auto t1 = std::chrono::high_resolution_clock::now(); + jacobian(M, S, J); + auto t2 = std::chrono::high_resolution_clock::now(); + + std::cout + << "Time for jacobian with common subexpressions (with cache) : \t " + << std::setw(15) << std::setprecision(9) << std::fixed + << std::chrono::duration(t2 - t1).count() << std::endl; + + + t1 = std::chrono::high_resolution_clock::now(); + + LLVMDoubleVisitor v3; + bool symbolic_cse = true; + int opt_level = 3; + v3.init(v, { + J.get(0,0), + J.get(0,1), + J.get(0,2), + J.get(0,3), + J.get(0,4), + J.get(0,5), + J.get(0,6), + J.get(0,7), + J.get(0,8), + J.get(0,9)}, symbolic_cse, opt_level); + t2 = std::chrono::high_resolution_clock::now(); + std::cout << "Time for llvm init with common subexpressions (with cache) : \t " + << std::setw(15) << std::setprecision(9) << std::fixed + << std::chrono::duration(t2 - t1).count() << std::endl; + return 0; +} + +double NoCommonSubexprLLVM() +{ + RCP e; + + std::string tmp_str = "a"; + std::vector> v; + for (int i = 0; i < 2000; ++i) { + v.push_back(symbol(tmp_str)); + tmp_str += "a"; + } + + e = integer(23); + for (unsigned int i = 0; i < v.size(); ++i) { + RCP z = symbol(tmp_str); + e = pow(e, cos(sqrt(log(sin(pow(v[v.size() - i - 1], v[i])))))); + } + e = expand(e); + + DenseMatrix M, J, S; + M = DenseMatrix(1, 1, {e}); + S = DenseMatrix(10, 1, v); + J = DenseMatrix(1, 10); + + auto t1 = std::chrono::high_resolution_clock::now(); + jacobian(M, S, J, false); + auto t2 = std::chrono::high_resolution_clock::now(); + + std::cout + << "Time for jacobian without common subexpressions (without cache) : \t " + << std::setw(15) << std::setprecision(9) << std::fixed + << std::chrono::duration(t2 - t1).count() << std::endl; + + + t1 = std::chrono::high_resolution_clock::now(); + + LLVMDoubleVisitor v3; + bool symbolic_cse = true; + int opt_level = 3; + v3.init(v, { + J.get(0,0), + J.get(0,1), + J.get(0,2), + J.get(0,3), + J.get(0,4), + J.get(0,5), + J.get(0,6), + J.get(0,7), + J.get(0,8), + J.get(0,9)}, symbolic_cse, opt_level); + t2 = std::chrono::high_resolution_clock::now(); + std::cout << "Time for llvm init without common subexpressions (without cache) : \t " + << std::setw(15) << std::setprecision(9) << std::fixed + << std::chrono::duration(t2 - t1).count() << std::endl; + return 0; +} + +int main(int argc, char *argv[]) +{ + SymEngine::print_stack_on_segfault(); + CommonSubexprLLVM(); + NoCommonSubexprLLVM(); + return 0; +} + From a86cf45be906078fcdf0b48ed05e7d02c8fbc57d Mon Sep 17 00:00:00 2001 From: Simon Stelter Date: Wed, 11 Sep 2019 16:08:23 +0200 Subject: [PATCH 2/2] applied commit suggested by bot --- benchmarks/llvm_diff_cache.cpp | 51 ++++++++++++---------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/benchmarks/llvm_diff_cache.cpp b/benchmarks/llvm_diff_cache.cpp index 10c4ce5b7d..c7f841461d 100644 --- a/benchmarks/llvm_diff_cache.cpp +++ b/benchmarks/llvm_diff_cache.cpp @@ -59,27 +59,20 @@ double CommonSubexprLLVM() << std::setw(15) << std::setprecision(9) << std::fixed << std::chrono::duration(t2 - t1).count() << std::endl; - t1 = std::chrono::high_resolution_clock::now(); LLVMDoubleVisitor v3; bool symbolic_cse = true; int opt_level = 3; - v3.init(v, { - J.get(0,0), - J.get(0,1), - J.get(0,2), - J.get(0,3), - J.get(0,4), - J.get(0,5), - J.get(0,6), - J.get(0,7), - J.get(0,8), - J.get(0,9)}, symbolic_cse, opt_level); + v3.init(v, + {J.get(0, 0), J.get(0, 1), J.get(0, 2), J.get(0, 3), J.get(0, 4), + J.get(0, 5), J.get(0, 6), J.get(0, 7), J.get(0, 8), J.get(0, 9)}, + symbolic_cse, opt_level); t2 = std::chrono::high_resolution_clock::now(); - std::cout << "Time for llvm init with common subexpressions (with cache) : \t " - << std::setw(15) << std::setprecision(9) << std::fixed - << std::chrono::duration(t2 - t1).count() << std::endl; + std::cout + << "Time for llvm init with common subexpressions (with cache) : \t " + << std::setw(15) << std::setprecision(9) << std::fixed + << std::chrono::duration(t2 - t1).count() << std::endl; return 0; } @@ -110,30 +103,23 @@ double NoCommonSubexprLLVM() jacobian(M, S, J, false); auto t2 = std::chrono::high_resolution_clock::now(); - std::cout - << "Time for jacobian without common subexpressions (without cache) : \t " - << std::setw(15) << std::setprecision(9) << std::fixed - << std::chrono::duration(t2 - t1).count() << std::endl; - + std::cout << "Time for jacobian without common subexpressions (without " + "cache) : \t " + << std::setw(15) << std::setprecision(9) << std::fixed + << std::chrono::duration(t2 - t1).count() << std::endl; t1 = std::chrono::high_resolution_clock::now(); LLVMDoubleVisitor v3; bool symbolic_cse = true; int opt_level = 3; - v3.init(v, { - J.get(0,0), - J.get(0,1), - J.get(0,2), - J.get(0,3), - J.get(0,4), - J.get(0,5), - J.get(0,6), - J.get(0,7), - J.get(0,8), - J.get(0,9)}, symbolic_cse, opt_level); + v3.init(v, + {J.get(0, 0), J.get(0, 1), J.get(0, 2), J.get(0, 3), J.get(0, 4), + J.get(0, 5), J.get(0, 6), J.get(0, 7), J.get(0, 8), J.get(0, 9)}, + symbolic_cse, opt_level); t2 = std::chrono::high_resolution_clock::now(); - std::cout << "Time for llvm init without common subexpressions (without cache) : \t " + std::cout << "Time for llvm init without common subexpressions (without " + "cache) : \t " << std::setw(15) << std::setprecision(9) << std::fixed << std::chrono::duration(t2 - t1).count() << std::endl; return 0; @@ -146,4 +132,3 @@ int main(int argc, char *argv[]) NoCommonSubexprLLVM(); return 0; } -