Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: benchmarking various tree representations and linear allocator #1598

Open
wants to merge 70 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
1c6e804
Simplify parse_implicit_mul() and the parser
certik Aug 6, 2019
cb0e669
Update generated file
certik Aug 6, 2019
b8c896a
Get rid of rcp_static_cast()
certik Aug 6, 2019
b04d0f3
Simplify the grammar (slight speedup)
certik Aug 6, 2019
e4d4e2f
Update generated file
certik Aug 6, 2019
d7498ab
Move things together
certik Aug 6, 2019
bdcb6c9
Fix the shift/reduce conflict
certik Aug 6, 2019
ee175c1
Regenerate
certik Aug 6, 2019
7df06e6
Use better formatting
certik Aug 6, 2019
92e3c30
Regenerate
certik Aug 6, 2019
372c0ce
Simplify func rule
certik Aug 6, 2019
e254b7c
Polish the syntax
certik Aug 6, 2019
6afdbf9
Update
certik Aug 6, 2019
64f0eb7
Simplify a few lines
certik Aug 6, 2019
f0a38da
Update generated file
certik Aug 6, 2019
4f1a90d
Better formatting
certik Aug 6, 2019
5fd6c92
Update generated file
certik Aug 6, 2019
4b70f67
Enable warnings in Bison
certik Aug 6, 2019
cec1fde
Fix all warnings
certik Aug 6, 2019
f6cc107
Regenerate
certik Aug 6, 2019
5f8eea5
Consolidate semantic declaration lines
certik Aug 6, 2019
6e0ca77
Regenerate
certik Aug 6, 2019
07c40dd
XX simplify
certik Aug 6, 2019
a066e9c
Simplify benchmark
certik Aug 6, 2019
a32bfad
Simplify grammar
certik Aug 6, 2019
16c8981
Simplify
certik Aug 6, 2019
71744c7
Only do integers
certik Aug 6, 2019
470fe57
Simple
certik Aug 6, 2019
db27753
Use macros
certik Aug 6, 2019
1399d41
Add sem.h
certik Aug 6, 2019
5cb0086
Update
certik Aug 6, 2019
6d5cbd5
stype
certik Aug 6, 2019
ef181ce
Return int
certik Aug 6, 2019
bfcea0b
Update
certik Aug 6, 2019
3d99bec
Works
certik Aug 6, 2019
82c30ff
Work on C structures
certik Aug 6, 2019
a15c65e
Improve
certik Aug 6, 2019
f581c2f
Works
certik Aug 6, 2019
7fed806
WIP
certik Aug 6, 2019
73bad52
WIP working
certik Aug 6, 2019
69ddb0d
header
certik Aug 7, 2019
3fa8ee6
Update
certik Aug 7, 2019
6d38433
Update
certik Aug 7, 2019
7e8a2fe
Update
certik Aug 7, 2019
b332315
Upd
certik Aug 7, 2019
ed9560e
upd
certik Aug 7, 2019
46bcf73
Update
certik Aug 7, 2019
1757065
Add timings
certik Aug 7, 2019
11db9fd
Add unique_ptr benchmark
certik Aug 7, 2019
4e976dc
Upd
certik Aug 7, 2019
a9c5a26
Add sem7
certik Aug 7, 2019
12ff27c
Add, works
certik Aug 7, 2019
a950ec7
Update bench
certik Aug 7, 2019
7dc7fc3
Count the number of symbols
certik Aug 7, 2019
73a25e4
Speedup bench creation
certik Aug 8, 2019
ccdd31b
Update
certik Aug 8, 2019
684039d
Update
certik Aug 8, 2019
ca82887
Update
certik Aug 8, 2019
5df3ade
Update
certik Aug 8, 2019
ed911e4
Update
certik Aug 8, 2019
b4d0d75
Add a linear allocator
certik Aug 8, 2019
e8434e6
Use it
certik Aug 8, 2019
933bf98
Works and it's fast
certik Aug 8, 2019
f141c39
Works
certik Aug 8, 2019
2950c36
Update
certik Aug 8, 2019
6470734
Use allocators evehere.
certik Aug 8, 2019
6d14fd9
Use allocator in SymEngine
certik Aug 8, 2019
abaddbf
Use allocator
certik Aug 8, 2019
7f2b176
Update
certik Aug 8, 2019
2f4cc79
Update
certik Aug 8, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Expand Up @@ -35,10 +35,10 @@ endif()
# Enable C++11 support in all compilers. SymEngine will not compile unless
# the C++11 support is enabled.
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|Intel")
set(CXX11_OPTIONS "-std=c++11")
set(CXX11_OPTIONS "-std=c++17")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI")
# pgcpp
set(CXX11_OPTIONS "--gnu --c++11 -D__GXX_EXPERIMENTAL_CXX0X__")
set(CXX11_OPTIONS "--gnu --c++17 -D__GXX_EXPERIMENTAL_CXX0X__")
endif ()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CXX11_OPTIONS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CXX11_OPTIONS}")
Expand Down
57 changes: 9 additions & 48 deletions benchmarks/parsing.cpp
Expand Up @@ -3,68 +3,29 @@
#include <symengine/parser.h>
#include <symengine/parser/parser.h>

using SymEngine::Basic;
using SymEngine::RCP;
using SymEngine::print_stack_on_segfault;
using SymEngine::parse;
using SymEngine::parse_old;

int main(int argc, char *argv[])
{
SymEngine::print_stack_on_segfault();

RCP<const Basic> a;
int N;

auto t1 = std::chrono::high_resolution_clock::now();
a = parse("0");
auto t2 = std::chrono::high_resolution_clock::now();
std::cout << "parse('0') = " << *a << ": "
<< std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1)
.count()
<< "us" << std::endl;

N = 5000;
N = 50000;
std::string text;
std::string t0 = "(x + y - sin(x)/(z**2-4) - x**(y**z))";
std::string t0 = "(a*z+3+2*x + 3*y - x/(z**2-4) - x**(y**z))";
text.reserve(10000000);
text = t0;
std::cout << "Construct" << std::endl;
for (int i = 0; i < N; i++) {
text = text + " * " + t0;
text.append(" * " + t0);
}

t1 = std::chrono::high_resolution_clock::now();
a = parse(text);
t2 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1)
.count()
<< "ms" << std::endl;
std::cout << *a << std::endl;

t1 = std::chrono::high_resolution_clock::now();
a = parse_old(text);
t2 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1)
.count()
<< "ms" << std::endl;
std::cout << *a << std::endl;

/* ------------------------------------------------- */

N = 3000;
t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; i++) {
a = parse(t0);
}
t2 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1)
.count()
<< "ms" << std::endl;

t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < N; i++) {
a = parse_old(t0);
}
t2 = std::chrono::high_resolution_clock::now();
std::cout << "Parse" << std::endl;
auto t1 = std::chrono::high_resolution_clock::now();
parse(text);
auto t2 = std::chrono::high_resolution_clock::now();
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1)
.count()
<< "ms" << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion symengine/CMakeLists.txt
Expand Up @@ -8,7 +8,7 @@ endif()

if (WITH_GENERATE_PARSER)
add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/parser/parser.tab.cc
COMMAND ${BISON_EXECUTABLE} -d parser.yy
COMMAND ${BISON_EXECUTABLE} -Wall -d parser.yy
DEPENDS parser/parser.yy
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/parser
)
Expand Down
3 changes: 3 additions & 0 deletions symengine/constants.cpp
Expand Up @@ -3,6 +3,7 @@
#include <symengine/infinity.h>
#include <symengine/pow.h>
#include <symengine/nan.h>
#include <symengine/parser/alloc.h>

namespace SymEngine
{
Expand Down Expand Up @@ -35,6 +36,8 @@ int Constant::compare(const Basic &o) const
return name_ < s.name_ ? -1 : 1;
}

Allocator al(1000000000);

RCP<const Integer> zero = integer(0);
RCP<const Integer> one = integer(1);
RCP<const Integer> minus_one = integer(-1);
Expand Down
6 changes: 3 additions & 3 deletions symengine/cwrapper.cpp
Expand Up @@ -503,17 +503,17 @@ CWRAPPER_OUTPUT_TYPE basic_assign(basic a, const basic b)
CWRAPPER_OUTPUT_TYPE basic_parse(basic b, const char *str)
{
CWRAPPER_BEGIN
b->m = SymEngine::parse(str);
//b->m = SymEngine::parse(str);
CWRAPPER_END
}

CWRAPPER_OUTPUT_TYPE basic_parse2(basic b, const char *str, int convert_xor)
{
CWRAPPER_BEGIN
if (convert_xor > 0) {
b->m = SymEngine::parse(str);
//b->m = SymEngine::parse(str);
} else {
b->m = SymEngine::parse(str, false);
//b->m = SymEngine::parse(str, false);
}
CWRAPPER_END
}
Expand Down
2 changes: 1 addition & 1 deletion symengine/expression.cpp
Expand Up @@ -18,7 +18,7 @@ std::string poly_print(const Expression &x)

Expression::Expression(const std::string &s)
{
m_basic = parse(s);
//m_basic = parse(s);
}

} // SymEngine
2 changes: 1 addition & 1 deletion symengine/parser.h
Expand Up @@ -6,7 +6,7 @@
namespace SymEngine
{

RCP<const Basic> parse(const std::string &s, bool convert_xor = true);
void parse(const std::string &s);
RCP<const Basic> parse_old(const std::string &s, bool convert_xor = true);
}

Expand Down
52 changes: 52 additions & 0 deletions symengine/parser/alloc.h
@@ -0,0 +1,52 @@
#ifndef SYMENGINE_PARSER_ALLOC_H
#define SYMENGINE_PARSER_ALLOC_H

#define ALIGNMENT 8

inline size_t align(size_t n) {
return (n + ALIGNMENT - 1) & ~(ALIGNMENT - 1);
}

class Allocator
{
void *start;
size_t current_pos;
size_t size;
public:
Allocator(size_t s) {
start = malloc(s);
if (start == nullptr) {
throw std::runtime_error("malloc failed.");
}
current_pos = (size_t)start;
current_pos = align(current_pos);
size = s;
}

void *allocate(size_t s) {
if (start == nullptr) {
throw std::runtime_error("malloc failed 2.");
}
size_t addr = current_pos;
/*
std::cout << "start:" << (size_t)start << std::endl;
std::cout << "addr:" << addr << std::endl;
std::cout << "size:" << size << std::endl;
std::cout << "s:" << s << std::endl;
std::cout << "align(s):" << align(s) << std::endl;
*/
current_pos += align(s);
if (current_pos - (size_t)start > size) {
throw std::runtime_error("Linear allocator too small.");
}
return (void*)addr;
}

template <typename T, typename... Args> T* make_new(Args &&... args) {
return new(allocate(sizeof(T))) T(std::forward<Args>(args)...);
// To test the default "new", comment the above and uncomment this:
//return new T(std::forward<Args>(args)...);
}
};

#endif
22 changes: 7 additions & 15 deletions symengine/parser/parser.cpp
Expand Up @@ -6,24 +6,21 @@
namespace SymEngine
{

RCP<const Basic> parse(const std::string &s, bool convert_xor)
void parse(const std::string &s)
{
// This is expensive:
Parser p;
// If you need to parse multiple strings, initialize Parser first, then
// call Parser::parse() repeatedly.
return p.parse(s, convert_xor);
p.parse(s);
}

RCP<const Basic> Parser::parse(const std::string &input, bool convert_xor)
void Parser::parse(const std::string &input)
{
inp = input;
if (convert_xor) {
std::replace(inp.begin(), inp.end(), '^', '@');
}
m_tokenizer.set_string(inp);
if (yyparse(*this) == 0)
return this->res;
return;
throw ParseError("Parsing Unsuccessful");
}

Expand Down Expand Up @@ -283,20 +280,15 @@ Parser::parse_implicit_mul(const std::string &expr)
char *endptr = 0;
std::strtod(startptr, &endptr);

RCP<const Basic> num = one, sym;

// Numerical part of the result of e.g. "100x";
size_t length = endptr - startptr;
std::string lexpr = std::string(startptr, length);
num = parse_numeric(lexpr);
RCP<const Basic> num = parse_numeric(lexpr);

// get the rest of the string
lexpr = std::string(startptr + length, expr.length() - length);
if (lexpr.length() == 0) {
sym = one;
} else {
sym = parse_identifier(lexpr);
}
SYMENGINE_ASSERT(lexpr.length() > 0);
RCP<const Basic> sym = parse_identifier(lexpr);
return std::make_tuple(num, sym);
}

Expand Down
2 changes: 1 addition & 1 deletion symengine/parser/parser.h
Expand Up @@ -35,7 +35,7 @@ class Parser
Tokenizer m_tokenizer;
RCP<const Basic> res;

RCP<const Basic> parse(const std::string &input, bool convert_xor = true);
void parse(const std::string &input);
int parse();

RCP<const Basic> functionify(const std::string &name, vec_basic &params);
Expand Down