Skip to content

Commit

Permalink
changed node to use std::vector
Browse files Browse the repository at this point in the history
  • Loading branch information
Magdalen Dobson committed Apr 4, 2024
1 parent ce2c4f9 commit 9aeff04
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 108 deletions.
5 changes: 5 additions & 0 deletions benchmarks/concurrentKNN/octTree/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

set -o xtrace

##NORMAL BENCH
# lock-based
g++ -DHOMEGROWN -pthread -mcx16 -O3 -std=c++17 -DNDEBUG -I . -DNoHelp -DVersioned -DHWStamp -include neighbors_bench.h -o neighbors_bench ../bench/neighborsTime.C -DHOMEGROWN -pthread -ldl -L/usr/local/lib -ljemalloc

Expand All @@ -17,6 +18,7 @@ g++ -DHOMEGROWN -pthread -mcx16 -O3 -std=c++17 -DNDEBUG -I . -DVersioned -DLazyS
# lock-free, path copying
g++ -DHOMEGROWN -pthread -mcx16 -O3 -std=c++17 -DNDEBUG -I . -DVersioned -DLazyStamp -DPathCopy -include neighbors_bench.h -o neighbors_bench_path_copy_lockfree ../bench/neighborsTime.C -DHOMEGROWN -pthread -ldl -L/usr/local/lib -ljemalloc

##WORKING SET BENCH
# lock-based
g++ -DHOMEGROWN -pthread -mcx16 -O3 -std=c++17 -DNDEBUG -I . -DNoHelp -DVersioned -DHWStamp -include working_set_bench.h -o working_set_bench ../bench/neighborsTime.C -DHOMEGROWN -pthread -ldl -L/usr/local/lib -ljemalloc

Expand All @@ -25,3 +27,6 @@ g++ -DHOMEGROWN -pthread -mcx16 -O3 -std=c++17 -DNDEBUG -I . -DNoHelp -DVersione

# lock-based, path copying
g++ -DHOMEGROWN -pthread -mcx16 -O3 -std=c++17 -DNDEBUG -I . -DNoHelp -DVersioned -DPathCopy -DHWStamp -include working_set_bench.h -o working_set_bench_path_copy ../bench/neighborsTime.C -DHOMEGROWN -pthread -ldl -L/usr/local/lib -ljemalloc

# lock-free
g++ -DHOMEGROWN -pthread -mcx16 -O3 -std=c++17 -DNDEBUG -I . -DVersioned -DLazyStamp -include working_set_bench.h -o working_set_bench_lockfree ../bench/neighborsTime.C -DHOMEGROWN -pthread -ldl -L/usr/local/lib -ljemalloc
31 changes: 14 additions & 17 deletions benchmarks/concurrentKNN/octTree/create_graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def __init__(self, color, marker, linestyle, name, binary, ds_type):
'neighbors_bench_hoh-10' : DSInfo("C6", mk[6], "-", "CLEANN-Tree-HOH, k=10", "blah", "blah"),
'working_set_bench-1' : DSInfo("C0", mk[0], "-", "CLEANN-Tree, k=1", "blah", "blah"),
'working_set_bench-10' : DSInfo("C1", mk[1], "-", "CLEANN-Tree, k=10", "blah", "blah"),
'working_set_bench_lockfree-1' : DSInfo("C7", mk[7], "-", "CLEANN-Tree-LF, k=1", "blah", "blah"),
'working_set_bench_lockfree-10' : DSInfo("C8", mk[8], "-", "CLEANN-Tree-LF, k=10", "blah", "blah"),
'working_set_bench_hoh-1' : DSInfo("C5", mk[5], "-", "CLEANN-Tree-HOH, k=1", "blah", "blah"),
'working_set_bench_hoh-10' : DSInfo("C6", mk[6], "-", "CLEANN-Tree-HOH, k=10", "blah", "blah"),
'working_set_bench_path_copy-1' : DSInfo("C3", mk[3], "-", "CLEANN-Tree-PC, k=1", "blah", "blah"),
Expand All @@ -36,6 +38,8 @@ def __init__(self, color, marker, linestyle, name, binary, ds_type):
'neighbors_bench_path_copy-10' : DSInfo("C4", mk[4], "-", "CLEANN-Tree-PC, k=10", "blah", "blah"),
'neighbors_bench_lockfree-1' : DSInfo("C7", mk[7], "-", "CLEANN-Tree-LF, k=1", "blah", "blah"),
'neighbors_bench_lockfree-10' : DSInfo("C8", mk[8], "-", "CLEANN-Tree-LF, k=10", "blah", "blah"),
'neighbors_bench_path_copy_lockfree-1' : DSInfo("C2", mk[2], "-", "CLEANN-Tree-PC, k=1", "blah", "blah"),
'neighbors_bench_path_copy_lockfree-10' : DSInfo("C9", mk[9], "-", "CLEANN-Tree-PC, k=10", "blah", "blah"),
'range_bench-.014' : DSInfo("C0", mk[0], "-", "CLEANN-Tree, r=5", "blah", "blah"),
'range_bench-.0176' : DSInfo("C1", mk[1], "-", "CLEANN-Tree, r=10", "blah", "blah"),
'range_bench_path_copy-.014' : DSInfo("C3", mk[3], "-", "CLEANN-Tree-PC, r=5", "blah", "blah"),
Expand All @@ -48,13 +52,6 @@ def __init__(self, color, marker, linestyle, name, binary, ds_type):
def toString(algname, th, ratio, size):
return algname + '-' + str(th) + 'u-' + str(ratio) + "s-" + str(size)

# def export_legend(legend, filename="legend.pdf", expand=[-5,-5,5,5]):
# fig = legend.figure
# fig.canvas.draw()
# bbox = legend.get_window_extent()
# bbox = bbox.from_extents(*(bbox.extents + np.array(expand)))
# bbox = bbox.transformed(fig.dpi_scale_trans.inverted())
# fig.savefig(filename, dpi="figure", bbox_inches=bbox)

def export_legend(legend, filename="legend.pdf"):
fig = legend.figure
Expand Down Expand Up @@ -305,6 +302,10 @@ def plot_size_graph(throughput, stddev, thread, ratios, maxkeys, algs, graph_nam
plt.title(graphtitle)
plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y))
plt.savefig(outputFile, bbox_inches='tight')

if paper_ver:
legend = plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y), ncol=8, framealpha=0.0)
export_legend(legend, 'graphs/' + graph_name + '_legend.pdf')
plt.close('all')

def plot_size_graphs(throughput, stddev, threads, ratios, maxkeys, algs, graph_name, paper_ver=False):
Expand Down Expand Up @@ -393,6 +394,10 @@ def plot_ratio_graph(throughput, stddev, thread, ratios, size, algs, graph_name,
plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y))

plt.savefig(outputFile, bbox_inches='tight')

if paper_ver:
legend = plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y), ncol=8, framealpha=0.0)
export_legend(legend, 'graphs/' + graph_name + '_legend.pdf')
plt.close('all')

def plot_ratio_graphs(throughput, stddev, threads, ratios, size, algs, graph_name, paper_ver=False):
Expand Down Expand Up @@ -476,17 +481,9 @@ def plot_scalability_graph(throughput, stddev, threads, ratio, size, algs, graph
plt.savefig(outputFile, bbox_inches='tight')

if paper_ver:
if graph_name == 'lists':
legend = plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y), ncol=2, framealpha=0.0)
elif graph_name == 'sets':
legend = plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y), ncol=3, framealpha=0.0)
else:
legend = plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y), ncol=8, framealpha=0.0)
# outputFile = 'graphs/' + graph_name + '_legend.pdf'
# legend = plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y), ncol=7, framealpha=0.0)
legend = plt.legend(loc='center left', bbox_to_anchor=(legend_x, legend_y), ncol=8, framealpha=0.0)
export_legend(legend, 'graphs/' + graph_name + '_legend.pdf')
# plt.close('all')
# return


plt.close('all')

Expand Down
29 changes: 19 additions & 10 deletions benchmarks/concurrentKNN/octTree/experiments.sh
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
#!/bin/bash
mkdir -p graphs
#run to quickly test the setup
python3 run_experiments.py [working_set_bench,working_set_bench_hoh] [36,72,144] [50] [1] 3 [3DinCube_WorkingSet_11M]
# python3 run_experiments.py [neighbors_bench] [36,72,144] [50] [1,10] 3 [3DinCube_20M]
# python3 run_experiments.py [working_set_bench,working_set_bench_hoh,working_set_bench_path_copy] [1,2,8,12,36,72,144] [50] [1] 3 [3DinCube_WorkingSet_11M]


# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy,neighbors_bench_lockfree,neighbors_bench_hoh] [1,2,4,8,12,36,72,144] [100] [1] 3 [3DinCube_20M]
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,4,8,12,36,72,144] [50] [1,10] 3 3DinCube_20M
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,4,8,12,36,72,144] [10] [1,10] 3 3DinCube_20M
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,8,12,36,72,144] [100] [1,10] 3 [3DinCube_20M]
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,8,12,36,72,144] [50] [1,10] 3 3DinCube_20M
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,8,12,36,72,144] [10] [1,10] 3 3DinCube_20M



# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,4,8,12,36,72,144] [50] [1,10] 2 [2DinCube_20M]

# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [144] [50] [1,10] 3 [3DinCube_2M,3DinCube_20M,3DinCube_200M,3DinCube_2B]

# python3 run_experiments.py [neighbors_bench] [144] [0,25,50,75,100] [1] 3 [3Dplummer_20M]
# python3 run_experiments.py [neighbors_bench] [144] [0,25,50,75,100] [1] 3 [3DinCube_20M]

# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,4,8,12,36,72,144] [10] [1,10] 3 3DPlummer_20M
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [144] [0,25,50,75,100] [1] 3 [3Dplummer_20M]
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [144] [0,25,50,75,100] [1] 3 [3DinCube_20M]

# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,4,8,12,36,72,144] [50] [1,10] 3 lucy3D_14M
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,8,12,36,72,144] [10] [1,10] 3 [3Dplummer_20M]

# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,4,8,12,36,72,144] [50] [1,10] 3 thai_statue5M
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,8,12,36,72,144] [50] [1,10] 3 [lucy3D_14M]

# python3 run_experiments.py [range_bench,range_bench_path_copy] [1,2,4,8,12,36,72,144] [10] [.014,.0176] 3 [3Dplummer_20M]
# python3 run_experiments.py [neighbors_bench,neighbors_bench_path_copy] [1,2,8,12,36,72,144] [50] [1,10] 3 [thai_statue5M]

# python3 run_experiments.py [range_bench,range_bench_path_copy] [1,2,8,12,36,72,144] [10] [.014,.0176] 3 [3Dplummer_20M]

# python3 run_experiments.py [neighbors_bench] [144] [50] [1] 3 [3DinCube_2M,3DinCube_20M,3DinCube_200M,3DinCube_2B]

##OVERSUBSCRIPTION

# python3 run_experiments.py [neighbors_bench,neighbors_bench_lockfree,neighbors_bench_path_copy,neighbors_bench_path_copy_lockfree] [144,196,288,432,500] [50] [1] 3 [3DinCube_20M]
python3 run_experiments.py [working_set_bench,working_set_bench_lockfree] [144,196,288,432,500] [50] [1] 3 [3DinCube_WorkingSet_11M]



Expand Down
43 changes: 26 additions & 17 deletions benchmarks/concurrentKNN/octTree/k_nearest_neighbors.h
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,12 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a
for(indexed_point p : T->Indexed_Pts()) {
if(points_equal(p.second->pt, q.second->pt)) return false;
}

auto points = parlay::tabulate(T->size()+1, [&] (long i) {
return (i == T->size()) ? q : T->Indexed_Pts()[i];
}, 1000);
std::vector<indexed_point> points;
for(auto i : T->Indexed_Pts()) points.push_back(i);
points.push_back(q);
// auto points = parlay::tabulate(T->size()+1, [&] (long i) {
// return (i == T->size()) ? q : T->Indexed_Pts()[i];
// }, 1000);
//two cases: either (1) the leaf size is below the cutoff, in which case
//we create a new leaf with the point q added, or (2) the leaf needs to be
//split into an internal node and two leaf children
Expand Down Expand Up @@ -684,9 +686,12 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a
cut_point = parlay::internal::binary_search(points, less);
new_bit--;
}
parlay::slice<indexed_point*, indexed_point*> pts = parlay::make_slice(points);
auto left_s = parlay::tabulate(cut_point, [&] (size_t i) {return points[i];}, 1000);
auto right_s = parlay::tabulate(points.size()-cut_point, [&] (size_t i) {return points[cut_point+i];}, 1000);
std::vector<indexed_point> left_s;
std::vector<indexed_point> right_s;
for(size_t i=0; i<points.size(); i++){
if(i<cut_point) left_s.push_back(points[i]);
else right_s.push_back(points[i]);
}
node* L = node::new_leaf(std::move(left_s), new_bit);
node* R = node::new_leaf(std::move(right_s), new_bit);
node* new_l = node::new_node(L, R, new_bit+1);
Expand Down Expand Up @@ -716,7 +721,7 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a
//we know we are in case 1
//form leaf
parlay::sequence<indexed_point> points = {q};
node* R = node::new_leaf(parlay::make_slice(std::move(points)), cur_bit-1);
node* R = node::new_leaf(std::move(points), cur_bit-1);
//new parent node should replace T as G's child
node* P;
if(lookup_bit(q.first, cur_bit) == 0) P = node::new_node(R, T, cur_bit);
Expand Down Expand Up @@ -784,8 +789,8 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a
//we know we are in case 1
//form leaf
node* G = parent;
parlay::sequence<indexed_point> points = {q};
node* R = node::new_leaf(parlay::make_slice(points), cur_bit-1);
std::vector<indexed_point> points = {q};
node* R = node::new_leaf(points, cur_bit-1);
//new parent node should replace T as G's child
node* P;
if(lookup_bit(q.first, cur_bit) == 0) P = node::new_node(R, T, cur_bit);
Expand Down Expand Up @@ -860,8 +865,9 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a
}
}

auto points = parlay::tabulate(T->size()+1, [&] (long i) {
return (i == T->size()) ? q : T->Indexed_Pts()[i];}, 1000);
std::vector<indexed_point> points;
for(auto i : T->Indexed_Pts()) points.push_back(i);
points.push_back(q);
node* G = parent;
bool left;
if(G != nullptr) left = (G->Left() == T);
Expand Down Expand Up @@ -900,9 +906,12 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a
cut_point = parlay::internal::binary_search(points, less);
new_bit--;
}
parlay::slice<indexed_point*, indexed_point*> pts = parlay::make_slice(points);
auto left_s = parlay::tabulate(cut_point, [&] (size_t i) {return points[i];}, 1000);
auto right_s = parlay::tabulate(points.size()-cut_point, [&] (size_t i) {return points[cut_point+i];}, 1000);
std::vector<indexed_point> left_s;
std::vector<indexed_point> right_s;
for(size_t i=0; i<points.size(); i++){
if(i<cut_point) left_s.push_back(points[i]);
else right_s.push_back(points[i]);
}
node* L = node::new_leaf(std::move(left_s), new_bit);
node* R = node::new_leaf(std::move(right_s), new_bit);
node* P = node::new_node(L, R, new_bit+1);
Expand Down Expand Up @@ -1143,7 +1152,7 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a

// grandparent is the last node in 'path'
bool delete_from_leaf_path_copy(indexed_point q, node* parent, node* grandparent, node* T, std::vector<link> &path){
parlay::sequence<indexed_point> pts;
std::vector<indexed_point> pts;
bool cont = false;
bool q_present = false;
for(indexed_point p : T->Indexed_Pts()){
Expand Down Expand Up @@ -1223,7 +1232,7 @@ node* find_leaf(node* T){ //takes in a point since interleave_bits() takes in a
}

pair<bool, bool> delete_from_leaf(indexed_point q, node* parent, node* grandparent, node* T){
parlay::sequence<indexed_point> pts;
std::vector<indexed_point> pts;
bool cont = false;
bool q_present = false;
for(indexed_point p : T->Indexed_Pts()){
Expand Down
74 changes: 11 additions & 63 deletions benchmarks/concurrentKNN/octTree/oct_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ struct oct_tree {

// generates a box consisting of a lower left corner,
// and an upper right corner.
static box get_box(parlay::sequence<indexed_point> &V) { // parlay::sequence<vtx*> &V) {
template<typename Seq>
static box get_box(Seq &V) { // parlay::sequence<vtx*> &V) {
size_t n = V.size();
// std::cout << n << std::endl;
auto minmax = [&] (box x, box y) {
Expand Down Expand Up @@ -111,7 +112,7 @@ struct oct_tree {
return (L.load() == nullptr) && (R.load() == nullptr);}
node* Left() {return L.load();}
node* Right() {return R.load();}
parlay::sequence<indexed_point>& Indexed_Pts(){return indexed_pts;}
std::vector<indexed_point>& Indexed_Pts(){return indexed_pts;}
// leaf_seq& Vertices() {return P;}

void set_size(size_t s){n=s;}
Expand All @@ -131,7 +132,7 @@ struct oct_tree {
}

// construct a leaf node with a sequence of points directly in it
node(parlay::sequence<indexed_point> &Pts, int currentBit) : removed(false), n(Pts.size()) {
node(std::vector<indexed_point> &Pts, int currentBit) : removed(false), n(Pts.size()) {
// strips off the integer tag, no longer needed
indexed_pts = std::move(Pts);
L = R = nullptr;
Expand All @@ -141,7 +142,7 @@ struct oct_tree {
}

// construct a leaf node with a sequence of points directly in it
node(parlay::sequence<indexed_point> &Pts, int currentBit, box &B) : removed(false), n(Pts.size()) {
node(std::vector<indexed_point> &Pts, int currentBit, box &B) : removed(false), n(Pts.size()) {
// strips off the integer tag, no longer needed
indexed_pts = std::move(Pts);
L = R = nullptr;
Expand All @@ -150,39 +151,6 @@ struct oct_tree {
bit = currentBit;
}

// construct a leaf node with a sequence of points directly in it
node(slice_t Pts, int currentBit, box &B) : removed(false), n(Pts.size()) {
// strips off the integer tag, no longer needed
indexed_pts = parlay::sequence<indexed_point>(n);
for (int i = 0; i < n; i++) {
indexed_pts[i] = Pts[i];
}
L = R = nullptr;
b = B;
set_center();
bit = currentBit;
}


// construct a leaf node with a sequence of points directly in it
node(slice_t Pts, int currentBit) : removed(false), n(Pts.size()) {
// strips off the integer tag, no longer needed
indexed_pts = parlay::sequence<indexed_point>(n);
for (int i = 0; i < n; i++) {
if(indexed_pts.size() < n) {
std::stringstream ss;
ss << "n = " << n << std::endl << "P.size() = " << indexed_pts.size() << std::endl;
std::cout << ss.str() << std::endl;
exit(1);
}
indexed_pts[i] = Pts[i];
}
L = R = nullptr;
b = get_box(indexed_pts);
set_center();
bit = currentBit;
}

// construct an internal binary node
node(node* L, node* R, int currentBit) : removed(false), L(L), R(R) {
b = box(L->b.first.minCoords(R->b.first),
Expand All @@ -209,52 +177,30 @@ struct oct_tree {
}
}

static node* new_leaf(slice_t Pts, int currentBit) {
node* r = alloc_node(Pts, currentBit);
assert(Pts.begin() != nullptr);
// new (r) node();
return r;
}

static node* new_leaf(slice_t Pts, int currentBit, box B) {
node* r = alloc_node(Pts, currentBit, B);
assert(Pts.begin() != nullptr);
// new (r) node();
return r;
}

static node* new_leaf(parlay::sequence<indexed_point> Pts, int currentBit) {
static node* new_leaf(std::vector<indexed_point> Pts, int currentBit) {
node* r = alloc_node(Pts, currentBit);
assert(Pts.begin() != nullptr);
// new (r) node();
return r;
}

static node* new_leaf(parlay::sequence<indexed_point> Pts, int currentBit, box B) {
static node* new_leaf(std::vector<indexed_point> Pts, int currentBit, box B) {
node* r = alloc_node(Pts, currentBit, B);
assert(Pts.begin() != nullptr);
// new (r) node();
return r;
}

static node* new_node(node* L, node* R, int currentBit) {
node* nd = alloc_node(L, R, currentBit);
// new (nd) node();
return nd;
}

static node* new_node(node* L, node* R, int currentBit, box B) {
node* nd = alloc_node(L, R, currentBit, B);
// new (nd) node();
return nd;
}

// ~node() {
// // need to collect in parallel
// parlay::par_do_if(n > 1000,
// [&] () { delete_tree(L.load());},
// [&] () { delete_tree(R.load());});
// }

parlay::sequence<vtx*> flatten() {
parlay::sequence<vtx*> r(n);
Expand Down Expand Up @@ -322,7 +268,7 @@ struct oct_tree {
verlib::versioned_ptr<node> R;
box b;
point centerv;
parlay::sequence<indexed_point> indexed_pts;
std::vector<indexed_point> indexed_pts;
// leaf_seq P;

void set_center() {
Expand Down Expand Up @@ -430,7 +376,9 @@ struct oct_tree {

// if run out of bit, or small then generate a leaf
if (bit == 0 || n < node_cutoff) {
return node::new_leaf(Pts, bit);
std::vector<indexed_point> points;
for(auto i : Pts) points.push_back(i);
return node::new_leaf(points, bit);
} else {

// this was extracted to lookup_bit but left as is here since the less function requires mask and val
Expand Down
Loading

0 comments on commit 9aeff04

Please sign in to comment.