mplang-nightly 0.1.dev246__tar.gz → 0.1.dev266__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/PKG-INFO +3 -3
  2. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/__init__.py +143 -90
  3. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/crypto_impl.py +124 -0
  4. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/func_impl.py +3 -1
  5. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_driver/http.py +2 -0
  6. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_driver/mem.py +13 -15
  7. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_driver/ops.py +9 -7
  8. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_worker/http.py +15 -6
  9. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_worker/ops.py +22 -25
  10. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/spu_impl.py +18 -94
  11. mplang_nightly-0.1.dev266/mplang/v2/backends/spu_state.py +124 -0
  12. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/store_impl.py +4 -0
  13. mplang_nightly-0.1.dev266/mplang/v2/backends/table_impl.py +838 -0
  14. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/tee_impl.py +2 -1
  15. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/tensor_impl.py +7 -3
  16. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/cli.py +1 -1
  17. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/crypto.py +172 -8
  18. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/table.py +40 -13
  19. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/tee.py +26 -51
  20. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/tensor.py +0 -3
  21. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/__init__.py +10 -2
  22. mplang_nightly-0.1.dev266/mplang/v2/edsl/context.py +311 -0
  23. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/graph.py +1 -2
  24. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/jit.py +8 -1
  25. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/tracer.py +4 -9
  26. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/device/__init__.py +2 -0
  27. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/device/api.py +111 -16
  28. mplang_nightly-0.1.dev266/mplang/v2/libs/ml/__init__.py +23 -0
  29. {mplang_nightly-0.1.dev246/examples/v2 → mplang_nightly-0.1.dev266/mplang/v2/libs/ml}/sgb.py +26 -299
  30. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/vole/ldpc.py +3 -2
  31. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/runtime/interpreter.py +45 -37
  32. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/pyproject.toml +11 -7
  33. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/simp_driver/test_http.py +4 -3
  34. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/simp_worker/test_http.py +7 -12
  35. mplang_nightly-0.1.dev266/tests/v2/backends/test_crypto_impl.py +541 -0
  36. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_simp_integration.py +61 -27
  37. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_spu_impl.py +3 -1
  38. mplang_nightly-0.1.dev266/tests/v2/backends/test_table_impl.py +436 -0
  39. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_tee_impl.py +4 -7
  40. mplang_nightly-0.1.dev266/tests/v2/conftest.py +54 -0
  41. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_crypto.py +70 -0
  42. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_tee.py +22 -55
  43. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_context.py +78 -1
  44. mplang_nightly-0.1.dev266/tests/v2/libs/ml/__init__.py +15 -0
  45. mplang_nightly-0.1.dev266/tests/v2/libs/ml/test_sgb.py +164 -0
  46. mplang_nightly-0.1.dev246/examples/v2/sgb_bench.py → mplang_nightly-0.1.dev266/tests/v2/libs/ml/test_sgb_bench.py +1 -2
  47. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/analytics/test_permutation.py +6 -14
  48. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/ot/test_ot.py +5 -13
  49. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/runtime/test_interpreter_async.py +4 -4
  50. mplang_nightly-0.1.dev266/tests/v2/test_fetch_semantics.py +129 -0
  51. mplang_nightly-0.1.dev266/tests/v2/test_pytree_io.py +231 -0
  52. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v2/00_device_basics.py +6 -6
  53. mplang_nightly-0.1.dev266/tutorials/v2/02_simulation_and_driver.py +125 -0
  54. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v2/05_run_sql.py +25 -25
  55. mplang_nightly-0.1.dev246/examples/v2/stax_nn.py → mplang_nightly-0.1.dev266/tutorials/v2/07_stax_nn.py +21 -43
  56. mplang_nightly-0.1.dev246/examples/v2/bfv_sort_agg.py +0 -213
  57. mplang_nightly-0.1.dev246/examples/v2/pcall_jax.py +0 -97
  58. mplang_nightly-0.1.dev246/examples/v2/phe_sort_agg.py +0 -190
  59. mplang_nightly-0.1.dev246/examples/v2/secure_shuffle_agg.py +0 -131
  60. mplang_nightly-0.1.dev246/mplang/v2/backends/func_primitive_backends.md +0 -93
  61. mplang_nightly-0.1.dev246/mplang/v2/backends/table_impl.py +0 -272
  62. mplang_nightly-0.1.dev246/mplang/v2/edsl/context.py +0 -163
  63. mplang_nightly-0.1.dev246/tests/v2/backends/test_crypto_impl.py +0 -238
  64. mplang_nightly-0.1.dev246/tests/v2/backends/test_table_impl.py +0 -92
  65. mplang_nightly-0.1.dev246/tests/v2/conftest.py +0 -46
  66. mplang_nightly-0.1.dev246/tests/v2/libs/device/test_context_root.py +0 -93
  67. mplang_nightly-0.1.dev246/tutorials/v2/02_simulation_and_driver.py +0 -181
  68. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/.gitignore +0 -0
  69. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/LICENSE +0 -0
  70. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/README.md +0 -0
  71. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/conf/3pc.yaml +0 -0
  72. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/stax_nn/README.md +0 -0
  73. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/stax_nn/models.py +0 -0
  74. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/stax_nn/stax_nn.py +0 -0
  75. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/xgboost/bench_fhe_hist.py +0 -0
  76. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/xgboost/hist_jax.py +0 -0
  77. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/xgboost/hist_jax_test.py +0 -0
  78. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/xgboost/naive_np.py +0 -0
  79. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/xgboost/readme.md +0 -0
  80. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/xgboost/sgb.py +0 -0
  81. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/examples/v1/xgboost/sgb_test.py +0 -0
  82. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/hatch_build.py +0 -0
  83. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/__init__.py +0 -0
  84. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/__init__.py +0 -0
  85. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/_device.py +0 -0
  86. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/analysis/__init__.py +0 -0
  87. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/analysis/diagram.py +0 -0
  88. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/__init__.py +0 -0
  89. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/cluster.py +0 -0
  90. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/comm.py +0 -0
  91. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/context_mgr.py +0 -0
  92. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/dtypes.py +0 -0
  93. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/__init__.py +0 -0
  94. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/ast.py +0 -0
  95. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/evaluator.py +0 -0
  96. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/printer.py +0 -0
  97. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/transformer.py +0 -0
  98. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/utils.py +0 -0
  99. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/visitor.py +0 -0
  100. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/expr/walk.py +0 -0
  101. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/interp.py +0 -0
  102. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/mask.py +0 -0
  103. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/mpir.py +0 -0
  104. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/mpobject.py +0 -0
  105. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/mptype.py +0 -0
  106. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/pfunc.py +0 -0
  107. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/primitive.py +0 -0
  108. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/table.py +0 -0
  109. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/tensor.py +0 -0
  110. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/core/tracer.py +0 -0
  111. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/host.py +0 -0
  112. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/__init__.py +0 -0
  113. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/base.py +0 -0
  114. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/basic.py +0 -0
  115. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/context.py +0 -0
  116. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/crypto.py +0 -0
  117. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/fhe.py +0 -0
  118. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/mock_tee.py +0 -0
  119. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/phe.py +0 -0
  120. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/spu.py +0 -0
  121. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/sql_duckdb.py +0 -0
  122. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/stablehlo.py +0 -0
  123. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/kernels/value.py +0 -0
  124. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/__init__.py +0 -0
  125. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/base.py +0 -0
  126. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/basic.py +0 -0
  127. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/crypto.py +0 -0
  128. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/fhe.py +0 -0
  129. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/jax_cc.py +0 -0
  130. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/nnx_cc.py +0 -0
  131. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/phe.py +0 -0
  132. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/spu.py +0 -0
  133. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/sql_cc.py +0 -0
  134. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/ops/tee.py +0 -0
  135. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/protos/v1alpha1/mpir_pb2.py +0 -0
  136. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/protos/v1alpha1/mpir_pb2.pyi +0 -0
  137. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/protos/v1alpha1/value_pb2.py +0 -0
  138. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/protos/v1alpha1/value_pb2.pyi +0 -0
  139. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/__init__.py +0 -0
  140. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/cli.py +0 -0
  141. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/client.py +0 -0
  142. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/communicator.py +0 -0
  143. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/data_providers.py +0 -0
  144. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/driver.py +0 -0
  145. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/exceptions.py +0 -0
  146. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/http_api.md +0 -0
  147. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/link_comm.py +0 -0
  148. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/server.py +0 -0
  149. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/session.py +0 -0
  150. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/runtime/simulation.py +0 -0
  151. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/simp/__init__.py +0 -0
  152. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/simp/api.py +0 -0
  153. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/simp/mpi.py +0 -0
  154. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/simp/party.py +0 -0
  155. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/simp/random.py +0 -0
  156. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/simp/smpc.py +0 -0
  157. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/utils/__init__.py +0 -0
  158. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/utils/crypto.py +0 -0
  159. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/utils/func_utils.py +0 -0
  160. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/utils/spu_utils.py +0 -0
  161. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v1/utils/table_utils.py +0 -0
  162. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/__init__.py +0 -0
  163. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/bfv_impl.py +0 -0
  164. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/field_impl.py +0 -0
  165. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/phe_impl.py +0 -0
  166. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_design.md +0 -0
  167. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_driver/__init__.py +0 -0
  168. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_driver/state.py +0 -0
  169. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_driver/values.py +0 -0
  170. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_worker/__init__.py +0 -0
  171. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_worker/mem.py +0 -0
  172. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/backends/simp_worker/state.py +0 -0
  173. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/cli_guide.md +0 -0
  174. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/__init__.py +0 -0
  175. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/bfv.py +0 -0
  176. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/dtypes.py +0 -0
  177. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/field.py +0 -0
  178. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/func.py +0 -0
  179. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/phe.py +0 -0
  180. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/simp.py +0 -0
  181. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/spu.py +0 -0
  182. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/dialects/store.py +0 -0
  183. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/README.md +0 -0
  184. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/object.py +0 -0
  185. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/primitive.py +0 -0
  186. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/printer.py +0 -0
  187. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/registry.py +0 -0
  188. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/serde.py +0 -0
  189. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/edsl/typing.py +0 -0
  190. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/kernels/Makefile +0 -0
  191. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/kernels/__init__.py +0 -0
  192. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/kernels/gf128.cpp +0 -0
  193. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/kernels/ldpc.cpp +0 -0
  194. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/kernels/okvs.cpp +0 -0
  195. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/kernels/okvs_opt.cpp +0 -0
  196. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/kernels/py_kernels.py +0 -0
  197. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/collective.py +0 -0
  198. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/device/cluster.py +0 -0
  199. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/__init__.py +0 -0
  200. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/_utils.py +0 -0
  201. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/analytics/__init__.py +0 -0
  202. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/analytics/aggregation.py +0 -0
  203. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/analytics/groupby.md +0 -0
  204. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/analytics/groupby.py +0 -0
  205. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/analytics/permutation.py +0 -0
  206. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/common/constants.py +0 -0
  207. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/ot/__init__.py +0 -0
  208. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/ot/base.py +0 -0
  209. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/ot/extension.py +0 -0
  210. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/ot/silent.py +0 -0
  211. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/psi/__init__.py +0 -0
  212. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/psi/cuckoo.py +0 -0
  213. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/psi/okvs.py +0 -0
  214. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/psi/okvs_gct.py +0 -0
  215. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/psi/oprf.py +0 -0
  216. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/psi/rr22.py +0 -0
  217. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/psi/unbalanced.py +0 -0
  218. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/vole/__init__.py +0 -0
  219. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/vole/gilboa.py +0 -0
  220. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/libs/mpc/vole/silver.py +0 -0
  221. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/runtime/__init__.py +0 -0
  222. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/runtime/dialect_state.py +0 -0
  223. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/runtime/object_store.py +0 -0
  224. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/mplang/v2/runtime/value.py +0 -0
  225. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/__init__.py +0 -0
  226. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/conftest.py +0 -0
  227. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/__init__.py +0 -0
  228. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/analysis/test_diagram.py +0 -0
  229. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/conftest.py +0 -0
  230. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/__init__.py +0 -0
  231. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/expr/__init__.py +0 -0
  232. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/expr/conftest.py +0 -0
  233. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/expr/test_ast.py +0 -0
  234. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/expr/test_printer.py +0 -0
  235. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/expr/test_utils.py +0 -0
  236. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/expr/test_walk.py +0 -0
  237. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_cluster.py +0 -0
  238. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_dtype.py +0 -0
  239. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_mask.py +0 -0
  240. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_mpir.py +0 -0
  241. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_mptype.py +0 -0
  242. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_primitive.py +0 -0
  243. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_table.py +0 -0
  244. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_tensor.py +0 -0
  245. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/core/test_tracer.py +0 -0
  246. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/device/__init__.py +0 -0
  247. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/device/test_device_basic.py +0 -0
  248. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/integration/README.md +0 -0
  249. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/integration/test_crypto_roundtrip.py +0 -0
  250. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/integration/test_http_e2e.py +0 -0
  251. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/integration/test_symbols_roundtrip.py +0 -0
  252. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/integration/test_tee_workflow.py +0 -0
  253. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/integration/test_tutorials.py +0 -0
  254. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/integration/test_unused_param_integration.py +0 -0
  255. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/__init__.py +0 -0
  256. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_basic.py +0 -0
  257. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_debug_print.py +0 -0
  258. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_fhe.py +0 -0
  259. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_kernel_binding.py +0 -0
  260. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_phe.py +0 -0
  261. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_spu.py +0 -0
  262. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_sql_duckdb.py +0 -0
  263. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_stablehlo.py +0 -0
  264. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_value.py +0 -0
  265. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/kernels/test_value_serde.py +0 -0
  266. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/__init__.py +0 -0
  267. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/dummy.py +0 -0
  268. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_basic_pack.py +0 -0
  269. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_crypto.py +0 -0
  270. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_feop_base.py +0 -0
  271. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_jax_cc.py +0 -0
  272. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_nnx_cc.py +0 -0
  273. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_phe.py +0 -0
  274. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_spu.py +0 -0
  275. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_spu_defensive.py +0 -0
  276. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_sql.py +0 -0
  277. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_sql_cc.py +0 -0
  278. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/ops/test_table_tensor_conversion.py +0 -0
  279. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/runtime/__init__.py +0 -0
  280. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/runtime/test_cli.py +0 -0
  281. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/runtime/test_communicator.py +0 -0
  282. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/runtime/test_driver.py +0 -0
  283. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/runtime/test_server.py +0 -0
  284. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/runtime/test_simulation.py +0 -0
  285. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/simp/test_mpi.py +0 -0
  286. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/simp/test_random.py +0 -0
  287. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/simp/test_smpc.py +0 -0
  288. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/simp/test_sugar.py +0 -0
  289. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/utils/__init__.py +0 -0
  290. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/utils/server_fixtures.py +0 -0
  291. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/utils/test_func_utils.py +0 -0
  292. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/utils/test_spu_utils.py +0 -0
  293. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v1/utils/test_table_utils.py +0 -0
  294. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/__init__.py +0 -0
  295. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/__init__.py +0 -0
  296. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/simp_driver/__init__.py +0 -0
  297. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/simp_worker/__init__.py +0 -0
  298. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/simp_worker/test_mem.py +0 -0
  299. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_bfv_impl.py +0 -0
  300. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_okvs_binding.py +0 -0
  301. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_simp_object_store.py +0 -0
  302. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_tensor_impl.py +0 -0
  303. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/backends/test_verify_clean.py +0 -0
  304. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/__init__.py +0 -0
  305. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_bfv.py +0 -0
  306. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_dtypes.py +0 -0
  307. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_field.py +0 -0
  308. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_func.py +0 -0
  309. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_okvs.py +0 -0
  310. /mplang_nightly-0.1.dev246/examples/v2/okvs_microbench.py → /mplang_nightly-0.1.dev266/tests/v2/dialects/test_okvs_bench.py +0 -0
  311. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_phe.py +0 -0
  312. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_simp.py +0 -0
  313. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_simp_comm.py +0 -0
  314. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_spu.py +0 -0
  315. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_table.py +0 -0
  316. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/dialects/test_tensor.py +0 -0
  317. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/__init__.py +0 -0
  318. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_graph.py +0 -0
  319. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_primitive.py +0 -0
  320. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_primitive_multi_output.py +0 -0
  321. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_printer.py +0 -0
  322. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_serde.py +0 -0
  323. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_tracer.py +0 -0
  324. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_typing.py +0 -0
  325. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/edsl/test_typing_graph_serde.py +0 -0
  326. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/device/__init__.py +0 -0
  327. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/device/conftest.py +0 -0
  328. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/device/test_device_api_errors.py +0 -0
  329. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/device/test_device_dialects.py +0 -0
  330. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/device/test_device_layouts.py +0 -0
  331. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/device/test_device_tee.py +0 -0
  332. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/__init__.py +0 -0
  333. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/analytics/__init__.py +0 -0
  334. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/analytics/test_aggregation.py +0 -0
  335. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/analytics/test_groupby.py +0 -0
  336. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/ot/__init__.py +0 -0
  337. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/ot/test_ot_extension.py +0 -0
  338. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/ot/test_silent_ot.py +0 -0
  339. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/psi/__init__.py +0 -0
  340. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/psi/test_okvs_gct.py +0 -0
  341. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/psi/test_oprf.py +0 -0
  342. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/psi/test_psi.py +0 -0
  343. /mplang_nightly-0.1.dev246/examples/v2/psi_bench.py → /mplang_nightly-0.1.dev266/tests/v2/libs/mpc/psi/test_psi_bench.py +0 -0
  344. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/psi/test_rr22.py +0 -0
  345. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/psi/verify_psi_okvs_logic.py +0 -0
  346. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/test_field_gf128.py +0 -0
  347. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/test_utils.py +0 -0
  348. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/vole/__init__.py +0 -0
  349. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/vole/test_gilboa_manual.py +0 -0
  350. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/vole/test_ldpc.py +0 -0
  351. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/vole/test_silver_vole.py +0 -0
  352. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/vole/test_vole.py +0 -0
  353. /mplang_nightly-0.1.dev246/examples/v2/vole_bench.py → /mplang_nightly-0.1.dev266/tests/v2/libs/mpc/vole/test_vole_bench.py +0 -0
  354. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/mpc/vole/verify_vole_logic.py +0 -0
  355. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/test_collective.py +0 -0
  356. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/libs/test_simple_guide.py +0 -0
  357. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/runtime/test_object_store.py +0 -0
  358. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/runtime/test_object_store_fs.py +0 -0
  359. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/test_store.py +0 -0
  360. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/utils/__init__.py +0 -0
  361. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tests/v2/utils/tensor_patch.py +0 -0
  362. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/MIGRATION.md +0 -0
  363. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/README.md +0 -0
  364. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/__init__.py +0 -0
  365. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/data/alice.csv +0 -0
  366. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/data/bob.csv +0 -0
  367. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/data/prepare_vertical_iris.py +0 -0
  368. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/run.sh +0 -0
  369. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/00_device_basics.py +0 -0
  370. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/01_function_decorator.py +0 -0
  371. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/02_simulation_and_driver.py +0 -0
  372. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/03_run_jax.py +0 -0
  373. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/04_run_sql.py +0 -0
  374. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/05_pipeline.py +0 -0
  375. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/06_ir_dump_and_analysis.py +0 -0
  376. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/device/07_run_nnx.py +0 -0
  377. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/pitfalls/late_binding.py +0 -0
  378. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/pitfalls/rand.py +0 -0
  379. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/00_basic.py +0 -0
  380. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/01_condition.py +0 -0
  381. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/02_whileloop.py +0 -0
  382. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/03_stdio.py +0 -0
  383. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/04_phe.py +0 -0
  384. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/05_tee.py +0 -0
  385. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/06_fhe.py +0 -0
  386. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/07_advanced.py +0 -0
  387. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v1/simp/08_simple_secret_sharing.py +0 -0
  388. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v2/01_function_decorator.py +0 -0
  389. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v2/03_run_jax.py +0 -0
  390. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v2/04_ir_dump_and_analysis.py +0 -0
  391. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v2/06_pipeline.py +0 -0
  392. {mplang_nightly-0.1.dev246 → mplang_nightly-0.1.dev266}/tutorials/v2/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mplang-nightly
3
- Version: 0.1.dev246
3
+ Version: 0.1.dev266
4
4
  Summary: Multi-Party Programming Language
5
5
  Author-email: SecretFlow Team <secretflow-contact@service.alipay.com>
6
6
  License: Apache License
@@ -211,7 +211,7 @@ Requires-Dist: cryptography>=43.0.0
211
211
  Requires-Dist: duckdb>=1.0.0
212
212
  Requires-Dist: fastapi
213
213
  Requires-Dist: flax>=0.12.0
214
- Requires-Dist: httpx>=0.27.0
214
+ Requires-Dist: httpx<1.0.0,>=0.27.0
215
215
  Requires-Dist: jax[cpu]==0.8.0
216
216
  Requires-Dist: lightphe<0.1.0,>=0.0.15
217
217
  Requires-Dist: numpy>=2.0.0
@@ -219,7 +219,7 @@ Requires-Dist: pandas>=2.0.0
219
219
  Requires-Dist: protobuf<6.0,>=5.0
220
220
  Requires-Dist: pyarrow>=14.0.0
221
221
  Requires-Dist: pyyaml>=6.0
222
- Requires-Dist: spu>=0.10.0.dev20251211
222
+ Requires-Dist: spu>=0.10.0.dev20251208
223
223
  Requires-Dist: sqlglot>=23.0.0
224
224
  Requires-Dist: tenseal==0.3.16
225
225
  Requires-Dist: typing-extensions
@@ -52,15 +52,19 @@ from mplang.v2.edsl import (
52
52
  TracedFunction,
53
53
  Tracer,
54
54
  Value,
55
+ find_context,
56
+ find_context_with_state,
57
+ find_interpreter,
55
58
  format_graph,
56
59
  get_current_context,
57
60
  get_default_context,
58
- get_root_context,
61
+ is_tracing,
59
62
  jit,
60
63
  pop_context,
61
64
  primitive,
62
65
  push_context,
63
66
  register_default_context_factory,
67
+ set_root_context,
64
68
  trace,
65
69
  )
66
70
  from mplang.v2.edsl.registry import get_profiler
@@ -89,6 +93,7 @@ from mplang.v2.libs.device import (
89
93
  put,
90
94
  set_dev_attr,
91
95
  )
96
+ from mplang.v2.libs.device import fetch as device_fetch
92
97
  from mplang.v2.runtime.interpreter import Interpreter
93
98
 
94
99
  # =============================================================================
@@ -96,34 +101,6 @@ from mplang.v2.runtime.interpreter import Interpreter
96
101
  # =============================================================================
97
102
 
98
103
 
99
- def set_root_context(context: Interpreter, force: bool = False) -> None:
100
- """Set the global/root execution context.
101
-
102
- This explicitly sets the provided interpreter as the Root Context.
103
- All subsequent operations (compile, evaluate, device resolution) will
104
- use this context as the default environment.
105
-
106
- Args:
107
- context: Interpreter to use as the root context.
108
- force: If True, clears the existing context stack before setting.
109
- If False (default), pushes onto the stack.
110
- """
111
- from mplang.v2.edsl.context import _context_stack, get_current_context
112
-
113
- if force:
114
- _context_stack.clear()
115
- _context_stack.append(context)
116
- return
117
-
118
- if get_current_context() is not None:
119
- raise RuntimeError(
120
- "Cannot set root context: Context stack is not empty. "
121
- "Use force=True to overwrite the existing root context."
122
- )
123
-
124
- push_context(context)
125
-
126
-
127
104
  def _get_context(context: Interpreter | None) -> Interpreter:
128
105
  """Get context from parameter or context stack."""
129
106
  if context is not None:
@@ -186,92 +163,165 @@ def evaluate(
186
163
  inputs = fn.prepare_inputs(*args, **kwargs)
187
164
  inputs = [unwrap_if_interp(v) for v in inputs]
188
165
  raw_result = interp.evaluate_graph(fn.graph, inputs)
189
- return fn.reconstruct_outputs(raw_result)
166
+ wrapped = [
167
+ InterpObject(v, fn.graph.outputs[i].type, interp)
168
+ for i, v in enumerate(raw_result)
169
+ ]
170
+ return fn.reconstruct_outputs(wrapped)
190
171
 
191
172
  return fn(*args, **kwargs)
192
173
 
193
174
 
194
175
  def fetch(
195
176
  result: Any,
196
- party: int | str | None = None,
197
177
  *,
178
+ follow_device: bool = True,
198
179
  context: Interpreter | None = None,
199
180
  ) -> Any:
200
- """Fetch the result, optionally for a specific party.
181
+ """Fetch results from interpreter context to Python.
182
+
183
+ This is a meta-function that operates at execution boundaries, not a traced
184
+ dialect operation. It brings data from the distributed/MPC runtime back to
185
+ the Python host.
186
+
187
+ Behavior in different contexts:
188
+ - **Tracing (compile)**: Returns the input unchanged (identity). The graph
189
+ outputs are determined by the function's return statement, not fetch calls.
190
+ - **Execution (evaluate)**: Actually fetches data from workers/parties.
191
+
192
+ Design Note (A vs B tradeoff):
193
+ Two designs were considered for fetch behavior during tracing:
194
+
195
+ - **Design A (chosen)**: fetch = identity during tracing. Graph outputs
196
+ are determined solely by the return statement. This is simpler and
197
+ avoids ambiguity when fetch and return reference different values.
198
+
199
+ - **Design B (alternative)**: fetch marks output points in the graph.
200
+ This would allow fetch(a), fetch(b), return b to output both a and b.
201
+ However, it complicates the semantics and requires tracking fetch
202
+ points separately from return values.
203
+
204
+ Design A was chosen for simplicity. If a value needs to be an output,
205
+ it should be returned. fetch's role is purely for execution-time I/O.
201
206
 
202
207
  Args:
203
- result: The result to fetch (DriverVar or other value).
204
- party: Optional party index or device name (e.g., "P0").
205
- context: Optional interpreter context. If None, uses current context.
208
+ result: Object(s) to fetch. Can be a single InterpObject, DriverVar,
209
+ or nested structure containing them.
210
+ follow_device: If True and object has device attribute, dispatch to
211
+ device.fetch which fetches from the correct rank based on device.
212
+ If False, fetch from all parties.
213
+ context: Interpreter context. If None, uses current context.
206
214
 
207
215
  Returns:
208
- The fetched data (unwrapped from Value wrappers).
209
-
210
- Example:
211
- >>> with mp.make_simulator(3) as sim:
212
- ... data = mp.fetch(result, "P0") # uses sim from context
216
+ Fetched Python values. For device objects with follow_device=True,
217
+ returns single value from the device's rank(s). Otherwise returns
218
+ list of values (one per party) or single value for world_size=1.
219
+ During tracing, returns the input unchanged.
213
220
  """
214
- from typing import cast
221
+ from jax.tree_util import tree_map
215
222
 
216
- from mplang.v2.backends.simp_driver.state import SimpDriver
217
223
  from mplang.v2.backends.simp_driver.values import DriverVar
218
- from mplang.v2.backends.table_impl import TableValue
219
- from mplang.v2.backends.tensor_impl import TensorValue
224
+ from mplang.v2.edsl.context import is_tracing
220
225
  from mplang.v2.runtime.interpreter import InterpObject
226
+ from mplang.v2.runtime.value import WrapValue
221
227
 
222
- interp = _get_context(context)
228
+ # Check if we are in tracing context - if so, return identity
229
+ if is_tracing():
230
+ # Design A: fetch = identity during tracing
231
+ # Graph outputs are determined by return statement, not fetch calls
232
+ return result
223
233
 
224
- def _unwrap_value(val: Any) -> Any:
225
- """Unwrap Value types to get the underlying data."""
226
- if isinstance(val, TensorValue):
227
- return val.data
228
- elif isinstance(val, TableValue):
229
- return val.data
230
- return val
234
+ # Execution context - actually fetch data
235
+ interp = _get_context(context)
231
236
 
232
- # Unwrap InterpObject to get the runtime value
233
- if isinstance(result, InterpObject):
234
- result = result.runtime_obj
235
-
236
- # Get simp state for fetching
237
- simp_state = cast(SimpDriver | None, interp.get_dialect_state("simp"))
238
- cluster_spec = getattr(interp, "_cluster_spec", None)
239
-
240
- # Fetch from DriverVar
241
- if isinstance(result, DriverVar):
242
- resolved_values = []
243
- for rank, val in enumerate(result.values):
244
- if isinstance(val, str) and "://" in val:
245
- if simp_state is not None:
246
- fut = simp_state.fetch(rank, val)
247
- resolved_values.append(fut.result())
248
- else:
249
- resolved_values.append(val)
250
- else:
251
- resolved_values.append(val)
252
-
253
- # Select party if needed
254
- if party is not None:
255
- if isinstance(party, str) and cluster_spec is not None:
256
- device_info = cluster_spec.devices.get(party)
257
- if device_info and device_info.members:
258
- party = device_info.members[0].rank
237
+ def _fetch_single(var: Any) -> Any:
238
+ """Fetch a single value from InterpObject."""
239
+ # InterpObject (from mp.evaluate) - extract runtime_obj
240
+ if isinstance(var, InterpObject):
241
+ if follow_device and is_device_obj(var):
242
+ return device_fetch(var)
243
+ var = var.runtime_obj # extract and continue processing
244
+
245
+ # DriverVar (simp dialect) - remote fetch from workers
246
+ if isinstance(var, DriverVar):
247
+ from mplang.v2.backends.simp_driver.state import SimpDriver
248
+
249
+ simp_state = interp.get_dialect_state("simp")
250
+ assert isinstance(simp_state, SimpDriver), "DriverVar requires simp state"
251
+
252
+ resolved: list[Any] = []
253
+ for rank, uri in enumerate(var.values):
254
+ if uri is None:
255
+ resolved.append(None)
259
256
  else:
260
- raise ValueError(f"Unknown party: {party}")
261
- else:
262
- # Default logic for int
263
- pass
257
+ fetched = simp_state.fetch(rank, uri).result()
258
+ if isinstance(fetched, WrapValue):
259
+ fetched = fetched.data
260
+ resolved.append(fetched)
264
261
 
265
- p_idx = cast(int, party)
266
- return _unwrap_value(resolved_values[p_idx]) # type: ignore[no-any-return]
267
- return [_unwrap_value(v) for v in resolved_values]
262
+ return resolved[0] if len(resolved) == 1 else resolved
268
263
 
269
- # Unwrap Value types to get the underlying data
270
- return _unwrap_value(result)
264
+ # WrapValue (TensorValue, TableValue, etc.) - unwrap
265
+ if isinstance(var, WrapValue):
266
+ return var.data
267
+
268
+ # Plain values pass through
269
+ return var
270
+
271
+ with interp:
272
+ return tree_map(_fetch_single, result)
271
273
 
272
274
 
273
275
  # Alias for compatibility
274
- function = jit # @mp.function -> @mp2.function (JIT compilation)
276
+ def function(fn: Callable[..., Any] | None = None) -> Callable[..., Any]:
277
+ """Decorator defining a Multi-Party Function (MP Program).
278
+
279
+ This decorator "lifts" a local function into a distributed program by
280
+ automatically wrapping it in a `simp.pcall_static` that targets ALL available
281
+ parties in the current context.
282
+
283
+ Semantics: f(args) -> pcall(ALL, f, args)
284
+
285
+ Args:
286
+ fn: The function to decorate.
287
+
288
+ Returns:
289
+ A wrapper function that, when called, executes the original function
290
+ on all workers.
291
+ """
292
+ import functools
293
+
294
+ from mplang.v2.dialects import simp
295
+
296
+ if fn is None:
297
+ return function
298
+
299
+ def has_simp_state(ctx: Any) -> bool:
300
+ if hasattr(ctx, "get_dialect_state"):
301
+ state = ctx.get_dialect_state("simp")
302
+ return state is not None and hasattr(state, "world_size")
303
+ return False
304
+
305
+ @functools.wraps(fn)
306
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
307
+ from mplang.v2.edsl.context import find_context
308
+
309
+ # Find context with simp dialect state
310
+ ctx = find_context(has_simp_state)
311
+ if ctx is None:
312
+ raise RuntimeError(
313
+ "mp.function requires a context with world_size information "
314
+ "(e.g. SimpSimulator or Driver initialized)."
315
+ )
316
+
317
+ # ctx found by predicate so we know it has get_dialect_state
318
+ simp_state = ctx.get_dialect_state("simp") # type: ignore[attr-defined]
319
+ world_size = simp_state.world_size # type: ignore
320
+
321
+ all_parties = tuple(range(world_size))
322
+ return simp.pcall_static(all_parties, fn, *args, **kwargs)
323
+
324
+ return wrapper
275
325
 
276
326
 
277
327
  def compile(
@@ -334,10 +384,14 @@ __all__ = [ # noqa: RUF022
334
384
  "compile",
335
385
  "evaluate",
336
386
  "fetch",
387
+ "find_context",
388
+ "find_context_with_state",
389
+ "find_interpreter",
337
390
  "format_graph",
338
391
  "function",
339
392
  "get_current_context",
340
393
  "get_default_context",
394
+ "is_tracing",
341
395
  "jit",
342
396
  "mplang",
343
397
  "pop_context",
@@ -363,7 +417,6 @@ __all__ = [ # noqa: RUF022
363
417
  # Dialects
364
418
  "dialects",
365
419
  "register_default_context_factory",
366
- "get_root_context",
367
420
  "get_profiler",
368
421
  ]
369
422
 
@@ -271,6 +271,27 @@ def bytes_to_point_impl(
271
271
 
272
272
  # --- Sym / Hash Impl ---
273
273
 
274
+ # Supported symmetric encryption algorithms
275
+ _SUPPORTED_ALGOS = {"aes-gcm"}
276
+
277
+
278
+ def _validate_algo(algo: str, operation: str) -> None:
279
+ """Validate that the algorithm is supported.
280
+
281
+ Args:
282
+ algo: Algorithm name to validate
283
+ operation: Operation name for error message (e.g., "encryption", "decryption")
284
+
285
+ Raises:
286
+ ValueError: If algo is not supported
287
+ """
288
+ if algo not in _SUPPORTED_ALGOS:
289
+ supported = ", ".join(sorted(_SUPPORTED_ALGOS))
290
+ raise ValueError(
291
+ f"Unsupported {operation} algorithm: {algo!r}. "
292
+ f"Supported algorithms: {supported}"
293
+ )
294
+
274
295
 
275
296
  @crypto.hash_p.def_impl
276
297
  def hash_impl(interpreter: Interpreter, op: Operation, data: Value) -> Value:
@@ -336,6 +357,10 @@ def sym_encrypt_impl(
336
357
  numpy arrays, scalars, etc.). This supports both high-level API usage
337
358
  (with TensorValue) and elementwise operations (with raw scalars).
338
359
  """
360
+ # Read and validate algo parameter (must be provided by frontend)
361
+ algo = op.attrs["algo"]
362
+ _validate_algo(algo, "encryption")
363
+
339
364
  # Get raw key bytes - strict type checking
340
365
  if isinstance(key, SymmetricKeyValue):
341
366
  k = key.key_bytes
@@ -376,6 +401,10 @@ def sym_decrypt_impl(
376
401
  on what was encrypted - could be a Value subclass (TensorValue, BytesValue),
377
402
  a numpy array, or a scalar (int, float, etc.) when used in elementwise ops.
378
403
  """
404
+ # Read and validate algo parameter (must be provided by frontend)
405
+ algo = op.attrs["algo"]
406
+ _validate_algo(algo, "decryption")
407
+
379
408
  # Get raw key bytes - strict type checking
380
409
  if isinstance(key, SymmetricKeyValue):
381
410
  k = key.key_bytes
@@ -585,6 +614,101 @@ def kem_derive_impl(
585
614
  return SymmetricKeyValue(suite=suite, key_bytes=secret)
586
615
 
587
616
 
617
+ @crypto.hkdf_p.def_impl
618
+ def hkdf_impl(
619
+ interpreter: Interpreter,
620
+ op: Operation,
621
+ secret: SymmetricKeyValue | TensorValue,
622
+ ) -> SymmetricKeyValue:
623
+ """HKDF key derivation implementation using SHA-256.
624
+
625
+ Implements RFC 5869 HKDF with HMAC-SHA256. This is the NIST SP 800-56C
626
+ compliant way to derive symmetric keys from ECDH shared secrets.
627
+
628
+ Current implementation supports only SHA-256. Future versions will add
629
+ SHA-512, SHA3-256, and BLAKE2b support.
630
+
631
+ Security Notes:
632
+ - Uses salt=None (defaults to 32-byte all-zero salt per RFC 5869)
633
+ - ONLY SAFE for high-entropy IKM (e.g., 256-bit ECDH shared secrets)
634
+ - NOT suitable for: passwords, low-entropy secrets, or repeated key derivations
635
+ - For session keys with same ECDH pair: use unique 'info' per session
636
+
637
+ Per NIST SP 800-56C Rev. 2:
638
+ "If the IKM is already cryptographically strong (e.g., from ECDH),
639
+ a salt may not be necessary, but using one does not hurt."
640
+
641
+ Args:
642
+ interpreter: Runtime interpreter context
643
+ op: Operation node containing attributes (info, hash_algo)
644
+ secret: Input key material (IKM) as SymmetricKeyValue or TensorValue
645
+ Must be high-entropy (≥256 bits) for security with salt=None
646
+
647
+ Returns:
648
+ SymmetricKeyValue with suite="hkdf-{hash_algo}" and 32-byte key_bytes
649
+
650
+ Raises:
651
+ TypeError: If secret is not SymmetricKeyValue or TensorValue
652
+ ValueError: If info parameter is empty (required for domain separation)
653
+ NotImplementedError: If hash_algo is not "sha256"
654
+ """
655
+ from cryptography.hazmat.primitives import hashes
656
+ from cryptography.hazmat.primitives.kdf.hkdf import HKDF
657
+
658
+ # Extract operation attributes
659
+ info_str = op.attrs.get("info", "")
660
+ hash_algo = (
661
+ op.attrs.get("hash_algo", "sha256").lower().replace("-", "").replace("_", "")
662
+ )
663
+
664
+ # Validate info parameter (REQUIRED for domain separation per NIST)
665
+ if not info_str:
666
+ raise ValueError(
667
+ "HKDF requires non-empty 'info' parameter for domain separation. "
668
+ "The info string binds the derived key to a specific protocol/context. "
669
+ "Recommended format: 'namespace/component/purpose/version'"
670
+ )
671
+
672
+ info_bytes = info_str.encode("utf-8")
673
+
674
+ # Extract input key material (IKM) bytes
675
+ if isinstance(secret, SymmetricKeyValue):
676
+ ikm = secret.key_bytes
677
+ elif isinstance(secret, TensorValue):
678
+ ikm = secret.unwrap().tobytes()
679
+ else:
680
+ raise TypeError(
681
+ f"hkdf secret must be SymmetricKeyValue or TensorValue, "
682
+ f"got {type(secret).__name__}"
683
+ )
684
+
685
+ # Validate hash algorithm (currently only SHA-256 implemented)
686
+ if hash_algo != "sha256":
687
+ raise NotImplementedError(
688
+ f"HKDF with hash algorithm '{hash_algo}' is not yet implemented. "
689
+ f"Currently only 'sha256' is supported. "
690
+ f"Planned future support: sha512, sha3256, blake2b"
691
+ )
692
+
693
+ # Perform HKDF derivation using cryptography library
694
+ # Note: salt=None uses 32-byte all-zero salt (not random salt!)
695
+ # This is secure ONLY because ECDH outputs are already high-entropy (256-bit uniform)
696
+ # For low-entropy inputs or repeated derivations, a random salt would be required
697
+ hkdf = HKDF(
698
+ algorithm=hashes.SHA256(),
699
+ length=32, # Output length in bytes (AES-256 key = 32 bytes)
700
+ salt=None, # 32-byte zero salt (secure for high-entropy ECDH shared secrets)
701
+ info=info_bytes, # Context-specific binding for domain separation
702
+ )
703
+
704
+ derived_key = hkdf.derive(ikm)
705
+
706
+ # Return SymmetricKeyValue with composite suite name
707
+ # Format: "hkdf-{hash_algo}" to indicate derivation method and hash function
708
+ suite = f"hkdf-{hash_algo}"
709
+ return SymmetricKeyValue(suite=suite, key_bytes=derived_key)
710
+
711
+
588
712
  @crypto.random_bytes_p.def_impl
589
713
  def random_bytes_impl(interpreter: Interpreter, op: Operation) -> TensorValue:
590
714
  """Generate random bytes using os.urandom."""
@@ -102,4 +102,6 @@ def _call_impl(
102
102
  raise TypeError(f"func.call expects FunctionValue, got {type(fn_obj)}")
103
103
 
104
104
  call_args = list(args)
105
- return interpreter.evaluate_graph(fn_obj.graph, call_args)
105
+ result = interpreter.evaluate_graph(fn_obj.graph, call_args)
106
+ # Return single value or list based on graph outputs
107
+ return result[0] if len(fn_obj.graph.outputs) == 1 else result
@@ -26,6 +26,7 @@ import httpx
26
26
  from mplang.v2.backends.simp_driver.state import SimpDriver
27
27
  from mplang.v2.edsl import serde
28
28
  from mplang.v2.runtime.interpreter import Interpreter
29
+ from mplang.v2.runtime.object_store import ObjectStore
29
30
 
30
31
  if TYPE_CHECKING:
31
32
  from concurrent.futures import Future
@@ -159,6 +160,7 @@ def make_driver(endpoints: list[str], *, cluster_spec: Any = None) -> Interprete
159
160
  name="DriverInterpreter",
160
161
  root_dir=state.driver_root,
161
162
  handlers=handlers,
163
+ store=ObjectStore(fs_root=str(state.driver_root)),
162
164
  )
163
165
  interp.set_dialect_state("simp", state)
164
166
  interp._cluster_spec = cluster_spec # type: ignore[attr-defined]
@@ -154,6 +154,10 @@ class SimpMemDriver(SimpDriver):
154
154
  self._workers = workers
155
155
  self._mesh = mesh
156
156
 
157
+ def shutdown(self) -> None:
158
+ """Shutdown the local memory driver and its mesh."""
159
+ self._mesh.shutdown()
160
+
157
161
  @property
158
162
  def world_size(self) -> int:
159
163
  return self._world_size
@@ -201,27 +205,20 @@ class SimpMemDriver(SimpDriver):
201
205
  worker_interp = self._workers[rank]
202
206
  worker_ctx = cast(SimpWorker, worker_interp.get_dialect_state("simp"))
203
207
 
204
- # Resolve URI inputs
205
- resolved_inputs = []
206
- for inp in inputs:
207
- if isinstance(inp, str) and "://" in inp:
208
- resolved_inputs.append(worker_ctx.store.get(inp))
209
- else:
210
- resolved_inputs.append(inp)
208
+ # Resolve URI inputs (None means rank has no data)
209
+ resolved_inputs = [
210
+ worker_ctx.store.get(inp) if inp is not None else None for inp in inputs
211
+ ]
211
212
 
212
213
  # Execute
213
214
  results = worker_interp.evaluate_graph(graph, resolved_inputs, job_id)
214
215
 
215
- # Store results
216
+ # Store results (results is always a list)
216
217
  if not graph.outputs:
217
218
  return None
218
- if len(graph.outputs) == 1:
219
- val = results
220
- if val is None:
221
- return None
222
- return worker_ctx.store.put(val)
223
- else:
224
- return [worker_ctx.store.put(res) for res in results]
219
+ return [
220
+ worker_ctx.store.put(res) if res is not None else None for res in results
221
+ ]
225
222
 
226
223
 
227
224
  def make_simulator(
@@ -268,6 +265,7 @@ def make_simulator(
268
265
  root_dir=cluster.host_root,
269
266
  handlers=handlers,
270
267
  tracer=cluster.tracer,
268
+ store=ObjectStore(fs_root=str(cluster.host_root)),
271
269
  )
272
270
  interp.set_dialect_state("simp", state)
273
271
 
@@ -68,7 +68,8 @@ def _collect_to_hostvars(results: list[Any], num_outputs: int, world_size: int)
68
68
  """Collect worker results into DriverVar(s).
69
69
 
70
70
  Args:
71
- results: List of results from each worker (length = world_size)
71
+ results: List of results from each worker (length = world_size).
72
+ Each result is a list of URIs (one per output).
72
73
  num_outputs: Number of outputs per worker
73
74
  world_size: Total number of workers
74
75
 
@@ -78,15 +79,16 @@ def _collect_to_hostvars(results: list[Any], num_outputs: int, world_size: int)
78
79
  if num_outputs == 0:
79
80
  return None
80
81
 
81
- if num_outputs == 1:
82
- return DriverVar(results)
83
-
84
- # Multiple outputs: transpose [worker][output] -> [output][worker]
82
+ # Transpose [worker][output] -> [output][worker]
83
+ # results[worker_idx] is a list of URIs for that worker's outputs
85
84
  transposed = []
86
- for i in range(num_outputs):
85
+ for out_idx in range(num_outputs):
87
86
  transposed.append(
88
- DriverVar([res[i] if res is not None else None for res in results])
87
+ DriverVar([res[out_idx] if res is not None else None for res in results])
89
88
  )
89
+
90
+ if num_outputs == 1:
91
+ return transposed[0]
90
92
  return transposed
91
93
 
92
94
 
@@ -49,9 +49,9 @@ from pydantic import BaseModel
49
49
 
50
50
  from mplang.v2.backends import spu_impl as _spu_impl # noqa: F401
51
51
  from mplang.v2.backends import tensor_impl as _tensor_impl # noqa: F401
52
- from mplang.v2.backends.simp_worker import SimpWorker
53
52
 
54
53
  # Register operation implementations (side-effect imports)
54
+ from mplang.v2.backends.simp_worker import SimpWorker
55
55
  from mplang.v2.backends.simp_worker import ops as _simp_worker_ops # noqa: F401
56
56
  from mplang.v2.edsl import serde
57
57
  from mplang.v2.edsl.graph import Graph
@@ -232,7 +232,9 @@ def create_worker_app(
232
232
  # func_impl is already imported at module level for side-effects
233
233
  handlers: dict[str, Callable[..., Any]] = {**WORKER_HANDLERS} # type: ignore[dict-item]
234
234
 
235
- worker = Interpreter(tracer=tracer, root_dir=root_dir, handlers=handlers)
235
+ worker = Interpreter(
236
+ tracer=tracer, root_dir=root_dir, handlers=handlers, store=store
237
+ )
236
238
  # Register SimpWorker context as 'simp' dialect state
237
239
  worker.set_dialect_state("simp", ctx)
238
240
 
@@ -242,11 +244,18 @@ def create_worker_app(
242
244
 
243
245
  def _do_execute(graph: Graph, inputs: list[Any], job_id: str | None = None) -> Any:
244
246
  """Execute graph in worker thread."""
245
- # Note: we ignore job_id for now as generic Interpreter doesn't take it.
246
- # But we could set it in thread local if needed.
247
- result = worker.evaluate_graph(graph, inputs)
247
+ # Resolve URI inputs (None means rank has no data)
248
+ resolved_inputs = [
249
+ store.get(inp) if inp is not None else None for inp in inputs
250
+ ]
251
+
252
+ result = worker.evaluate_graph(graph, resolved_inputs)
248
253
  comm.wait_pending_sends()
249
- return result
254
+
255
+ # Store results and return URIs (result is always a list)
256
+ if not graph.outputs:
257
+ return None
258
+ return [store.put(res) if res is not None else None for res in result]
250
259
 
251
260
  @app.post("/exec")
252
261
  async def execute(req: ExecRequest) -> dict[str, str]: