2024-03-07 12:04:57 -05:00
/*
* < Short Description >
* Copyright ( C ) 2024 Brett Terpstra
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
*/
# include <lilfbtf/test3.h>
# include <blt/std/array.h>
# include "blt/std/utility.h"
# include "blt/std/logging.h"
2024-03-07 15:46:12 -05:00
# include "blt/std/allocator.h"
2024-03-08 12:26:54 -05:00
# include "blt/profiling/profiler_v2.h"
2024-03-07 15:46:12 -05:00
# include <lilfbtf/test2.h>
# include <stack>
2024-03-07 12:04:57 -05:00
namespace fb
{
2024-03-07 15:46:12 -05:00
using TYPE = double ;
class base_t
2024-03-07 12:04:57 -05:00
{
2024-03-07 12:46:21 -05:00
private :
2024-03-07 14:05:34 -05:00
blt : : size_t argc_ = 0 ;
2024-03-07 15:46:12 -05:00
protected :
TYPE value = 0 ;
2024-03-07 12:46:21 -05:00
public :
2024-03-07 15:46:12 -05:00
explicit base_t ( blt : : size_t argc ) : argc_ ( argc )
2024-03-07 14:05:34 -05:00
{ }
[[nodiscard]] inline blt : : size_t argc ( ) const
2024-03-07 15:46:12 -05:00
{ return argc_ ; }
[[nodiscard]] inline TYPE getValue ( ) const
{
return value ;
}
inline virtual void call ( blt : : span < TYPE > args ) = 0 ;
virtual ~ base_t ( ) = default ;
} ;
class add_t : public base_t
{
public :
add_t ( ) : base_t ( 2 )
{ }
inline void call ( blt : : span < TYPE > args ) final
{
value = args [ 0 ] + args [ 1 ] ;
}
} ;
class sub_t : public base_t
{
public :
sub_t ( ) : base_t ( 2 )
{ }
inline void call ( blt : : span < TYPE > args ) final
{
value = args [ 0 ] - args [ 1 ] ;
}
} ;
class mul_t : public base_t
{
public :
mul_t ( ) : base_t ( 2 )
{ }
inline void call ( blt : : span < TYPE > args ) final
{
value = args [ 0 ] * args [ 1 ] ;
}
} ;
class div_t : public base_t
{
public :
div_t ( ) : base_t ( 2 )
{ }
inline void call ( blt : : span < TYPE > args ) final
{
if ( args [ 1 ] = = 0 )
value = 0 ;
else
value = args [ 0 ] / args [ 1 ] ;
}
} ;
class value_t : public base_t
{
public :
value_t ( ) : base_t ( 0 )
{
value = random_value ( ) ;
}
inline void call ( blt : : span < TYPE > ) final
{ }
} ;
2024-03-08 12:26:54 -05:00
blt : : bump_allocator < blt : : BLT_2MB_SIZE , true > alloc ;
2024-03-07 15:46:12 -05:00
base_t * create_node_type ( type_t i )
{
switch ( i )
{
case type_t : : ADD :
return alloc . emplace < add_t > ( ) ;
case type_t : : SUB :
return alloc . emplace < sub_t > ( ) ;
case type_t : : MUL :
return alloc . emplace < mul_t > ( ) ;
case type_t : : DIV :
return alloc . emplace < div_t > ( ) ;
case type_t : : VALUE :
return alloc . emplace < value_t > ( ) ;
default :
BLT_ERROR ( " Hey maybe something weird is going on here " ) ;
return nullptr ;
}
}
class tree2
{
private :
struct node_t
{
base_t * type ;
std : : array < node_t * , 2 > children { nullptr } ;
explicit node_t ( type_t type ) : type ( create_node_type ( type ) )
{ }
void evaluate ( )
{
2024-03-08 12:26:54 -05:00
if ( type - > argc ( ) > 0 )
{
TYPE v1 = children [ 0 ] - > type - > getValue ( ) ;
TYPE v2 = children [ 1 ] - > type - > getValue ( ) ;
TYPE d [ 2 ] { v1 , v2 } ;
type - > call ( blt : : span { d } ) ;
} else
type - > call ( { } ) ;
2024-03-07 15:46:12 -05:00
}
double evaluate_tree ( )
{
std : : stack < node_t * > nodes ;
std : : stack < node_t * > node_stack ;
nodes . push ( this ) ;
while ( ! nodes . empty ( ) )
{
auto * top = nodes . top ( ) ;
node_stack . push ( top ) ;
nodes . pop ( ) ;
for ( blt : : size_t i = 0 ; i < top - > type - > argc ( ) ; i + + )
nodes . push ( top - > children [ i ] ) ;
}
while ( ! node_stack . empty ( ) )
{
node_stack . top ( ) - > evaluate ( ) ;
node_stack . pop ( ) ;
}
2024-03-08 12:26:54 -05:00
return type - > getValue ( ) ;
2024-03-07 15:46:12 -05:00
}
~ node_t ( )
{
for ( blt : : size_t i = 0 ; i < type - > argc ( ) ; i + + )
{
alloc . destroy ( children [ i ] ) ;
alloc . deallocate ( children [ i ] ) ;
}
2024-03-08 12:26:54 -05:00
alloc . destroy ( type ) ;
alloc . deallocate ( type ) ;
2024-03-07 15:46:12 -05:00
}
} ;
node_t * root = nullptr ;
public :
void create ( blt : : u64 size )
{
root = alloc . template emplace < node_t > ( random_type ( ) ) ;
std : : stack < std : : pair < node_t * , blt : : size_t > > stack ;
stack . emplace ( root , 0 ) ;
while ( ! stack . empty ( ) )
{
auto top = stack . top ( ) ;
auto * node = top . first ;
auto depth = top . second ;
//BLT_WARN("gen type %ld with argc: %ld", node->type, node->argc);
stack . pop ( ) ;
//BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n";
2024-03-08 12:26:54 -05:00
for ( blt : : size_t i = 0 ; i < node - > type - > argc ( ) ; i + + )
2024-03-07 15:46:12 -05:00
{
if ( depth > = size )
{
node - > children [ i ] = alloc . template emplace < node_t > ( type_t : : VALUE ) ;
//BLT_INFO("Skipping due to size, value %lf", node->children[i]->value);
continue ;
}
if ( choice ( ) )
node - > children [ i ] = alloc . template emplace < node_t > ( random_type ( ) ) ;
else
node - > children [ i ] = alloc . template emplace < node_t > ( random_type_sub ( ) ) ;
//BLT_INFO("child %p to %p has type generated %ld with argc %d, value %lf", node->children[i], node,
// static_cast<int>(node->children[i]->type), node->children[i]->argc, node->children[i]->value);
if ( depth < size )
stack . emplace ( node - > children [ i ] , depth + 1 ) ;
}
//BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n";
}
// BLT_INFO("We have %ld adds, %ld subs, %ld mul, %ld div, %ld val, == %ld", t1_add, t1_sub, t1_mul, t1_div, t1_val,
// t1_add + t1_sub + t1_mul + t1_val + t1_div);
}
double evaluate ( )
{
return root - > evaluate_tree ( ) ;
}
~ tree2 ( )
2024-03-07 14:05:34 -05:00
{
2024-03-08 12:26:54 -05:00
BLT_START_INTERVAL ( " Tree Destruction " , " Inheritance Tree " ) ;
2024-03-07 15:46:12 -05:00
alloc . destroy ( root ) ;
alloc . deallocate ( root ) ;
2024-03-08 12:26:54 -05:00
BLT_END_INTERVAL ( " Tree Destruction " , " Inheritance Tree " ) ;
2024-03-07 14:05:34 -05:00
}
2024-03-07 12:04:57 -05:00
} ;
2024-03-08 12:26:54 -05:00
class tree3
{
private :
struct node_t
{
base_t * type = nullptr ;
node_t * * children = nullptr ;
2024-03-08 16:37:37 -05:00
type_t type_value ;
2024-03-08 12:26:54 -05:00
2024-03-08 16:37:37 -05:00
explicit node_t ( type_t type ) : type ( create_node_type ( type ) ) , type_value ( type )
2024-03-08 12:26:54 -05:00
{
if ( this - > type = = nullptr )
throw std : : bad_alloc ( ) ;
2024-03-08 16:37:37 -05:00
else if ( reinterpret_cast < blt : : size_t > ( this - > type ) % alignof ( base_t * ) ! = 0 )
BLT_WARN ( " type pointer %p is misaligned, expecting alignment of %ld reminder %ld " , this - > type , alignof ( base_t * ) ,
reinterpret_cast < blt : : size_t > ( this - > type ) % alignof ( base_t * ) ) ;
2024-03-08 12:26:54 -05:00
children = alloc . emplace_many < node_t * > ( this - > type - > argc ( ) ) ;
2024-03-08 16:37:37 -05:00
for ( blt : : size_t i = 0 ; i < this - > type - > argc ( ) ; i + + )
children [ i ] = nullptr ;
if ( reinterpret_cast < blt : : size_t > ( this - > children ) % alignof ( node_t * * ) ! = 0 )
BLT_WARN ( " children pointer is misaligned, expecting alignment of %ld remainder %ld " , this - > children , alignof ( node_t * * ) ,
reinterpret_cast < blt : : size_t > ( this - > children ) % alignof ( node_t * * ) ) ;
2024-03-08 12:26:54 -05:00
}
void evaluate ( ) const
{
if ( type - > argc ( ) > 0 )
{
TYPE v1 = children [ 0 ] - > type - > getValue ( ) ;
TYPE v2 = children [ 1 ] - > type - > getValue ( ) ;
TYPE d [ 2 ] { v1 , v2 } ;
type - > call ( blt : : span { d } ) ;
} else
type - > call ( { } ) ;
}
double evaluate_tree ( )
{
std : : stack < node_t * > nodes ;
std : : stack < node_t * > node_stack ;
nodes . push ( this ) ;
while ( ! nodes . empty ( ) )
{
auto * top = nodes . top ( ) ;
node_stack . push ( top ) ;
nodes . pop ( ) ;
for ( blt : : size_t i = 0 ; i < top - > type - > argc ( ) ; i + + )
nodes . push ( top - > children [ i ] ) ;
}
while ( ! node_stack . empty ( ) )
{
node_stack . top ( ) - > evaluate ( ) ;
node_stack . pop ( ) ;
}
return type - > getValue ( ) ;
}
~ node_t ( )
{
2024-03-08 16:37:37 -05:00
for ( blt : : size_t i = 0 ; i < type - > argc ( ) ; i + + )
2024-03-08 12:26:54 -05:00
{
2024-03-08 16:37:37 -05:00
alloc . destroy ( children [ i ] ) ;
alloc . deallocate ( children [ i ] ) ;
}
2024-03-08 12:26:54 -05:00
alloc . deallocate ( children ) ;
alloc . destroy ( type ) ;
alloc . deallocate ( type ) ;
}
} ;
node_t * root = nullptr ;
public :
tree3 ( )
{
// BLT_INFO(alignof(node_t*));
// BLT_TRACE(alignof(node_t*[2]));
// BLT_DEBUG(alignof(node_t*[3]));
// BLT_INFO(sizeof(node_t*));
// std::exit(0);
}
void create ( blt : : u64 size )
{
root = alloc . template emplace < node_t > ( random_type ( ) ) ;
std : : stack < std : : pair < node_t * , blt : : size_t > > stack ;
stack . emplace ( root , 0 ) ;
while ( ! stack . empty ( ) )
{
auto top = stack . top ( ) ;
auto * node = top . first ;
auto depth = top . second ;
//BLT_WARN("gen type %ld with argc: %ld", node->type, node->argc);
stack . pop ( ) ;
//BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n";
for ( blt : : size_t i = 0 ; i < node - > type - > argc ( ) ; i + + )
{
if ( depth > = size )
{
node - > children [ i ] = alloc . template emplace < node_t > ( type_t : : VALUE ) ;
//BLT_INFO("Skipping due to size, value %lf", node->children[i]->value);
continue ;
}
if ( choice ( ) )
node - > children [ i ] = alloc . template emplace < node_t > ( random_type ( ) ) ;
else
node - > children [ i ] = alloc . template emplace < node_t > ( random_type_sub ( ) ) ;
//BLT_INFO("child %p to %p has type generated %ld with argc %d, value %lf", node->children[i], node,
// static_cast<int>(node->children[i]->type), node->children[i]->argc, node->children[i]->value);
if ( depth < size )
stack . emplace ( node - > children [ i ] , depth + 1 ) ;
}
//BLT_TRACE0_STREAM << "Size: " << stack.size() << "\n";
}
// BLT_INFO("We have %ld adds, %ld subs, %ld mul, %ld div, %ld val, == %ld", t1_add, t1_sub, t1_mul, t1_div, t1_val,
// t1_add + t1_sub + t1_mul + t1_val + t1_div);
}
double evaluate ( )
{
return root - > evaluate_tree ( ) ;
}
~ tree3 ( )
{
BLT_START_INTERVAL ( " Tree Destruction " , " Inheritance Tree v2 " ) ;
alloc . destroy ( root ) ;
alloc . deallocate ( root ) ;
BLT_END_INTERVAL ( " Tree Destruction " , " Inheritance Tree v2 " ) ;
}
} ;
void run ( )
{
constexpr auto size = 512 ;
constexpr auto tree_size = 17 ;
engine . reset ( ) ;
tree2 love [ size ] ;
BLT_START_INTERVAL ( " Tree Construction " , " Inheritance Tree " ) ;
for ( auto & i : love )
i . create ( tree_size ) ;
BLT_END_INTERVAL ( " Tree Construction " , " Inheritance Tree " ) ;
BLT_START_INTERVAL ( " Tree Evaluation " , " Inheritance Tree " ) ;
for ( auto & i : love )
blt : : black_box ( i . evaluate ( ) ) ;
BLT_END_INTERVAL ( " Tree Evaluation " , " Inheritance Tree " ) ;
}
void run2 ( )
{
constexpr auto size = 512 ;
constexpr auto tree_size = 17 ;
engine . reset ( ) ;
tree3 love [ size ] ;
BLT_START_INTERVAL ( " Tree Construction " , " Inheritance Tree v2 " ) ;
for ( auto & i : love )
i . create ( tree_size ) ;
BLT_END_INTERVAL ( " Tree Construction " , " Inheritance Tree v2 " ) ;
BLT_START_INTERVAL ( " Tree Evaluation " , " Inheritance Tree v2 " ) ;
for ( auto & i : love )
blt : : black_box ( i . evaluate ( ) ) ;
BLT_END_INTERVAL ( " Tree Evaluation " , " Inheritance Tree v2 " ) ;
}
2024-03-07 12:04:57 -05:00
void test3 ( )
{
auto cum = new blt : : u8 [ 512 ] ;
auto v = blt : : array < int > : : construct ( cum , 512 ) ;
auto & vr = * v ;
BLT_TRACE ( " %p " , cum ) ;
BLT_TRACE ( v ) ;
BLT_TRACE ( * vr ) ;
vr [ 0 ] = 0 ;
BLT_TRACE ( * vr ) ;
vr [ 1 ] = 0 ;
BLT_TRACE ( * vr ) ;
vr [ 5 ] = 50 ;
BLT_DEBUG ( vr [ 5 ] ) ;
BLT_TRACE ( * vr ) ;
blt : : black_box ( v ) ;
delete [ ] cum ;
2024-03-08 12:26:54 -05:00
2024-03-08 16:37:37 -05:00
run ( ) ;
2024-03-08 12:26:54 -05:00
run2 ( ) ;
2024-03-08 16:37:37 -05:00
// using testing = blt::size_t;
// constexpr blt::size_t INT_SIZE = blt::BLT_2MB_SIZE * 8 / sizeof(testing);
// auto** data = new testing*[INT_SIZE];
//
// for (blt::size_t i = 0; i < INT_SIZE; i++)
// {
// data[i] = alloc.emplace<testing>();
// *data[i] = 256;
// }
//
// for (blt::size_t i = 0; i < INT_SIZE; i++)
// {
// alloc.deallocate(data[i]);
// auto* blk = alloc.blk(data[i]);
// if (*data[i] != 256)
// BLT_WARN("Data is not 256 (%d)! %ld || %ld || 0x%lx || 0x%lx pointer %p part of block %p", *data[i], i % blt::BLT_2MB_SIZE, i, i, i % blt::BLT_2MB_SIZE, data[i], blk);
// }
// delete[] data;
2024-03-07 12:04:57 -05:00
}
}