Loading src/tree/tree.c +9 −523 Original line number Diff line number Diff line Loading @@ -281,77 +281,6 @@ void compute_medians_and_check(global_context_t *ctx, float_t *data) { free(medians_rcv); } void check_pc(global_context_t *ctx, float_t *best_guess, float_t *data, int d, float_t prop) { if (ctx->mpi_rank == 0) { int count = 0; int idx = (int)(prop * (ctx->world_size)); // idx = idx - 1; for (int i = 0; i < ctx->n_points; ++i) { count += data[i * ctx->dims + d] <= best_guess[d]; } mpi_printf(ctx,"Choosing %lf percentile on dimension %d: empirical prop %lf\n", prop, d, (float_t)count / (float_t)(ctx->n_points)); } } void check_pc_pointset(global_context_t *ctx, pointset_t *ps, float_t *best_guess, int d, float_t prop) { float_t *tmp_data; int *rcv_count; int tmp_local_count = (int)ps->n_points; int *displs; int point_count = 0; /* * ONLY FOR TEST PURPOSES * gather on master all data * perform the count on master */ if (I_AM_MASTER) { rcv_count = (int *)malloc(ctx->world_size * sizeof(int)); displs = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Gather(&tmp_local_count, 1, MPI_INT, rcv_count, 1, MPI_INT, 0, ctx->mpi_communicator); int tot_count = 0; for (int p = 0; p < ctx->world_size; ++p) { point_count += rcv_count[p]; displs[p] = tot_count; tot_count += rcv_count[p] * ps->dims; rcv_count[p] = rcv_count[p] * ps->dims; } tmp_data = (float_t *)malloc(tot_count * sizeof(float_t)); MPI_Gatherv(ps->data, ps->n_points * ps->dims, MPI_MY_FLOAT, tmp_data, rcv_count, displs, MPI_MY_FLOAT, 0, ctx->mpi_communicator); } else { MPI_Gather(&(ps->n_points), 1, MPI_INT, rcv_count, 1, MPI_INT, 0, ctx->mpi_communicator); MPI_Gatherv(ps->data, ps->n_points * ps->dims, MPI_MY_FLOAT, tmp_data, rcv_count, displs, MPI_MY_FLOAT, 0, ctx->mpi_communicator); } if (I_AM_MASTER) { MPI_DB_PRINT("[MASTER] Gathered %d points from procs\n", point_count); int count = 0; int idx = (int)(prop * (ctx->world_size)); // idx = idx - 1; for (int i = 0; i < point_count; ++i) { count += tmp_data[i * ps->dims + d] <= best_guess[d]; } mpi_printf(ctx, "[PS TEST]: "); mpi_printf(ctx, "Choosing %lf percentile on dimension %d: empirical prop %lf\n", prop, d, (float_t)count / (float_t)(point_count)); free(rcv_count); free(tmp_data); free(displs); } } float_t check_pc_pointset_parallel(global_context_t *ctx, pointset_t *ps, guess_t g, int d, float_t prop) { /* * ONLY FOR TEST PURPOSES Loading Loading @@ -437,390 +366,6 @@ void compute_bounding_box_pointset(global_context_t *ctx, pointset_t *ps) { #undef ub } void compute_adaptive_binning_pointset(global_context_t *ctx, pointset_t *ps, int k_local, int k_global, int d, float_t *bin_bounds, float_t *global_bin_counts) { float_t nn = (float_t)nn; // int use_qselect = (float_t)k < 2.*log2(nn)/nn + 1.; /* TODO: unset this */ int use_qselect = 1; int stride = ps->n_points / k_local; if (use_qselect) { // quickselect_data_element(ctx -> local_data , ctx -> dims, ctx -> // local_n_points, 1, 5); int idx = 0; while (idx < ps->n_points) { int offset = idx * ps->dims; // MPI_DB_PRINT("Startig from %d w stride %d -- %d \n", idx, stride, ctx // -> local_n_points - idx); if (ps->n_points - idx > stride) quickselect_data_element(ps->data + offset, ps->dims, ps->n_points - idx, d, stride); idx = idx + stride; } } else { qsort(ps->data, ps->n_points, ps->dims * sizeof(float_t), compare_data_element_sort); } /* * Now what is more convenient? We have to also * keep track of who owns the most "median thing" * so who owns the lb and ub of each interval * * MY approach would be to * - compute the local binning * - found the most median bin * - ask each processor to find the point nearest to that bin */ int leftover = ps->n_points - stride * k_local + stride; MPI_DB_PRINT("%lu %d %d leftover %d\n", ps->n_points, k_local, stride * k_local, leftover); /* fill the first one and the last one with the bb values */ bin_bounds[0] = 9999999; bin_bounds[k_local] = -99999999; for (size_t i = 0; i < ps->n_points; ++i) { bin_bounds[0] = MIN(ps->data[i * ps->dims + d], bin_bounds[0]); bin_bounds[k_local] = MAX(ps->data[i * ps->dims + d], bin_bounds[k_local]); } // bin_bounds[0] = ctx -> lb_box[d]; // bin_bounds[k_local] = ctx -> ub_box[d]; for (int i = 1; i < k_local; ++i) { /* retrieve the index of the datapoint on the bound */ int idx = (stride * i) - 1; /* write the value on the bins */ bin_bounds[i] = ps->data[idx * ps->dims + d]; } /* alloc and initialize global bins */ for (int i = 0; i < k_global; ++i) global_bin_counts[i] = 0; /* retrieve strides for each processor */ int *all_proc_strides = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&stride, 1, MPI_INT, all_proc_strides, 1, MPI_INT, ctx->mpi_communicator); /* retrieve leftovers for each proc */ int *all_proc_leftovers = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&leftover, 1, MPI_INT, all_proc_leftovers, 1, MPI_INT, ctx->mpi_communicator); for (int i = 0; i < ctx->world_size; ++i) { // MPI_DB_PRINT("[MASTER] recieved from proc %d stride %d leftover %d\n", i, // all_proc_strides[i], all_proc_leftovers[i]); } float_t *all_proc_bounds = (float_t *)malloc(ctx->world_size * (k_local + 1) * sizeof(float_t)); MPI_Allgather(bin_bounds, k_local + 1, MPI_MY_FLOAT, all_proc_bounds, k_local + 1, MPI_MY_FLOAT, ctx->mpi_communicator); /* exchange bounds */ /* printf("[RANK %d] bounds: [", ctx -> mpi_rank); for(int i = 0; i < k_local + 1; ++i) printf("%lf ", bin_bounds[i]); printf("]\n"); */ /* MPI_Barrier(ctx -> mpi_communicator); for(int i = 0; i < ctx -> world_size; ++i) { MPI_DB_PRINT("["); for(int b = 0; b < k_local + 1; ++b) MPI_DB_PRINT("%lf ", all_proc_bounds[i*(k_local + 1) + b]); MPI_DB_PRINT("]\n"); } */ /* * now let the dance begin * fill the global count array */ /* compute intersection between local bin and global bin */ float_t box_lb = ps->lb_box[d]; float_t box_ub = ps->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; for (int i = 0; i < ctx->world_size; ++i) for (int local_bin_idx = 0; local_bin_idx < k_local; ++local_bin_idx) { float_t local_bin_lb = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx]; float_t local_bin_ub = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx + 1]; float_t local_bin_width = local_bin_ub - local_bin_lb; int local_bin_count = local_bin_idx == k_local - 1 ? all_proc_leftovers[i] : all_proc_strides[i]; // MPI_DB_PRINT("%d \n", local_bin_count); if (local_bin_count > 0) { float_t local_bin_density = (float_t)(local_bin_count) / local_bin_width; // MPI_DB_PRINT("%lf\n", local_bin_width ); for (int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { float_t global_bin_lb = box_lb + global_bin_width * global_bin_idx; float_t global_bin_ub = box_lb + global_bin_width * (global_bin_idx + 1); float_t intersenction_lb = MAX(global_bin_lb, local_bin_lb); float_t intersenction_ub = MIN(global_bin_ub, local_bin_ub); float_t intersection_width = intersenction_ub - intersenction_lb; if (intersection_width > 0) { float_t intersection_count = intersection_width * local_bin_density; global_bin_counts[global_bin_idx] += intersection_count; } } } } /*float_t cc = 0;*/ /* MPI_DB_PRINT("Global bins: ["); for(int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { MPI_DB_PRINT("%.2lf ", global_bin_counts[global_bin_idx]); cc += global_bin_counts[global_bin_idx]; } MPI_DB_PRINT("] tot %lf\n", cc); */ /* * */ free(all_proc_strides); free(all_proc_leftovers); free(all_proc_bounds); } void compute_binning(global_context_t *ctx, int k_local, int k_global, int d, float_t *bin_bounds, float_t *global_bin_counts) { float_t nn = (float_t)nn; // int use_qselect = (float_t)k < 2.*log2(nn)/nn + 1.; /* TODO: unset this */ int use_qselect = 1; int stride = ctx->local_n_points / k_local; if (use_qselect) { // quickselect_data_element(ctx -> local_data , ctx -> dims, ctx -> // local_n_points, 1, 5); int idx = 0; while (idx < ctx->local_n_points) { int offset = idx * ctx->dims; // MPI_DB_PRINT("Startig from %d w stride %d -- %d \n", idx, stride, ctx // -> local_n_points - idx); if (ctx->local_n_points - idx > stride) quickselect_data_element(ctx->local_data + offset, ctx->dims, ctx->local_n_points - idx, d, stride); idx = idx + stride; } } else { qsort(ctx->local_data, ctx->local_n_points, ctx->dims * sizeof(float_t), compare_data_element_sort); } /* * Now what is more convenient? We have to also * keep track of who owns the most "median thing" * so who owns the lb and ub of each interval * * MY approach would be to * - compute the local binning * - found the most median bin * - ask each processor to find the point nearest to that bin */ int leftover = ctx->local_n_points - stride * k_local + stride; MPI_DB_PRINT("%lu %d %d leftover %d\n", ctx->local_n_points, k_local, stride * k_local, leftover); /* fill the first one and the last one with the bb values */ bin_bounds[0] = 9999999; bin_bounds[k_local] = -99999999; for (size_t i = 0; i < ctx->local_n_points; ++i) { bin_bounds[0] = MIN(ctx->local_data[i * ctx->dims + d], bin_bounds[0]); bin_bounds[k_local] = MAX(ctx->local_data[i * ctx->dims + d], bin_bounds[k_local]); } // bin_bounds[0] = ctx -> lb_box[d]; // bin_bounds[k_local] = ctx -> ub_box[d]; for (int i = 1; i < k_local; ++i) { /* retrieve the index of the datapoint on the bound */ int idx = (stride * i) - 1; /* write the value on the bins */ bin_bounds[i] = ctx->local_data[idx * ctx->dims + d]; } /* alloc and initialize global bins */ for (int i = 0; i < k_global; ++i) global_bin_counts[i] = 0; /* retrieve strides for each processor */ int *all_proc_strides = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&stride, 1, MPI_INT, all_proc_strides, 1, MPI_INT, ctx->mpi_communicator); /* retrieve leftovers for each proc */ int *all_proc_leftovers = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&leftover, 1, MPI_INT, all_proc_leftovers, 1, MPI_INT, ctx->mpi_communicator); for (int i = 0; i < ctx->world_size; ++i) { // MPI_DB_PRINT("[MASTER] recieved from proc %d stride %d leftover %d\n", i, // all_proc_strides[i], all_proc_leftovers[i]); } float_t *all_proc_bounds = (float_t *)malloc(ctx->world_size * (k_local + 1) * sizeof(float_t)); MPI_Allgather(bin_bounds, k_local + 1, MPI_MY_FLOAT, all_proc_bounds, k_local + 1, MPI_MY_FLOAT, ctx->mpi_communicator); /* exchange bounds */ /* printf("[RANK %d] bounds: [", ctx -> mpi_rank); for(int i = 0; i < k_local + 1; ++i) printf("%lf ", bin_bounds[i]); printf("]\n"); */ /* MPI_Barrier(ctx -> mpi_communicator); for(int i = 0; i < ctx -> world_size; ++i) { MPI_DB_PRINT("["); for(int b = 0; b < k_local + 1; ++b) MPI_DB_PRINT("%lf ", all_proc_bounds[i*(k_local + 1) + b]); MPI_DB_PRINT("]\n"); } */ float_t bin_width = ctx->ub_box[d] - ctx->lb_box[d]; /* compute intersection between local bin and global bin */ float_t box_lb = ctx->lb_box[d]; float_t box_ub = ctx->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; for (int i = 0; i < ctx->world_size; ++i) for (int local_bin_idx = 0; local_bin_idx < k_local; ++local_bin_idx) { float_t local_bin_lb = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx]; float_t local_bin_ub = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx + 1]; float_t local_bin_width = local_bin_ub - local_bin_lb; int local_bin_count = local_bin_idx == k_local - 1 ? all_proc_leftovers[i] : all_proc_strides[i]; //MPI_DB_PRINT("%d \n", local_bin_count); if (local_bin_count > 0) { float_t local_bin_density = (float_t)(local_bin_count) / local_bin_width; // MPI_DB_PRINT("%lf\n", local_bin_width ); for (int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { float_t global_bin_lb = box_lb + global_bin_width * global_bin_idx; float_t global_bin_ub = box_lb + global_bin_width * (global_bin_idx + 1); float_t intersenction_lb = MAX(global_bin_lb, local_bin_lb); float_t intersenction_ub = MIN(global_bin_ub, local_bin_ub); float_t intersection_width = intersenction_ub - intersenction_lb; if (intersection_width > 0) { float_t intersection_count = intersection_width * local_bin_density; global_bin_counts[global_bin_idx] += intersection_count; } } } } float_t cc = 0; /* MPI_DB_PRINT("Global bins: ["); for(int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { MPI_DB_PRINT("%.2lf ", global_bin_counts[global_bin_idx]); cc += global_bin_counts[global_bin_idx]; } MPI_DB_PRINT("] tot %lf\n", cc); */ free(all_proc_strides); free(all_proc_leftovers); free(all_proc_bounds); } int retrieve_guess_adaptive(global_context_t *ctx, pointset_t *ps, float_t *global_bin_counts, float_t *best_guess, int k_global, int d, float_t pc) { float_t total_count = 0.; for (int i = 0; i < k_global; ++i) total_count += global_bin_counts[i]; float_t cumulative_count = 0; int idx = 0; while ((cumulative_count + global_bin_counts[idx]) / total_count < pc) { cumulative_count += global_bin_counts[idx]; idx++; } /* find best spot in the bin */ float_t box_lb = ps->lb_box[d]; float_t box_ub = ps->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; float_t x0 = box_lb + (global_bin_width * (idx)); float_t x1 = box_lb + (global_bin_width * (idx + 1)); float_t y0 = (cumulative_count) / total_count; float_t y1 = (cumulative_count + global_bin_counts[idx]) / total_count; float_t x_guess = (pc - y0) / (y1 - y0) * (x1 - x0) + x0; /* MPI_DB_PRINT("[MASTER] best guess @ %lf is %lf on bin %d on dimension %d --- x0 %lf x1 %lf y0 %lf y1 %lf\n", pc, x_guess, idx, d, x0, x1, y0, y1); */ /* find nearest point btw guess */ int best_idx = 0; float_t best_val = 999999; for (int i = 0; i < ps->n_points; ++i) { float_t dist = fabs(x_guess - ps->data[i * ps->dims + d]); int c = dist < best_val; best_val = c ? dist : best_val; best_idx = c ? i : best_idx; } mpi_double_int best = {.val = best_val, .key = ctx->mpi_rank}; MPI_Allreduce(MPI_IN_PLACE, &best, 1, MPI_DOUBLE_INT, MPI_MINLOC, ctx->mpi_communicator); // printf("%lf %d\n", best.val, best.key); /* broadcast best guess */ if (ctx->mpi_rank == best.key) { memcpy(best_guess, ps->data + best_idx * ps->dims, ps->dims * sizeof(float_t)); } MPI_Bcast(best_guess, ps->dims, MPI_MY_FLOAT, best.key, ctx->mpi_communicator); /* recieved ? */ MPI_DB_PRINT("[MASTER] ["); for (int i = 0; i < ps->dims; ++i) MPI_DB_PRINT("%lf ", best_guess[i]); MPI_DB_PRINT("]\n"); /* printf("[rank %d] [", ctx -> mpi_rank); for(int i = 0; i < ctx -> dims; ++i) printf("%lf ", best_guess[i]); printf("]\n"); */ return idx; } guess_t retrieve_guess_pure(global_context_t *ctx, pointset_t *ps, uint64_t *global_bin_counts, Loading Loading @@ -876,68 +421,6 @@ guess_t retrieve_guess_pure(global_context_t *ctx, pointset_t *ps, return g; } void retrieve_pc(global_context_t *ctx, float_t *global_bin_counts, float_t *best_guess, int k_global, int d, float_t pc) { float_t total_count = 0.; for (int i = 0; i < k_global; ++i) total_count += global_bin_counts[i]; float_t cumulative_count = 0; int idx = 0; while ((cumulative_count + global_bin_counts[idx]) / total_count < pc) { cumulative_count += global_bin_counts[idx]; idx++; } /* find best spot in the bin */ float_t box_lb = ctx->lb_box[d]; float_t box_ub = ctx->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; float_t x0 = box_lb + (global_bin_width * (idx)); float_t x1 = box_lb + (global_bin_width * (idx + 1)); float_t y0 = (cumulative_count) / total_count; float_t y1 = (cumulative_count + global_bin_counts[idx]) / total_count; float_t x_guess = (pc - y0) / (y1 - y0) * (x1 - x0) + x0; MPI_DB_PRINT("[MASTER] best guess @ %lf is %lf on bin %d on dimension %d --> x0 %lf x1 %lf y0 %lf y1 %lf\n", pc, x_guess, idx, d, x0, x1, y0, y1); /* find nearest point btw guess */ int best_idx = 0; float_t best_val = 999999; for (int i = 0; i < ctx->local_n_points; ++i) { float_t dist = fabs(x_guess - ctx->local_data[i * ctx->dims + d]); int c = dist < best_val; best_val = c ? dist : best_val; best_idx = c ? i : best_idx; } mpi_double_int best = {.val = best_val, .key = ctx->mpi_rank}; MPI_Allreduce(MPI_IN_PLACE, &best, 1, MPI_DOUBLE_INT, MPI_MINLOC, ctx->mpi_communicator); // printf("%lf %d\n", best.val, best.key); /* broadcast best guess */ if (ctx->mpi_rank == best.key) { memcpy(best_guess, ctx->local_data + best_idx * ctx->dims, ctx->dims * sizeof(float_t)); } MPI_Bcast(best_guess, ctx->dims, MPI_MY_FLOAT, best.key, ctx->mpi_communicator); /* recieved ? */ MPI_DB_PRINT("[MASTER] ["); for (int i = 0; i < ctx->dims; ++i) MPI_DB_PRINT("%lf ", best_guess[i]); MPI_DB_PRINT("]\n"); /* printf("[rank %d] [", ctx -> mpi_rank); for(int i = 0; i < ctx -> dims; ++i) printf("%lf ", best_guess[i]); printf("]\n"); */ } void global_binning_check(global_context_t *ctx, float_t *data, int d, int k) { Loading Loading @@ -1227,6 +710,7 @@ top_kdtree_node_t* top_tree_generate_node(global_context_t* ctx, top_kdtree_t* t top_kdtree_node_t* ptr = tree -> _nodes + tree -> count; ptr -> lb_node_box = (float_t*)malloc(ctx -> dims * sizeof(float_t)); ptr -> ub_node_box = (float_t*)malloc(ctx -> dims * sizeof(float_t)); ptr -> owner = -1; ++tree -> count; return ptr; Loading @@ -1234,11 +718,12 @@ top_kdtree_node_t* top_tree_generate_node(global_context_t* ctx, top_kdtree_t* t void tree_print(global_context_t* ctx, top_kdtree_node_t* root) { MPI_DB_PRINT("Node: \n\tsplit_dim %d \n\tdata %lf", root -> split_dim, root -> data); MPI_DB_PRINT("Node %p: \n\tsplit_dim %d \n\tdata %lf", root, root -> split_dim, root -> data); MPI_DB_PRINT("\n\tparent %p", root -> parent); MPI_DB_PRINT("\n\towner %d", root -> owner); MPI_DB_PRINT("\n\tbox"); for(size_t d = 0; d < ctx -> dims; ++d) MPI_DB_PRINT("d%d:[%lf, %lf] ",(int)d, root -> lb_node_box[d], root -> lb_node_box[d]); MPI_DB_PRINT("\n"); for(size_t d = 0; d < ctx -> dims; ++d) MPI_DB_PRINT("\n\t d%d:[%lf, %lf]",(int)d, root -> lb_node_box[d], root -> ub_node_box[d]); MPI_DB_PRINT("\n\n"); if(root -> lch) tree_print(ctx, root -> lch); if(root -> rch) tree_print(ctx, root -> rch); } Loading Loading @@ -1406,6 +891,7 @@ void build_top_kdtree(global_context_t *ctx, pointset_t *og_pointset, top_kdtree } MPI_DB_PRINT("Root is %p\n", tree -> root); tree_print(ctx, tree -> root); free_queue(&queue); } Loading @@ -1432,7 +918,7 @@ void simulate_master_read_and_scatter(int dims, size_t n, global_context_t *ctx) if (ctx->mpi_rank == 0) { data = read_data_file(ctx, "../norm_data/std_LR_091_0001", MY_TRUE); data = read_data_file(ctx, "../norm_data/std_LR_091_0000", MY_TRUE); // std_g0163178_Me14_091_0000 // data = // read_data_file(ctx,"../norm_data/std_g0163178_Me14_091_0000",MY_TRUE); Loading Loading
src/tree/tree.c +9 −523 Original line number Diff line number Diff line Loading @@ -281,77 +281,6 @@ void compute_medians_and_check(global_context_t *ctx, float_t *data) { free(medians_rcv); } void check_pc(global_context_t *ctx, float_t *best_guess, float_t *data, int d, float_t prop) { if (ctx->mpi_rank == 0) { int count = 0; int idx = (int)(prop * (ctx->world_size)); // idx = idx - 1; for (int i = 0; i < ctx->n_points; ++i) { count += data[i * ctx->dims + d] <= best_guess[d]; } mpi_printf(ctx,"Choosing %lf percentile on dimension %d: empirical prop %lf\n", prop, d, (float_t)count / (float_t)(ctx->n_points)); } } void check_pc_pointset(global_context_t *ctx, pointset_t *ps, float_t *best_guess, int d, float_t prop) { float_t *tmp_data; int *rcv_count; int tmp_local_count = (int)ps->n_points; int *displs; int point_count = 0; /* * ONLY FOR TEST PURPOSES * gather on master all data * perform the count on master */ if (I_AM_MASTER) { rcv_count = (int *)malloc(ctx->world_size * sizeof(int)); displs = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Gather(&tmp_local_count, 1, MPI_INT, rcv_count, 1, MPI_INT, 0, ctx->mpi_communicator); int tot_count = 0; for (int p = 0; p < ctx->world_size; ++p) { point_count += rcv_count[p]; displs[p] = tot_count; tot_count += rcv_count[p] * ps->dims; rcv_count[p] = rcv_count[p] * ps->dims; } tmp_data = (float_t *)malloc(tot_count * sizeof(float_t)); MPI_Gatherv(ps->data, ps->n_points * ps->dims, MPI_MY_FLOAT, tmp_data, rcv_count, displs, MPI_MY_FLOAT, 0, ctx->mpi_communicator); } else { MPI_Gather(&(ps->n_points), 1, MPI_INT, rcv_count, 1, MPI_INT, 0, ctx->mpi_communicator); MPI_Gatherv(ps->data, ps->n_points * ps->dims, MPI_MY_FLOAT, tmp_data, rcv_count, displs, MPI_MY_FLOAT, 0, ctx->mpi_communicator); } if (I_AM_MASTER) { MPI_DB_PRINT("[MASTER] Gathered %d points from procs\n", point_count); int count = 0; int idx = (int)(prop * (ctx->world_size)); // idx = idx - 1; for (int i = 0; i < point_count; ++i) { count += tmp_data[i * ps->dims + d] <= best_guess[d]; } mpi_printf(ctx, "[PS TEST]: "); mpi_printf(ctx, "Choosing %lf percentile on dimension %d: empirical prop %lf\n", prop, d, (float_t)count / (float_t)(point_count)); free(rcv_count); free(tmp_data); free(displs); } } float_t check_pc_pointset_parallel(global_context_t *ctx, pointset_t *ps, guess_t g, int d, float_t prop) { /* * ONLY FOR TEST PURPOSES Loading Loading @@ -437,390 +366,6 @@ void compute_bounding_box_pointset(global_context_t *ctx, pointset_t *ps) { #undef ub } void compute_adaptive_binning_pointset(global_context_t *ctx, pointset_t *ps, int k_local, int k_global, int d, float_t *bin_bounds, float_t *global_bin_counts) { float_t nn = (float_t)nn; // int use_qselect = (float_t)k < 2.*log2(nn)/nn + 1.; /* TODO: unset this */ int use_qselect = 1; int stride = ps->n_points / k_local; if (use_qselect) { // quickselect_data_element(ctx -> local_data , ctx -> dims, ctx -> // local_n_points, 1, 5); int idx = 0; while (idx < ps->n_points) { int offset = idx * ps->dims; // MPI_DB_PRINT("Startig from %d w stride %d -- %d \n", idx, stride, ctx // -> local_n_points - idx); if (ps->n_points - idx > stride) quickselect_data_element(ps->data + offset, ps->dims, ps->n_points - idx, d, stride); idx = idx + stride; } } else { qsort(ps->data, ps->n_points, ps->dims * sizeof(float_t), compare_data_element_sort); } /* * Now what is more convenient? We have to also * keep track of who owns the most "median thing" * so who owns the lb and ub of each interval * * MY approach would be to * - compute the local binning * - found the most median bin * - ask each processor to find the point nearest to that bin */ int leftover = ps->n_points - stride * k_local + stride; MPI_DB_PRINT("%lu %d %d leftover %d\n", ps->n_points, k_local, stride * k_local, leftover); /* fill the first one and the last one with the bb values */ bin_bounds[0] = 9999999; bin_bounds[k_local] = -99999999; for (size_t i = 0; i < ps->n_points; ++i) { bin_bounds[0] = MIN(ps->data[i * ps->dims + d], bin_bounds[0]); bin_bounds[k_local] = MAX(ps->data[i * ps->dims + d], bin_bounds[k_local]); } // bin_bounds[0] = ctx -> lb_box[d]; // bin_bounds[k_local] = ctx -> ub_box[d]; for (int i = 1; i < k_local; ++i) { /* retrieve the index of the datapoint on the bound */ int idx = (stride * i) - 1; /* write the value on the bins */ bin_bounds[i] = ps->data[idx * ps->dims + d]; } /* alloc and initialize global bins */ for (int i = 0; i < k_global; ++i) global_bin_counts[i] = 0; /* retrieve strides for each processor */ int *all_proc_strides = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&stride, 1, MPI_INT, all_proc_strides, 1, MPI_INT, ctx->mpi_communicator); /* retrieve leftovers for each proc */ int *all_proc_leftovers = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&leftover, 1, MPI_INT, all_proc_leftovers, 1, MPI_INT, ctx->mpi_communicator); for (int i = 0; i < ctx->world_size; ++i) { // MPI_DB_PRINT("[MASTER] recieved from proc %d stride %d leftover %d\n", i, // all_proc_strides[i], all_proc_leftovers[i]); } float_t *all_proc_bounds = (float_t *)malloc(ctx->world_size * (k_local + 1) * sizeof(float_t)); MPI_Allgather(bin_bounds, k_local + 1, MPI_MY_FLOAT, all_proc_bounds, k_local + 1, MPI_MY_FLOAT, ctx->mpi_communicator); /* exchange bounds */ /* printf("[RANK %d] bounds: [", ctx -> mpi_rank); for(int i = 0; i < k_local + 1; ++i) printf("%lf ", bin_bounds[i]); printf("]\n"); */ /* MPI_Barrier(ctx -> mpi_communicator); for(int i = 0; i < ctx -> world_size; ++i) { MPI_DB_PRINT("["); for(int b = 0; b < k_local + 1; ++b) MPI_DB_PRINT("%lf ", all_proc_bounds[i*(k_local + 1) + b]); MPI_DB_PRINT("]\n"); } */ /* * now let the dance begin * fill the global count array */ /* compute intersection between local bin and global bin */ float_t box_lb = ps->lb_box[d]; float_t box_ub = ps->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; for (int i = 0; i < ctx->world_size; ++i) for (int local_bin_idx = 0; local_bin_idx < k_local; ++local_bin_idx) { float_t local_bin_lb = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx]; float_t local_bin_ub = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx + 1]; float_t local_bin_width = local_bin_ub - local_bin_lb; int local_bin_count = local_bin_idx == k_local - 1 ? all_proc_leftovers[i] : all_proc_strides[i]; // MPI_DB_PRINT("%d \n", local_bin_count); if (local_bin_count > 0) { float_t local_bin_density = (float_t)(local_bin_count) / local_bin_width; // MPI_DB_PRINT("%lf\n", local_bin_width ); for (int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { float_t global_bin_lb = box_lb + global_bin_width * global_bin_idx; float_t global_bin_ub = box_lb + global_bin_width * (global_bin_idx + 1); float_t intersenction_lb = MAX(global_bin_lb, local_bin_lb); float_t intersenction_ub = MIN(global_bin_ub, local_bin_ub); float_t intersection_width = intersenction_ub - intersenction_lb; if (intersection_width > 0) { float_t intersection_count = intersection_width * local_bin_density; global_bin_counts[global_bin_idx] += intersection_count; } } } } /*float_t cc = 0;*/ /* MPI_DB_PRINT("Global bins: ["); for(int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { MPI_DB_PRINT("%.2lf ", global_bin_counts[global_bin_idx]); cc += global_bin_counts[global_bin_idx]; } MPI_DB_PRINT("] tot %lf\n", cc); */ /* * */ free(all_proc_strides); free(all_proc_leftovers); free(all_proc_bounds); } void compute_binning(global_context_t *ctx, int k_local, int k_global, int d, float_t *bin_bounds, float_t *global_bin_counts) { float_t nn = (float_t)nn; // int use_qselect = (float_t)k < 2.*log2(nn)/nn + 1.; /* TODO: unset this */ int use_qselect = 1; int stride = ctx->local_n_points / k_local; if (use_qselect) { // quickselect_data_element(ctx -> local_data , ctx -> dims, ctx -> // local_n_points, 1, 5); int idx = 0; while (idx < ctx->local_n_points) { int offset = idx * ctx->dims; // MPI_DB_PRINT("Startig from %d w stride %d -- %d \n", idx, stride, ctx // -> local_n_points - idx); if (ctx->local_n_points - idx > stride) quickselect_data_element(ctx->local_data + offset, ctx->dims, ctx->local_n_points - idx, d, stride); idx = idx + stride; } } else { qsort(ctx->local_data, ctx->local_n_points, ctx->dims * sizeof(float_t), compare_data_element_sort); } /* * Now what is more convenient? We have to also * keep track of who owns the most "median thing" * so who owns the lb and ub of each interval * * MY approach would be to * - compute the local binning * - found the most median bin * - ask each processor to find the point nearest to that bin */ int leftover = ctx->local_n_points - stride * k_local + stride; MPI_DB_PRINT("%lu %d %d leftover %d\n", ctx->local_n_points, k_local, stride * k_local, leftover); /* fill the first one and the last one with the bb values */ bin_bounds[0] = 9999999; bin_bounds[k_local] = -99999999; for (size_t i = 0; i < ctx->local_n_points; ++i) { bin_bounds[0] = MIN(ctx->local_data[i * ctx->dims + d], bin_bounds[0]); bin_bounds[k_local] = MAX(ctx->local_data[i * ctx->dims + d], bin_bounds[k_local]); } // bin_bounds[0] = ctx -> lb_box[d]; // bin_bounds[k_local] = ctx -> ub_box[d]; for (int i = 1; i < k_local; ++i) { /* retrieve the index of the datapoint on the bound */ int idx = (stride * i) - 1; /* write the value on the bins */ bin_bounds[i] = ctx->local_data[idx * ctx->dims + d]; } /* alloc and initialize global bins */ for (int i = 0; i < k_global; ++i) global_bin_counts[i] = 0; /* retrieve strides for each processor */ int *all_proc_strides = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&stride, 1, MPI_INT, all_proc_strides, 1, MPI_INT, ctx->mpi_communicator); /* retrieve leftovers for each proc */ int *all_proc_leftovers = (int *)malloc(ctx->world_size * sizeof(int)); MPI_Allgather(&leftover, 1, MPI_INT, all_proc_leftovers, 1, MPI_INT, ctx->mpi_communicator); for (int i = 0; i < ctx->world_size; ++i) { // MPI_DB_PRINT("[MASTER] recieved from proc %d stride %d leftover %d\n", i, // all_proc_strides[i], all_proc_leftovers[i]); } float_t *all_proc_bounds = (float_t *)malloc(ctx->world_size * (k_local + 1) * sizeof(float_t)); MPI_Allgather(bin_bounds, k_local + 1, MPI_MY_FLOAT, all_proc_bounds, k_local + 1, MPI_MY_FLOAT, ctx->mpi_communicator); /* exchange bounds */ /* printf("[RANK %d] bounds: [", ctx -> mpi_rank); for(int i = 0; i < k_local + 1; ++i) printf("%lf ", bin_bounds[i]); printf("]\n"); */ /* MPI_Barrier(ctx -> mpi_communicator); for(int i = 0; i < ctx -> world_size; ++i) { MPI_DB_PRINT("["); for(int b = 0; b < k_local + 1; ++b) MPI_DB_PRINT("%lf ", all_proc_bounds[i*(k_local + 1) + b]); MPI_DB_PRINT("]\n"); } */ float_t bin_width = ctx->ub_box[d] - ctx->lb_box[d]; /* compute intersection between local bin and global bin */ float_t box_lb = ctx->lb_box[d]; float_t box_ub = ctx->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; for (int i = 0; i < ctx->world_size; ++i) for (int local_bin_idx = 0; local_bin_idx < k_local; ++local_bin_idx) { float_t local_bin_lb = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx]; float_t local_bin_ub = all_proc_bounds[(i) * (k_local + 1) + local_bin_idx + 1]; float_t local_bin_width = local_bin_ub - local_bin_lb; int local_bin_count = local_bin_idx == k_local - 1 ? all_proc_leftovers[i] : all_proc_strides[i]; //MPI_DB_PRINT("%d \n", local_bin_count); if (local_bin_count > 0) { float_t local_bin_density = (float_t)(local_bin_count) / local_bin_width; // MPI_DB_PRINT("%lf\n", local_bin_width ); for (int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { float_t global_bin_lb = box_lb + global_bin_width * global_bin_idx; float_t global_bin_ub = box_lb + global_bin_width * (global_bin_idx + 1); float_t intersenction_lb = MAX(global_bin_lb, local_bin_lb); float_t intersenction_ub = MIN(global_bin_ub, local_bin_ub); float_t intersection_width = intersenction_ub - intersenction_lb; if (intersection_width > 0) { float_t intersection_count = intersection_width * local_bin_density; global_bin_counts[global_bin_idx] += intersection_count; } } } } float_t cc = 0; /* MPI_DB_PRINT("Global bins: ["); for(int global_bin_idx = 0; global_bin_idx < k_global; ++global_bin_idx) { MPI_DB_PRINT("%.2lf ", global_bin_counts[global_bin_idx]); cc += global_bin_counts[global_bin_idx]; } MPI_DB_PRINT("] tot %lf\n", cc); */ free(all_proc_strides); free(all_proc_leftovers); free(all_proc_bounds); } int retrieve_guess_adaptive(global_context_t *ctx, pointset_t *ps, float_t *global_bin_counts, float_t *best_guess, int k_global, int d, float_t pc) { float_t total_count = 0.; for (int i = 0; i < k_global; ++i) total_count += global_bin_counts[i]; float_t cumulative_count = 0; int idx = 0; while ((cumulative_count + global_bin_counts[idx]) / total_count < pc) { cumulative_count += global_bin_counts[idx]; idx++; } /* find best spot in the bin */ float_t box_lb = ps->lb_box[d]; float_t box_ub = ps->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; float_t x0 = box_lb + (global_bin_width * (idx)); float_t x1 = box_lb + (global_bin_width * (idx + 1)); float_t y0 = (cumulative_count) / total_count; float_t y1 = (cumulative_count + global_bin_counts[idx]) / total_count; float_t x_guess = (pc - y0) / (y1 - y0) * (x1 - x0) + x0; /* MPI_DB_PRINT("[MASTER] best guess @ %lf is %lf on bin %d on dimension %d --- x0 %lf x1 %lf y0 %lf y1 %lf\n", pc, x_guess, idx, d, x0, x1, y0, y1); */ /* find nearest point btw guess */ int best_idx = 0; float_t best_val = 999999; for (int i = 0; i < ps->n_points; ++i) { float_t dist = fabs(x_guess - ps->data[i * ps->dims + d]); int c = dist < best_val; best_val = c ? dist : best_val; best_idx = c ? i : best_idx; } mpi_double_int best = {.val = best_val, .key = ctx->mpi_rank}; MPI_Allreduce(MPI_IN_PLACE, &best, 1, MPI_DOUBLE_INT, MPI_MINLOC, ctx->mpi_communicator); // printf("%lf %d\n", best.val, best.key); /* broadcast best guess */ if (ctx->mpi_rank == best.key) { memcpy(best_guess, ps->data + best_idx * ps->dims, ps->dims * sizeof(float_t)); } MPI_Bcast(best_guess, ps->dims, MPI_MY_FLOAT, best.key, ctx->mpi_communicator); /* recieved ? */ MPI_DB_PRINT("[MASTER] ["); for (int i = 0; i < ps->dims; ++i) MPI_DB_PRINT("%lf ", best_guess[i]); MPI_DB_PRINT("]\n"); /* printf("[rank %d] [", ctx -> mpi_rank); for(int i = 0; i < ctx -> dims; ++i) printf("%lf ", best_guess[i]); printf("]\n"); */ return idx; } guess_t retrieve_guess_pure(global_context_t *ctx, pointset_t *ps, uint64_t *global_bin_counts, Loading Loading @@ -876,68 +421,6 @@ guess_t retrieve_guess_pure(global_context_t *ctx, pointset_t *ps, return g; } void retrieve_pc(global_context_t *ctx, float_t *global_bin_counts, float_t *best_guess, int k_global, int d, float_t pc) { float_t total_count = 0.; for (int i = 0; i < k_global; ++i) total_count += global_bin_counts[i]; float_t cumulative_count = 0; int idx = 0; while ((cumulative_count + global_bin_counts[idx]) / total_count < pc) { cumulative_count += global_bin_counts[idx]; idx++; } /* find best spot in the bin */ float_t box_lb = ctx->lb_box[d]; float_t box_ub = ctx->ub_box[d]; float_t box_width = box_ub - box_lb; float_t global_bin_width = box_width / (float_t)k_global; float_t x0 = box_lb + (global_bin_width * (idx)); float_t x1 = box_lb + (global_bin_width * (idx + 1)); float_t y0 = (cumulative_count) / total_count; float_t y1 = (cumulative_count + global_bin_counts[idx]) / total_count; float_t x_guess = (pc - y0) / (y1 - y0) * (x1 - x0) + x0; MPI_DB_PRINT("[MASTER] best guess @ %lf is %lf on bin %d on dimension %d --> x0 %lf x1 %lf y0 %lf y1 %lf\n", pc, x_guess, idx, d, x0, x1, y0, y1); /* find nearest point btw guess */ int best_idx = 0; float_t best_val = 999999; for (int i = 0; i < ctx->local_n_points; ++i) { float_t dist = fabs(x_guess - ctx->local_data[i * ctx->dims + d]); int c = dist < best_val; best_val = c ? dist : best_val; best_idx = c ? i : best_idx; } mpi_double_int best = {.val = best_val, .key = ctx->mpi_rank}; MPI_Allreduce(MPI_IN_PLACE, &best, 1, MPI_DOUBLE_INT, MPI_MINLOC, ctx->mpi_communicator); // printf("%lf %d\n", best.val, best.key); /* broadcast best guess */ if (ctx->mpi_rank == best.key) { memcpy(best_guess, ctx->local_data + best_idx * ctx->dims, ctx->dims * sizeof(float_t)); } MPI_Bcast(best_guess, ctx->dims, MPI_MY_FLOAT, best.key, ctx->mpi_communicator); /* recieved ? */ MPI_DB_PRINT("[MASTER] ["); for (int i = 0; i < ctx->dims; ++i) MPI_DB_PRINT("%lf ", best_guess[i]); MPI_DB_PRINT("]\n"); /* printf("[rank %d] [", ctx -> mpi_rank); for(int i = 0; i < ctx -> dims; ++i) printf("%lf ", best_guess[i]); printf("]\n"); */ } void global_binning_check(global_context_t *ctx, float_t *data, int d, int k) { Loading Loading @@ -1227,6 +710,7 @@ top_kdtree_node_t* top_tree_generate_node(global_context_t* ctx, top_kdtree_t* t top_kdtree_node_t* ptr = tree -> _nodes + tree -> count; ptr -> lb_node_box = (float_t*)malloc(ctx -> dims * sizeof(float_t)); ptr -> ub_node_box = (float_t*)malloc(ctx -> dims * sizeof(float_t)); ptr -> owner = -1; ++tree -> count; return ptr; Loading @@ -1234,11 +718,12 @@ top_kdtree_node_t* top_tree_generate_node(global_context_t* ctx, top_kdtree_t* t void tree_print(global_context_t* ctx, top_kdtree_node_t* root) { MPI_DB_PRINT("Node: \n\tsplit_dim %d \n\tdata %lf", root -> split_dim, root -> data); MPI_DB_PRINT("Node %p: \n\tsplit_dim %d \n\tdata %lf", root, root -> split_dim, root -> data); MPI_DB_PRINT("\n\tparent %p", root -> parent); MPI_DB_PRINT("\n\towner %d", root -> owner); MPI_DB_PRINT("\n\tbox"); for(size_t d = 0; d < ctx -> dims; ++d) MPI_DB_PRINT("d%d:[%lf, %lf] ",(int)d, root -> lb_node_box[d], root -> lb_node_box[d]); MPI_DB_PRINT("\n"); for(size_t d = 0; d < ctx -> dims; ++d) MPI_DB_PRINT("\n\t d%d:[%lf, %lf]",(int)d, root -> lb_node_box[d], root -> ub_node_box[d]); MPI_DB_PRINT("\n\n"); if(root -> lch) tree_print(ctx, root -> lch); if(root -> rch) tree_print(ctx, root -> rch); } Loading Loading @@ -1406,6 +891,7 @@ void build_top_kdtree(global_context_t *ctx, pointset_t *og_pointset, top_kdtree } MPI_DB_PRINT("Root is %p\n", tree -> root); tree_print(ctx, tree -> root); free_queue(&queue); } Loading @@ -1432,7 +918,7 @@ void simulate_master_read_and_scatter(int dims, size_t n, global_context_t *ctx) if (ctx->mpi_rank == 0) { data = read_data_file(ctx, "../norm_data/std_LR_091_0001", MY_TRUE); data = read_data_file(ctx, "../norm_data/std_LR_091_0000", MY_TRUE); // std_g0163178_Me14_091_0000 // data = // read_data_file(ctx,"../norm_data/std_g0163178_Me14_091_0000",MY_TRUE); Loading