mplang-nightly 0.1.dev154__tar.gz → 0.1.dev156__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 (166) hide show
  1. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/PKG-INFO +1 -1
  2. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/cluster.py +1 -1
  3. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/evaluator.py +0 -1
  4. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/mptype.py +0 -34
  5. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/base.py +11 -35
  6. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/context.py +70 -17
  7. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/crypto.py +8 -7
  8. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/mock_tee.py +4 -3
  9. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/spu.py +14 -21
  10. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/stablehlo.py +8 -5
  11. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/data_providers.py +13 -19
  12. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/session.py +1 -2
  13. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/kernels/test_builtin.py +1 -3
  14. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/kernels/test_stablehlo.py +0 -2
  15. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/.gitignore +0 -0
  16. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/LICENSE +0 -0
  17. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/README.md +0 -0
  18. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/conf/3pc.yaml +0 -0
  19. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/stax_nn/README.md +0 -0
  20. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/stax_nn/models.py +0 -0
  21. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/stax_nn/stax_nn.py +0 -0
  22. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/xgboost/hist_jax.py +0 -0
  23. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/xgboost/hist_jax_test.py +0 -0
  24. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/xgboost/naive_np.py +0 -0
  25. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/xgboost/readme.md +0 -0
  26. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/xgboost/sgb.py +0 -0
  27. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/examples/xgboost/sgb_test.py +0 -0
  28. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/hatch_build.py +0 -0
  29. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/__init__.py +0 -0
  30. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/analysis/__init__.py +0 -0
  31. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/analysis/diagram.py +0 -0
  32. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/api.py +0 -0
  33. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/__init__.py +0 -0
  34. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/comm.py +0 -0
  35. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/context_mgr.py +0 -0
  36. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/dtype.py +0 -0
  37. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/__init__.py +0 -0
  38. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/ast.py +0 -0
  39. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/printer.py +0 -0
  40. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/transformer.py +0 -0
  41. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/utils.py +0 -0
  42. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/visitor.py +0 -0
  43. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/expr/walk.py +0 -0
  44. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/interp.py +0 -0
  45. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/mask.py +0 -0
  46. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/mpir.py +0 -0
  47. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/mpobject.py +0 -0
  48. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/pfunc.py +0 -0
  49. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/primitive.py +0 -0
  50. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/table.py +0 -0
  51. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/tensor.py +0 -0
  52. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/core/tracer.py +0 -0
  53. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/device.py +0 -0
  54. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/__init__.py +0 -0
  55. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/builtin.py +0 -0
  56. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/phe.py +0 -0
  57. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/kernels/sql_duckdb.py +0 -0
  58. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/__init__.py +0 -0
  59. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/base.py +0 -0
  60. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/builtin.py +0 -0
  61. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/crypto.py +0 -0
  62. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/ibis_cc.py +0 -0
  63. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/jax_cc.py +0 -0
  64. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/phe.py +0 -0
  65. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/spu.py +0 -0
  66. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/sql.py +0 -0
  67. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/ops/tee.py +0 -0
  68. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/protos/v1alpha1/mpir_pb2.py +0 -0
  69. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/protos/v1alpha1/mpir_pb2.pyi +0 -0
  70. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/protos/v1alpha1/mpir_pb2_grpc.py +0 -0
  71. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/__init__.py +0 -0
  72. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/cli.py +0 -0
  73. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/client.py +0 -0
  74. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/communicator.py +0 -0
  75. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/driver.py +0 -0
  76. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/exceptions.py +0 -0
  77. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/http_api.md +0 -0
  78. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/link_comm.py +0 -0
  79. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/server.py +0 -0
  80. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/runtime/simulation.py +0 -0
  81. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/simp/__init__.py +0 -0
  82. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/simp/mpi.py +0 -0
  83. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/simp/random.py +0 -0
  84. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/simp/smpc.py +0 -0
  85. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/utils/__init__.py +0 -0
  86. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/utils/crypto.py +0 -0
  87. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/utils/func_utils.py +0 -0
  88. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/utils/spu_utils.py +0 -0
  89. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/mplang/utils/table_utils.py +0 -0
  90. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/pyproject.toml +0 -0
  91. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/__init__.py +0 -0
  92. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/analysis/test_diagram.py +0 -0
  93. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/conftest.py +0 -0
  94. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/__init__.py +0 -0
  95. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/expr/__init__.py +0 -0
  96. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/expr/conftest.py +0 -0
  97. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/expr/test_ast.py +0 -0
  98. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/expr/test_printer.py +0 -0
  99. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/expr/test_utils.py +0 -0
  100. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/expr/test_walk.py +0 -0
  101. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_cluster.py +0 -0
  102. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_dtype.py +0 -0
  103. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_mask.py +0 -0
  104. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_mpir.py +0 -0
  105. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_mptype.py +0 -0
  106. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_primitive.py +0 -0
  107. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_table.py +0 -0
  108. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_tensor.py +0 -0
  109. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/core/test_tracer.py +0 -0
  110. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/device/__init__.py +0 -0
  111. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/device/test_device_basic.py +0 -0
  112. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/integration/README.md +0 -0
  113. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/integration/test_crypto_roundtrip.py +0 -0
  114. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/integration/test_http_e2e.py +0 -0
  115. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/integration/test_symbols_roundtrip.py +0 -0
  116. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/integration/test_tutorials.py +0 -0
  117. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/integration/test_unused_param_integration.py +0 -0
  118. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/kernels/test_debug_print.py +0 -0
  119. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/kernels/test_kernel_binding.py +0 -0
  120. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/kernels/test_phe.py +0 -0
  121. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/kernels/test_spu.py +0 -0
  122. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/kernels/test_sql_duckdb.py +0 -0
  123. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/__init__.py +0 -0
  124. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/dummy.py +0 -0
  125. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_builtin_pack.py +0 -0
  126. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_crypto_tee.py +0 -0
  127. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_feop_base.py +0 -0
  128. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_ibis.py +0 -0
  129. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_ibis_cc.py +0 -0
  130. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_jax_cc.py +0 -0
  131. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_phe.py +0 -0
  132. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_spu.py +0 -0
  133. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_spu_defensive.py +0 -0
  134. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_sql.py +0 -0
  135. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/ops/test_table_tensor_conversion.py +0 -0
  136. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/runtime/__init__.py +0 -0
  137. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/runtime/test_cli.py +0 -0
  138. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/runtime/test_communicator.py +0 -0
  139. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/runtime/test_driver.py +0 -0
  140. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/runtime/test_server.py +0 -0
  141. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/runtime/test_simulation.py +0 -0
  142. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/simp/test_mpi.py +0 -0
  143. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/simp/test_random.py +0 -0
  144. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/simp/test_simp.py +0 -0
  145. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/simp/test_smpc.py +0 -0
  146. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/simp/test_sugar.py +0 -0
  147. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/utils/__init__.py +0 -0
  148. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/utils/server_fixtures.py +0 -0
  149. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/utils/test_func_utils.py +0 -0
  150. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/utils/test_spu_utils.py +0 -0
  151. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tests/utils/test_table_utils.py +0 -0
  152. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/0_basic.py +0 -0
  153. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/10_analysis.py +0 -0
  154. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/1_condition.py +0 -0
  155. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/2_whileloop.py +0 -0
  156. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/3_device.py +0 -0
  157. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/4_simulation.py +0 -0
  158. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/5_ir_dump.py +0 -0
  159. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/6_advanced.py +0 -0
  160. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/7_stdio.py +0 -0
  161. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/8_phe.py +0 -0
  162. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/9_tee.py +0 -0
  163. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/__init__.py +0 -0
  164. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/pitfalls/late_binding.py +0 -0
  165. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/pitfalls/rand.py +0 -0
  166. {mplang_nightly-0.1.dev154 → mplang_nightly-0.1.dev156}/tutorials/run.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mplang-nightly
3
- Version: 0.1.dev154
3
+ Version: 0.1.dev156
4
4
  Summary: Multi-Party Programming Language
5
5
  Author-email: SecretFlow Team <secretflow-contact@service.alipay.com>
6
6
  License: Apache License
@@ -255,7 +255,7 @@ class ClusterSpec:
255
255
  Optional explicit endpoint list of length ``world_size``. Each element may
256
256
  include scheme (``http://``) or not; stored verbatim. If not provided we
257
257
  synthesize ``localhost:{5000 + i}`` (5000 is a fixed default; pass explicit
258
- endpoints for control). Deprecated ``base_port`` legacy kwarg can adjust it.
258
+ endpoints for control).
259
259
  spu_protocol / spu_field:
260
260
  SPU device config values.
261
261
  runtime_version / runtime_platform:
@@ -66,7 +66,6 @@ class EvalSemantic:
66
66
  """Shared evaluation semantics and utilities for evaluators.
67
67
 
68
68
  Minimal dataclass carrying runtime execution context (rank/env/comm/runtime).
69
- Legacy handler-based execution (pfunc_handles) has been fully removed.
70
69
  """
71
70
 
72
71
  rank: int
@@ -400,39 +400,5 @@ class MPType:
400
400
  "Table object detection for non-pandas objects not fully implemented yet"
401
401
  )
402
402
 
403
- # Check if it's a table-like object (legacy check for backward compatibility)
404
- if hasattr(obj, "dtypes") and hasattr(obj, "columns"):
405
- # Basic pandas DataFrame support
406
- try:
407
- import pandas as pd
408
-
409
- if isinstance(obj, pd.DataFrame):
410
- from mplang.core.dtype import DType
411
-
412
- schema_dict = {}
413
- for col_name in obj.columns:
414
- pandas_dtype = obj[col_name].dtype
415
- # Convert pandas dtype to DType
416
- if pandas_dtype.kind in (
417
- "O",
418
- "U",
419
- "S",
420
- ): # object, unicode, string
421
- schema_dict[col_name] = (
422
- DType.from_numpy(pandas_dtype)
423
- if pandas_dtype.kind != "O"
424
- else STRING
425
- )
426
- else:
427
- schema_dict[col_name] = DType.from_numpy(pandas_dtype)
428
- schema = TableType.from_dict(schema_dict)
429
- return cls(schema, pmask, attrs)
430
- except ImportError:
431
- pass
432
- # For other table-like objects without pandas
433
- raise NotImplementedError(
434
- "Table object detection not fully implemented yet"
435
- )
436
-
437
403
  # Otherwise treat as tensor-like
438
404
  return cls.from_tensor(obj, pmask, **attrs)
@@ -34,7 +34,10 @@ from __future__ import annotations
34
34
  import contextvars
35
35
  from collections.abc import Callable
36
36
  from dataclasses import dataclass
37
- from typing import Any
37
+ from typing import TYPE_CHECKING, Any
38
+
39
+ if TYPE_CHECKING:
40
+ from mplang.kernels.context import RuntimeContext
38
41
 
39
42
  __all__ = [
40
43
  "KernelContext",
@@ -48,12 +51,15 @@ __all__ = [
48
51
 
49
52
  @dataclass
50
53
  class KernelContext:
51
- """Ephemeral call context set via contextvar while a kernel runs."""
54
+ """Ephemeral per-kernel invocation context.
55
+
56
+ Cross-kernel persistent state (RNGs, compiled artifacts, environment handles)
57
+ should be stored in RuntimeContext.
58
+ """
52
59
 
53
60
  rank: int
54
61
  world_size: int
55
- state: dict[str, dict[str, Any]] # backend namespace -> pocket
56
- cache: dict[str, Any] # runtime-level shared cache (per BackendRuntime)
62
+ runtime: RuntimeContext
57
63
 
58
64
 
59
65
  _CTX_VAR: contextvars.ContextVar[KernelContext | None] = contextvars.ContextVar(
@@ -62,37 +68,7 @@ _CTX_VAR: contextvars.ContextVar[KernelContext | None] = contextvars.ContextVar(
62
68
 
63
69
 
64
70
  def cur_kctx() -> KernelContext:
65
- """Return the current kernel execution context (only valid inside a kernel).
66
-
67
- Two storages:
68
- - state: namespaced pockets (dict[str, dict]) for backend-local mutable helpers
69
- - cache: global (per runtime) shared dict; prefer state unless truly cross-backend
70
-
71
- Examples:
72
- 1) Compile cache::
73
- @kernel_def("mlir.stablehlo")
74
- def _exec(pfunc, args):
75
- ctx = cur_kctx()
76
- pocket = ctx.state.setdefault("stablehlo", {})
77
- cache = pocket.setdefault("compile_cache", {})
78
- text = pfunc.fn_text
79
- mod = cache.get(text)
80
- if mod is None:
81
- mod = compile_mlir(text)
82
- cache[text] = mod
83
- return run(mod, args)
84
-
85
- 2) Deterministic RNG::
86
- @kernel_def("crypto.keygen")
87
- def _keygen(pfunc, args):
88
- ctx = cur_kctx()
89
- pocket = ctx.state.setdefault("crypto", {})
90
- rng = pocket.get("rng")
91
- if rng is None:
92
- rng = np.random.default_rng(1234 + ctx.rank * 7919)
93
- pocket["rng"] = rng
94
- return (rng.integers(0, 256, size=(32,), dtype=np.uint8),)
95
- """
71
+ """Return current kernel execution context (only valid inside kernel)."""
96
72
  ctx = _CTX_VAR.get()
97
73
  if ctx is None:
98
74
  raise RuntimeError("cur_kctx() called outside backend kernel execution")
@@ -118,12 +118,21 @@ class RuntimeContext:
118
118
  op_type -> kernel_id and form a *template* for dispatch. After
119
119
  initialization, all (re)binding must go through ``bind_op`` /
120
120
  ``rebind_op`` on this context (scoped to THIS runtime only).
121
- state / cache / stats : dict, optional
122
- Mutable pockets reused across kernel invocations. If omitted, new
123
- dictionaries are created.
121
+ state : dict, optional
122
+ Mutable per-runtime key/value storage for kernels. Flat key space;
123
+ callers SHOULD use dotted prefixes (e.g. "stablehlo.compile_cache").
124
+ Kernels own their *state* (functional correctness data, caches,
125
+ handles, compiled objects, RNGs, etc.). Runtime does not interpret
126
+ structure—values may themselves be dicts if a kernel wants its own
127
+ pocket. Created empty when omitted.
128
+ stats : dict, optional
129
+ Mutable statistics/telemetry owned by the runtime (usage counters,
130
+ timings, profiling aids). Kernels may increment counters but should
131
+ avoid storing functional state here. A default "op_calls" mapping is
132
+ ensured. Created empty when omitted.
124
133
  """
125
134
 
126
- __slots__ = ("_ibindings", "cache", "rank", "state", "stats", "world_size")
135
+ __slots__ = ("_ibindings", "rank", "state", "stats", "world_size")
127
136
 
128
137
  def __init__(
129
138
  self,
@@ -131,8 +140,7 @@ class RuntimeContext:
131
140
  world_size: int,
132
141
  initial_bindings: Mapping[str, str] | None = None,
133
142
  *,
134
- state: dict[str, dict[str, Any]] | None = None,
135
- cache: dict[str, Any] | None = None,
143
+ state: dict[str, Any] | None = None,
136
144
  stats: dict[str, Any] | None = None,
137
145
  ) -> None:
138
146
  _ensure_impl_imported()
@@ -144,7 +152,6 @@ class RuntimeContext:
144
152
  **(initial_bindings or {}),
145
153
  }
146
154
  self.state = state if state is not None else {}
147
- self.cache = cache if cache is not None else {}
148
155
  self.stats = stats if stats is not None else {}
149
156
  self.stats.setdefault("op_calls", {})
150
157
 
@@ -168,19 +175,15 @@ class RuntimeContext:
168
175
  if isinstance(ins_spec, TensorType):
169
176
  _validate_tensor_arg(fn_type, idx, ins_spec, val)
170
177
  continue
178
+
171
179
  # install kernel context
172
- kctx = KernelContext(
173
- rank=self.rank,
174
- world_size=self.world_size,
175
- state=self.state,
176
- cache=self.cache,
177
- )
178
- token = base._CTX_VAR.set(kctx) # type: ignore[attr-defined]
180
+ kctx = KernelContext(rank=self.rank, world_size=self.world_size, runtime=self)
181
+ token = base._CTX_VAR.set(kctx)
179
182
  try:
180
183
  raw = fn(pfunc, *arg_list)
181
184
  finally:
182
- base._CTX_VAR.reset(token) # type: ignore[attr-defined]
183
- # Stats (best effort)
185
+ base._CTX_VAR.reset(token)
186
+
184
187
  try:
185
188
  op_calls = self.stats.setdefault("op_calls", {})
186
189
  op_calls[fn_type] = op_calls.get(fn_type, 0) + 1
@@ -213,7 +216,57 @@ class RuntimeContext:
213
216
 
214
217
  def reset(self) -> None:
215
218
  self.state.clear()
216
- self.cache.clear()
219
+
220
+ # ---- runtime state API (flat key space) ----
221
+ # Keys are treated atomically; convention encourages dotted prefixes
222
+ # (e.g. 'stablehlo.compile_cache.hash', 'crypto.rng'). Implementation
223
+ # does NOT parse or create hierarchical dicts—any grouping is purely
224
+ # by string prefix. Values themselves MAY be dicts if callers want a
225
+ # manual pocket. This keeps semantics simple and predictable.
226
+
227
+ def ensure_state(self, key: str, factory: type | Any = dict) -> Any:
228
+ """Return value for key; if absent create via factory and store.
229
+
230
+ Key is not parsed; dotted forms are allowed but treated as a single
231
+ map key. Use consistent prefixes for grouping (e.g. 'spu.config').
232
+ """
233
+ if not key:
234
+ raise ValueError("empty state key")
235
+ val = self.state.get(key)
236
+ if val is None:
237
+ val = factory()
238
+ self.state[key] = val
239
+ return val
240
+
241
+ def get_state(self, key: str, default: Any | None = None) -> Any:
242
+ if not key:
243
+ raise ValueError("empty state key")
244
+ return self.state.get(key, default)
245
+
246
+ def set_state(self, key: str, value: Any) -> None:
247
+ if not key:
248
+ raise ValueError("empty state key")
249
+ self.state[key] = value
250
+
251
+ def del_state(self, key: str) -> None:
252
+ if not key:
253
+ raise ValueError("empty state key")
254
+ self.state.pop(key, None)
255
+
256
+ def list_state(self, prefix: str = "") -> dict[str, Any]:
257
+ """Return mapping of key -> value; optional prefix filter.
258
+
259
+ Prefix match is string-based; if prefix is non-empty include keys
260
+ where key == prefix or key starts with prefix + '.'.
261
+ """
262
+ if not prefix:
263
+ return dict(self.state)
264
+ pref = prefix if prefix.endswith(".") else prefix + "."
265
+ out: dict[str, Any] = {}
266
+ for k, v in self.state.items():
267
+ if k == prefix or k.startswith(pref):
268
+ out[k] = v
269
+ return out
217
270
 
218
271
  # ---- explicit (re)binding API ----
219
272
  def bind_op(self, op_type: str, kernel_id: str, *, force: bool = False) -> None:
@@ -29,16 +29,17 @@ __all__: list[str] = [] # flat kernels only
29
29
  def _get_rng() -> np.random.Generator:
30
30
  """Get (and lazily create) per-rank RNG for crypto kernels.
31
31
 
32
- Seed rule matches legacy handler: MPLANG_CRYPTO_SEED + rank*7919
32
+ Runtime state is untyped, so we narrow the type explicitly for mypy.
33
33
  """
34
34
  kctx = cur_kctx()
35
- pocket = kctx.state.setdefault("crypto", {})
36
- rng = pocket.get("rng")
37
- if rng is None:
35
+ rt = kctx.runtime
36
+ rng_obj = rt.get_state("crypto.rng")
37
+ if rng_obj is None:
38
38
  seed = int(os.environ.get("MPLANG_CRYPTO_SEED", "0")) + kctx.rank * 7919
39
- rng = np.random.default_rng(seed)
40
- pocket["rng"] = rng
41
- return rng
39
+ rng_obj = np.random.default_rng(seed)
40
+ rt.set_state("crypto.rng", rng_obj)
41
+ assert isinstance(rng_obj, np.random.Generator) # narrow
42
+ return rng_obj
42
43
 
43
44
 
44
45
  def _keystream(key: bytes, nonce: bytes, length: int) -> bytes:
@@ -28,12 +28,13 @@ __all__: list[str] = []
28
28
 
29
29
  def _rng() -> np.random.Generator:
30
30
  kctx = cur_kctx()
31
- pocket = kctx.state.setdefault("tee", {})
32
- r = pocket.get("rng")
31
+ rt = kctx.runtime
32
+ r = rt.get_state("tee.rng")
33
33
  if r is None:
34
34
  seed = int(os.environ.get("MPLANG_TEE_SEED", "0")) + kctx.rank * 10007
35
35
  r = np.random.default_rng(seed)
36
- pocket["rng"] = r
36
+ rt.set_state("tee.rng", r)
37
+ assert isinstance(r, np.random.Generator) # type narrowing for mypy
37
38
  return r
38
39
 
39
40
 
@@ -63,17 +63,10 @@ class SpuValue:
63
63
  return f"SpuValue({self.shape},{self.dtype},{self.vtype})"
64
64
 
65
65
 
66
- # SpuHandler removed (legacy handler API deprecated)
67
-
68
-
69
- def _get_spu_pocket() -> dict[str, Any]:
70
- return cur_kctx().state.setdefault("spu", {})
71
-
72
-
73
66
  def _get_spu_config_and_world() -> tuple[libspu.RuntimeConfig, int]:
74
- pocket = _get_spu_pocket()
75
- cfg = pocket.get("config")
76
- world = pocket.get("world")
67
+ kctx = cur_kctx()
68
+ cfg = kctx.runtime.get_state("spu.config")
69
+ world = kctx.runtime.get_state("spu.world")
77
70
  if cfg is None or world is None:
78
71
  raise RuntimeError("SPU kernel state not initialized (config/world)")
79
72
  return cfg, int(world)
@@ -87,12 +80,12 @@ def _register_spu_env(
87
80
  Idempotent: if config/world already set, they must match; link is recorded per rank.
88
81
  This replaces previous global fallback seeding logic.
89
82
  """
90
- pocket = _get_spu_pocket()
91
- prev_cfg = pocket.get("config")
92
- prev_world = pocket.get("world")
83
+ kctx = cur_kctx()
84
+ prev_cfg = kctx.runtime.get_state("spu.config")
85
+ prev_world = kctx.runtime.get_state("spu.world")
93
86
  if prev_cfg is None:
94
- pocket["config"] = config
95
- pocket["world"] = world_size
87
+ kctx.runtime.set_state("spu.config", config)
88
+ kctx.runtime.set_state("spu.world", world_size)
96
89
  else:
97
90
  # libspu RuntimeConfig may not implement __eq__; compare serialized repr
98
91
  same_cfg = (
@@ -105,7 +98,7 @@ def _register_spu_env(
105
98
  raise RuntimeError("Conflicting SPU env registration")
106
99
  # Store single link per runtime (one runtime per rank)
107
100
  if link_ctx is not None:
108
- pocket["link"] = link_ctx
101
+ kctx.runtime.set_state("spu.link", link_ctx)
109
102
 
110
103
 
111
104
  @kernel_def("spu.seed_env")
@@ -200,16 +193,16 @@ def _spu_run_mlir(pfunc: PFunction, *args: Any) -> Any:
200
193
  )
201
194
 
202
195
  cfg, _ = _get_spu_config_and_world()
203
- pocket = _get_spu_pocket()
204
- link_ctx: LinkCommunicator | None = pocket.get("link")
196
+ kctx = cur_kctx()
197
+ link_ctx = kctx.runtime.get_state("spu.link")
205
198
  if link_ctx is None:
206
199
  raise RuntimeError("Rank not participating in SPU; no link set via seed_env")
207
200
 
208
- # Lazy runtime cache
209
- spu_rt = pocket.get("runtime")
201
+ # Lazy runtime cache under key spu.runtime
202
+ spu_rt = kctx.runtime.get_state("spu.runtime")
210
203
  if spu_rt is None:
211
204
  spu_rt = spu_api.Runtime(link_ctx.get_lctx(), cfg)
212
- pocket["runtime"] = spu_rt
205
+ kctx.runtime.set_state("spu.runtime", spu_rt)
213
206
 
214
207
  # Validate that all inputs are SpuValue objects
215
208
  for i, arg in enumerate(args):
@@ -36,11 +36,14 @@ def _stablehlo_exec(pfunc: PFunction, *args: Any) -> Any:
36
36
  if isinstance(mlir_text, bytes):
37
37
  mlir_text = mlir_text.decode("utf-8")
38
38
 
39
- # Simple compile cache per runtime (state pocket per backend namespace)
39
+ # Flat-key compile cache: stablehlo.compile_cache.<hash>
40
40
  ctx = cur_kctx()
41
- pocket = ctx.state.setdefault("stablehlo", {})
42
- cache = pocket.setdefault("compile_cache", {})
43
- compiled = cache.get(mlir_text)
41
+ rt = ctx.runtime
42
+ import hashlib
43
+
44
+ h = hashlib.sha256(mlir_text.encode("utf-8")).hexdigest()[:16]
45
+ key = f"stablehlo.compile_cache.{h}"
46
+ compiled = rt.get_state(key)
44
47
  if compiled is None:
45
48
  backend = jax.default_backend()
46
49
  client = xla_bridge.get_backend(backend)
@@ -49,7 +52,7 @@ def _stablehlo_exec(pfunc: PFunction, *args: Any) -> Any:
49
52
  compiled = client.compile(mlir_text, compile_options)
50
53
  except Exception as e: # pragma: no cover
51
54
  raise RuntimeError(f"StableHLO compile failed: {e}") from e
52
- cache[mlir_text] = compiled
55
+ rt.set_state(key, compiled)
53
56
 
54
57
  # Handle JAX's unused parameter elimination via arg_keep_map
55
58
  runtime_args = args
@@ -173,38 +173,32 @@ class FileProvider(DataProvider):
173
173
  np.save(path, np.asarray(value))
174
174
 
175
175
 
176
- class _KeyedPocket:
177
- """Small helper to keep a dict in KernelContext.state under a namespaced key."""
178
-
179
- def __init__(self, ns: str):
180
- self.ns = ns
181
-
182
- def get_map(self, ctx: KernelContext) -> dict[str, Any]:
183
- pocket = ctx.state.setdefault("resource.providers", {})
184
- store = pocket.get(self.ns)
185
- if store is None:
186
- store = {}
187
- pocket[self.ns] = store
188
- return store # type: ignore[return-value]
189
-
190
-
191
176
  class MemProvider(DataProvider):
192
177
  """In-memory per-runtime KV provider (per rank, per session/runtime)."""
193
178
 
194
- def __init__(self) -> None:
195
- self._pocket = _KeyedPocket("mem")
179
+ STATE_KEY = "resource.providers.mem"
180
+
181
+ @staticmethod
182
+ def _store(ctx: KernelContext) -> dict[str, Any]:
183
+ # Use ensure_state so creation is atomic & centralized; enforce dict.
184
+ store = ctx.runtime.ensure_state(MemProvider.STATE_KEY, dict)
185
+ if not isinstance(store, dict): # pragma: no cover - defensive
186
+ raise TypeError(
187
+ f"runtime state key '{MemProvider.STATE_KEY}' expected dict, got {type(store).__name__}"
188
+ )
189
+ return store # type: ignore[return-value]
196
190
 
197
191
  def read(
198
192
  self, uri: ResolvedURI, out_spec: TensorType | TableType, *, ctx: KernelContext
199
193
  ) -> Any:
200
- store = self._pocket.get_map(ctx)
194
+ store = self._store(ctx)
201
195
  key = uri.raw
202
196
  if key not in store:
203
197
  raise FileNotFoundError(f"mem resource not found: {key}")
204
198
  return store[key]
205
199
 
206
200
  def write(self, uri: ResolvedURI, value: Any, *, ctx: KernelContext) -> None:
207
- store = self._pocket.get_map(ctx)
201
+ store = self._store(ctx)
208
202
  store[uri.raw] = value
209
203
 
210
204
 
@@ -184,8 +184,7 @@ class Session:
184
184
  return
185
185
 
186
186
  link_ctx = None
187
- # Fixed port offset for SPU runtime link services (legacy value retained).
188
- # TODO: make configurable if future deployments require dynamic offset.
187
+ # TODO(jint): reuse same port for mplang and spu.
189
188
  SPU_PORT_OFFSET = 100
190
189
 
191
190
  if self.is_spu_party:
@@ -23,9 +23,7 @@ from mplang.core.tensor import TensorType
23
23
  from mplang.kernels.context import RuntimeContext
24
24
 
25
25
 
26
- class TestBuiltinHandler:
27
- """Tests for flat builtin kernels (legacy name retained)."""
28
-
26
+ class TestBuiltin:
29
27
  def setup_method(self):
30
28
  # initialize backend context for rank 0 (world_size=1) once per test
31
29
  self.runtime = RuntimeContext(rank=0, world_size=1)
@@ -155,5 +155,3 @@ class TestStablehloKernel:
155
155
  ev = create_evaluator(0, {}, comm, runtime)
156
156
  with pytest.raises(NotImplementedError):
157
157
  ev._exec_pfunc(invalid_pfunc, []) # type: ignore[attr-defined]
158
-
159
- # No legacy handler path anymore; only NotImplementedError is expected.