mplang-nightly 0.1.dev250__tar.gz → 0.1.dev252__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 (380) hide show
  1. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/PKG-INFO +1 -1
  2. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/pcall_jax.py +10 -18
  3. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/stax_nn.py +2 -2
  4. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/__init__.py +52 -59
  5. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/func_impl.py +3 -1
  6. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_driver/mem.py +8 -15
  7. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_driver/ops.py +9 -7
  8. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_worker/http.py +11 -4
  9. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_worker/ops.py +19 -19
  10. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/tensor_impl.py +7 -3
  11. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/tracer.py +4 -9
  12. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/device/__init__.py +2 -0
  13. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/device/api.py +71 -0
  14. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/runtime/interpreter.py +7 -23
  15. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/simp_driver/test_http.py +4 -3
  16. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/simp_worker/test_http.py +7 -12
  17. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_spu_impl.py +3 -1
  18. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/runtime/test_interpreter_async.py +4 -4
  19. mplang_nightly-0.1.dev252/tests/v2/test_pytree_io.py +231 -0
  20. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v2/00_device_basics.py +6 -6
  21. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/.gitignore +0 -0
  22. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/LICENSE +0 -0
  23. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/README.md +0 -0
  24. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/conf/3pc.yaml +0 -0
  25. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/stax_nn/README.md +0 -0
  26. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/stax_nn/models.py +0 -0
  27. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/stax_nn/stax_nn.py +0 -0
  28. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/xgboost/bench_fhe_hist.py +0 -0
  29. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/xgboost/hist_jax.py +0 -0
  30. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/xgboost/hist_jax_test.py +0 -0
  31. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/xgboost/naive_np.py +0 -0
  32. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/xgboost/readme.md +0 -0
  33. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/xgboost/sgb.py +0 -0
  34. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v1/xgboost/sgb_test.py +0 -0
  35. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/bfv_sort_agg.py +0 -0
  36. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/okvs_microbench.py +0 -0
  37. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/phe_sort_agg.py +0 -0
  38. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/psi_bench.py +0 -0
  39. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/secure_shuffle_agg.py +0 -0
  40. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/sgb.py +0 -0
  41. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/sgb_bench.py +0 -0
  42. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/examples/v2/vole_bench.py +0 -0
  43. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/hatch_build.py +0 -0
  44. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/__init__.py +0 -0
  45. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/__init__.py +0 -0
  46. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/_device.py +0 -0
  47. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/analysis/__init__.py +0 -0
  48. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/analysis/diagram.py +0 -0
  49. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/__init__.py +0 -0
  50. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/cluster.py +0 -0
  51. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/comm.py +0 -0
  52. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/context_mgr.py +0 -0
  53. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/dtypes.py +0 -0
  54. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/__init__.py +0 -0
  55. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/ast.py +0 -0
  56. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/evaluator.py +0 -0
  57. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/printer.py +0 -0
  58. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/transformer.py +0 -0
  59. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/utils.py +0 -0
  60. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/visitor.py +0 -0
  61. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/expr/walk.py +0 -0
  62. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/interp.py +0 -0
  63. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/mask.py +0 -0
  64. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/mpir.py +0 -0
  65. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/mpobject.py +0 -0
  66. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/mptype.py +0 -0
  67. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/pfunc.py +0 -0
  68. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/primitive.py +0 -0
  69. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/table.py +0 -0
  70. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/tensor.py +0 -0
  71. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/core/tracer.py +0 -0
  72. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/host.py +0 -0
  73. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/__init__.py +0 -0
  74. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/base.py +0 -0
  75. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/basic.py +0 -0
  76. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/context.py +0 -0
  77. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/crypto.py +0 -0
  78. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/fhe.py +0 -0
  79. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/mock_tee.py +0 -0
  80. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/phe.py +0 -0
  81. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/spu.py +0 -0
  82. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/sql_duckdb.py +0 -0
  83. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/stablehlo.py +0 -0
  84. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/kernels/value.py +0 -0
  85. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/__init__.py +0 -0
  86. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/base.py +0 -0
  87. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/basic.py +0 -0
  88. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/crypto.py +0 -0
  89. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/fhe.py +0 -0
  90. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/jax_cc.py +0 -0
  91. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/nnx_cc.py +0 -0
  92. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/phe.py +0 -0
  93. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/spu.py +0 -0
  94. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/sql_cc.py +0 -0
  95. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/ops/tee.py +0 -0
  96. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/protos/v1alpha1/mpir_pb2.py +0 -0
  97. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/protos/v1alpha1/mpir_pb2.pyi +0 -0
  98. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/protos/v1alpha1/value_pb2.py +0 -0
  99. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/protos/v1alpha1/value_pb2.pyi +0 -0
  100. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/__init__.py +0 -0
  101. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/cli.py +0 -0
  102. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/client.py +0 -0
  103. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/communicator.py +0 -0
  104. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/data_providers.py +0 -0
  105. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/driver.py +0 -0
  106. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/exceptions.py +0 -0
  107. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/http_api.md +0 -0
  108. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/link_comm.py +0 -0
  109. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/server.py +0 -0
  110. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/session.py +0 -0
  111. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/runtime/simulation.py +0 -0
  112. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/simp/__init__.py +0 -0
  113. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/simp/api.py +0 -0
  114. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/simp/mpi.py +0 -0
  115. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/simp/party.py +0 -0
  116. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/simp/random.py +0 -0
  117. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/simp/smpc.py +0 -0
  118. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/utils/__init__.py +0 -0
  119. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/utils/crypto.py +0 -0
  120. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/utils/func_utils.py +0 -0
  121. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/utils/spu_utils.py +0 -0
  122. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v1/utils/table_utils.py +0 -0
  123. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/__init__.py +0 -0
  124. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/bfv_impl.py +0 -0
  125. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/crypto_impl.py +0 -0
  126. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/field_impl.py +0 -0
  127. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/phe_impl.py +0 -0
  128. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_design.md +0 -0
  129. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_driver/__init__.py +0 -0
  130. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_driver/http.py +0 -0
  131. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_driver/state.py +0 -0
  132. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_driver/values.py +0 -0
  133. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_worker/__init__.py +0 -0
  134. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_worker/mem.py +0 -0
  135. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/simp_worker/state.py +0 -0
  136. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/spu_impl.py +0 -0
  137. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/store_impl.py +0 -0
  138. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/table_impl.py +0 -0
  139. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/backends/tee_impl.py +0 -0
  140. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/cli.py +0 -0
  141. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/cli_guide.md +0 -0
  142. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/__init__.py +0 -0
  143. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/bfv.py +0 -0
  144. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/crypto.py +0 -0
  145. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/dtypes.py +0 -0
  146. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/field.py +0 -0
  147. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/func.py +0 -0
  148. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/phe.py +0 -0
  149. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/simp.py +0 -0
  150. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/spu.py +0 -0
  151. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/store.py +0 -0
  152. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/table.py +0 -0
  153. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/tee.py +0 -0
  154. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/dialects/tensor.py +0 -0
  155. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/README.md +0 -0
  156. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/__init__.py +0 -0
  157. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/context.py +0 -0
  158. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/graph.py +0 -0
  159. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/jit.py +0 -0
  160. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/object.py +0 -0
  161. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/primitive.py +0 -0
  162. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/printer.py +0 -0
  163. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/registry.py +0 -0
  164. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/serde.py +0 -0
  165. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/edsl/typing.py +0 -0
  166. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/kernels/Makefile +0 -0
  167. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/kernels/__init__.py +0 -0
  168. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/kernels/gf128.cpp +0 -0
  169. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/kernels/ldpc.cpp +0 -0
  170. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/kernels/okvs.cpp +0 -0
  171. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/kernels/okvs_opt.cpp +0 -0
  172. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/kernels/py_kernels.py +0 -0
  173. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/collective.py +0 -0
  174. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/device/cluster.py +0 -0
  175. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/__init__.py +0 -0
  176. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/_utils.py +0 -0
  177. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/analytics/__init__.py +0 -0
  178. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/analytics/aggregation.py +0 -0
  179. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/analytics/groupby.md +0 -0
  180. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/analytics/groupby.py +0 -0
  181. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/analytics/permutation.py +0 -0
  182. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/common/constants.py +0 -0
  183. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/ot/__init__.py +0 -0
  184. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/ot/base.py +0 -0
  185. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/ot/extension.py +0 -0
  186. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/ot/silent.py +0 -0
  187. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/psi/__init__.py +0 -0
  188. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/psi/cuckoo.py +0 -0
  189. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/psi/okvs.py +0 -0
  190. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/psi/okvs_gct.py +0 -0
  191. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/psi/oprf.py +0 -0
  192. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/psi/rr22.py +0 -0
  193. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/psi/unbalanced.py +0 -0
  194. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/vole/__init__.py +0 -0
  195. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/vole/gilboa.py +0 -0
  196. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/vole/ldpc.py +0 -0
  197. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/libs/mpc/vole/silver.py +0 -0
  198. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/runtime/__init__.py +0 -0
  199. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/runtime/dialect_state.py +0 -0
  200. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/runtime/object_store.py +0 -0
  201. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/mplang/v2/runtime/value.py +0 -0
  202. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/pyproject.toml +0 -0
  203. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/__init__.py +0 -0
  204. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/conftest.py +0 -0
  205. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/__init__.py +0 -0
  206. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/analysis/test_diagram.py +0 -0
  207. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/conftest.py +0 -0
  208. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/__init__.py +0 -0
  209. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/expr/__init__.py +0 -0
  210. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/expr/conftest.py +0 -0
  211. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/expr/test_ast.py +0 -0
  212. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/expr/test_printer.py +0 -0
  213. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/expr/test_utils.py +0 -0
  214. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/expr/test_walk.py +0 -0
  215. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_cluster.py +0 -0
  216. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_dtype.py +0 -0
  217. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_mask.py +0 -0
  218. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_mpir.py +0 -0
  219. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_mptype.py +0 -0
  220. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_primitive.py +0 -0
  221. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_table.py +0 -0
  222. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_tensor.py +0 -0
  223. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/core/test_tracer.py +0 -0
  224. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/device/__init__.py +0 -0
  225. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/device/test_device_basic.py +0 -0
  226. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/integration/README.md +0 -0
  227. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/integration/test_crypto_roundtrip.py +0 -0
  228. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/integration/test_http_e2e.py +0 -0
  229. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/integration/test_symbols_roundtrip.py +0 -0
  230. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/integration/test_tee_workflow.py +0 -0
  231. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/integration/test_tutorials.py +0 -0
  232. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/integration/test_unused_param_integration.py +0 -0
  233. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/__init__.py +0 -0
  234. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_basic.py +0 -0
  235. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_debug_print.py +0 -0
  236. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_fhe.py +0 -0
  237. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_kernel_binding.py +0 -0
  238. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_phe.py +0 -0
  239. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_spu.py +0 -0
  240. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_sql_duckdb.py +0 -0
  241. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_stablehlo.py +0 -0
  242. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_value.py +0 -0
  243. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/kernels/test_value_serde.py +0 -0
  244. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/__init__.py +0 -0
  245. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/dummy.py +0 -0
  246. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_basic_pack.py +0 -0
  247. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_crypto.py +0 -0
  248. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_feop_base.py +0 -0
  249. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_jax_cc.py +0 -0
  250. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_nnx_cc.py +0 -0
  251. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_phe.py +0 -0
  252. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_spu.py +0 -0
  253. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_spu_defensive.py +0 -0
  254. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_sql.py +0 -0
  255. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_sql_cc.py +0 -0
  256. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/ops/test_table_tensor_conversion.py +0 -0
  257. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/runtime/__init__.py +0 -0
  258. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/runtime/test_cli.py +0 -0
  259. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/runtime/test_communicator.py +0 -0
  260. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/runtime/test_driver.py +0 -0
  261. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/runtime/test_server.py +0 -0
  262. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/runtime/test_simulation.py +0 -0
  263. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/simp/test_mpi.py +0 -0
  264. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/simp/test_random.py +0 -0
  265. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/simp/test_smpc.py +0 -0
  266. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/simp/test_sugar.py +0 -0
  267. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/utils/__init__.py +0 -0
  268. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/utils/server_fixtures.py +0 -0
  269. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/utils/test_func_utils.py +0 -0
  270. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/utils/test_spu_utils.py +0 -0
  271. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v1/utils/test_table_utils.py +0 -0
  272. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/__init__.py +0 -0
  273. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/__init__.py +0 -0
  274. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/simp_driver/__init__.py +0 -0
  275. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/simp_worker/__init__.py +0 -0
  276. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/simp_worker/test_mem.py +0 -0
  277. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_bfv_impl.py +0 -0
  278. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_crypto_impl.py +0 -0
  279. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_okvs_binding.py +0 -0
  280. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_simp_integration.py +0 -0
  281. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_simp_object_store.py +0 -0
  282. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_table_impl.py +0 -0
  283. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_tee_impl.py +0 -0
  284. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_tensor_impl.py +0 -0
  285. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/backends/test_verify_clean.py +0 -0
  286. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/conftest.py +0 -0
  287. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/__init__.py +0 -0
  288. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_bfv.py +0 -0
  289. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_crypto.py +0 -0
  290. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_dtypes.py +0 -0
  291. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_field.py +0 -0
  292. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_func.py +0 -0
  293. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_okvs.py +0 -0
  294. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_phe.py +0 -0
  295. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_simp.py +0 -0
  296. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_simp_comm.py +0 -0
  297. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_spu.py +0 -0
  298. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_table.py +0 -0
  299. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_tee.py +0 -0
  300. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/dialects/test_tensor.py +0 -0
  301. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/__init__.py +0 -0
  302. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_context.py +0 -0
  303. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_graph.py +0 -0
  304. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_primitive.py +0 -0
  305. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_primitive_multi_output.py +0 -0
  306. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_printer.py +0 -0
  307. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_serde.py +0 -0
  308. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_tracer.py +0 -0
  309. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_typing.py +0 -0
  310. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/edsl/test_typing_graph_serde.py +0 -0
  311. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/device/__init__.py +0 -0
  312. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/device/conftest.py +0 -0
  313. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/device/test_context_root.py +0 -0
  314. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/device/test_device_api_errors.py +0 -0
  315. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/device/test_device_dialects.py +0 -0
  316. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/device/test_device_layouts.py +0 -0
  317. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/device/test_device_tee.py +0 -0
  318. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/__init__.py +0 -0
  319. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/analytics/__init__.py +0 -0
  320. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/analytics/test_aggregation.py +0 -0
  321. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/analytics/test_groupby.py +0 -0
  322. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/analytics/test_permutation.py +0 -0
  323. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/ot/__init__.py +0 -0
  324. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/ot/test_ot.py +0 -0
  325. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/ot/test_ot_extension.py +0 -0
  326. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/ot/test_silent_ot.py +0 -0
  327. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/psi/__init__.py +0 -0
  328. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/psi/test_okvs_gct.py +0 -0
  329. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/psi/test_oprf.py +0 -0
  330. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/psi/test_psi.py +0 -0
  331. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/psi/test_rr22.py +0 -0
  332. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/psi/verify_psi_okvs_logic.py +0 -0
  333. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/test_field_gf128.py +0 -0
  334. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/test_utils.py +0 -0
  335. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/vole/__init__.py +0 -0
  336. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/vole/test_gilboa_manual.py +0 -0
  337. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/vole/test_ldpc.py +0 -0
  338. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/vole/test_silver_vole.py +0 -0
  339. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/vole/test_vole.py +0 -0
  340. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/mpc/vole/verify_vole_logic.py +0 -0
  341. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/test_collective.py +0 -0
  342. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/libs/test_simple_guide.py +0 -0
  343. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/runtime/test_object_store.py +0 -0
  344. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/runtime/test_object_store_fs.py +0 -0
  345. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/test_store.py +0 -0
  346. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/utils/__init__.py +0 -0
  347. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tests/v2/utils/tensor_patch.py +0 -0
  348. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/MIGRATION.md +0 -0
  349. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/README.md +0 -0
  350. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/__init__.py +0 -0
  351. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/data/alice.csv +0 -0
  352. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/data/bob.csv +0 -0
  353. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/data/prepare_vertical_iris.py +0 -0
  354. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/run.sh +0 -0
  355. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/00_device_basics.py +0 -0
  356. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/01_function_decorator.py +0 -0
  357. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/02_simulation_and_driver.py +0 -0
  358. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/03_run_jax.py +0 -0
  359. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/04_run_sql.py +0 -0
  360. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/05_pipeline.py +0 -0
  361. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/06_ir_dump_and_analysis.py +0 -0
  362. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/device/07_run_nnx.py +0 -0
  363. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/pitfalls/late_binding.py +0 -0
  364. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/pitfalls/rand.py +0 -0
  365. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/00_basic.py +0 -0
  366. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/01_condition.py +0 -0
  367. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/02_whileloop.py +0 -0
  368. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/03_stdio.py +0 -0
  369. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/04_phe.py +0 -0
  370. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/05_tee.py +0 -0
  371. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/06_fhe.py +0 -0
  372. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/07_advanced.py +0 -0
  373. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v1/simp/08_simple_secret_sharing.py +0 -0
  374. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v2/01_function_decorator.py +0 -0
  375. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v2/02_simulation_and_driver.py +0 -0
  376. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v2/03_run_jax.py +0 -0
  377. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v2/04_ir_dump_and_analysis.py +0 -0
  378. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v2/05_run_sql.py +0 -0
  379. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/tutorials/v2/06_pipeline.py +0 -0
  380. {mplang_nightly-0.1.dev250 → mplang_nightly-0.1.dev252}/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.dev250
3
+ Version: 0.1.dev252
4
4
  Summary: Multi-Party Programming Language
5
5
  Author-email: SecretFlow Team <secretflow-contact@service.alipay.com>
6
6
  License: Apache License
@@ -22,9 +22,7 @@ import jax.numpy as jnp
22
22
  import numpy as np
23
23
 
24
24
  import mplang.v2.edsl as el
25
- import mplang.v2.edsl.typing as elt
26
- from mplang.v2.dialects.simp import pcall_static
27
- from mplang.v2.dialects.tensor import jax_fn
25
+ from mplang.v2.dialects import simp, tensor
28
26
 
29
27
 
30
28
  def main():
@@ -37,27 +35,21 @@ def main():
37
35
  def add(x: jnp.ndarray, y: jnp.ndarray) -> jnp.ndarray:
38
36
  return jnp.add(x, y)
39
37
 
40
- # Prepare input data (MP types)
41
- x = el.InterpObject(
42
- np.array([1.0, 2.0, 3.0]),
43
- elt.MPType(elt.TensorType(elt.f32, (3,)), (0,)), # P0 holds
44
- )
45
-
46
- y = el.InterpObject(
47
- np.array([4.0, 5.0, 6.0]),
48
- elt.MPType(elt.TensorType(elt.f32, (3,)), (0,)), # P0 holds
49
- )
50
-
51
38
  # Define computation using pcall + jax_fn
52
- def compute(x, y):
39
+ # Use simp.constant to create data at parties
40
+ def compute():
41
+ # P0 holds x and y as constants
42
+ x = simp.constant((0,), np.array([1.0, 2.0, 3.0], dtype=np.float32))
43
+ y = simp.constant((0,), np.array([4.0, 5.0, 6.0], dtype=np.float32))
44
+
53
45
  # P0 executes JAX square computation
54
- squared = pcall_static((0,), jax_fn(square), x)
46
+ squared = simp.pcall_static((0,), tensor.jax_fn(square), x)
55
47
  # P0 executes JAX add computation
56
- result = pcall_static((0,), jax_fn(add), squared, y)
48
+ result = simp.pcall_static((0,), tensor.jax_fn(add), squared, y)
57
49
  return result
58
50
 
59
51
  # Trace to generate graph
60
- traced = el.trace(compute, x, y)
52
+ traced = el.trace(compute)
61
53
 
62
54
  # Print computation graph using EDSL printer
63
55
  print("=" * 70)
@@ -163,9 +163,9 @@ def train(
163
163
 
164
164
  opt_state_p0_final = do_train(opt_state)
165
165
 
166
- # Fetch results to driver
166
+ # Fetch results to driver (data is already on P0 with device attribute)
167
167
  print("Fetching results...")
168
- opt_state_final = tree_map(lambda x: mp.fetch(x, party="P0"), opt_state_p0_final)
168
+ opt_state_final = tree_map(lambda x: mp.fetch(x), opt_state_p0_final)
169
169
 
170
170
  # Extract params
171
171
  params = get_params(opt_state_final)
@@ -89,6 +89,7 @@ from mplang.v2.libs.device import (
89
89
  put,
90
90
  set_dev_attr,
91
91
  )
92
+ from mplang.v2.libs.device import fetch as device_fetch
92
93
  from mplang.v2.runtime.interpreter import Interpreter
93
94
 
94
95
  # =============================================================================
@@ -186,88 +187,80 @@ def evaluate(
186
187
  inputs = fn.prepare_inputs(*args, **kwargs)
187
188
  inputs = [unwrap_if_interp(v) for v in inputs]
188
189
  raw_result = interp.evaluate_graph(fn.graph, inputs)
189
- return fn.reconstruct_outputs(raw_result)
190
+ wrapped = [
191
+ InterpObject(v, fn.graph.outputs[i].type, interp)
192
+ for i, v in enumerate(raw_result)
193
+ ]
194
+ return fn.reconstruct_outputs(wrapped)
190
195
 
191
196
  return fn(*args, **kwargs)
192
197
 
193
198
 
194
199
  def fetch(
195
200
  result: Any,
196
- party: int | str | None = None,
197
201
  *,
202
+ follow_device: bool = True,
198
203
  context: Interpreter | None = None,
199
204
  ) -> Any:
200
- """Fetch the result, optionally for a specific party.
205
+ """Fetch results from interpreter context to Python.
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.
213
219
  """
214
- from typing import cast
215
220
 
216
- from mplang.v2.backends.simp_driver.state import SimpDriver
221
+ from jax.tree_util import tree_map
222
+
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
220
224
  from mplang.v2.runtime.interpreter import InterpObject
225
+ from mplang.v2.runtime.value import WrapValue
221
226
 
222
227
  interp = _get_context(context)
223
228
 
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
231
-
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
229
+ def _fetch_single(var: Any) -> Any:
230
+ """Fetch a single value from InterpObject."""
231
+ # InterpObject (from mp.evaluate) - extract runtime_obj
232
+ if isinstance(var, InterpObject):
233
+ if follow_device and is_device_obj(var):
234
+ return device_fetch(var)
235
+ var = var.runtime_obj # extract and continue processing
236
+
237
+ # DriverVar (simp dialect) - remote fetch from workers
238
+ if isinstance(var, DriverVar):
239
+ from mplang.v2.backends.simp_driver.state import SimpDriver
240
+
241
+ simp_state = interp.get_dialect_state("simp")
242
+ assert isinstance(simp_state, SimpDriver), "DriverVar requires simp state"
243
+
244
+ resolved: list[Any] = []
245
+ for rank, uri in enumerate(var.values):
246
+ if uri is None:
247
+ resolved.append(None)
259
248
  else:
260
- raise ValueError(f"Unknown party: {party}")
261
- else:
262
- # Default logic for int
263
- pass
249
+ fetched = simp_state.fetch(rank, uri).result()
250
+ if isinstance(fetched, WrapValue):
251
+ fetched = fetched.data
252
+ resolved.append(fetched)
253
+
254
+ return resolved[0] if len(resolved) == 1 else resolved
255
+
256
+ # WrapValue (TensorValue, TableValue, etc.) - unwrap
257
+ if isinstance(var, WrapValue):
258
+ return var.data
264
259
 
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]
260
+ # Plain values pass through
261
+ return var
268
262
 
269
- # Unwrap Value types to get the underlying data
270
- return _unwrap_value(result)
263
+ return tree_map(_fetch_single, result)
271
264
 
272
265
 
273
266
  # Alias for compatibility
@@ -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
@@ -201,27 +201,20 @@ class SimpMemDriver(SimpDriver):
201
201
  worker_interp = self._workers[rank]
202
202
  worker_ctx = cast(SimpWorker, worker_interp.get_dialect_state("simp"))
203
203
 
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)
204
+ # Resolve URI inputs (None means rank has no data)
205
+ resolved_inputs = [
206
+ worker_ctx.store.get(inp) if inp is not None else None for inp in inputs
207
+ ]
211
208
 
212
209
  # Execute
213
210
  results = worker_interp.evaluate_graph(graph, resolved_inputs, job_id)
214
211
 
215
- # Store results
212
+ # Store results (results is always a list)
216
213
  if not graph.outputs:
217
214
  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]
215
+ return [
216
+ worker_ctx.store.put(res) if res is not None else None for res in results
217
+ ]
225
218
 
226
219
 
227
220
  def make_simulator(
@@ -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
 
@@ -244,11 +244,18 @@ def create_worker_app(
244
244
 
245
245
  def _do_execute(graph: Graph, inputs: list[Any], job_id: str | None = None) -> Any:
246
246
  """Execute graph in worker thread."""
247
- # Note: we ignore job_id for now as generic Interpreter doesn't take it.
248
- # But we could set it in thread local if needed.
249
- 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)
250
253
  comm.wait_pending_sends()
251
- 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]
252
259
 
253
260
  @app.post("/exec")
254
261
  async def execute(req: ExecRequest) -> dict[str, str]:
@@ -51,17 +51,17 @@ def _pcall_static_worker_impl(
51
51
  interpreter.current_parties = parties # type: ignore[attr-defined]
52
52
 
53
53
  try:
54
- return interpreter.evaluate_graph(fn_graph, list(args))
54
+ result = interpreter.evaluate_graph(fn_graph, list(args))
55
+ # Return single value for single output (interpreter expects this)
56
+ return result[0] if len(op.outputs) == 1 else result
55
57
  finally:
56
58
  if prev_parties is None:
57
59
  del interpreter.current_parties # type: ignore[attr-defined]
58
60
  else:
59
61
  interpreter.current_parties = prev_parties # type: ignore[attr-defined]
60
62
  else:
61
- if len(op.outputs) == 1:
62
- return None
63
- else:
64
- return [None] * len(op.outputs)
63
+ # No data for this rank
64
+ return None if len(op.outputs) == 1 else [None] * len(op.outputs)
65
65
 
66
66
 
67
67
  def _pcall_dynamic_worker_impl(
@@ -69,7 +69,8 @@ def _pcall_dynamic_worker_impl(
69
69
  ) -> Any:
70
70
  """Worker implementation of pcall_dynamic."""
71
71
  fn_graph = op.regions[0]
72
- return interpreter.evaluate_graph(fn_graph, list(args))
72
+ result = interpreter.evaluate_graph(fn_graph, list(args))
73
+ return result[0] if len(op.outputs) == 1 else result
73
74
 
74
75
 
75
76
  def _shuffle_static_worker_impl(
@@ -122,9 +123,10 @@ def _uniform_cond_worker_impl(
122
123
  pred = bool(pred.unwrap())
123
124
 
124
125
  if pred:
125
- return interpreter.evaluate_graph(op.regions[0], list(args))
126
+ result = interpreter.evaluate_graph(op.regions[0], list(args))
126
127
  else:
127
- return interpreter.evaluate_graph(op.regions[1], list(args))
128
+ result = interpreter.evaluate_graph(op.regions[1], list(args))
129
+ return result[0] if len(op.outputs) == 1 else result
128
130
 
129
131
 
130
132
  def _while_loop_worker_impl(interpreter: Interpreter, op: Operation, *args: Any) -> Any:
@@ -142,22 +144,20 @@ def _while_loop_worker_impl(interpreter: Interpreter, op: Operation, *args: Any)
142
144
  region_inputs = current_state + captures
143
145
 
144
146
  cond_res = interpreter.evaluate_graph(cond_graph, region_inputs)
147
+ # cond_res is a list, extract the single boolean
148
+ cond_val = cond_res[0] if cond_res else False
145
149
 
146
- if isinstance(cond_res, TensorValue):
147
- cond_res = bool(cond_res.unwrap())
150
+ if isinstance(cond_val, TensorValue):
151
+ cond_val = bool(cond_val.unwrap())
148
152
 
149
- if not cond_res:
153
+ if not cond_val:
150
154
  break
151
155
 
152
156
  body_res = interpreter.evaluate_graph(body_graph, region_inputs)
153
- if isinstance(body_res, list):
154
- current_state = body_res
155
- else:
156
- current_state = [body_res]
157
-
158
- if len(current_state) == 1:
159
- return current_state[0]
160
- return current_state
157
+ current_state = body_res # body_res is always a list now
158
+
159
+ # Return single value for single output
160
+ return current_state[0] if len(current_state) == 1 else current_state
161
161
 
162
162
 
163
163
  WORKER_HANDLERS = {
@@ -266,8 +266,9 @@ def elementwise_impl(interpreter: Interpreter, op: Operation, *args: Value) -> A
266
266
  subgraph = op.regions[0]
267
267
 
268
268
  if shape == ():
269
- # Scalar case
270
- return interpreter.evaluate_graph(subgraph, list(args))
269
+ # Scalar case - return first element from result list
270
+ result = interpreter.evaluate_graph(subgraph, list(args))
271
+ return result[0] if len(result) == 1 else result
271
272
 
272
273
  for index in np.ndindex(shape):
273
274
  # Prepare inputs for this element (list ordered by subgraph.inputs)
@@ -295,7 +296,10 @@ def elementwise_impl(interpreter: Interpreter, op: Operation, *args: Value) -> A
295
296
  scalar_inputs.append(arg)
296
297
 
297
298
  # Recursive execution
298
- scalar_out = interpreter.evaluate_graph(subgraph, scalar_inputs)
299
+ scalar_out_list = interpreter.evaluate_graph(subgraph, scalar_inputs)
300
+ scalar_out = (
301
+ scalar_out_list[0] if len(scalar_out_list) == 1 else scalar_out_list
302
+ )
299
303
 
300
304
  # Unwrap result if it's a TensorValue (to store in numpy array)
301
305
  # We store raw values in the object array for now, but will wrap the final array
@@ -573,24 +573,19 @@ class TracedFunction:
573
573
  all_inputs = explicit_inputs + list(self.captured)
574
574
  return all_inputs
575
575
 
576
- def reconstruct_outputs(self, execution_result: Any) -> Any:
576
+ def reconstruct_outputs(self, execution_result: list[Any]) -> Any:
577
577
  """Reconstruct structured output from execution result.
578
578
 
579
579
  Used by the runtime to format the result of graph execution.
580
580
 
581
581
  Args:
582
- execution_result: Raw result from interpreter.evaluate_graph().
582
+ execution_result: List of results from interpreter.evaluate_graph().
583
583
 
584
584
  Returns:
585
585
  Structured output matching the original function's return signature.
586
586
  """
587
- # Normalize to list
588
- if len(self.graph.outputs) == 1:
589
- results = [execution_result]
590
- elif len(self.graph.outputs) == 0:
591
- results = []
592
- else:
593
- results = execution_result # It's already a list/tuple
587
+ # execution_result is always a list (now that evaluate_graph returns list)
588
+ results = execution_result
594
589
 
595
590
  # Reconstruct
596
591
  total_len = len(self.out_imms) + len(self.out_var_pos)
@@ -25,6 +25,7 @@ from .api import (
25
25
  DeviceInferenceError,
26
26
  DeviceNotFoundError,
27
27
  device,
28
+ fetch,
28
29
  get_dev_attr,
29
30
  is_device_obj,
30
31
  put,
@@ -41,6 +42,7 @@ __all__ = [
41
42
  "DeviceNotFoundError",
42
43
  "Node",
43
44
  "device",
45
+ "fetch",
44
46
  "get_dev_attr",
45
47
  "is_device_obj",
46
48
  "jax_fn",
@@ -715,3 +715,74 @@ def put(to_dev_id: str, obj: Any) -> Object:
715
715
 
716
716
  else:
717
717
  raise DeviceError(f"Cannot put to device kind '{dev_info.kind}'")
718
+
719
+
720
+ def fetch(obj: Object) -> Any:
721
+ """Fetch data from device to host based on device attribute.
722
+
723
+ This function fetches data from the device the object resides on.
724
+ For PPU/TEE: fetches from the single member rank.
725
+ For SPU: fetches from all parties (returns reconstructed value).
726
+
727
+ Args:
728
+ obj: Object with device attribute to fetch.
729
+
730
+ Returns:
731
+ Python value (numpy array, scalar, etc.)
732
+ """
733
+ from mplang.v2.backends.simp_driver.state import SimpDriver
734
+ from mplang.v2.backends.simp_driver.values import DriverVar
735
+ from mplang.v2.backends.table_impl import TableValue
736
+ from mplang.v2.backends.tensor_impl import TensorValue
737
+ from mplang.v2.edsl.context import get_current_context
738
+ from mplang.v2.runtime.interpreter import InterpObject, Interpreter
739
+
740
+ def _unwrap_value(val: Any) -> Any:
741
+ """Unwrap Value types to get the underlying data."""
742
+ if isinstance(val, TensorValue):
743
+ return val.data
744
+ elif isinstance(val, TableValue):
745
+ return val.data
746
+ return val
747
+
748
+ # Get device info
749
+ if not is_device_obj(obj):
750
+ raise DeviceError(
751
+ "Object does not have device attribute. Use mp.fetch() directly."
752
+ )
753
+
754
+ dev_id = get_dev_attr(obj)
755
+ cluster = _resolve_cluster()
756
+ dev_info = cluster.devices[dev_id]
757
+
758
+ # Get interpreter context
759
+ ctx = get_current_context()
760
+ if not isinstance(ctx, Interpreter):
761
+ raise RuntimeError("No interpreter context available for fetch")
762
+
763
+ simp_state = cast(SimpDriver | None, ctx.get_dialect_state("simp"))
764
+
765
+ # Unwrap InterpObject
766
+ assert isinstance(obj, InterpObject), f"Expected InterpObject, got {type(obj)}"
767
+ runtime_obj = obj.runtime_obj
768
+
769
+ def _fetch_from_rank(rank: int) -> Any:
770
+ """Fetch value from a rank (DriverVar values are always URIs)."""
771
+ uri = runtime_obj.values[rank]
772
+ assert isinstance(uri, str) and "://" in uri, f"Expected URI, got {uri}"
773
+ assert simp_state is not None, "No simp state for fetch"
774
+ return _unwrap_value(simp_state.fetch(rank, uri).result())
775
+
776
+ # Handle DriverVar
777
+ if isinstance(runtime_obj, DriverVar):
778
+ # For PPU/TEE: single member
779
+ if dev_info.kind.upper() in ("PPU", "TEE"):
780
+ assert len(dev_info.members) == 1
781
+ return _fetch_from_rank(dev_info.members[0].rank)
782
+
783
+ # For SPU: fetch from first member (should be revealed first)
784
+ elif dev_info.kind.upper() == "SPU":
785
+ return _fetch_from_rank(dev_info.members[0].rank)
786
+
787
+ # Direct value
788
+ return _unwrap_value(runtime_obj)
@@ -442,13 +442,7 @@ class Interpreter(AbstractInterpreter):
442
442
 
443
443
  # Execute graph (may have 0 outputs if all were immediates)
444
444
  if graph.outputs:
445
- result_runtime = self.evaluate_graph(graph, inputs_list)
446
-
447
- # Normalize runtime result to list for structural matching
448
- if len(graph.outputs) == 1:
449
- result_runtime_list = [result_runtime]
450
- else:
451
- result_runtime_list = list(result_runtime)
445
+ result_runtime_list = self.evaluate_graph(graph, inputs_list)
452
446
  else:
453
447
  result_runtime_list = []
454
448
 
@@ -557,10 +551,6 @@ class Interpreter(AbstractInterpreter):
557
551
  # Execute graph
558
552
  results_runtime = self.evaluate_graph(graph, inputs_list)
559
553
 
560
- # If single output, wrap in list for uniform handling
561
- if len(target_outputs) == 1:
562
- results_runtime = [results_runtime]
563
-
564
554
  # Cache all results
565
555
  for val, res in zip(target_outputs, results_runtime, strict=True):
566
556
  # Wrap as InterpObject and cache
@@ -586,10 +576,9 @@ class Interpreter(AbstractInterpreter):
586
576
  # Constants: pass through unchanged
587
577
  return obj
588
578
 
589
- # TODO: change output sigature to list[Any]
590
579
  def evaluate_graph(
591
580
  self, graph: Graph, inputs: list[Any], job_id: str | None = None
592
- ) -> Any:
581
+ ) -> list[Any]:
593
582
  """Execute a Graph IR with runtime data.
594
583
 
595
584
  Can be overridden by subclasses to implement remote execution or compilation.
@@ -600,7 +589,7 @@ class Interpreter(AbstractInterpreter):
600
589
  job_id: Optional unique ID for this execution job (for profiling/tracing).
601
590
 
602
591
  Returns:
603
- Runtime execution results corresponding to graph.outputs
592
+ List of runtime execution results corresponding to graph.outputs.
604
593
  """
605
594
  if self.executor:
606
595
  return self._evaluate_graph_async(graph, inputs, job_id)
@@ -609,7 +598,7 @@ class Interpreter(AbstractInterpreter):
609
598
 
610
599
  def _evaluate_graph_sync(
611
600
  self, graph: Graph, inputs: list[Any], job_id: str | None = None
612
- ) -> Any:
601
+ ) -> list[Any]:
613
602
  """Synchronous execution (Baseline)."""
614
603
  # Local environment: Value -> Runtime Object
615
604
  env = dict(zip(graph.inputs, inputs, strict=True))
@@ -648,7 +637,6 @@ class Interpreter(AbstractInterpreter):
648
637
  f"No implementation registered for opcode: {op.opcode}"
649
638
  )
650
639
 
651
- # Update environment with outputs
652
640
  # Update environment with outputs
653
641
  # Handler should return a single value or a tuple/list of values
654
642
  if len(op.outputs) == 0:
@@ -667,14 +655,11 @@ class Interpreter(AbstractInterpreter):
667
655
  if self.tracer and job_id:
668
656
  self.tracer.save_trace(job_id=job_id, rank=self.trace_pid)
669
657
 
670
- if len(graph.outputs) == 1:
671
- return env[graph.outputs[0]]
672
- else:
673
- return [env[out] for out in graph.outputs]
658
+ return [env[out] for out in graph.outputs]
674
659
 
675
660
  def _evaluate_graph_async(
676
661
  self, graph: Graph, inputs: list[Any], job_id: str | None = None
677
- ) -> Any:
662
+ ) -> list[Any]:
678
663
  """Asynchronous execution with non-blocking DAG scheduling."""
679
664
  # Tracer setup (if not provided, use a disabled stub)
680
665
  tracer: ExecutionTracer | _NullTracer
@@ -851,5 +836,4 @@ class Interpreter(AbstractInterpreter):
851
836
  if self.tracer and job_id:
852
837
  self.tracer.save_trace(job_id=job_id, rank=self.trace_pid)
853
838
 
854
- final_results = [env[out] for out in graph.outputs]
855
- return final_results[0] if len(final_results) == 1 else final_results
839
+ return [env[out] for out in graph.outputs]
@@ -161,8 +161,8 @@ class TestDriverExecution:
161
161
  return y
162
162
 
163
163
  result = mp.evaluate(transfer)
164
- # y is on P1, so fetch from P1
165
- value = mp.fetch(result, party="P1")
164
+ # y is on P1, so fetch will use device attribute to get from P1
165
+ value = mp.fetch(result)
166
166
  assert value == 100
167
167
 
168
168
  @pytest.mark.skip(
@@ -193,7 +193,8 @@ class TestDriverFetch:
193
193
  return mp.device("P0")(lambda: 999)()
194
194
 
195
195
  result = mp.evaluate(create_on_p0)
196
- value = mp.fetch(result, party="P0")
196
+ # fetch uses device attribute to get from P0
197
+ value = mp.fetch(result)
197
198
  assert value == 999
198
199
 
199
200
  def test_fetch_all_parties(self, driver_cluster):