cuju 0.1.0__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 (280) hide show
  1. cuju-0.1.0/.clang-format +17 -0
  2. cuju-0.1.0/.dockerignore +5 -0
  3. cuju-0.1.0/.gitattributes +3 -0
  4. cuju-0.1.0/.github/ISSUE_TEMPLATE/bug.yml +27 -0
  5. cuju-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  6. cuju-0.1.0/.github/ISSUE_TEMPLATE/difference.yml +58 -0
  7. cuju-0.1.0/.github/ISSUE_TEMPLATE/grf-feature.yml +20 -0
  8. cuju-0.1.0/.github/ISSUE_TEMPLATE/install.yml +30 -0
  9. cuju-0.1.0/.github/ISSUE_TEMPLATE/performance.yml +22 -0
  10. cuju-0.1.0/.github/pull_request_template.md +6 -0
  11. cuju-0.1.0/.github/workflows/ci.yml +73 -0
  12. cuju-0.1.0/.github/workflows/release.yml +312 -0
  13. cuju-0.1.0/.gitignore +7 -0
  14. cuju-0.1.0/AGENTS.md +159 -0
  15. cuju-0.1.0/CHANGELOG.md +88 -0
  16. cuju-0.1.0/CITATION.cff +60 -0
  17. cuju-0.1.0/CMakeLists.txt +289 -0
  18. cuju-0.1.0/CODE_OF_CONDUCT.md +119 -0
  19. cuju-0.1.0/CONTRIBUTING.md +38 -0
  20. cuju-0.1.0/Dockerfile +43 -0
  21. cuju-0.1.0/LICENSE +202 -0
  22. cuju-0.1.0/LICENSES/BSD-3-Clause.txt +31 -0
  23. cuju-0.1.0/LICENSES/BSL-1.0.txt +23 -0
  24. cuju-0.1.0/LICENSES/CC-BY-4.0.txt +396 -0
  25. cuju-0.1.0/LICENSES/LGPL-2.1-or-later.txt +502 -0
  26. cuju-0.1.0/LICENSES/MIT.txt +23 -0
  27. cuju-0.1.0/LICENSES/SunPro.txt +8 -0
  28. cuju-0.1.0/NOTICE +24 -0
  29. cuju-0.1.0/PKG-INFO +287 -0
  30. cuju-0.1.0/README.md +247 -0
  31. cuju-0.1.0/SECURITY.md +35 -0
  32. cuju-0.1.0/apptainer.def +39 -0
  33. cuju-0.1.0/ci/check_wheel.py +60 -0
  34. cuju-0.1.0/ci/compare_builds.py +129 -0
  35. cuju-0.1.0/ci/cpu_only.py +43 -0
  36. cuju-0.1.0/ci/data_checksums.py +27 -0
  37. cuju-0.1.0/ci/install_cuda.sh +33 -0
  38. cuju-0.1.0/docs/api.md +361 -0
  39. cuju-0.1.0/docs/backends.md +409 -0
  40. cuju-0.1.0/docs/concepts.md +145 -0
  41. cuju-0.1.0/docs/custom-scenarios.md +163 -0
  42. cuju-0.1.0/docs/differences-from-grf.md +153 -0
  43. cuju-0.1.0/docs/episodes-and-seeds.md +254 -0
  44. cuju-0.1.0/docs/exactness.md +236 -0
  45. cuju-0.1.0/docs/faq.md +219 -0
  46. cuju-0.1.0/docs/index.md +151 -0
  47. cuju-0.1.0/docs/installation.md +423 -0
  48. cuju-0.1.0/docs/migrating-from-grf.md +629 -0
  49. cuju-0.1.0/docs/observations.md +371 -0
  50. cuju-0.1.0/docs/performance.md +230 -0
  51. cuju-0.1.0/docs/recipes.md +426 -0
  52. cuju-0.1.0/docs/rewards-and-actions.md +201 -0
  53. cuju-0.1.0/docs/scenarios.md +184 -0
  54. cuju-0.1.0/docs/states.md +192 -0
  55. cuju-0.1.0/examples/README.md +65 -0
  56. cuju-0.1.0/examples/benchmark.py +110 -0
  57. cuju-0.1.0/examples/compare_with_grf.py +390 -0
  58. cuju-0.1.0/examples/cuda_graph_step.py +59 -0
  59. cuju-0.1.0/examples/cuju_quickstart.ipynb +633 -0
  60. cuju-0.1.0/examples/dumps.py +92 -0
  61. cuju-0.1.0/examples/evaluate.py +116 -0
  62. cuju-0.1.0/examples/kaggle_agent.py +73 -0
  63. cuju-0.1.0/examples/mixed_batch.py +57 -0
  64. cuju-0.1.0/examples/multi_gpu.py +91 -0
  65. cuju-0.1.0/examples/ppo.py +285 -0
  66. cuju-0.1.0/examples/random_rollout.py +57 -0
  67. cuju-0.1.0/examples/self_play.py +131 -0
  68. cuju-0.1.0/examples/states.py +138 -0
  69. cuju-0.1.0/include/cuju/ai_time.h +409 -0
  70. cuju-0.1.0/include/cuju/animation/animation_data.h +307 -0
  71. cuju-0.1.0/include/cuju/animation/animation_derived.h +168 -0
  72. cuju-0.1.0/include/cuju/animation/apply.h +367 -0
  73. cuju-0.1.0/include/cuju/animation/keyframes.h +194 -0
  74. cuju-0.1.0/include/cuju/animation/skeleton.h +224 -0
  75. cuju-0.1.0/include/cuju/assets/scenario_builder.h +784 -0
  76. cuju-0.1.0/include/cuju/ball.h +348 -0
  77. cuju-0.1.0/include/cuju/batch/agent_setup.h +164 -0
  78. cuju-0.1.0/include/cuju/batch/batch_core.h +755 -0
  79. cuju-0.1.0/include/cuju/batch/batch_environment.h +621 -0
  80. cuju-0.1.0/include/cuju/batch/memory_estimate.h +72 -0
  81. cuju-0.1.0/include/cuju/batch/stacked_state.h +82 -0
  82. cuju-0.1.0/include/cuju/batch/state_difference.h +128 -0
  83. cuju-0.1.0/include/cuju/batch/tables.h +93 -0
  84. cuju-0.1.0/include/cuju/cpu/batch_environment.h +460 -0
  85. cuju-0.1.0/include/cuju/cpu/job_thread.h +121 -0
  86. cuju-0.1.0/include/cuju/cpu/placement.h +214 -0
  87. cuju-0.1.0/include/cuju/cpu/processors.h +152 -0
  88. cuju-0.1.0/include/cuju/file_path.h +24 -0
  89. cuju-0.1.0/include/cuju/floating_point.h +60 -0
  90. cuju-0.1.0/include/cuju/game_definitions.h +36 -0
  91. cuju-0.1.0/include/cuju/gpu/batch_environment.cuh +221 -0
  92. cuju-0.1.0/include/cuju/gpu/device_data.h +138 -0
  93. cuju-0.1.0/include/cuju/host_device.h +46 -0
  94. cuju-0.1.0/include/cuju/inline_vector.h +95 -0
  95. cuju-0.1.0/include/cuju/libm/acos_double.h +143 -0
  96. cuju-0.1.0/include/cuju/libm/asinf.h +95 -0
  97. cuju-0.1.0/include/cuju/libm/common.h +120 -0
  98. cuju-0.1.0/include/cuju/libm/inverse_trigonometric_float.h +272 -0
  99. cuju-0.1.0/include/cuju/libm/pow.h +651 -0
  100. cuju-0.1.0/include/cuju/libm/powf.h +198 -0
  101. cuju-0.1.0/include/cuju/libm/sin_double.h +266 -0
  102. cuju-0.1.0/include/cuju/libm/sincos_double.h +19 -0
  103. cuju-0.1.0/include/cuju/libm/sincosf.h +212 -0
  104. cuju-0.1.0/include/cuju/libm/trigonometric_double.h +8 -0
  105. cuju-0.1.0/include/cuju/libm/trigonometric_tables_double.h +1408 -0
  106. cuju-0.1.0/include/cuju/math_utilities.h +41 -0
  107. cuju-0.1.0/include/cuju/nvtx.h +44 -0
  108. cuju-0.1.0/include/cuju/possession.h +123 -0
  109. cuju-0.1.0/include/cuju/profiling.h +70 -0
  110. cuju-0.1.0/include/cuju/quaternion.h +286 -0
  111. cuju-0.1.0/include/cuju/real_to_string.h +53 -0
  112. cuju-0.1.0/include/cuju/rng.h +115 -0
  113. cuju-0.1.0/include/cuju/simulation/access.h +65 -0
  114. cuju-0.1.0/include/cuju/simulation/ai_controller.h +2494 -0
  115. cuju-0.1.0/include/cuju/simulation/ai_functions.h +190 -0
  116. cuju-0.1.0/include/cuju/simulation/ball_touch.h +143 -0
  117. cuju-0.1.0/include/cuju/simulation/camera.h +170 -0
  118. cuju-0.1.0/include/cuju/simulation/collisions.h +608 -0
  119. cuju-0.1.0/include/cuju/simulation/containers.h +26 -0
  120. cuju-0.1.0/include/cuju/simulation/enumerations.h +64 -0
  121. cuju-0.1.0/include/cuju/simulation/environment.h +593 -0
  122. cuju-0.1.0/include/cuju/simulation/geometry_offsets.h +200 -0
  123. cuju-0.1.0/include/cuju/simulation/human_controller.h +117 -0
  124. cuju-0.1.0/include/cuju/simulation/humanoid.h +422 -0
  125. cuju-0.1.0/include/cuju/simulation/humanoid_process.h +681 -0
  126. cuju-0.1.0/include/cuju/simulation/match_process.h +374 -0
  127. cuju-0.1.0/include/cuju/simulation/observation_encoding.h +182 -0
  128. cuju-0.1.0/include/cuju/simulation/officials.h +398 -0
  129. cuju-0.1.0/include/cuju/simulation/player_controller.h +248 -0
  130. cuju-0.1.0/include/cuju/simulation/player_possession.h +126 -0
  131. cuju-0.1.0/include/cuju/simulation/referee.h +353 -0
  132. cuju-0.1.0/include/cuju/simulation/reset.h +721 -0
  133. cuju-0.1.0/include/cuju/simulation/select_animation.h +2795 -0
  134. cuju-0.1.0/include/cuju/simulation/state_io.h +94 -0
  135. cuju-0.1.0/include/cuju/simulation/static_data.h +108 -0
  136. cuju-0.1.0/include/cuju/simulation/team_ai.h +533 -0
  137. cuju-0.1.0/include/cuju/simulation/team_process.h +312 -0
  138. cuju-0.1.0/include/cuju/simulation/team_select.h +207 -0
  139. cuju-0.1.0/include/cuju/simulation/touch.h +400 -0
  140. cuju-0.1.0/include/cuju/simulation/world.h +170 -0
  141. cuju-0.1.0/include/cuju/span.h +27 -0
  142. cuju-0.1.0/include/cuju/state/archive.h +195 -0
  143. cuju-0.1.0/include/cuju/state/environment_state.h +892 -0
  144. cuju-0.1.0/include/cuju/vector3.h +232 -0
  145. cuju-0.1.0/include/cuju/warp.h +252 -0
  146. cuju-0.1.0/include/cuju/x86.h +35 -0
  147. cuju-0.1.0/pyproject.toml +94 -0
  148. cuju-0.1.0/python/cuju/__init__.py +142 -0
  149. cuju-0.1.0/python/cuju/_batch/__init__.py +4 -0
  150. cuju-0.1.0/python/cuju/_batch/allocator.py +52 -0
  151. cuju-0.1.0/python/cuju/_batch/assets.py +68 -0
  152. cuju-0.1.0/python/cuju/_batch/environment.py +1502 -0
  153. cuju-0.1.0/python/cuju/_batch/frame_stack.py +114 -0
  154. cuju-0.1.0/python/cuju/_batch/library.py +276 -0
  155. cuju-0.1.0/python/cuju/_batch/log.py +96 -0
  156. cuju-0.1.0/python/cuju/_batch/memory.py +70 -0
  157. cuju-0.1.0/python/cuju/_batch/operators.py +55 -0
  158. cuju-0.1.0/python/cuju/_batch/pinned.py +39 -0
  159. cuju-0.1.0/python/cuju/_batch/state.py +77 -0
  160. cuju-0.1.0/python/cuju/_checksums.py +60 -0
  161. cuju-0.1.0/python/cuju/_python_players.py +215 -0
  162. cuju-0.1.0/python/cuju/_replays.py +411 -0
  163. cuju-0.1.0/python/cuju/_version.py +6 -0
  164. cuju-0.1.0/python/cuju/action_log.py +371 -0
  165. cuju-0.1.0/python/cuju/check.py +479 -0
  166. cuju-0.1.0/python/cuju/data/SHA256SUMS +20 -0
  167. cuju-0.1.0/python/cuju/data/animations.bin +0 -0
  168. cuju-0.1.0/python/cuju/data/assets/11_vs_11_competition_l0_r0.cjb +0 -0
  169. cuju-0.1.0/python/cuju/data/assets/11_vs_11_easy_stochastic_l0_r0.cjb +0 -0
  170. cuju-0.1.0/python/cuju/data/assets/11_vs_11_hard_stochastic_l0_r0.cjb +0 -0
  171. cuju-0.1.0/python/cuju/data/assets/11_vs_11_kaggle_l0_r0.cjb +0 -0
  172. cuju-0.1.0/python/cuju/data/assets/11_vs_11_stochastic_l0_r0.cjb +0 -0
  173. cuju-0.1.0/python/cuju/data/assets/1_vs_1_easy_l0_r0.cjb +0 -0
  174. cuju-0.1.0/python/cuju/data/assets/5_vs_5_l0_r0.cjb +0 -0
  175. cuju-0.1.0/python/cuju/data/assets/academy_3_vs_1_with_keeper_l0_r0.cjb +0 -0
  176. cuju-0.1.0/python/cuju/data/assets/academy_corner_l0_r0.cjb +0 -0
  177. cuju-0.1.0/python/cuju/data/assets/academy_counterattack_easy_l0_r0.cjb +0 -0
  178. cuju-0.1.0/python/cuju/data/assets/academy_counterattack_hard_l0_r0.cjb +0 -0
  179. cuju-0.1.0/python/cuju/data/assets/academy_empty_goal_close_l0_r0.cjb +0 -0
  180. cuju-0.1.0/python/cuju/data/assets/academy_empty_goal_l0_r0.cjb +0 -0
  181. cuju-0.1.0/python/cuju/data/assets/academy_pass_and_shoot_with_keeper_l0_r0.cjb +0 -0
  182. cuju-0.1.0/python/cuju/data/assets/academy_run_pass_and_shoot_with_keeper_l0_r0.cjb +0 -0
  183. cuju-0.1.0/python/cuju/data/assets/academy_run_to_score_l0_r0.cjb +0 -0
  184. cuju-0.1.0/python/cuju/data/assets/academy_run_to_score_with_keeper_l0_r0.cjb +0 -0
  185. cuju-0.1.0/python/cuju/data/assets/academy_single_goal_versus_lazy_l0_r0.cjb +0 -0
  186. cuju-0.1.0/python/cuju/data/assets/test_example_multiagent_l0_r0.cjb +0 -0
  187. cuju-0.1.0/python/cuju/data/digests.json +186 -0
  188. cuju-0.1.0/python/cuju/data/scenarios/11_vs_11_competition.py +45 -0
  189. cuju-0.1.0/python/cuju/data/scenarios/11_vs_11_easy_stochastic.py +44 -0
  190. cuju-0.1.0/python/cuju/data/scenarios/11_vs_11_hard_stochastic.py +44 -0
  191. cuju-0.1.0/python/cuju/data/scenarios/11_vs_11_kaggle.py +46 -0
  192. cuju-0.1.0/python/cuju/data/scenarios/11_vs_11_stochastic.py +44 -0
  193. cuju-0.1.0/python/cuju/data/scenarios/1_vs_1_easy.py +25 -0
  194. cuju-0.1.0/python/cuju/data/scenarios/5_vs_5.py +33 -0
  195. cuju-0.1.0/python/cuju/data/scenarios/academy_3_vs_1_with_keeper.py +28 -0
  196. cuju-0.1.0/python/cuju/data/scenarios/academy_corner.py +45 -0
  197. cuju-0.1.0/python/cuju/data/scenarios/academy_counterattack_easy.py +45 -0
  198. cuju-0.1.0/python/cuju/data/scenarios/academy_counterattack_hard.py +45 -0
  199. cuju-0.1.0/python/cuju/data/scenarios/academy_empty_goal.py +25 -0
  200. cuju-0.1.0/python/cuju/data/scenarios/academy_empty_goal_close.py +25 -0
  201. cuju-0.1.0/python/cuju/data/scenarios/academy_pass_and_shoot_with_keeper.py +27 -0
  202. cuju-0.1.0/python/cuju/data/scenarios/academy_run_pass_and_shoot_with_keeper.py +27 -0
  203. cuju-0.1.0/python/cuju/data/scenarios/academy_run_to_score.py +30 -0
  204. cuju-0.1.0/python/cuju/data/scenarios/academy_run_to_score_with_keeper.py +30 -0
  205. cuju-0.1.0/python/cuju/data/scenarios/academy_single_goal_versus_lazy.py +49 -0
  206. cuju-0.1.0/python/cuju/data/scenarios/test_example_multiagent.py +28 -0
  207. cuju-0.1.0/python/cuju/dumps.py +909 -0
  208. cuju-0.1.0/python/cuju/env.py +1130 -0
  209. cuju-0.1.0/python/cuju/errors.py +92 -0
  210. cuju-0.1.0/python/cuju/gfootball/__init__.py +30 -0
  211. cuju-0.1.0/python/cuju/gfootball/dump_to_txt.py +52 -0
  212. cuju-0.1.0/python/cuju/gfootball/env/__init__.py +36 -0
  213. cuju-0.1.0/python/cuju/gfootball/env/config.py +284 -0
  214. cuju-0.1.0/python/cuju/gfootball/env/football_action_set.py +158 -0
  215. cuju-0.1.0/python/cuju/gfootball/env/football_env.py +68 -0
  216. cuju-0.1.0/python/cuju/gfootball/env/observation_preprocessing.py +98 -0
  217. cuju-0.1.0/python/cuju/gfootball/env/player_base.py +44 -0
  218. cuju-0.1.0/python/cuju/gfootball/env/players/__init__.py +9 -0
  219. cuju-0.1.0/python/cuju/gfootball/env/players/replay.py +40 -0
  220. cuju-0.1.0/python/cuju/gfootball/env/scenario_builder.py +70 -0
  221. cuju-0.1.0/python/cuju/gfootball/env/script_helpers.py +102 -0
  222. cuju-0.1.0/python/cuju/gfootball/env/wrappers.py +523 -0
  223. cuju-0.1.0/python/cuju/gfootball/replay.py +80 -0
  224. cuju-0.1.0/python/cuju/gfootball/scenarios.py +38 -0
  225. cuju-0.1.0/python/cuju/kaggle.py +266 -0
  226. cuju-0.1.0/python/cuju/multi_device.py +382 -0
  227. cuju-0.1.0/python/cuju/players.py +260 -0
  228. cuju-0.1.0/python/cuju/raw.py +93 -0
  229. cuju-0.1.0/python/cuju/scenarios.py +657 -0
  230. cuju-0.1.0/python/cuju/wrappers.py +325 -0
  231. cuju-0.1.0/src/cuju_cpu.cpp +37 -0
  232. cuju-0.1.0/src/cuju_cuda.cu +12 -0
  233. cuju-0.1.0/src/environment_api.h +528 -0
  234. cuju-0.1.0/src/environment_state.cpp +103 -0
  235. cuju-0.1.0/src/scenario_api.h +118 -0
  236. cuju-0.1.0/src/state_api.h +50 -0
  237. cuju-0.1.0/tests/conftest.py +98 -0
  238. cuju-0.1.0/tests/test_action_log.py +122 -0
  239. cuju-0.1.0/tests/test_allocator.py +67 -0
  240. cuju-0.1.0/tests/test_async.py +157 -0
  241. cuju-0.1.0/tests/test_auto_device.py +36 -0
  242. cuju-0.1.0/tests/test_backends.py +19 -0
  243. cuju-0.1.0/tests/test_bundle_cache.py +158 -0
  244. cuju-0.1.0/tests/test_check.py +129 -0
  245. cuju-0.1.0/tests/test_compare_with_grf.py +185 -0
  246. cuju-0.1.0/tests/test_compile.py +104 -0
  247. cuju-0.1.0/tests/test_data_checksums.py +38 -0
  248. cuju-0.1.0/tests/test_device_checks.py +148 -0
  249. cuju-0.1.0/tests/test_devices.py +53 -0
  250. cuju-0.1.0/tests/test_difficulty.py +34 -0
  251. cuju-0.1.0/tests/test_digests.py +53 -0
  252. cuju-0.1.0/tests/test_distribution.py +193 -0
  253. cuju-0.1.0/tests/test_dump_replay.py +94 -0
  254. cuju-0.1.0/tests/test_dumps.py +301 -0
  255. cuju-0.1.0/tests/test_env.py +331 -0
  256. cuju-0.1.0/tests/test_errors.py +91 -0
  257. cuju-0.1.0/tests/test_first_index.py +54 -0
  258. cuju-0.1.0/tests/test_fork.py +101 -0
  259. cuju-0.1.0/tests/test_gfootball.py +615 -0
  260. cuju-0.1.0/tests/test_gpu_errors.py +21 -0
  261. cuju-0.1.0/tests/test_grf_config.py +109 -0
  262. cuju-0.1.0/tests/test_import.py +59 -0
  263. cuju-0.1.0/tests/test_kaggle.py +143 -0
  264. cuju-0.1.0/tests/test_long.py +69 -0
  265. cuju-0.1.0/tests/test_masked_reset.py +119 -0
  266. cuju-0.1.0/tests/test_memory.py +106 -0
  267. cuju-0.1.0/tests/test_memory_estimate.py +207 -0
  268. cuju-0.1.0/tests/test_multi_device.py +136 -0
  269. cuju-0.1.0/tests/test_nvtx.py +40 -0
  270. cuju-0.1.0/tests/test_players.py +274 -0
  271. cuju-0.1.0/tests/test_processors.py +75 -0
  272. cuju-0.1.0/tests/test_python_players.py +227 -0
  273. cuju-0.1.0/tests/test_reset_seeds.py +87 -0
  274. cuju-0.1.0/tests/test_shapes.py +55 -0
  275. cuju-0.1.0/tests/test_stacked_state.py +155 -0
  276. cuju-0.1.0/tests/test_state.py +30 -0
  277. cuju-0.1.0/tests/test_state_errors.py +52 -0
  278. cuju-0.1.0/tests/test_version.py +35 -0
  279. cuju-0.1.0/tests/test_wrappers.py +278 -0
  280. cuju-0.1.0/tests/test_write_dump.py +105 -0
@@ -0,0 +1,17 @@
1
+ BasedOnStyle: Google
2
+ Language: Cpp
3
+ Standard: c++17
4
+ ColumnLimit: 100
5
+ IndentWidth: 4
6
+ ContinuationIndentWidth: 4
7
+ ConstructorInitializerIndentWidth: 4
8
+ AccessModifierOffset: -4
9
+ DerivePointerAlignment: false
10
+ PointerAlignment: Right
11
+ ReferenceAlignment: Right
12
+ AllowShortFunctionsOnASingleLine: All
13
+ AllowShortIfStatementsOnASingleLine: WithoutElse
14
+ AllowShortLoopsOnASingleLine: true
15
+ IncludeBlocks: Preserve
16
+ SortIncludes: Never
17
+ ReflowComments: true
@@ -0,0 +1,5 @@
1
+ .git
2
+ build
3
+ dist
4
+ wheelhouse
5
+ **/__pycache__
@@ -0,0 +1,3 @@
1
+ * text=auto eol=lf
2
+ *.bin binary
3
+ *.cjb binary
@@ -0,0 +1,27 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ name: Bug
5
+ description: Something else doesn't work as the documentation says.
6
+ labels: [bug]
7
+ body:
8
+ - type: input
9
+ id: cuju-version
10
+ attributes:
11
+ label: cuju version
12
+ validations:
13
+ required: true
14
+ - type: textarea
15
+ id: reproduce
16
+ attributes:
17
+ label: How to reproduce it
18
+ description: The shortest code that shows the problem.
19
+ render: python
20
+ validations:
21
+ required: true
22
+ - type: textarea
23
+ id: expected
24
+ attributes:
25
+ label: What you expected, and what happened
26
+ validations:
27
+ required: true
@@ -0,0 +1,8 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ blank_issues_enabled: false
5
+ contact_links:
6
+ - name: Questions
7
+ url: https://github.com/AndreKoraleski/cuju/discussions
8
+ about: Ask and discuss in GitHub Discussions.
@@ -0,0 +1,58 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ name: Difference from GRF
5
+ description: cuju and Google Research Football give different outputs for the same input.
6
+ labels: [difference]
7
+ body:
8
+ - type: markdown
9
+ attributes:
10
+ value: |
11
+ Thank you. A difference we can reproduce is a bug, and we fix it toward GRF.
12
+ The fastest way to a fix is the state from `get_state` just before the two diverge.
13
+ - type: input
14
+ id: cuju-version
15
+ attributes:
16
+ label: cuju version
17
+ description: "`python -c \"import importlib.metadata as m; print(m.version('cuju'))\"`"
18
+ validations:
19
+ required: true
20
+ - type: dropdown
21
+ id: backend
22
+ attributes:
23
+ label: Backend
24
+ options: [cuda, cpu, both]
25
+ validations:
26
+ required: true
27
+ - type: textarea
28
+ id: grf-build
29
+ attributes:
30
+ label: Your GRF
31
+ description: The GRF version or commit, the operating system, and the glibc and GCC it was built with.
32
+ validations:
33
+ required: true
34
+ - type: textarea
35
+ id: setup
36
+ attributes:
37
+ label: Scenario, options and seed
38
+ description: The `BatchEnvironment` call, and the `create_environment` call on the GRF side.
39
+ render: python
40
+ validations:
41
+ required: true
42
+ - type: textarea
43
+ id: divergence
44
+ attributes:
45
+ label: Where they diverge
46
+ description: The first step that differs and what differs (observation, reward, done flag or state).
47
+ validations:
48
+ required: true
49
+ - type: textarea
50
+ id: attachments
51
+ attributes:
52
+ label: State and actions
53
+ description: Attach the state bytes and the actions that reproduce it, if you can.
54
+ - type: textarea
55
+ id: self-check
56
+ attributes:
57
+ label: "Output of `pytest tests/`"
58
+ render: text
@@ -0,0 +1,20 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ name: Missing GRF feature
5
+ description: Something Google Research Football offers that cuju doesn't.
6
+ labels: [grf-feature]
7
+ body:
8
+ - type: input
9
+ id: grf-call
10
+ attributes:
11
+ label: The GRF call or option
12
+ description: Such as an option of `create_environment` or a wrapper.
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: use
17
+ attributes:
18
+ label: What you use it for
19
+ validations:
20
+ required: true
@@ -0,0 +1,30 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ name: Installation problem
5
+ description: cuju doesn't install, build or load.
6
+ labels: [install]
7
+ body:
8
+ - type: dropdown
9
+ id: route
10
+ attributes:
11
+ label: How you installed
12
+ options: [pip install cuju, from source, Docker, WSL2]
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: system
17
+ attributes:
18
+ label: System
19
+ description: |
20
+ The output of `nvidia-smi`, `nvcc --version` (for a source build), `python -c "import torch; print(torch.__version__, torch.version.cuda)"`, and `grep -o -w 'avx2\|bmi2\|fma' /proc/cpuinfo | sort -u`.
21
+ render: text
22
+ validations:
23
+ required: true
24
+ - type: textarea
25
+ id: log
26
+ attributes:
27
+ label: The error and the log
28
+ render: text
29
+ validations:
30
+ required: true
@@ -0,0 +1,22 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ name: Performance
5
+ description: cuju runs slower than the published numbers on comparable hardware.
6
+ labels: [performance]
7
+ body:
8
+ - type: textarea
9
+ id: hardware
10
+ attributes:
11
+ label: Hardware
12
+ description: The GPU or CPU model, the driver, and how many cores the process may use.
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: run
17
+ attributes:
18
+ label: What you ran
19
+ description: The command of `examples/benchmark.py`, or your own code, and the number you got.
20
+ render: text
21
+ validations:
22
+ required: true
@@ -0,0 +1,6 @@
1
+ What this changes and why:
2
+
3
+ - [ ] `pytest tests/` passes (and on a GPU, if the change touches it)
4
+ - [ ] `ruff check`, `ruff format --check` and `clang-format --dry-run -Werror` pass
5
+ - [ ] A change to `include/` or `src/` keeps every output, or moves it toward GRF with a reproducing
6
+ case
@@ -0,0 +1,73 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ name: ci
5
+
6
+ on:
7
+ push:
8
+ pull_request:
9
+
10
+ jobs:
11
+ cpu:
12
+ runs-on: ubuntu-24.04
13
+ steps:
14
+ - uses: actions/checkout@v7
15
+ - uses: actions/setup-python@v7
16
+ with:
17
+ python-version: '3.12'
18
+ - name: Install PyTorch for the CPU
19
+ run: pip install torch --index-url https://download.pytorch.org/whl/cpu
20
+ - name: Build and install the CPU backend
21
+ run: CMAKE_ARGS=-DCUJU_CUDA=OFF pip install '.[test,spaces]' ruff
22
+ - name: Lint
23
+ run: |
24
+ ruff check python tests examples
25
+ ruff format --check python tests examples
26
+ find include src -name '*.h' -o -name '*.cuh' -o -name '*.cpp' -o -name '*.cu' \
27
+ | xargs clang-format-18 --dry-run -Werror
28
+ - name: Self-check
29
+ run: pytest tests
30
+
31
+ # The same expected digests on an aarch64 host, which is what lets aarch64 wheels ship.
32
+ cpu-arm:
33
+ runs-on: ubuntu-24.04-arm
34
+ steps:
35
+ - uses: actions/checkout@v7
36
+ - uses: actions/setup-python@v7
37
+ with:
38
+ python-version: '3.12'
39
+ - name: Install PyTorch for the CPU
40
+ run: pip install torch --index-url https://download.pytorch.org/whl/cpu
41
+ - name: Build and install the CPU backend
42
+ run: CMAKE_ARGS=-DCUJU_CUDA=OFF pip install '.[test,spaces]'
43
+ - name: Self-check
44
+ run: pytest tests
45
+
46
+ # The same expected digests from MSVC on Windows, which a Windows wheel would need first.
47
+ cpu-windows:
48
+ runs-on: windows-2022
49
+ steps:
50
+ - uses: actions/checkout@v7
51
+ - uses: actions/setup-python@v7
52
+ with:
53
+ python-version: '3.12'
54
+ - name: Install PyTorch for the CPU
55
+ run: pip install torch --index-url https://download.pytorch.org/whl/cpu
56
+ - name: Build and install the CPU backend
57
+ run: pip install ".[test,spaces]"
58
+ env:
59
+ CMAKE_ARGS: -DCUJU_CUDA=OFF
60
+ - name: Self-check
61
+ run: pytest tests
62
+
63
+ cuda-compile:
64
+ runs-on: ubuntu-24.04
65
+ container: nvidia/cuda:12.9.1-devel-ubuntu24.04
66
+ steps:
67
+ - uses: actions/checkout@v7
68
+ - name: Install the build tools
69
+ run: apt-get update && apt-get install -y --no-install-recommends cmake g++ make
70
+ - name: Compile the CUDA backend for one architecture
71
+ run: |
72
+ cmake -S . -B build -DCUJU_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=80
73
+ cmake --build build --target cuju_cuda -j 4
@@ -0,0 +1,312 @@
1
+ # Copyright 2026 The cuju Authors
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ name: release
5
+
6
+ # A tag or a dispatch builds and checks the sdist and every wheel. Only a dispatch with `publish`
7
+ # set publishes them, through PyPI's trusted publishing and the `pypi` environment's approval.
8
+ on:
9
+ push:
10
+ tags: ['v*']
11
+ workflow_dispatch:
12
+ inputs:
13
+ publish:
14
+ description: Publish the sdist and the wheels to PyPI
15
+ type: boolean
16
+ default: false
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ # Every build runs twice and the two must agree byte for byte, so anyone can rebuild a release from
22
+ # its tag and get the published files: each file is dated by the tagged commit (SOURCE_DATE_EPOCH)
23
+ # and the libraries hold no directory, process id or time of the build machine.
24
+ jobs:
25
+ sdist:
26
+ runs-on: ubuntu-24.04
27
+ steps:
28
+ - uses: actions/checkout@v7
29
+ - uses: actions/setup-python@v7
30
+ with:
31
+ python-version: '3.12'
32
+ - name: Date every file of the build by the commit
33
+ run: echo "SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)" >> "$GITHUB_ENV"
34
+ - name: Build the sdist twice and compare the bytes
35
+ run: |
36
+ pip install build
37
+ python -m build --sdist --outdir dist
38
+ python -m build --sdist --outdir "$RUNNER_TEMP/sdist-again"
39
+ python ci/compare_builds.py dist "$RUNNER_TEMP/sdist-again"
40
+ - uses: actions/upload-artifact@v7
41
+ with:
42
+ name: sdist
43
+ path: dist/*.tar.gz
44
+
45
+ # One wheel per platform. Linux builds in the manylinux_2_28 image with cibuildwheel, each build
46
+ # in a new container; macOS and Windows build on the runner, the second time from an empty
47
+ # build directory.
48
+ wheel:
49
+ name: wheel ${{ matrix.name }}
50
+ runs-on: ${{ matrix.runner }}
51
+ strategy:
52
+ fail-fast: false
53
+ matrix:
54
+ include:
55
+ # The CPU library from Clang, about 10% faster than GCC and as exact, and the
56
+ # CUDA library for the checked GPUs. `-real` keeps the PTX out: a driver would
57
+ # compile PTX for a GPU that no check covered, where the library must instead
58
+ # refuse to start.
59
+ - name: linux-x86-64
60
+ runner: ubuntu-24.04
61
+ cibuildwheel: cp312-manylinux_x86_64
62
+ before_all: bash ci/install_cuda.sh
63
+ environment: >-
64
+ PATH=/usr/local/cuda/bin:$PATH
65
+ CXX=clang++ CUDAHOSTCXX=g++
66
+ CMAKE_ARGS=-DCUJU_CUDA=ON
67
+ CMAKE_CUDA_ARCHITECTURES="75-real;80-real;86-real;89-real"
68
+ - name: linux-aarch64
69
+ runner: ubuntu-24.04-arm
70
+ cibuildwheel: cp312-manylinux_aarch64
71
+ before_all: dnf install -y clang
72
+ environment: CXX=clang++ CMAKE_ARGS=-DCUJU_CUDA=OFF
73
+ cpu_only: true
74
+ # CUDA 12.9 takes the MSVC of Visual Studio 2017 to 2022, which windows-2025
75
+ # (Visual Studio 2026) has no longer.
76
+ - name: windows-x86-64
77
+ runner: windows-2022
78
+ cmake_args: -DCUJU_CUDA=ON
79
+ cuda_architectures: 75-real;80-real;86-real;89-real
80
+ cuda: true
81
+ - name: macos-arm64
82
+ runner: macos-14
83
+ cmake_args: -DCUJU_CUDA=OFF
84
+ deployment_target: '11.0'
85
+ cpu_only: true
86
+ # GitHub retired macos-13; macos-15-intel is the x86-64 image left.
87
+ - name: macos-x86-64
88
+ runner: macos-15-intel
89
+ cmake_args: -DCUJU_CUDA=OFF
90
+ deployment_target: '10.15'
91
+ cpu_only: true
92
+ defaults:
93
+ run:
94
+ shell: bash
95
+ env:
96
+ PIP_DISABLE_PIP_VERSION_CHECK: '1'
97
+ steps:
98
+ - uses: actions/checkout@v7
99
+ - uses: actions/setup-python@v7
100
+ with:
101
+ python-version: '3.12'
102
+ - name: Date every file of the build by the commit
103
+ run: echo "SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)" >> "$GITHUB_ENV"
104
+ - name: Install the CUDA toolkit
105
+ if: matrix.cuda
106
+ uses: Jimver/cuda-toolkit@v0.2.36
107
+ with:
108
+ cuda: '12.9.1'
109
+ method: network
110
+ sub-packages: '["nvcc", "cudart", "visual_studio_integration"]'
111
+ # What `vcvars64.bat` sets, for the steps that follow.
112
+ - name: Use MSVC from the command line
113
+ if: runner.os == 'Windows'
114
+ shell: pwsh
115
+ run: |
116
+ $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
117
+ $vs = & $vswhere -latest -products * -property installationPath `
118
+ -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64
119
+ $before = @{}
120
+ Get-ChildItem env: | ForEach-Object { $before[$_.Name] = $_.Value }
121
+ cmd /c "`"$vs\VC\Auxiliary\Build\vcvars64.bat`" >nul && set" | ForEach-Object {
122
+ if ($_ -match '^([^=]+)=(.*)$' -and $before[$matches[1]] -ne $matches[2]) {
123
+ "$($matches[1])=$($matches[2])" >> $env:GITHUB_ENV
124
+ }
125
+ }
126
+ - name: Describe the runner
127
+ run: |
128
+ python -c "import platform, sys; print(platform.platform(), platform.machine(), sys.version)"
129
+ cmake --version | head -n 1
130
+ if [ "$RUNNER_OS" = Windows ]; then cl 2>&1 | head -n 1; nvcc --version | tail -n 2;
131
+ elif [ "$RUNNER_OS" = macOS ]; then clang++ --version | head -n 1; sysctl -n machdep.cpu.brand_string;
132
+ fi
133
+ - name: Build the wheel twice in the manylinux image
134
+ if: runner.os == 'Linux'
135
+ env:
136
+ CIBW_BUILD: ${{ matrix.cibuildwheel }}
137
+ CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
138
+ CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
139
+ CIBW_BEFORE_ALL: ${{ matrix.before_all }}
140
+ CIBW_ENVIRONMENT: ${{ matrix.environment }}
141
+ CIBW_ENVIRONMENT_PASS_LINUX: SOURCE_DATE_EPOCH
142
+ CIBW_CONFIG_SETTINGS: build.verbose=true
143
+ CIBW_BUILD_VERBOSITY: '1'
144
+ run: |
145
+ python -m pip install cibuildwheel==4.3.4
146
+ python -m cibuildwheel --output-dir wheelhouse 2>&1 | tee build.log
147
+ python -m cibuildwheel --output-dir wheelhouse-again 2>&1 | tee build-again.log
148
+ - name: Build the wheel twice on the runner
149
+ if: runner.os != 'Linux'
150
+ env:
151
+ CMAKE_ARGS: ${{ matrix.cmake_args }}
152
+ CMAKE_CUDA_ARCHITECTURES: ${{ matrix.cuda_architectures }}
153
+ MACOSX_DEPLOYMENT_TARGET: ${{ matrix.deployment_target }}
154
+ run: |
155
+ if [ -z "$CMAKE_CUDA_ARCHITECTURES" ]; then unset CMAKE_CUDA_ARCHITECTURES; fi
156
+ if [ -z "$MACOSX_DEPLOYMENT_TARGET" ]; then unset MACOSX_DEPLOYMENT_TARGET; fi
157
+ if [ "$RUNNER_OS" = Windows ]; then export CMAKE_GENERATOR=Ninja; fi
158
+ python -m pip install --upgrade pip ninja
159
+ python -m pip wheel . --no-deps -v -w wheelhouse -C build.verbose=true 2>&1 | tee build.log
160
+ rm -rf build
161
+ python -m pip wheel . --no-deps -v -w wheelhouse-again -C build.verbose=true 2>&1 \
162
+ | tee build-again.log
163
+ - name: Compare the two builds
164
+ run: python ci/compare_builds.py wheelhouse wheelhouse-again
165
+ - name: Check the compile flags
166
+ run: |
167
+ grep -ohE "fp:precise|ffp-contract=off" build.log | sort | uniq -c
168
+ if grep -E "fp:fast|fp:contract|ffast-math|ffp-contract=(fast|on)" build.log; then
169
+ echo "a contracting or fast-math flag reached the build"; exit 1
170
+ fi
171
+ - name: Check the licenses and the libraries of the wheel
172
+ run: |
173
+ python ci/check_wheel.py ${{ matrix.cpu_only && '--cpu-only' || '' }} wheelhouse/*.whl
174
+ ls -l wheelhouse
175
+ python -c "import sys, zipfile; [print(n) for n in zipfile.ZipFile(sys.argv[1]).namelist() if not n.startswith('cuju/gfootball')]" wheelhouse/*.whl
176
+ - uses: actions/upload-artifact@v7
177
+ with:
178
+ name: wheel-${{ matrix.name }}
179
+ path: wheelhouse/*.whl
180
+ - uses: actions/upload-artifact@v7
181
+ if: always()
182
+ with:
183
+ name: build-log-${{ matrix.name }}
184
+ path: build*.log
185
+
186
+ # Each wheel installs with pip into a new environment on a fresh runner of its platform, and the
187
+ # self-check plays every case on the CPU against the expected digests from outside the source
188
+ # tree. The runners have no GPU; the CUDA library is checked on a GPU of its own.
189
+ test:
190
+ name: test ${{ matrix.name }}
191
+ needs: wheel
192
+ # Each platform's test needs only its own wheel, so one failed build stops no other test.
193
+ if: ${{ !cancelled() }}
194
+ runs-on: ${{ matrix.runner }}
195
+ strategy:
196
+ fail-fast: false
197
+ matrix:
198
+ include:
199
+ - name: linux-x86-64
200
+ runner: ubuntu-24.04
201
+ torch: torch --index-url https://download.pytorch.org/whl/cpu
202
+ - name: linux-aarch64
203
+ runner: ubuntu-24.04-arm
204
+ torch: torch --index-url https://download.pytorch.org/whl/cpu
205
+ - name: windows-x86-64
206
+ runner: windows-2025
207
+ torch: torch --index-url https://download.pytorch.org/whl/cpu
208
+ - name: macos-arm64
209
+ runner: macos-15
210
+ torch: torch
211
+ # PyTorch's last x86-64 macOS wheel is 2.2.2, built against numpy 1.
212
+ - name: macos-x86-64
213
+ runner: macos-15-intel
214
+ torch: torch==2.2.2 'numpy<2'
215
+ defaults:
216
+ run:
217
+ shell: bash
218
+ env:
219
+ PIP_DISABLE_PIP_VERSION_CHECK: '1'
220
+ steps:
221
+ - uses: actions/checkout@v7
222
+ - uses: actions/setup-python@v7
223
+ with:
224
+ python-version: '3.12'
225
+ - uses: actions/download-artifact@v8
226
+ with:
227
+ name: wheel-${{ matrix.name }}
228
+ path: wheelhouse
229
+ - name: Make a new environment
230
+ run: |
231
+ python -m venv "$RUNNER_TEMP/venv"
232
+ if [ "$RUNNER_OS" = Windows ]; then
233
+ echo "VENV_PYTHON=$RUNNER_TEMP/venv/Scripts/python.exe" >> "$GITHUB_ENV"
234
+ else
235
+ echo "VENV_PYTHON=$RUNNER_TEMP/venv/bin/python" >> "$GITHUB_ENV"
236
+ fi
237
+ - name: Install PyTorch for the CPU
238
+ run: '"$VENV_PYTHON" -m pip install ${{ matrix.torch }}'
239
+ - name: Install the wheel
240
+ run: |
241
+ wheel=$(ls wheelhouse/cuju-*.whl)
242
+ echo "WHEEL=$wheel" >> "$GITHUB_ENV"
243
+ "$VENV_PYTHON" -m pip install "$wheel"
244
+ "$VENV_PYTHON" -m pip list
245
+ - name: cuju.check on the CPU
246
+ working-directory: ${{ runner.temp }}
247
+ run: '"$VENV_PYTHON" -I -m cuju.check --device cpu 2>&1 | tee check.log'
248
+ # The tests take the extras.
249
+ - name: The public tests
250
+ working-directory: ${{ runner.temp }}
251
+ run: |
252
+ "$VENV_PYTHON" -m pip install "$GITHUB_WORKSPACE/$WHEEL[test,spaces]"
253
+ "$VENV_PYTHON" -m pytest -ra -p no:cacheprovider "$GITHUB_WORKSPACE/tests"
254
+ - uses: actions/upload-artifact@v7
255
+ if: always()
256
+ with:
257
+ name: check-${{ matrix.name }}
258
+ path: ${{ runner.temp }}/check.log
259
+ if-no-files-found: ignore
260
+
261
+ # An SPDX document per wheel and per sdist. syft reads the package's metadata; the code that the
262
+ # libraries compile in or link statically (see NOTICE, and the CUDA runtime) has no metadata it
263
+ # can read.
264
+ sbom:
265
+ needs: [sdist, wheel]
266
+ runs-on: ubuntu-24.04
267
+ steps:
268
+ - uses: actions/download-artifact@v8
269
+ with:
270
+ path: dist
271
+ pattern: '{sdist,wheel-*}'
272
+ merge-multiple: true
273
+ - uses: anchore/sbom-action/download-syft@v0
274
+ id: syft
275
+ - name: Write the SBOM of each wheel and sdist
276
+ run: |
277
+ mkdir -p sbom unpacked
278
+ for file in dist/*.whl dist/*.tar.gz; do
279
+ name=$(basename "$file" .whl)
280
+ name=${name%.tar.gz}
281
+ version=$(echo "$name" | cut -d- -f2)
282
+ mkdir -p "unpacked/$name"
283
+ case $file in
284
+ *.whl) unzip -q "$file" -d "unpacked/$name" ;;
285
+ *) tar -xzf "$file" -C "unpacked/$name" ;;
286
+ esac
287
+ "${{ steps.syft.outputs.cmd }}" scan "dir:unpacked/$name" \
288
+ --source-name "${name%%-*}" --source-version "$version" \
289
+ -o "spdx-json=sbom/$name.spdx.json"
290
+ done
291
+ ls -l sbom
292
+ - uses: actions/upload-artifact@v7
293
+ with:
294
+ name: sbom
295
+ path: sbom/*.spdx.json
296
+
297
+ # Only the sdist and the wheels of `cuju` are published; the SBOMs stay workflow artifacts.
298
+ publish:
299
+ needs: [sdist, wheel, test, sbom]
300
+ if: github.event_name == 'workflow_dispatch' && inputs.publish
301
+ runs-on: ubuntu-24.04
302
+ # The environment requires a maintainer's approval before anything is published.
303
+ environment: pypi
304
+ permissions:
305
+ id-token: write
306
+ steps:
307
+ - uses: actions/download-artifact@v8
308
+ with:
309
+ path: dist
310
+ pattern: '{sdist,wheel-*}'
311
+ merge-multiple: true
312
+ - uses: pypa/gh-action-pypi-publish@release/v1
cuju-0.1.0/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ build/
2
+ dist/
3
+ wheelhouse/
4
+ *.egg-info/
5
+ __pycache__/
6
+ .venv/
7
+ *.so