Browse Source

heap insert

avadapal 1 year ago
parent
commit
3e39153736
2 changed files with 210 additions and 63 deletions
  1. 206 62
      heap.cpp
  2. 4 1
      heap.hpp

+ 206 - 62
heap.cpp

@@ -3,9 +3,9 @@
 #include "types.hpp"
 #include "duoram.hpp"
 #include "cell.hpp"
-#include  "rdpf.hpp"
+#include "rdpf.hpp"
 #include "shapes.hpp"
-#include  "heap.hpp"
+#include "heap.hpp"
 
 
 // The optimized insertion protocol works as follows
@@ -33,28 +33,31 @@ int MinHeap::insert_optimized(MPCTIO tio, yield_t & yield, RegAS val) {
     std::cout << "height = " << height << std::endl;
     RDPF<1> dpf2(tio, yield, foundidx, height, false, false);
     RegAS * ones_array = new RegAS[height];
+    RegBS * flags_array = new RegBS[height];
     for(size_t j = 0; j < height; ++j)
     {
         if(tio.player() !=2) 
         {
          RDPF<1>::LeafNode tmp = dpf2.leaf(j, tio.aes_ops());
          RegAS bitshare = dpf2.unit_as(tmp);
-         ones_array[j] = bitshare;
+         RegBS tmp__ = dpf2.unit_bs(tmp);
+         ones_array[j]  = bitshare;
+         flags_array[j] =  tmp__;
          if(j > 0) ones_array[j] = ones_array[j] + ones_array[j-1];
+         if(j > 0) flags_array[j] = flags_array[j] ^ flags_array[j-1];
         }
     }
 
     RegAS * z_array2 = new RegAS[height];
-    
+    RegAS * z2_tmp   = new RegAS[height]; 
     for(size_t j = 0; j < height; ++j) z_array2[j] = P[j];            
  
     for(size_t j = 1; j < height; ++j)
     {
-        RegAS z2; 
-        mpc_mul(tio, yield, z2, ones_array[j-1], (z_array2[j-1]-z_array2[j]), 64);    
-        P[j] += z2;
+      mpc_flagmult(tio, yield, z2_tmp[j], flags_array[j-1], (z_array2[j-1]-z_array2[j]), 64); 
     }
 
+    for(size_t j = 1; j < height; ++j) P[j] += z2_tmp[j];
 
     typename Duoram<RegAS>::template OblivIndex<RegXS,1> oidx(tio, yield, foundidx, height);
         
@@ -98,7 +101,7 @@ int MinHeap::insert(MPCTIO tio, yield_t & yield, RegAS val) {
 
         HeapArray[childindex]  = sharechild;
         HeapArray[parentindex] = shareparent;
-
+   
         childindex = parentindex;
         parentindex = parentindex / 2;
     }
@@ -106,6 +109,8 @@ int MinHeap::insert(MPCTIO tio, yield_t & yield, RegAS val) {
     return 1;
 }
 
+
+
 int MinHeap::verify_heap_property(MPCTIO tio, yield_t & yield) {
     std::cout << std::endl << std::endl << "verify_heap_property is being called " << std::endl;
     auto HeapArray = oram.flat(tio, yield);
@@ -122,10 +127,16 @@ int MinHeap::verify_heap_property(MPCTIO tio, yield_t & yield) {
             std::cout << heapreconstruction[j] << std::endl;
             std::cout << "2*j = " << 2 * j << std::endl;
             std::cout << heapreconstruction[2 * j] << std::endl;
-
         }
-        assert(heapreconstruction[j] <= heapreconstruction[2 * j]);
-        assert(heapreconstruction[j] <= heapreconstruction[2 * j + 1]);
+              if (heapreconstruction[j] > heapreconstruction[2 * j + 1]) {
+            std::cout << "heap property failure\n\n";
+            std::cout << "j = " << j << std::endl;
+            std::cout << heapreconstruction[j] << std::endl;
+            std::cout << "2*j + 1 = " << 2 * j + 1<< std::endl;
+            std::cout << heapreconstruction[2 * j + 1] << std::endl;
+        }
+        //assert(heapreconstruction[j] <= heapreconstruction[2 * j]);
+        //assert(heapreconstruction[j] <= heapreconstruction[2 * j + 1]);
 
     }
 
@@ -161,6 +172,8 @@ void verify_parent_children_heaps(MPCTIO tio, yield_t & yield, RegAS parent, Reg
 RegXS MinHeap::restore_heap_property(MPCTIO tio, yield_t & yield, RegXS index) {
     RegAS smallest;
     auto HeapArray = oram.flat(tio, yield);
+
+
     RegAS parent = HeapArray[index];
     RegXS leftchildindex = index;
     leftchildindex = index << 1;
@@ -170,43 +183,60 @@ RegXS MinHeap::restore_heap_property(MPCTIO tio, yield_t & yield, RegXS index) {
 
     RegAS leftchild = HeapArray[leftchildindex];
     RegAS rightchild = HeapArray[rightchildindex];
+ 
     RegAS sum = parent + leftchild + rightchild;
-    CDPF cdpf = tio.cdpf(yield);
-    auto[lt, eq, gt] = cdpf.compare(tio, yield, leftchild - rightchild, tio.aes_ops());
 
+    CDPF cdpf = tio.cdpf(yield);
+    auto[lt_c, eq_c, gt_c] = cdpf.compare(tio, yield, leftchild - rightchild, tio.aes_ops());
+    auto lteq = lt_c ^ eq_c;    
     RegXS smallerindex;
-    //mpc_select(tio, yield, smallerindex, lt, rightchildindex, leftchildindex, 64); 
+    
+
+    uint64_t LC_rec = mpc_reconstruct(tio, yield, leftchildindex);
 
-    smallerindex = leftchildindex ^ lt;
-    //smallerindex stores either the index of the left or child (whichever has the smaller value) 
+    std::cout << "LC_rec = " << LC_rec << std::endl;
+
+    //smallerindex    = leftchildindex ^ lt_c;
+    mpc_select(tio, yield, smallerindex, lteq, rightchildindex, leftchildindex, 64);
+    uint64_t smallerindex_rec = mpc_reconstruct(tio, yield, smallerindex);
+
+    std::cout << "smallerindex_rec = " << smallerindex_rec << std::endl; 
 
     RegAS smallerchild;
-    mpc_select(tio, yield, smallerchild, lt, rightchild, leftchild, 64);
-    // the value smallerchild holds smaller of left and right child 
-    RegAS largerchild = sum - parent - smallerchild;
+    mpc_select(tio, yield, smallerchild, lt_c, rightchild, leftchild, 64);
+
     CDPF cdpf0 = tio.cdpf(yield);
-    auto[lt1, eq1, gt1] = cdpf0.compare(tio, yield, smallerchild - parent, tio.aes_ops());
-    //comparison between the smallerchild and the parent
+    auto[lt_p, eq_p, gt_p] = cdpf0.compare(tio, yield, smallerchild - parent, tio.aes_ops());
+    
+    auto lt_p_eq_p = lt_p ^ eq_p;
 
-    mpc_select(tio, yield, smallest, lt1, parent, smallerchild, 64);
-    // smallest holds smaller of left/right child and parent
+    RegBS ltlt1;
+    
+    mpc_and(tio, yield, ltlt1, lteq, lt_p_eq_p);
+
+    RegAS z, zz;
 
-    RegAS otherchild;
-    //mpc_select(tio, yield, otherchild, gt1, parent, smallerchild, 64);
-    otherchild = sum - smallest - largerchild;
-    // otherchild holds max(min(leftchild, rightchild), parent)
+    run_coroutines(tio, [&tio, &zz, ltlt1, parent, leftchild](yield_t &yield)
+            { mpc_flagmult(tio, yield, zz, ltlt1, (parent - leftchild), 64);},
+            [&tio, &z, lt_p, parent, smallerchild](yield_t &yield)
+            {mpc_flagmult(tio, yield, z, lt_p, smallerchild - parent, 64);}
+            );
+
+    
+    RegAS leftchildplusparent = RegAS(HeapArray[index]) + RegAS(HeapArray[leftchildindex]);
+    RegAS tmp = (sum - leftchildplusparent);
 
-    HeapArray[index] = smallest;
-    HeapArray[smallerindex] = otherchild;
+    HeapArray[index]           += z;
+    HeapArray[leftchildindex]  += zz;
+    HeapArray[rightchildindex] += tmp - rightchild;
 
+    
     verify_parent_children_heaps(tio, yield, HeapArray[index], HeapArray[leftchildindex] , HeapArray[rightchildindex]);
 
     return smallerindex;
 }
 
-/*
 
-*/
 
 auto MinHeap::restore_heap_property_optimized(MPCTIO tio, yield_t & yield, RegXS index, size_t layer, size_t depth, typename Duoram < RegAS > ::template OblivIndex < RegXS, 3 > (oidx)) {
 
@@ -231,16 +261,20 @@ auto MinHeap::restore_heap_property_optimized(MPCTIO tio, yield_t & yield, RegXS
     RegAS sum = parent_tmp + leftchild_tmp + rightchild_tmp;
 
     CDPF cdpf = tio.cdpf(yield);
+
     auto[lt, eq, gt] = cdpf.compare(tio, yield, leftchild_tmp - rightchild_tmp, tio.aes_ops());
-   
     auto lteq = lt ^ eq;
 
     RegXS smallerindex;
+    RegAS smallerchild;
 
-    mpc_select(tio, yield, smallerindex, lteq, rightchildindex, leftchildindex, 64);
+    // mpc_select(tio, yield, smallerindex, lteq, rightchildindex, leftchildindex, 64);
+    // mpc_select(tio, yield, smallerchild, lt, rightchild_tmp, leftchild_tmp, 64);
 
-    RegAS smallerchild;
-    mpc_select(tio, yield, smallerchild, lt, rightchild_tmp, leftchild_tmp, 64);
+    run_coroutines(tio, [&tio, &smallerindex, lteq, rightchildindex, leftchildindex](yield_t &yield)
+            { mpc_select(tio, yield, smallerindex, lteq, rightchildindex, leftchildindex, 64);;},
+            [&tio, &smallerchild, lt, rightchild_tmp, leftchild_tmp](yield_t &yield)
+            { mpc_select(tio, yield, smallerchild, lt, rightchild_tmp, leftchild_tmp, 64);;});
 
     CDPF cdpf0 = tio.cdpf(yield);
     auto[lt1, eq1, gt1] = cdpf0.compare(tio, yield, smallerchild - parent_tmp, tio.aes_ops());
@@ -249,13 +283,18 @@ auto MinHeap::restore_heap_property_optimized(MPCTIO tio, yield_t & yield, RegXS
     mpc_flagmult(tio, yield, z, lt1, smallerchild - parent_tmp, 64);
 
     P[oidx] += z;
-
     auto lt1eq1 = lt1 ^ eq1;
-    RegBS ltlt1;
-    mpc_and(tio, yield, ltlt1, lteq, lt1eq1);
 
+    RegBS ltlt1;
     RegAS zz;
-    mpc_flagmult(tio, yield, zz, ltlt1, (parent_tmp - leftchild_tmp), 64);
+    
+    // mpc_and(tio, yield, ltlt1, lteq, lt1eq1);
+    // mpc_flagmult(tio, yield, zz, ltlt1, (parent_tmp - leftchild_tmp), 64);
+
+    run_coroutines(tio, [&tio, &ltlt1, lteq, lt1eq1](yield_t &yield)
+            { mpc_and(tio, yield, ltlt1, lteq, lt1eq1);},
+            [&tio, &zz, ltlt1, parent_tmp, leftchild_tmp](yield_t &yield)
+            { mpc_flagmult(tio, yield, zz, ltlt1, (parent_tmp - leftchild_tmp), 64);});
 
     L[oidx] += zz;// - leftchild_tmp;
 
@@ -272,47 +311,91 @@ void MinHeap::initialize(MPCTIO tio, yield_t & yield) {
     HeapArray.init(0x7fffffffffffff);
 }
 
+void MinHeap::initialize_random(MPCTIO tio, yield_t & yield) {
+    auto HeapArray = oram.flat(tio, yield);
+    std::cout << "initialize_random " << num_items << std::endl;
+    for(size_t j = 1; j <= num_items; ++j)
+    {
+        RegAS inserted_val;
+        inserted_val.randomize(10);
+        HeapArray[j] = inserted_val;
+    }
+ //   HeapArray.init(0x7fffffffffffff);
+}
 void MinHeap::print_heap(MPCTIO tio, yield_t & yield) {
     auto HeapArray = oram.flat(tio, yield);
-    for(size_t j = 0; j < num_items; ++j) 
+    for(size_t j = 0; j <= num_items; ++j) 
             { 
                 uint64_t Pjreconstruction = mpc_reconstruct(tio, yield, HeapArray[j]);
-                 std::cout << j << "-->> HeapArray[" << j << "] = " << std::hex << Pjreconstruction << std::endl;
+                 std::cout << j << "-->> HeapArray[" << j << "] = " << std::dec << Pjreconstruction << std::endl;
             }
 }
 
-auto MinHeap::restore_heap_property_at_root(MPCTIO tio, yield_t & yield) {
+auto MinHeap::restore_heap_property_at_root(MPCTIO tio, yield_t & yield, size_t index = 1) {
 
-    size_t index = 1;
+   // size_t index = 1;
+    std::cout << "index = " << index << std::endl;
     auto HeapArray = oram.flat(tio, yield);
     RegAS parent = HeapArray[index];
     RegAS leftchild = HeapArray[2 * index];
     RegAS rightchild = HeapArray[2 * index + 1];
+    RegAS sum = parent + leftchild + rightchild;
     CDPF cdpf = tio.cdpf(yield);
     auto[lt, eq, gt] = cdpf.compare(tio, yield, leftchild - rightchild, tio.aes_ops()); // c_1 in the paper
     RegAS smallerchild;
     mpc_select(tio, yield, smallerchild, lt, rightchild, leftchild, 64); // smallerchild holds smaller of left and right child
-    CDPF cdpf0 = tio.cdpf(yield);
-    auto[lt1, eq1, gt1] = cdpf0.compare(tio, yield, smallerchild - parent, tio.aes_ops()); //c_0 in the paper
-    RegAS smallest;
-    mpc_select(tio, yield, smallest, lt1, parent, smallerchild, 64); // smallest holds smaller of left/right child and parent
-    RegAS larger_p;
-    mpc_select(tio, yield, larger_p, gt1, parent, smallerchild, 64); // smallest holds smaller of left/right child and parent
-    parent = smallest;
-    leftchild = larger_p;
-    HeapArray[index] = smallest;
-
+    auto lteq = lt ^ eq;
     RegXS smallerindex(lt);
     uint64_t leftchildindex = (2 * index);
     uint64_t rightchildindex = (2 * index) + 1;
+    smallerindex = (RegXS(lteq) & leftchildindex) ^ (RegXS(gt) & rightchildindex);    
+  
+
+    CDPF cdpf0 = tio.cdpf(yield);
+    auto[lt1, eq1, gt1] = cdpf0.compare(tio, yield, smallerchild - parent, tio.aes_ops());
+    
+     auto lt_p_eq_p = lt1 ^ eq1;
+
+    RegBS ltlt1;
+    
+    mpc_and(tio, yield, ltlt1, lteq, lt_p_eq_p);
 
-    auto lteq = lt^eq;
-    smallerindex = (RegXS(lteq) & leftchildindex) ^ (RegXS(gt) & rightchildindex);
-    HeapArray[smallerindex] = larger_p;
+    RegAS z, zz;
+
+    run_coroutines(tio, [&tio, &zz, ltlt1, parent, leftchild](yield_t &yield)
+            { mpc_flagmult(tio, yield, zz, ltlt1, (parent - leftchild), 64);},
+            [&tio, &z, lt1, parent, smallerchild](yield_t &yield)
+            {mpc_flagmult(tio, yield, z, lt1, smallerchild - parent, 64);}
+            );
+
+    
+    RegAS leftchildplusparent = RegAS(HeapArray[index]) + RegAS(HeapArray[leftchildindex]);
+    RegAS tmp = (sum - leftchildplusparent);
+
+    HeapArray[index]           += z;
+    HeapArray[leftchildindex]  += zz;
+    HeapArray[rightchildindex] += tmp - rightchild;
+
+
+    RegAS new_parent = HeapArray[index];
+    RegAS new_left   = HeapArray[leftchildindex];
+    RegAS new_right  = HeapArray[rightchildindex]; 
+
+    uint64_t parent_R = mpc_reconstruct(tio, yield, new_parent);
+    uint64_t left_R = mpc_reconstruct(tio, yield, new_left);
+    uint64_t right_R = mpc_reconstruct(tio, yield, new_right);
+
+    std::cout << "parent_R = " << parent_R << std::endl;
+        std::cout << "left_R = " << left_R << std::endl;
+            std::cout << "right_R = " << right_R << std::endl;
+    verify_parent_children_heaps(tio, yield, HeapArray[index], HeapArray[leftchildindex] , HeapArray[rightchildindex]);
 
     return std::make_pair(smallerindex, gt);
 }
 
+    
+
+
 RegAS MinHeap::extract_min(MPCTIO tio, yield_t & yield, int is_optimized) {
 
     RegAS minval;
@@ -354,6 +437,50 @@ RegAS MinHeap::extract_min(MPCTIO tio, yield_t & yield, int is_optimized) {
     return minval;
 }
 
+
+void MinHeap::heapify2(MPCTIO tio, yield_t & yield, size_t index = 1) {
+
+    auto outroot = restore_heap_property_at_root(tio, yield, index);
+
+    RegXS smaller = outroot.first;
+    uint64_t smaller_rec = mpc_reconstruct(tio, yield, smaller, 64);
+    std::cout << "smaller_rec = " << smaller_rec << std::endl;
+    std::cout << "num_items = " << num_items << std::endl;
+    std::cout << "index = " << index << std::endl;
+    size_t height =  std::log2(num_items) - std::floor(log2(index)) ;
+    std::cout << "height = " << height << std::endl << "===================" << std::endl;
+    for (size_t i = 0; i < height - 1; ++i) {
+        std::cout << "index = " << index <<  ",  i = " << i << std::endl; 
+         uint64_t smaller_rec = mpc_reconstruct(tio, yield, smaller, 64);
+         std::cout << "[inside loop] smaller_rec = " << smaller_rec << std::endl;
+        smaller = restore_heap_property(tio, yield, smaller);    
+    }
+}
+
+void MinHeap::heapify(MPCTIO tio, yield_t & yield) {
+
+    size_t startIdx = ((num_items + 1) / 2) - 1;
+    std::cout << "startIdx " << startIdx << std::endl;
+    // Perform reverse level order traversal
+    // from last non-leaf node and heapify
+    // each node
+
+    for (size_t i = startIdx; i >= 1; i--) {
+
+//             printf("\n==[Before Heapify]==\n\n");
+//      print_heap(tio, yield);
+ 
+// printf("\n====\n\n");
+//     std::cout << "heap printed \n\n";
+     heapify2(tio, yield, i);
+    
+     // printf("\n==[After Heapify]==\n\n");
+     // print_heap(tio, yield);
+     // printf("\n====\n\n");
+     // std::cout << "heap printed \n\n";
+     }
+}   
+
 void Heap(MPCIO & mpcio,
     const PRACOptions & opts, char ** args) {
     nbits_t depth     = atoi(args[0]);
@@ -379,7 +506,7 @@ void Heap(MPCIO & mpcio,
 
     MPCTIO tio(mpcio, 0, opts.num_threads);
 
-    run_coroutines(tio, [ & tio, depth, items, n_inserts, n_extracts, is_optimized](yield_t & yield) {
+    run_coroutines(tio, [ & tio, depth, items, n_inserts, n_extracts, is_optimized, &mpcio](yield_t & yield) {
         size_t size = size_t(1) << depth;
         std::cout << "size = " << size << std::endl;
 
@@ -390,15 +517,23 @@ void Heap(MPCIO & mpcio,
             RegAS inserted_val;
             inserted_val.randomize(40);
             inserted_val.ashare = inserted_val.ashare;
+            uint64_t inserted_val_rec = mpc_reconstruct(tio, yield, inserted_val, 64);
+            std::cout << "inserted_val_rec = " << inserted_val_rec << std::endl << std::endl;
             if(is_optimized > 0)  tree.insert_optimized(tio, yield, inserted_val);
             if(is_optimized == 0) tree.insert(tio, yield, inserted_val);
-             //tree.print_heap(tio, yield);
+            tree.print_heap(tio, yield);
         }
 
   
-        
+        tio.sync_lamport();
+        mpcio.dump_stats(std::cout);
+        std::cout << "\n===== INSERTS =====\n";
+        mpcio.reset_stats();
+        tio.reset_lamport();
+
+
         std::cout << std::endl << "=============[Insert Done]================ " << std::endl << std::endl;
-        //tree.verify_heap_property(tio, yield);
+        tree.verify_heap_property(tio, yield);
         
         for (size_t j = 0; j < n_extracts; ++j) {
             std::cout << "j = " << j << std::endl;
@@ -410,9 +545,18 @@ void Heap(MPCIO & mpcio,
             // tree.verify_heap_property(tio, yield);
             // tree.print_heap(tio, yield);
         }
-
+        tio.sync_lamport();
+        mpcio.dump_stats(std::cout);
+        std::cout << "\n===== Extract Min =====\n";
+        mpcio.reset_stats();
+        tio.reset_lamport();
         std::cout << std::endl << "=============[Extract Min Done]================" << std::endl << std::endl;
-       // tree.verify_heap_property(tio, yield);
+        tree.verify_heap_property(tio, yield);
         
+        // tree.num_items = (size_t(1) << depth) - 1;
+        // std::cout << "num_items " << tree.num_items << std::endl;
+        // tree.initialize_random(tio, yield);
+        // tree.heapify(tio, yield);
+        // tree.verify_heap_property(tio, yield);
     });
 }

+ 4 - 1
heap.hpp

@@ -20,13 +20,16 @@ class MinHeap {
     
     RegAS extract_min(MPCTIO tio, yield_t & yield, int is_optimized);
     void initialize(MPCTIO tio, yield_t & yield);
+    void initialize_random(MPCTIO tio, yield_t & yield);
     int insert(MPCTIO tio, yield_t & yield, RegAS val);
     int insert_optimized(MPCTIO tio, yield_t & yield, RegAS val);
     int verify_heap_property(MPCTIO tio, yield_t & yield);
     RegXS restore_heap_property(MPCTIO tio, yield_t & yield, RegXS index);
     auto restore_heap_property_optimized(MPCTIO tio, yield_t & yield, RegXS index, size_t depth, size_t layer, typename Duoram<RegAS>::template OblivIndex<RegXS,3> oidx);
-    auto restore_heap_property_at_root(MPCTIO tio, yield_t & yield);
+    auto restore_heap_property_at_root(MPCTIO tio, yield_t & yield,  size_t index);
     void print_heap(MPCTIO tio, yield_t & yield);
+    void heapify(MPCTIO tio, yield_t & yield);
+     void heapify2(MPCTIO tio, yield_t & yield, size_t index);
 };
 
 void Heap(MPCIO &mpcio,