shapes.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #ifndef __SHAPES_HPP__
  2. #define __SHAPES_HPP__
  3. // Various Shapes beyond the standard Flat (in duoram.hpp)
  4. #include "duoram.hpp"
  5. // A Pad is a Shape that pads an underlying Shape so that read accesses
  6. // past the end return a fixed constant value. Do _not_ write into a
  7. // Pad!
  8. template <typename T>
  9. class Duoram<T>::Pad : public Duoram<T>::Shape {
  10. // These are pointers because we need to be able to return a
  11. // (non-const) T& even from a const Pad.
  12. T *padvalp;
  13. T *peerpadvalp;
  14. T *zerop;
  15. address_t padded_size;
  16. inline size_t indexmap(size_t idx) const override {
  17. return this->parent.indexmap(idx);
  18. }
  19. Pad &operator=(const Pad &) = delete;
  20. public:
  21. // Constructor for the Pad shape. The parent must _not_ be in
  22. // explicit-only mode.
  23. Pad(Shape &parent, MPCTIO &tio, yield_t &yield,
  24. address_t padded_size, value_t padval = 0x7fffffffffffffff);
  25. // Copy the given Pad except for the tio and yield
  26. Pad(const Pad &copy_from, MPCTIO &tio, yield_t &yield);
  27. // Destructor
  28. ~Pad();
  29. // Update the context (MPCTIO and yield if you've started a new
  30. // thread, or just yield if you've started a new coroutine in the
  31. // same thread). Returns a new Shape with an updated context.
  32. Pad context(MPCTIO &new_tio, yield_t &new_yield) const {
  33. return Pad(*this, new_tio, new_yield);
  34. }
  35. Pad context(yield_t &new_yield) const {
  36. return Pad(*this, this->tio, new_yield);
  37. }
  38. // Get a pair (for the server) of references to the underlying
  39. // Duoram entries at share virtual index idx. (That is, it gets
  40. // duoram.p0_blind[indexmap(idx)], etc.)
  41. inline std::tuple<T&,T&> get_server(size_t idx,
  42. std::nullopt_t null = std::nullopt) const override {
  43. if (idx < this->parent.shape_size) {
  44. size_t physaddr = indexmap(idx);
  45. return std::tie(
  46. this->duoram.p0_blind[physaddr],
  47. this->duoram.p1_blind[physaddr]);
  48. } else {
  49. return std::tie(*zerop, *zerop);
  50. }
  51. }
  52. // Get a triple (for the computational players) of references to the
  53. // underlying Duoram entries at share virtual index idx. (That is,
  54. // it gets duoram.database[indexmap(idx)], etc.)
  55. inline std::tuple<T&,T&,T&> get_comp(size_t idx,
  56. std::nullopt_t null = std::nullopt) const override {
  57. if (idx < this->parent.shape_size) {
  58. size_t physaddr = indexmap(idx);
  59. return std::tie(
  60. this->duoram.database[physaddr],
  61. this->duoram.blind[physaddr],
  62. this->duoram.peer_blinded_db[physaddr]);
  63. } else {
  64. return std::tie(*padvalp, *zerop, *peerpadvalp);
  65. }
  66. }
  67. // Index into this Pad in various ways
  68. typename Duoram::Shape::template MemRefS<RegAS,T,std::nullopt_t,Pad>
  69. operator[](const RegAS &idx) {
  70. typename Duoram<T>::Shape::
  71. template MemRefS<RegAS,T,std::nullopt_t,Pad>
  72. res(*this, idx, std::nullopt);
  73. return res;
  74. }
  75. typename Duoram::Shape::template MemRefS<RegXS,T,std::nullopt_t,Pad>
  76. operator[](const RegXS &idx) {
  77. typename Duoram<T>::Shape::
  78. template MemRefS<RegXS,T,std::nullopt_t,Pad>
  79. res(*this, idx, std::nullopt);
  80. return res;
  81. }
  82. typename Duoram::Shape::template MemRefExpl<T,std::nullopt_t>
  83. operator[](address_t idx) {
  84. typename Duoram<T>::Shape::
  85. template MemRefExpl<T,std::nullopt_t>
  86. res(*this, idx, std::nullopt);
  87. return res;
  88. }
  89. template <typename U>
  90. Duoram::Shape::MemRefInd<U, Pad>
  91. operator[](const std::vector<U> &indcs) {
  92. typename Duoram<T>::Shape::
  93. template MemRefInd<U,Pad>
  94. res(*this, indcs);
  95. return res;
  96. }
  97. template <typename U, size_t N>
  98. Duoram::Shape::MemRefInd<U, Pad>
  99. operator[](const std::array<U,N> &indcs) {
  100. typename Duoram<T>::Shape::
  101. template MemRefInd<U,Pad>
  102. res(*this, indcs);
  103. return res;
  104. }
  105. };
  106. // A Stride is a Shape that represents evenly spaced elements of its
  107. // parent Shape, starting with some offset, and then every stride
  108. // elements.
  109. template <typename T>
  110. class Duoram<T>::Stride : public Duoram<T>::Shape {
  111. size_t offset;
  112. size_t stride;
  113. inline size_t indexmap(size_t idx) const override {
  114. size_t paridx = offset + idx*stride;
  115. return this->parent.indexmap(paridx);
  116. }
  117. public:
  118. // Constructor
  119. Stride(Shape &parent, MPCTIO &tio, yield_t &yield, size_t offset,
  120. size_t stride);
  121. // Copy the given Stride except for the tio and yield
  122. Stride(const Stride &copy_from, MPCTIO &tio, yield_t &yield) :
  123. Shape(copy_from, tio, yield), offset(copy_from.offset),
  124. stride(copy_from.stride) {}
  125. // Update the context (MPCTIO and yield if you've started a new
  126. // thread, or just yield if you've started a new coroutine in the
  127. // same thread). Returns a new Shape with an updated context.
  128. Stride context(MPCTIO &new_tio, yield_t &new_yield) const {
  129. return Stride(*this, new_tio, new_yield);
  130. }
  131. Stride context(yield_t &new_yield) const {
  132. return Stride(*this, this->tio, new_yield);
  133. }
  134. // Index into this Stride in various ways
  135. typename Duoram::Shape::template MemRefS<RegAS,T,std::nullopt_t,Stride>
  136. operator[](const RegAS &idx) {
  137. typename Duoram<T>::Shape::
  138. template MemRefS<RegAS,T,std::nullopt_t,Stride>
  139. res(*this, idx, std::nullopt);
  140. return res;
  141. }
  142. typename Duoram::Shape::template MemRefS<RegXS,T,std::nullopt_t,Stride>
  143. operator[](const RegXS &idx) {
  144. typename Duoram<T>::Shape::
  145. template MemRefS<RegXS,T,std::nullopt_t,Stride>
  146. res(*this, idx, std::nullopt);
  147. return res;
  148. }
  149. typename Duoram::Shape::template MemRefExpl<T,std::nullopt_t>
  150. operator[](address_t idx) {
  151. typename Duoram<T>::Shape::
  152. template MemRefExpl<T,std::nullopt_t>
  153. res(*this, idx, std::nullopt);
  154. return res;
  155. }
  156. template <typename U>
  157. Duoram::Shape::MemRefInd<U, Stride>
  158. operator[](const std::vector<U> &indcs) {
  159. typename Duoram<T>::Shape::
  160. template MemRefInd<U,Stride>
  161. res(*this, indcs);
  162. return res;
  163. }
  164. template <typename U, size_t N>
  165. Duoram::Shape::MemRefInd<U, Stride>
  166. operator[](const std::array<U,N> &indcs) {
  167. typename Duoram<T>::Shape::
  168. template MemRefInd<U,Stride>
  169. res(*this, indcs);
  170. return res;
  171. }
  172. };
  173. #include "shapes.tcc"
  174. #endif