warp-lang 0.9.0__py3-none-win_amd64.whl → 0.11.0__py3-none-win_amd64.whl

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.

Potentially problematic release.


This version of warp-lang might be problematic. Click here for more details.

Files changed (315) hide show
  1. warp/__init__.py +15 -7
  2. warp/__init__.pyi +1 -0
  3. warp/bin/warp-clang.dll +0 -0
  4. warp/bin/warp.dll +0 -0
  5. warp/build.py +22 -443
  6. warp/build_dll.py +384 -0
  7. warp/builtins.py +998 -488
  8. warp/codegen.py +1307 -739
  9. warp/config.py +5 -3
  10. warp/constants.py +6 -0
  11. warp/context.py +1291 -548
  12. warp/dlpack.py +31 -31
  13. warp/fabric.py +326 -0
  14. warp/fem/__init__.py +27 -0
  15. warp/fem/cache.py +389 -0
  16. warp/fem/dirichlet.py +181 -0
  17. warp/fem/domain.py +263 -0
  18. warp/fem/field/__init__.py +101 -0
  19. warp/fem/field/field.py +149 -0
  20. warp/fem/field/nodal_field.py +299 -0
  21. warp/fem/field/restriction.py +21 -0
  22. warp/fem/field/test.py +181 -0
  23. warp/fem/field/trial.py +183 -0
  24. warp/fem/geometry/__init__.py +19 -0
  25. warp/fem/geometry/closest_point.py +70 -0
  26. warp/fem/geometry/deformed_geometry.py +271 -0
  27. warp/fem/geometry/element.py +744 -0
  28. warp/fem/geometry/geometry.py +186 -0
  29. warp/fem/geometry/grid_2d.py +373 -0
  30. warp/fem/geometry/grid_3d.py +435 -0
  31. warp/fem/geometry/hexmesh.py +953 -0
  32. warp/fem/geometry/partition.py +376 -0
  33. warp/fem/geometry/quadmesh_2d.py +532 -0
  34. warp/fem/geometry/tetmesh.py +840 -0
  35. warp/fem/geometry/trimesh_2d.py +577 -0
  36. warp/fem/integrate.py +1616 -0
  37. warp/fem/operator.py +191 -0
  38. warp/fem/polynomial.py +213 -0
  39. warp/fem/quadrature/__init__.py +2 -0
  40. warp/fem/quadrature/pic_quadrature.py +245 -0
  41. warp/fem/quadrature/quadrature.py +294 -0
  42. warp/fem/space/__init__.py +292 -0
  43. warp/fem/space/basis_space.py +489 -0
  44. warp/fem/space/collocated_function_space.py +105 -0
  45. warp/fem/space/dof_mapper.py +236 -0
  46. warp/fem/space/function_space.py +145 -0
  47. warp/fem/space/grid_2d_function_space.py +267 -0
  48. warp/fem/space/grid_3d_function_space.py +306 -0
  49. warp/fem/space/hexmesh_function_space.py +352 -0
  50. warp/fem/space/partition.py +350 -0
  51. warp/fem/space/quadmesh_2d_function_space.py +369 -0
  52. warp/fem/space/restriction.py +160 -0
  53. warp/fem/space/shape/__init__.py +15 -0
  54. warp/fem/space/shape/cube_shape_function.py +738 -0
  55. warp/fem/space/shape/shape_function.py +103 -0
  56. warp/fem/space/shape/square_shape_function.py +611 -0
  57. warp/fem/space/shape/tet_shape_function.py +567 -0
  58. warp/fem/space/shape/triangle_shape_function.py +429 -0
  59. warp/fem/space/tetmesh_function_space.py +292 -0
  60. warp/fem/space/topology.py +295 -0
  61. warp/fem/space/trimesh_2d_function_space.py +221 -0
  62. warp/fem/types.py +77 -0
  63. warp/fem/utils.py +495 -0
  64. warp/native/array.h +164 -55
  65. warp/native/builtin.h +150 -174
  66. warp/native/bvh.cpp +75 -328
  67. warp/native/bvh.cu +406 -23
  68. warp/native/bvh.h +37 -45
  69. warp/native/clang/clang.cpp +136 -24
  70. warp/native/crt.cpp +1 -76
  71. warp/native/crt.h +111 -104
  72. warp/native/cuda_crt.h +1049 -0
  73. warp/native/cuda_util.cpp +15 -3
  74. warp/native/cuda_util.h +3 -1
  75. warp/native/cutlass/tools/library/scripts/conv2d_operation.py +463 -0
  76. warp/native/cutlass/tools/library/scripts/conv3d_operation.py +321 -0
  77. warp/native/cutlass/tools/library/scripts/gemm_operation.py +988 -0
  78. warp/native/cutlass/tools/library/scripts/generator.py +4625 -0
  79. warp/native/cutlass/tools/library/scripts/library.py +799 -0
  80. warp/native/cutlass/tools/library/scripts/manifest.py +402 -0
  81. warp/native/cutlass/tools/library/scripts/pycutlass/docs/source/conf.py +96 -0
  82. warp/native/cutlass/tools/library/scripts/pycutlass/profile/conv/conv2d_f16_sm80.py +106 -0
  83. warp/native/cutlass/tools/library/scripts/pycutlass/profile/gemm/gemm_f32_sm80.py +91 -0
  84. warp/native/cutlass/tools/library/scripts/pycutlass/setup.py +80 -0
  85. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/__init__.py +48 -0
  86. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/arguments.py +118 -0
  87. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/c_types.py +241 -0
  88. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/compiler.py +432 -0
  89. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/conv2d_operation.py +631 -0
  90. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/epilogue.py +1026 -0
  91. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/frontend.py +104 -0
  92. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/gemm_operation.py +1276 -0
  93. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/library.py +744 -0
  94. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/memory_manager.py +74 -0
  95. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/operation.py +110 -0
  96. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/parser.py +619 -0
  97. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/reduction_operation.py +398 -0
  98. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/tensor_ref.py +70 -0
  99. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/__init__.py +4 -0
  100. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/conv2d_testbed.py +646 -0
  101. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_grouped_testbed.py +235 -0
  102. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/gemm_testbed.py +557 -0
  103. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/test/profiler.py +70 -0
  104. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/type_hint.py +39 -0
  105. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/__init__.py +1 -0
  106. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/device.py +76 -0
  107. warp/native/cutlass/tools/library/scripts/pycutlass/src/pycutlass/utils/reference_model.py +255 -0
  108. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/__init__.py +0 -0
  109. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +201 -0
  110. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +177 -0
  111. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +98 -0
  112. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_dgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +95 -0
  113. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_few_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +163 -0
  114. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_fixed_channels_f16nhwc_f16nhwc_f16nhwc_tensor_op_f32_sm80.py +187 -0
  115. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +309 -0
  116. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +54 -0
  117. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  118. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_fprop_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  119. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_strided_dgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +253 -0
  120. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f16nhwc_tensor_op_f16_sm80.py +97 -0
  121. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f16nhwc_f16nhwc_f32nhwc_tensor_op_f32_sm80.py +242 -0
  122. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_f32nhwc_f32nhwc_f32nhwc_simt_f32_sm80.py +96 -0
  123. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/conv2d_wgrad_implicit_gemm_tf32nhwc_tf32nhwc_f32nhwc_tensor_op_f32_sm80.py +107 -0
  124. warp/native/cutlass/tools/library/scripts/pycutlass/test/conv/run_all_tests.py +10 -0
  125. warp/native/cutlass/tools/library/scripts/pycutlass/test/frontend/test_frontend.py +146 -0
  126. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/__init__.py +0 -0
  127. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_bf16_sm80.py +96 -0
  128. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f16_sm80.py +447 -0
  129. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f32_sm80.py +146 -0
  130. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_f64_sm80.py +102 -0
  131. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_grouped_sm80.py +203 -0
  132. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/gemm_s8_sm80.py +229 -0
  133. warp/native/cutlass/tools/library/scripts/pycutlass/test/gemm/run_all_tests.py +9 -0
  134. warp/native/cutlass/tools/library/scripts/pycutlass/test/unit/test_sm80.py +453 -0
  135. warp/native/cutlass/tools/library/scripts/rank_2k_operation.py +398 -0
  136. warp/native/cutlass/tools/library/scripts/rank_k_operation.py +387 -0
  137. warp/native/cutlass/tools/library/scripts/rt.py +796 -0
  138. warp/native/cutlass/tools/library/scripts/symm_operation.py +400 -0
  139. warp/native/cutlass/tools/library/scripts/trmm_operation.py +407 -0
  140. warp/native/cutlass_gemm.cu +5 -3
  141. warp/native/exports.h +1240 -949
  142. warp/native/fabric.h +228 -0
  143. warp/native/hashgrid.cpp +4 -4
  144. warp/native/hashgrid.h +22 -2
  145. warp/native/initializer_array.h +2 -2
  146. warp/native/intersect.h +22 -7
  147. warp/native/intersect_adj.h +8 -8
  148. warp/native/intersect_tri.h +13 -16
  149. warp/native/marching.cu +157 -161
  150. warp/native/mat.h +119 -19
  151. warp/native/matnn.h +2 -2
  152. warp/native/mesh.cpp +108 -83
  153. warp/native/mesh.cu +243 -6
  154. warp/native/mesh.h +1547 -458
  155. warp/native/nanovdb/NanoVDB.h +1 -1
  156. warp/native/noise.h +272 -329
  157. warp/native/quat.h +51 -8
  158. warp/native/rand.h +45 -35
  159. warp/native/range.h +6 -2
  160. warp/native/reduce.cpp +157 -0
  161. warp/native/reduce.cu +348 -0
  162. warp/native/runlength_encode.cpp +62 -0
  163. warp/native/runlength_encode.cu +46 -0
  164. warp/native/scan.cu +11 -13
  165. warp/native/scan.h +1 -0
  166. warp/native/solid_angle.h +442 -0
  167. warp/native/sort.cpp +13 -0
  168. warp/native/sort.cu +9 -1
  169. warp/native/sparse.cpp +338 -0
  170. warp/native/sparse.cu +545 -0
  171. warp/native/spatial.h +2 -2
  172. warp/native/temp_buffer.h +30 -0
  173. warp/native/vec.h +126 -24
  174. warp/native/volume.h +120 -0
  175. warp/native/warp.cpp +658 -53
  176. warp/native/warp.cu +660 -68
  177. warp/native/warp.h +112 -12
  178. warp/optim/__init__.py +1 -0
  179. warp/optim/linear.py +922 -0
  180. warp/optim/sgd.py +92 -0
  181. warp/render/render_opengl.py +392 -152
  182. warp/render/render_usd.py +11 -11
  183. warp/sim/__init__.py +2 -2
  184. warp/sim/articulation.py +385 -185
  185. warp/sim/collide.py +21 -8
  186. warp/sim/import_mjcf.py +297 -106
  187. warp/sim/import_urdf.py +389 -210
  188. warp/sim/import_usd.py +198 -97
  189. warp/sim/inertia.py +17 -18
  190. warp/sim/integrator_euler.py +14 -8
  191. warp/sim/integrator_xpbd.py +161 -19
  192. warp/sim/model.py +795 -291
  193. warp/sim/optimizer.py +2 -6
  194. warp/sim/render.py +65 -3
  195. warp/sim/utils.py +3 -0
  196. warp/sparse.py +1227 -0
  197. warp/stubs.py +665 -223
  198. warp/tape.py +66 -15
  199. warp/tests/__main__.py +3 -6
  200. warp/tests/assets/curlnoise_golden.npy +0 -0
  201. warp/tests/assets/pnoise_golden.npy +0 -0
  202. warp/tests/assets/torus.usda +105 -105
  203. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  204. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  205. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  206. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  207. warp/tests/aux_test_unresolved_func.py +14 -0
  208. warp/tests/aux_test_unresolved_symbol.py +14 -0
  209. warp/tests/disabled_kinematics.py +239 -0
  210. warp/tests/run_coverage_serial.py +31 -0
  211. warp/tests/test_adam.py +103 -106
  212. warp/tests/test_arithmetic.py +128 -74
  213. warp/tests/test_array.py +1497 -211
  214. warp/tests/test_array_reduce.py +150 -0
  215. warp/tests/test_atomic.py +64 -28
  216. warp/tests/test_bool.py +99 -0
  217. warp/tests/test_builtins_resolution.py +1292 -0
  218. warp/tests/test_bvh.py +75 -43
  219. warp/tests/test_closest_point_edge_edge.py +54 -57
  220. warp/tests/test_codegen.py +233 -128
  221. warp/tests/test_compile_consts.py +28 -20
  222. warp/tests/test_conditional.py +108 -24
  223. warp/tests/test_copy.py +10 -12
  224. warp/tests/test_ctypes.py +112 -88
  225. warp/tests/test_dense.py +21 -14
  226. warp/tests/test_devices.py +98 -0
  227. warp/tests/test_dlpack.py +136 -108
  228. warp/tests/test_examples.py +277 -0
  229. warp/tests/test_fabricarray.py +955 -0
  230. warp/tests/test_fast_math.py +15 -11
  231. warp/tests/test_fem.py +1271 -0
  232. warp/tests/test_fp16.py +53 -19
  233. warp/tests/test_func.py +187 -74
  234. warp/tests/test_generics.py +194 -49
  235. warp/tests/test_grad.py +180 -116
  236. warp/tests/test_grad_customs.py +176 -0
  237. warp/tests/test_hash_grid.py +52 -37
  238. warp/tests/test_import.py +10 -23
  239. warp/tests/test_indexedarray.py +577 -24
  240. warp/tests/test_intersect.py +18 -9
  241. warp/tests/test_large.py +141 -0
  242. warp/tests/test_launch.py +251 -15
  243. warp/tests/test_lerp.py +64 -65
  244. warp/tests/test_linear_solvers.py +154 -0
  245. warp/tests/test_lvalue.py +493 -0
  246. warp/tests/test_marching_cubes.py +12 -13
  247. warp/tests/test_mat.py +508 -2778
  248. warp/tests/test_mat_lite.py +115 -0
  249. warp/tests/test_mat_scalar_ops.py +2889 -0
  250. warp/tests/test_math.py +103 -9
  251. warp/tests/test_matmul.py +305 -69
  252. warp/tests/test_matmul_lite.py +410 -0
  253. warp/tests/test_mesh.py +71 -14
  254. warp/tests/test_mesh_query_aabb.py +41 -25
  255. warp/tests/test_mesh_query_point.py +325 -34
  256. warp/tests/test_mesh_query_ray.py +39 -22
  257. warp/tests/test_mlp.py +30 -22
  258. warp/tests/test_model.py +92 -89
  259. warp/tests/test_modules_lite.py +39 -0
  260. warp/tests/test_multigpu.py +88 -114
  261. warp/tests/test_noise.py +12 -11
  262. warp/tests/test_operators.py +16 -20
  263. warp/tests/test_options.py +11 -11
  264. warp/tests/test_pinned.py +17 -18
  265. warp/tests/test_print.py +32 -11
  266. warp/tests/test_quat.py +275 -129
  267. warp/tests/test_rand.py +18 -16
  268. warp/tests/test_reload.py +38 -34
  269. warp/tests/test_rounding.py +50 -43
  270. warp/tests/test_runlength_encode.py +190 -0
  271. warp/tests/test_smoothstep.py +9 -11
  272. warp/tests/test_snippet.py +143 -0
  273. warp/tests/test_sparse.py +460 -0
  274. warp/tests/test_spatial.py +276 -243
  275. warp/tests/test_streams.py +110 -85
  276. warp/tests/test_struct.py +331 -85
  277. warp/tests/test_tape.py +39 -21
  278. warp/tests/test_torch.py +118 -89
  279. warp/tests/test_transient_module.py +12 -13
  280. warp/tests/test_types.py +614 -0
  281. warp/tests/test_utils.py +494 -0
  282. warp/tests/test_vec.py +354 -1987
  283. warp/tests/test_vec_lite.py +73 -0
  284. warp/tests/test_vec_scalar_ops.py +2099 -0
  285. warp/tests/test_volume.py +457 -293
  286. warp/tests/test_volume_write.py +124 -134
  287. warp/tests/unittest_serial.py +35 -0
  288. warp/tests/unittest_suites.py +341 -0
  289. warp/tests/unittest_utils.py +568 -0
  290. warp/tests/unused_test_misc.py +71 -0
  291. warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
  292. warp/thirdparty/appdirs.py +36 -45
  293. warp/thirdparty/unittest_parallel.py +549 -0
  294. warp/torch.py +72 -30
  295. warp/types.py +1744 -713
  296. warp/utils.py +360 -350
  297. warp_lang-0.11.0.dist-info/LICENSE.md +36 -0
  298. warp_lang-0.11.0.dist-info/METADATA +238 -0
  299. warp_lang-0.11.0.dist-info/RECORD +332 -0
  300. {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/WHEEL +1 -1
  301. warp/bin/warp-clang.exp +0 -0
  302. warp/bin/warp-clang.lib +0 -0
  303. warp/bin/warp.exp +0 -0
  304. warp/bin/warp.lib +0 -0
  305. warp/tests/test_all.py +0 -215
  306. warp/tests/test_array_scan.py +0 -60
  307. warp/tests/test_base.py +0 -208
  308. warp/tests/test_unresolved_func.py +0 -7
  309. warp/tests/test_unresolved_symbol.py +0 -7
  310. warp_lang-0.9.0.dist-info/METADATA +0 -20
  311. warp_lang-0.9.0.dist-info/RECORD +0 -177
  312. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  313. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  314. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  315. {warp_lang-0.9.0.dist-info → warp_lang-0.11.0.dist-info}/top_level.txt +0 -0
warp/tests/test_array.py CHANGED
@@ -5,14 +5,12 @@
5
5
  # distribution of this software and related documentation without an express
6
6
  # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
7
 
8
- # include parent path
8
+ import unittest
9
+
9
10
  import numpy as np
10
- import math
11
11
 
12
12
  import warp as wp
13
- from warp.tests.test_base import *
14
-
15
- import unittest
13
+ from warp.tests.unittest_utils import *
16
14
 
17
15
  wp.init()
18
16
 
@@ -313,6 +311,12 @@ def test_reshape(test, device):
313
311
  assert_array_equal(grad, ones)
314
312
  test.assertEqual(loss.numpy()[0], 15)
315
313
 
314
+ np_arr = np.arange(6, dtype=float)
315
+ arr = wp.array(np_arr, dtype=float, device=device)
316
+ arr_infer = arr.reshape((-1, 3))
317
+ arr_comp = wp.array(np_arr.reshape((-1, 3)), dtype=float, device=device)
318
+ assert_array_equal(arr_infer, arr_comp)
319
+
316
320
 
317
321
  @wp.kernel
318
322
  def compare_stepped_window_a(x: wp.array2d(dtype=float)):
@@ -391,7 +395,7 @@ def test_slicing(test, device):
391
395
  assert_array_equal(wp_arr[:5], wp.array(np_arr[:5], dtype=int, device=device))
392
396
  assert_array_equal(wp_arr[1:5], wp.array(np_arr[1:5], dtype=int, device=device))
393
397
  assert_array_equal(wp_arr[-9:-5:1], wp.array(np_arr[-9:-5:1], dtype=int, device=device))
394
- assert_array_equal(wp_arr[:5,], wp.array(np_arr[:5], dtype=int, device=device))
398
+ assert_array_equal(wp_arr[:5,], wp.array(np_arr[:5], dtype=int, device=device)) # noqa: E231
395
399
 
396
400
 
397
401
  def test_view(test, device):
@@ -469,205 +473,1280 @@ def test_transpose(test, device):
469
473
  assert np.array_equal(np_arr.transpose(), arr.transpose().numpy())
470
474
 
471
475
 
472
- def test_fill_zero(test, device):
476
+ def test_fill_scalar(test, device):
473
477
  dim_x = 4
474
478
 
475
- # test zeroing:
476
479
  for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
477
480
  a1 = wp.zeros(dim_x, dtype=wptype, device=device)
478
481
  a2 = wp.zeros((dim_x, dim_x), dtype=wptype, device=device)
479
482
  a3 = wp.zeros((dim_x, dim_x, dim_x), dtype=wptype, device=device)
480
483
  a4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=wptype, device=device)
481
484
 
482
- a1.fill_(127)
483
- a2.fill_(127)
484
- a3.fill_(127)
485
- a4.fill_(127)
485
+ assert_np_equal(a1.numpy(), np.zeros(a1.shape, dtype=nptype))
486
+ assert_np_equal(a2.numpy(), np.zeros(a2.shape, dtype=nptype))
487
+ assert_np_equal(a3.numpy(), np.zeros(a3.shape, dtype=nptype))
488
+ assert_np_equal(a4.numpy(), np.zeros(a4.shape, dtype=nptype))
489
+
490
+ # fill with int value
491
+ fill_value = 42
492
+
493
+ a1.fill_(fill_value)
494
+ a2.fill_(fill_value)
495
+ a3.fill_(fill_value)
496
+ a4.fill_(fill_value)
497
+
498
+ assert_np_equal(a1.numpy(), np.full(a1.shape, fill_value, dtype=nptype))
499
+ assert_np_equal(a2.numpy(), np.full(a2.shape, fill_value, dtype=nptype))
500
+ assert_np_equal(a3.numpy(), np.full(a3.shape, fill_value, dtype=nptype))
501
+ assert_np_equal(a4.numpy(), np.full(a4.shape, fill_value, dtype=nptype))
486
502
 
487
503
  a1.zero_()
488
504
  a2.zero_()
489
505
  a3.zero_()
490
506
  a4.zero_()
491
507
 
492
- assert_np_equal(a1.numpy(), np.zeros_like(a1.numpy()))
493
- assert_np_equal(a2.numpy(), np.zeros_like(a2.numpy()))
494
- assert_np_equal(a3.numpy(), np.zeros_like(a3.numpy()))
495
- assert_np_equal(a4.numpy(), np.zeros_like(a4.numpy()))
496
-
497
- # test some vector types too:
498
- v1 = wp.zeros(dim_x, dtype=wp.types.vector(3, wptype), device=device)
499
- v2 = wp.zeros((dim_x, dim_x), dtype=wp.types.vector(3, wptype), device=device)
500
- v3 = wp.zeros((dim_x, dim_x, dim_x), dtype=wp.types.vector(3, wptype), device=device)
501
- v4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=wp.types.vector(3, wptype), device=device)
502
-
503
- v1.fill_(127)
504
- v2.fill_(127)
505
- v3.fill_(127)
506
- v4.fill_(127)
507
-
508
- v1.zero_()
509
- v2.zero_()
510
- v3.zero_()
511
- v4.zero_()
512
-
513
- assert_np_equal(v1.numpy(), np.zeros_like(v1.numpy()))
514
- assert_np_equal(v2.numpy(), np.zeros_like(v2.numpy()))
515
- assert_np_equal(v3.numpy(), np.zeros_like(v3.numpy()))
516
- assert_np_equal(v4.numpy(), np.zeros_like(v4.numpy()))
517
-
518
- # test fill with scalar constant:
508
+ assert_np_equal(a1.numpy(), np.zeros(a1.shape, dtype=nptype))
509
+ assert_np_equal(a2.numpy(), np.zeros(a2.shape, dtype=nptype))
510
+ assert_np_equal(a3.numpy(), np.zeros(a3.shape, dtype=nptype))
511
+ assert_np_equal(a4.numpy(), np.zeros(a4.shape, dtype=nptype))
512
+
513
+ if wptype in wp.types.float_types:
514
+ # fill with float value
515
+ fill_value = 13.37
516
+
517
+ a1.fill_(fill_value)
518
+ a2.fill_(fill_value)
519
+ a3.fill_(fill_value)
520
+ a4.fill_(fill_value)
521
+
522
+ assert_np_equal(a1.numpy(), np.full(a1.shape, fill_value, dtype=nptype))
523
+ assert_np_equal(a2.numpy(), np.full(a2.shape, fill_value, dtype=nptype))
524
+ assert_np_equal(a3.numpy(), np.full(a3.shape, fill_value, dtype=nptype))
525
+ assert_np_equal(a4.numpy(), np.full(a4.shape, fill_value, dtype=nptype))
526
+
527
+ # fill with Warp scalar value
528
+ fill_value = wptype(17)
529
+
530
+ a1.fill_(fill_value)
531
+ a2.fill_(fill_value)
532
+ a3.fill_(fill_value)
533
+ a4.fill_(fill_value)
534
+
535
+ assert_np_equal(a1.numpy(), np.full(a1.shape, fill_value.value, dtype=nptype))
536
+ assert_np_equal(a2.numpy(), np.full(a2.shape, fill_value.value, dtype=nptype))
537
+ assert_np_equal(a3.numpy(), np.full(a3.shape, fill_value.value, dtype=nptype))
538
+ assert_np_equal(a4.numpy(), np.full(a4.shape, fill_value.value, dtype=nptype))
539
+
540
+
541
+ def test_fill_vector(test, device):
542
+ # test filling a vector array with scalar or vector values (vec_type, list, or numpy array)
543
+
544
+ dim_x = 4
545
+
546
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
547
+ # vector types
548
+ vector_types = [
549
+ wp.types.vector(2, wptype),
550
+ wp.types.vector(3, wptype),
551
+ wp.types.vector(4, wptype),
552
+ wp.types.vector(5, wptype),
553
+ ]
554
+
555
+ for vec_type in vector_types:
556
+ vec_len = vec_type._length_
557
+
558
+ a1 = wp.zeros(dim_x, dtype=vec_type, device=device)
559
+ a2 = wp.zeros((dim_x, dim_x), dtype=vec_type, device=device)
560
+ a3 = wp.zeros((dim_x, dim_x, dim_x), dtype=vec_type, device=device)
561
+ a4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=vec_type, device=device)
562
+
563
+ assert_np_equal(a1.numpy(), np.zeros((*a1.shape, vec_len), dtype=nptype))
564
+ assert_np_equal(a2.numpy(), np.zeros((*a2.shape, vec_len), dtype=nptype))
565
+ assert_np_equal(a3.numpy(), np.zeros((*a3.shape, vec_len), dtype=nptype))
566
+ assert_np_equal(a4.numpy(), np.zeros((*a4.shape, vec_len), dtype=nptype))
567
+
568
+ # fill with int scalar
569
+ fill_value = 42
570
+
571
+ a1.fill_(fill_value)
572
+ a2.fill_(fill_value)
573
+ a3.fill_(fill_value)
574
+ a4.fill_(fill_value)
575
+
576
+ assert_np_equal(a1.numpy(), np.full((*a1.shape, vec_len), fill_value, dtype=nptype))
577
+ assert_np_equal(a2.numpy(), np.full((*a2.shape, vec_len), fill_value, dtype=nptype))
578
+ assert_np_equal(a3.numpy(), np.full((*a3.shape, vec_len), fill_value, dtype=nptype))
579
+ assert_np_equal(a4.numpy(), np.full((*a4.shape, vec_len), fill_value, dtype=nptype))
580
+
581
+ # test zeroing
582
+ a1.zero_()
583
+ a2.zero_()
584
+ a3.zero_()
585
+ a4.zero_()
586
+
587
+ assert_np_equal(a1.numpy(), np.zeros((*a1.shape, vec_len), dtype=nptype))
588
+ assert_np_equal(a2.numpy(), np.zeros((*a2.shape, vec_len), dtype=nptype))
589
+ assert_np_equal(a3.numpy(), np.zeros((*a3.shape, vec_len), dtype=nptype))
590
+ assert_np_equal(a4.numpy(), np.zeros((*a4.shape, vec_len), dtype=nptype))
591
+
592
+ # vector values can be passed as a list, numpy array, or Warp vector instance
593
+ fill_list = [17, 42, 99, 101, 127][:vec_len]
594
+ fill_arr = np.array(fill_list, dtype=nptype)
595
+ fill_vec = vec_type(fill_list)
596
+
597
+ expected1 = np.tile(fill_arr, a1.size).reshape((*a1.shape, vec_len))
598
+ expected2 = np.tile(fill_arr, a2.size).reshape((*a2.shape, vec_len))
599
+ expected3 = np.tile(fill_arr, a3.size).reshape((*a3.shape, vec_len))
600
+ expected4 = np.tile(fill_arr, a4.size).reshape((*a4.shape, vec_len))
601
+
602
+ # fill with list of vector length
603
+ a1.fill_(fill_list)
604
+ a2.fill_(fill_list)
605
+ a3.fill_(fill_list)
606
+ a4.fill_(fill_list)
607
+
608
+ assert_np_equal(a1.numpy(), expected1)
609
+ assert_np_equal(a2.numpy(), expected2)
610
+ assert_np_equal(a3.numpy(), expected3)
611
+ assert_np_equal(a4.numpy(), expected4)
612
+
613
+ # clear
614
+ a1.zero_()
615
+ a2.zero_()
616
+ a3.zero_()
617
+ a4.zero_()
618
+
619
+ # fill with numpy array of vector length
620
+ a1.fill_(fill_arr)
621
+ a2.fill_(fill_arr)
622
+ a3.fill_(fill_arr)
623
+ a4.fill_(fill_arr)
624
+
625
+ assert_np_equal(a1.numpy(), expected1)
626
+ assert_np_equal(a2.numpy(), expected2)
627
+ assert_np_equal(a3.numpy(), expected3)
628
+ assert_np_equal(a4.numpy(), expected4)
629
+
630
+ # clear
631
+ a1.zero_()
632
+ a2.zero_()
633
+ a3.zero_()
634
+ a4.zero_()
635
+
636
+ # fill with vec instance
637
+ a1.fill_(fill_vec)
638
+ a2.fill_(fill_vec)
639
+ a3.fill_(fill_vec)
640
+ a4.fill_(fill_vec)
641
+
642
+ assert_np_equal(a1.numpy(), expected1)
643
+ assert_np_equal(a2.numpy(), expected2)
644
+ assert_np_equal(a3.numpy(), expected3)
645
+ assert_np_equal(a4.numpy(), expected4)
646
+
647
+ if wptype in wp.types.float_types:
648
+ # fill with float scalar
649
+ fill_value = 13.37
650
+
651
+ a1.fill_(fill_value)
652
+ a2.fill_(fill_value)
653
+ a3.fill_(fill_value)
654
+ a4.fill_(fill_value)
655
+
656
+ assert_np_equal(a1.numpy(), np.full((*a1.shape, vec_len), fill_value, dtype=nptype))
657
+ assert_np_equal(a2.numpy(), np.full((*a2.shape, vec_len), fill_value, dtype=nptype))
658
+ assert_np_equal(a3.numpy(), np.full((*a3.shape, vec_len), fill_value, dtype=nptype))
659
+ assert_np_equal(a4.numpy(), np.full((*a4.shape, vec_len), fill_value, dtype=nptype))
660
+
661
+ # fill with float list of vector length
662
+ fill_list = [-2.5, -1.25, 1.25, 2.5, 5.0][:vec_len]
663
+
664
+ a1.fill_(fill_list)
665
+ a2.fill_(fill_list)
666
+ a3.fill_(fill_list)
667
+ a4.fill_(fill_list)
668
+
669
+ expected1 = np.tile(np.array(fill_list, dtype=nptype), a1.size).reshape((*a1.shape, vec_len))
670
+ expected2 = np.tile(np.array(fill_list, dtype=nptype), a2.size).reshape((*a2.shape, vec_len))
671
+ expected3 = np.tile(np.array(fill_list, dtype=nptype), a3.size).reshape((*a3.shape, vec_len))
672
+ expected4 = np.tile(np.array(fill_list, dtype=nptype), a4.size).reshape((*a4.shape, vec_len))
673
+
674
+ assert_np_equal(a1.numpy(), expected1)
675
+ assert_np_equal(a2.numpy(), expected2)
676
+ assert_np_equal(a3.numpy(), expected3)
677
+ assert_np_equal(a4.numpy(), expected4)
678
+
679
+
680
+ def test_fill_matrix(test, device):
681
+ # test filling a matrix array with scalar or matrix values (mat_type, nested list, or 2d numpy array)
682
+
683
+ dim_x = 4
684
+
685
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
686
+ # matrix types
687
+ matrix_types = [
688
+ # square matrices
689
+ wp.types.matrix((2, 2), wptype),
690
+ wp.types.matrix((3, 3), wptype),
691
+ wp.types.matrix((4, 4), wptype),
692
+ wp.types.matrix((5, 5), wptype),
693
+ # non-square matrices
694
+ wp.types.matrix((2, 3), wptype),
695
+ wp.types.matrix((3, 2), wptype),
696
+ wp.types.matrix((3, 4), wptype),
697
+ wp.types.matrix((4, 3), wptype),
698
+ ]
699
+
700
+ for mat_type in matrix_types:
701
+ mat_len = mat_type._length_
702
+ mat_shape = mat_type._shape_
703
+
704
+ a1 = wp.zeros(dim_x, dtype=mat_type, device=device)
705
+ a2 = wp.zeros((dim_x, dim_x), dtype=mat_type, device=device)
706
+ a3 = wp.zeros((dim_x, dim_x, dim_x), dtype=mat_type, device=device)
707
+ a4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=mat_type, device=device)
708
+
709
+ assert_np_equal(a1.numpy(), np.zeros((*a1.shape, *mat_shape), dtype=nptype))
710
+ assert_np_equal(a2.numpy(), np.zeros((*a2.shape, *mat_shape), dtype=nptype))
711
+ assert_np_equal(a3.numpy(), np.zeros((*a3.shape, *mat_shape), dtype=nptype))
712
+ assert_np_equal(a4.numpy(), np.zeros((*a4.shape, *mat_shape), dtype=nptype))
713
+
714
+ # fill with scalar
715
+ fill_value = 42
716
+
717
+ a1.fill_(fill_value)
718
+ a2.fill_(fill_value)
719
+ a3.fill_(fill_value)
720
+ a4.fill_(fill_value)
721
+
722
+ assert_np_equal(a1.numpy(), np.full((*a1.shape, *mat_shape), fill_value, dtype=nptype))
723
+ assert_np_equal(a2.numpy(), np.full((*a2.shape, *mat_shape), fill_value, dtype=nptype))
724
+ assert_np_equal(a3.numpy(), np.full((*a3.shape, *mat_shape), fill_value, dtype=nptype))
725
+ assert_np_equal(a4.numpy(), np.full((*a4.shape, *mat_shape), fill_value, dtype=nptype))
726
+
727
+ # test zeroing
728
+ a1.zero_()
729
+ a2.zero_()
730
+ a3.zero_()
731
+ a4.zero_()
732
+
733
+ assert_np_equal(a1.numpy(), np.zeros((*a1.shape, *mat_shape), dtype=nptype))
734
+ assert_np_equal(a2.numpy(), np.zeros((*a2.shape, *mat_shape), dtype=nptype))
735
+ assert_np_equal(a3.numpy(), np.zeros((*a3.shape, *mat_shape), dtype=nptype))
736
+ assert_np_equal(a4.numpy(), np.zeros((*a4.shape, *mat_shape), dtype=nptype))
737
+
738
+ # matrix values can be passed as a 1d numpy array, 2d numpy array, flat list, nested list, or Warp matrix instance
739
+ if wptype != wp.bool:
740
+ fill_arr1 = np.arange(mat_len, dtype=nptype)
741
+ else:
742
+ fill_arr1 = np.ones(mat_len, dtype=nptype)
743
+ fill_arr2 = fill_arr1.reshape(mat_shape)
744
+ fill_list1 = list(fill_arr1)
745
+ fill_list2 = [list(row) for row in fill_arr2]
746
+ fill_mat = mat_type(fill_arr1)
747
+
748
+ expected1 = np.tile(fill_arr1, a1.size).reshape((*a1.shape, *mat_shape))
749
+ expected2 = np.tile(fill_arr1, a2.size).reshape((*a2.shape, *mat_shape))
750
+ expected3 = np.tile(fill_arr1, a3.size).reshape((*a3.shape, *mat_shape))
751
+ expected4 = np.tile(fill_arr1, a4.size).reshape((*a4.shape, *mat_shape))
752
+
753
+ # fill with 1d numpy array
754
+ a1.fill_(fill_arr1)
755
+ a2.fill_(fill_arr1)
756
+ a3.fill_(fill_arr1)
757
+ a4.fill_(fill_arr1)
758
+
759
+ assert_np_equal(a1.numpy(), expected1)
760
+ assert_np_equal(a2.numpy(), expected2)
761
+ assert_np_equal(a3.numpy(), expected3)
762
+ assert_np_equal(a4.numpy(), expected4)
763
+
764
+ # clear
765
+ a1.zero_()
766
+ a2.zero_()
767
+ a3.zero_()
768
+ a4.zero_()
769
+
770
+ # fill with 2d numpy array
771
+ a1.fill_(fill_arr2)
772
+ a2.fill_(fill_arr2)
773
+ a3.fill_(fill_arr2)
774
+ a4.fill_(fill_arr2)
775
+
776
+ assert_np_equal(a1.numpy(), expected1)
777
+ assert_np_equal(a2.numpy(), expected2)
778
+ assert_np_equal(a3.numpy(), expected3)
779
+ assert_np_equal(a4.numpy(), expected4)
780
+
781
+ # clear
782
+ a1.zero_()
783
+ a2.zero_()
784
+ a3.zero_()
785
+ a4.zero_()
786
+
787
+ # fill with flat list
788
+ a1.fill_(fill_list1)
789
+ a2.fill_(fill_list1)
790
+ a3.fill_(fill_list1)
791
+ a4.fill_(fill_list1)
792
+
793
+ assert_np_equal(a1.numpy(), expected1)
794
+ assert_np_equal(a2.numpy(), expected2)
795
+ assert_np_equal(a3.numpy(), expected3)
796
+ assert_np_equal(a4.numpy(), expected4)
797
+
798
+ # clear
799
+ a1.zero_()
800
+ a2.zero_()
801
+ a3.zero_()
802
+ a4.zero_()
803
+
804
+ # fill with nested list
805
+ a1.fill_(fill_list2)
806
+ a2.fill_(fill_list2)
807
+ a3.fill_(fill_list2)
808
+ a4.fill_(fill_list2)
809
+
810
+ assert_np_equal(a1.numpy(), expected1)
811
+ assert_np_equal(a2.numpy(), expected2)
812
+ assert_np_equal(a3.numpy(), expected3)
813
+ assert_np_equal(a4.numpy(), expected4)
814
+
815
+ # clear
816
+ a1.zero_()
817
+ a2.zero_()
818
+ a3.zero_()
819
+ a4.zero_()
820
+
821
+ # fill with mat instance
822
+ a1.fill_(fill_mat)
823
+ a2.fill_(fill_mat)
824
+ a3.fill_(fill_mat)
825
+ a4.fill_(fill_mat)
826
+
827
+ assert_np_equal(a1.numpy(), expected1)
828
+ assert_np_equal(a2.numpy(), expected2)
829
+ assert_np_equal(a3.numpy(), expected3)
830
+ assert_np_equal(a4.numpy(), expected4)
831
+
832
+
833
+ @wp.struct
834
+ class FillStruct:
835
+ # scalar members (make sure to test float16)
836
+ i1: wp.int8
837
+ i2: wp.int16
838
+ i4: wp.int32
839
+ i8: wp.int64
840
+ f2: wp.float16
841
+ f4: wp.float32
842
+ f8: wp.float16
843
+ # vector members (make sure to test vectors of float16)
844
+ v2: wp.types.vector(2, wp.int64)
845
+ v3: wp.types.vector(3, wp.float32)
846
+ v4: wp.types.vector(4, wp.float16)
847
+ v5: wp.types.vector(5, wp.uint8)
848
+ # matrix members (make sure to test matrices of float16)
849
+ m2: wp.types.matrix((2, 2), wp.float64)
850
+ m3: wp.types.matrix((3, 3), wp.int32)
851
+ m4: wp.types.matrix((4, 4), wp.float16)
852
+ m5: wp.types.matrix((5, 5), wp.int8)
853
+ # arrays
854
+ a1: wp.array(dtype=float)
855
+ a2: wp.array2d(dtype=float)
856
+ a3: wp.array3d(dtype=float)
857
+ a4: wp.array4d(dtype=float)
858
+
859
+
860
+ def test_fill_struct(test, device):
861
+ dim_x = 4
862
+
863
+ nptype = FillStruct.numpy_dtype()
864
+
865
+ a1 = wp.zeros(dim_x, dtype=FillStruct, device=device)
866
+ a2 = wp.zeros((dim_x, dim_x), dtype=FillStruct, device=device)
867
+ a3 = wp.zeros((dim_x, dim_x, dim_x), dtype=FillStruct, device=device)
868
+ a4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=FillStruct, device=device)
869
+
870
+ assert_np_equal(a1.numpy(), np.zeros(a1.shape, dtype=nptype))
871
+ assert_np_equal(a2.numpy(), np.zeros(a2.shape, dtype=nptype))
872
+ assert_np_equal(a3.numpy(), np.zeros(a3.shape, dtype=nptype))
873
+ assert_np_equal(a4.numpy(), np.zeros(a4.shape, dtype=nptype))
874
+
875
+ s = FillStruct()
876
+
877
+ # fill with default struct value (should be all zeros)
878
+ a1.fill_(s)
879
+ a2.fill_(s)
880
+ a3.fill_(s)
881
+ a4.fill_(s)
882
+
883
+ assert_np_equal(a1.numpy(), np.zeros(a1.shape, dtype=nptype))
884
+ assert_np_equal(a2.numpy(), np.zeros(a2.shape, dtype=nptype))
885
+ assert_np_equal(a3.numpy(), np.zeros(a3.shape, dtype=nptype))
886
+ assert_np_equal(a4.numpy(), np.zeros(a4.shape, dtype=nptype))
887
+
888
+ # scalars
889
+ s.i1 = -17
890
+ s.i2 = 42
891
+ s.i4 = 99
892
+ s.i8 = 101
893
+ s.f2 = -1.25
894
+ s.f4 = 13.37
895
+ s.f8 = 0.125
896
+ # vectors
897
+ s.v2 = [21, 22]
898
+ s.v3 = [31, 32, 33]
899
+ s.v4 = [41, 42, 43, 44]
900
+ s.v5 = [51, 52, 53, 54, 55]
901
+ # matrices
902
+ s.m2 = [[61, 62]] * 2
903
+ s.m3 = [[71, 72, 73]] * 3
904
+ s.m4 = [[81, 82, 83, 84]] * 4
905
+ s.m5 = [[91, 92, 93, 94, 95]] * 5
906
+ # arrays
907
+ s.a1 = wp.zeros((2,) * 1, dtype=float, device=device)
908
+ s.a2 = wp.zeros((2,) * 2, dtype=float, device=device)
909
+ s.a3 = wp.zeros((2,) * 3, dtype=float, device=device)
910
+ s.a4 = wp.zeros((2,) * 4, dtype=float, device=device)
911
+
912
+ # fill with custom struct value
913
+ a1.fill_(s)
914
+ a2.fill_(s)
915
+ a3.fill_(s)
916
+ a4.fill_(s)
917
+
918
+ ns = s.numpy_value()
919
+
920
+ expected1 = np.empty(a1.shape, dtype=nptype)
921
+ expected2 = np.empty(a2.shape, dtype=nptype)
922
+ expected3 = np.empty(a3.shape, dtype=nptype)
923
+ expected4 = np.empty(a4.shape, dtype=nptype)
924
+
925
+ expected1.fill(ns)
926
+ expected2.fill(ns)
927
+ expected3.fill(ns)
928
+ expected4.fill(ns)
929
+
930
+ assert_np_equal(a1.numpy(), expected1)
931
+ assert_np_equal(a2.numpy(), expected2)
932
+ assert_np_equal(a3.numpy(), expected3)
933
+ assert_np_equal(a4.numpy(), expected4)
934
+
935
+ # test clearing
936
+ a1.zero_()
937
+ a2.zero_()
938
+ a3.zero_()
939
+ a4.zero_()
940
+
941
+ assert_np_equal(a1.numpy(), np.zeros(a1.shape, dtype=nptype))
942
+ assert_np_equal(a2.numpy(), np.zeros(a2.shape, dtype=nptype))
943
+ assert_np_equal(a3.numpy(), np.zeros(a3.shape, dtype=nptype))
944
+ assert_np_equal(a4.numpy(), np.zeros(a4.shape, dtype=nptype))
945
+
946
+
947
+ def test_fill_slices(test, device):
948
+ # test fill_ and zero_ for non-contiguous arrays
949
+ # Note: we don't need to test the whole range of dtypes (vectors, matrices, structs) here
950
+
951
+ dim_x = 8
952
+
519
953
  for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
520
954
  a1 = wp.zeros(dim_x, dtype=wptype, device=device)
521
955
  a2 = wp.zeros((dim_x, dim_x), dtype=wptype, device=device)
522
956
  a3 = wp.zeros((dim_x, dim_x, dim_x), dtype=wptype, device=device)
523
957
  a4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=wptype, device=device)
524
958
 
525
- a1.fill_(127)
526
- a2.fill_(127)
527
- a3.fill_(127)
528
- a4.fill_(127)
529
-
530
- assert_np_equal(a1.numpy(), 127 * np.ones_like(a1.numpy()))
531
- assert_np_equal(a2.numpy(), 127 * np.ones_like(a2.numpy()))
532
- assert_np_equal(a3.numpy(), 127 * np.ones_like(a3.numpy()))
533
- assert_np_equal(a4.numpy(), 127 * np.ones_like(a4.numpy()))
534
-
535
- # test some vector types too:
536
- v1 = wp.zeros(dim_x, dtype=wp.types.vector(3, wptype), device=device)
537
- v2 = wp.zeros((dim_x, dim_x), dtype=wp.types.vector(3, wptype), device=device)
538
- v3 = wp.zeros((dim_x, dim_x, dim_x), dtype=wp.types.vector(3, wptype), device=device)
539
- v4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=wp.types.vector(3, wptype), device=device)
540
-
541
- v1.fill_(127)
542
- v2.fill_(127)
543
- v3.fill_(127)
544
- v4.fill_(127)
545
-
546
- assert_np_equal(v1.numpy(), 127 * np.ones_like(v1.numpy()))
547
- assert_np_equal(v2.numpy(), 127 * np.ones_like(v2.numpy()))
548
- assert_np_equal(v3.numpy(), 127 * np.ones_like(v3.numpy()))
549
- assert_np_equal(v4.numpy(), 127 * np.ones_like(v4.numpy()))
550
-
551
- # test fill with vector constant:
552
- for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
553
- vectype = wp.types.vector(3, wptype)
554
-
555
- vecvalue = vectype(1, 2, 3)
556
-
557
- # test some vector types too:
558
- v1 = wp.zeros(dim_x, dtype=vectype, device=device)
559
- v2 = wp.zeros((dim_x, dim_x), dtype=vectype, device=device)
560
- v3 = wp.zeros((dim_x, dim_x, dim_x), dtype=vectype, device=device)
561
- v4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=vectype, device=device)
562
-
563
- v1.fill_(vecvalue)
564
- v2.fill_(vecvalue)
565
- v3.fill_(vecvalue)
566
- v4.fill_(vecvalue)
567
-
568
- e1 = np.tile(np.array([1, 2, 3], dtype=nptype)[None, :], (dim_x, 1))
569
- e2 = np.tile(np.array([1, 2, 3], dtype=nptype)[None, None, :], (dim_x, dim_x, 1))
570
- e3 = np.tile(np.array([1, 2, 3], dtype=nptype)[None, None, None, :], (dim_x, dim_x, dim_x, 1))
571
- e4 = np.tile(np.array([1, 2, 3], dtype=nptype)[None, None, None, None, :], (dim_x, dim_x, dim_x, dim_x, 1))
572
-
573
- assert_np_equal(v1.numpy(), e1)
574
- assert_np_equal(v2.numpy(), e2)
575
- assert_np_equal(v3.numpy(), e3)
576
- assert_np_equal(v4.numpy(), e4)
577
-
578
- # specific tests for floating point values:
579
- for nptype in [np.dtype(np.float16), np.dtype(np.float32), np.dtype(np.float64)]:
580
- wptype = wp.types.np_dtype_to_warp_type[nptype]
581
-
582
- vectype = wp.types.vector(3, wptype)
583
-
584
- vecvalue = vectype(1.25, 2.5, 3.75)
585
-
586
- # test some vector types too:
587
- v1 = wp.zeros(dim_x, dtype=vectype, device=device)
588
- v2 = wp.zeros((dim_x, dim_x), dtype=vectype, device=device)
589
- v3 = wp.zeros((dim_x, dim_x, dim_x), dtype=vectype, device=device)
590
- v4 = wp.zeros((dim_x, dim_x, dim_x, dim_x), dtype=vectype, device=device)
591
-
592
- v1.fill_(vecvalue)
593
- v2.fill_(vecvalue)
594
- v3.fill_(vecvalue)
595
- v4.fill_(vecvalue)
596
-
597
- e1 = np.tile(np.array([1.25, 2.5, 3.75], dtype=nptype)[None, :], (dim_x, 1))
598
- e2 = np.tile(np.array([1.25, 2.5, 3.75], dtype=nptype)[None, None, :], (dim_x, dim_x, 1))
599
- e3 = np.tile(np.array([1.25, 2.5, 3.75], dtype=nptype)[None, None, None, :], (dim_x, dim_x, dim_x, 1))
600
- e4 = np.tile(
601
- np.array([1.25, 2.5, 3.75], dtype=nptype)[None, None, None, None, :], (dim_x, dim_x, dim_x, dim_x, 1)
602
- )
603
-
604
- assert_np_equal(v1.numpy(), e1)
605
- assert_np_equal(v2.numpy(), e2)
606
- assert_np_equal(v3.numpy(), e3)
607
- assert_np_equal(v4.numpy(), e4)
608
-
609
- # test fill small arrays with scalar constant:
610
- for xdim in [1, 2, 3, 5, 6, 7]:
959
+ assert_np_equal(a1.numpy(), np.zeros(a1.shape, dtype=nptype))
960
+ assert_np_equal(a2.numpy(), np.zeros(a2.shape, dtype=nptype))
961
+ assert_np_equal(a3.numpy(), np.zeros(a3.shape, dtype=nptype))
962
+ assert_np_equal(a4.numpy(), np.zeros(a4.shape, dtype=nptype))
963
+
964
+ # partititon each array into even and odd slices
965
+ a1a = a1[::2]
966
+ a1b = a1[1::2]
967
+ a2a = a2[::2]
968
+ a2b = a2[1::2]
969
+ a3a = a3[::2]
970
+ a3b = a3[1::2]
971
+ a4a = a4[::2]
972
+ a4b = a4[1::2]
973
+
974
+ # fill even slices
975
+ fill_a = 17
976
+ a1a.fill_(fill_a)
977
+ a2a.fill_(fill_a)
978
+ a3a.fill_(fill_a)
979
+ a4a.fill_(fill_a)
980
+
981
+ # ensure filled slices are correct
982
+ assert_np_equal(a1a.numpy(), np.full(a1a.shape, fill_a, dtype=nptype))
983
+ assert_np_equal(a2a.numpy(), np.full(a2a.shape, fill_a, dtype=nptype))
984
+ assert_np_equal(a3a.numpy(), np.full(a3a.shape, fill_a, dtype=nptype))
985
+ assert_np_equal(a4a.numpy(), np.full(a4a.shape, fill_a, dtype=nptype))
986
+
987
+ # ensure unfilled slices are unaffected
988
+ assert_np_equal(a1b.numpy(), np.zeros(a1b.shape, dtype=nptype))
989
+ assert_np_equal(a2b.numpy(), np.zeros(a2b.shape, dtype=nptype))
990
+ assert_np_equal(a3b.numpy(), np.zeros(a3b.shape, dtype=nptype))
991
+ assert_np_equal(a4b.numpy(), np.zeros(a4b.shape, dtype=nptype))
992
+
993
+ # fill odd slices
994
+ fill_b = 42
995
+ a1b.fill_(fill_b)
996
+ a2b.fill_(fill_b)
997
+ a3b.fill_(fill_b)
998
+ a4b.fill_(fill_b)
999
+
1000
+ # ensure filled slices are correct
1001
+ assert_np_equal(a1b.numpy(), np.full(a1b.shape, fill_b, dtype=nptype))
1002
+ assert_np_equal(a2b.numpy(), np.full(a2b.shape, fill_b, dtype=nptype))
1003
+ assert_np_equal(a3b.numpy(), np.full(a3b.shape, fill_b, dtype=nptype))
1004
+ assert_np_equal(a4b.numpy(), np.full(a4b.shape, fill_b, dtype=nptype))
1005
+
1006
+ # ensure unfilled slices are unaffected
1007
+ assert_np_equal(a1a.numpy(), np.full(a1a.shape, fill_a, dtype=nptype))
1008
+ assert_np_equal(a2a.numpy(), np.full(a2a.shape, fill_a, dtype=nptype))
1009
+ assert_np_equal(a3a.numpy(), np.full(a3a.shape, fill_a, dtype=nptype))
1010
+ assert_np_equal(a4a.numpy(), np.full(a4a.shape, fill_a, dtype=nptype))
1011
+
1012
+ # clear even slices
1013
+ a1a.zero_()
1014
+ a2a.zero_()
1015
+ a3a.zero_()
1016
+ a4a.zero_()
1017
+
1018
+ # ensure cleared slices are correct
1019
+ assert_np_equal(a1a.numpy(), np.zeros(a1a.shape, dtype=nptype))
1020
+ assert_np_equal(a2a.numpy(), np.zeros(a2a.shape, dtype=nptype))
1021
+ assert_np_equal(a3a.numpy(), np.zeros(a3a.shape, dtype=nptype))
1022
+ assert_np_equal(a4a.numpy(), np.zeros(a4a.shape, dtype=nptype))
1023
+
1024
+ # ensure uncleared slices are unaffected
1025
+ assert_np_equal(a1b.numpy(), np.full(a1b.shape, fill_b, dtype=nptype))
1026
+ assert_np_equal(a2b.numpy(), np.full(a2b.shape, fill_b, dtype=nptype))
1027
+ assert_np_equal(a3b.numpy(), np.full(a3b.shape, fill_b, dtype=nptype))
1028
+ assert_np_equal(a4b.numpy(), np.full(a4b.shape, fill_b, dtype=nptype))
1029
+
1030
+ # re-fill even slices
1031
+ a1a.fill_(fill_a)
1032
+ a2a.fill_(fill_a)
1033
+ a3a.fill_(fill_a)
1034
+ a4a.fill_(fill_a)
1035
+
1036
+ # clear odd slices
1037
+ a1b.zero_()
1038
+ a2b.zero_()
1039
+ a3b.zero_()
1040
+ a4b.zero_()
1041
+
1042
+ # ensure cleared slices are correct
1043
+ assert_np_equal(a1b.numpy(), np.zeros(a1b.shape, dtype=nptype))
1044
+ assert_np_equal(a2b.numpy(), np.zeros(a2b.shape, dtype=nptype))
1045
+ assert_np_equal(a3b.numpy(), np.zeros(a3b.shape, dtype=nptype))
1046
+ assert_np_equal(a4b.numpy(), np.zeros(a4b.shape, dtype=nptype))
1047
+
1048
+ # ensure uncleared slices are unaffected
1049
+ assert_np_equal(a1a.numpy(), np.full(a1a.shape, fill_a, dtype=nptype))
1050
+ assert_np_equal(a2a.numpy(), np.full(a2a.shape, fill_a, dtype=nptype))
1051
+ assert_np_equal(a3a.numpy(), np.full(a3a.shape, fill_a, dtype=nptype))
1052
+ assert_np_equal(a4a.numpy(), np.full(a4a.shape, fill_a, dtype=nptype))
1053
+
1054
+
1055
+ def test_full_scalar(test, device):
1056
+ dim = 4
1057
+
1058
+ for ndim in range(1, 5):
1059
+ shape = (dim,) * ndim
1060
+
1061
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
1062
+ # fill with int value and specific dtype
1063
+ fill_value = 42
1064
+ a = wp.full(shape, fill_value, dtype=wptype, device=device)
1065
+ na = a.numpy()
1066
+
1067
+ test.assertEqual(a.shape, shape)
1068
+ test.assertEqual(a.dtype, wptype)
1069
+ test.assertEqual(na.shape, shape)
1070
+ test.assertEqual(na.dtype, nptype)
1071
+ assert_np_equal(na, np.full(shape, fill_value, dtype=nptype))
1072
+
1073
+ if wptype in wp.types.float_types:
1074
+ # fill with float value and specific dtype
1075
+ fill_value = 13.37
1076
+ a = wp.full(shape, fill_value, dtype=wptype, device=device)
1077
+ na = a.numpy()
1078
+
1079
+ test.assertEqual(a.shape, shape)
1080
+ test.assertEqual(a.dtype, wptype)
1081
+ test.assertEqual(na.shape, shape)
1082
+ test.assertEqual(na.dtype, nptype)
1083
+ assert_np_equal(na, np.full(shape, fill_value, dtype=nptype))
1084
+
1085
+ # fill with int value and automatically inferred dtype
1086
+ fill_value = 42
1087
+ a = wp.full(shape, fill_value, device=device)
1088
+ na = a.numpy()
1089
+
1090
+ test.assertEqual(a.shape, shape)
1091
+ test.assertEqual(a.dtype, wp.int32)
1092
+ test.assertEqual(na.shape, shape)
1093
+ test.assertEqual(na.dtype, np.int32)
1094
+ assert_np_equal(na, np.full(shape, fill_value, dtype=np.int32))
1095
+
1096
+ # fill with float value and automatically inferred dtype
1097
+ fill_value = 13.37
1098
+ a = wp.full(shape, fill_value, device=device)
1099
+ na = a.numpy()
1100
+
1101
+ test.assertEqual(a.shape, shape)
1102
+ test.assertEqual(a.dtype, wp.float32)
1103
+ test.assertEqual(na.shape, shape)
1104
+ test.assertEqual(na.dtype, np.float32)
1105
+ assert_np_equal(na, np.full(shape, fill_value, dtype=np.float32))
1106
+
1107
+
1108
+ def test_full_vector(test, device):
1109
+ dim = 4
1110
+
1111
+ for ndim in range(1, 5):
1112
+ shape = (dim,) * ndim
1113
+
1114
+ # full from scalar
1115
+ for veclen in [2, 3, 4, 5]:
1116
+ npshape = (*shape, veclen)
1117
+
1118
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
1119
+ vectype = wp.types.vector(veclen, wptype)
1120
+
1121
+ # fill with scalar int value and specific dtype
1122
+ fill_value = 42
1123
+ a = wp.full(shape, fill_value, dtype=vectype, device=device)
1124
+ na = a.numpy()
1125
+
1126
+ test.assertEqual(a.shape, shape)
1127
+ test.assertEqual(a.dtype, vectype)
1128
+ test.assertEqual(na.shape, npshape)
1129
+ test.assertEqual(na.dtype, nptype)
1130
+ assert_np_equal(na, np.full(a.size * veclen, fill_value, dtype=nptype).reshape(npshape))
1131
+
1132
+ if wptype in wp.types.float_types:
1133
+ # fill with scalar float value and specific dtype
1134
+ fill_value = 13.37
1135
+ a = wp.full(shape, fill_value, dtype=vectype, device=device)
1136
+ na = a.numpy()
1137
+
1138
+ test.assertEqual(a.shape, shape)
1139
+ test.assertEqual(a.dtype, vectype)
1140
+ test.assertEqual(na.shape, npshape)
1141
+ test.assertEqual(na.dtype, nptype)
1142
+ assert_np_equal(na, np.full(a.size * veclen, fill_value, dtype=nptype).reshape(npshape))
1143
+
1144
+ # fill with vector value and specific dtype
1145
+ fill_vec = vectype(42)
1146
+ a = wp.full(shape, fill_vec, dtype=vectype, device=device)
1147
+ na = a.numpy()
1148
+
1149
+ test.assertEqual(a.shape, shape)
1150
+ test.assertEqual(a.dtype, vectype)
1151
+ test.assertEqual(na.shape, npshape)
1152
+ test.assertEqual(na.dtype, nptype)
1153
+ assert_np_equal(na, np.full(a.size * veclen, 42, dtype=nptype).reshape(npshape))
1154
+
1155
+ # fill with vector value and automatically inferred dtype
1156
+ a = wp.full(shape, fill_vec, device=device)
1157
+ na = a.numpy()
1158
+
1159
+ test.assertEqual(a.shape, shape)
1160
+ test.assertEqual(a.dtype, vectype)
1161
+ test.assertEqual(na.shape, npshape)
1162
+ test.assertEqual(na.dtype, nptype)
1163
+ assert_np_equal(na, np.full(a.size * veclen, 42, dtype=nptype).reshape(npshape))
1164
+
1165
+ fill_lists = [
1166
+ [17, 42],
1167
+ [17, 42, 99],
1168
+ [17, 42, 99, 101],
1169
+ [17, 42, 99, 101, 127],
1170
+ ]
1171
+
1172
+ # full from list and numpy array
1173
+ for fill_list in fill_lists:
1174
+ veclen = len(fill_list)
1175
+ npshape = (*shape, veclen)
1176
+
1177
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
1178
+ vectype = wp.types.vector(veclen, wptype)
1179
+
1180
+ # fill with list and specific dtype
1181
+ a = wp.full(shape, fill_list, dtype=vectype, device=device)
1182
+ na = a.numpy()
1183
+
1184
+ test.assertEqual(a.shape, shape)
1185
+ test.assertEqual(a.dtype, vectype)
1186
+ test.assertEqual(na.shape, npshape)
1187
+ test.assertEqual(na.dtype, nptype)
1188
+
1189
+ expected = np.tile(np.array(fill_list, dtype=nptype), a.size).reshape(npshape)
1190
+ assert_np_equal(na, expected)
1191
+
1192
+ fill_arr = np.array(fill_list, dtype=nptype)
1193
+
1194
+ # fill with numpy array and specific dtype
1195
+ a = wp.full(shape, fill_arr, dtype=vectype, device=device)
1196
+ na = a.numpy()
1197
+
1198
+ test.assertEqual(a.shape, shape)
1199
+ test.assertEqual(a.dtype, vectype)
1200
+ test.assertEqual(na.shape, npshape)
1201
+ test.assertEqual(na.dtype, nptype)
1202
+ assert_np_equal(na, expected)
1203
+
1204
+ # fill with numpy array and automatically infer dtype
1205
+ a = wp.full(shape, fill_arr, device=device)
1206
+ na = a.numpy()
1207
+
1208
+ test.assertEqual(a.shape, shape)
1209
+ test.assertTrue(wp.types.types_equal(a.dtype, vectype))
1210
+ test.assertEqual(na.shape, npshape)
1211
+ test.assertEqual(na.dtype, nptype)
1212
+ assert_np_equal(na, expected)
1213
+
1214
+ # fill with list and automatically infer dtype
1215
+ a = wp.full(shape, fill_list, device=device)
1216
+ na = a.numpy()
1217
+
1218
+ test.assertEqual(a.shape, shape)
1219
+
1220
+ # check that the inferred dtype is a vector
1221
+ # Note that we cannot guarantee the scalar type, because it depends on numpy and may vary by platform
1222
+ # (e.g. int64 on Linux and int32 on Windows).
1223
+ test.assertEqual(a.dtype._wp_generic_type_str_, "vec_t")
1224
+ test.assertEqual(a.dtype._length_, veclen)
1225
+
1226
+ expected = np.tile(np.array(fill_list), a.size).reshape(npshape)
1227
+ assert_np_equal(na, expected)
1228
+
1229
+
1230
+ def test_full_matrix(test, device):
1231
+ dim = 4
1232
+
1233
+ for ndim in range(1, 5):
1234
+ shape = (dim,) * ndim
1235
+
611
1236
  for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
612
- a1 = wp.zeros(xdim, dtype=wptype, device=device)
613
- a1.fill_(127)
614
- assert_np_equal(a1.numpy(), 127 * np.ones_like(a1.numpy()))
1237
+ matrix_types = [
1238
+ # square matrices
1239
+ wp.types.matrix((2, 2), wptype),
1240
+ wp.types.matrix((3, 3), wptype),
1241
+ wp.types.matrix((4, 4), wptype),
1242
+ wp.types.matrix((5, 5), wptype),
1243
+ # non-square matrices
1244
+ wp.types.matrix((2, 3), wptype),
1245
+ wp.types.matrix((3, 2), wptype),
1246
+ wp.types.matrix((3, 4), wptype),
1247
+ wp.types.matrix((4, 3), wptype),
1248
+ ]
1249
+
1250
+ for mattype in matrix_types:
1251
+ npshape = (*shape, *mattype._shape_)
1252
+
1253
+ # fill with scalar int value and specific dtype
1254
+ fill_value = 42
1255
+ a = wp.full(shape, fill_value, dtype=mattype, device=device)
1256
+ na = a.numpy()
1257
+
1258
+ test.assertEqual(a.shape, shape)
1259
+ test.assertEqual(a.dtype, mattype)
1260
+ test.assertEqual(na.shape, npshape)
1261
+ test.assertEqual(na.dtype, nptype)
1262
+ assert_np_equal(na, np.full(a.size * mattype._length_, fill_value, dtype=nptype).reshape(npshape))
1263
+
1264
+ if wptype in wp.types.float_types:
1265
+ # fill with scalar float value and specific dtype
1266
+ fill_value = 13.37
1267
+ a = wp.full(shape, fill_value, dtype=mattype, device=device)
1268
+ na = a.numpy()
1269
+
1270
+ test.assertEqual(a.shape, shape)
1271
+ test.assertEqual(a.dtype, mattype)
1272
+ test.assertEqual(na.shape, npshape)
1273
+ test.assertEqual(na.dtype, nptype)
1274
+ assert_np_equal(na, np.full(a.size * mattype._length_, fill_value, dtype=nptype).reshape(npshape))
1275
+
1276
+ # fill with matrix value and specific dtype
1277
+ fill_mat = mattype(42)
1278
+ a = wp.full(shape, fill_mat, dtype=mattype, device=device)
1279
+ na = a.numpy()
1280
+
1281
+ test.assertEqual(a.shape, shape)
1282
+ test.assertEqual(a.dtype, mattype)
1283
+ test.assertEqual(na.shape, npshape)
1284
+ test.assertEqual(na.dtype, nptype)
1285
+ assert_np_equal(na, np.full(a.size * mattype._length_, 42, dtype=nptype).reshape(npshape))
1286
+
1287
+ # fill with matrix value and automatically inferred dtype
1288
+ fill_mat = mattype(42)
1289
+ a = wp.full(shape, fill_mat, device=device)
1290
+ na = a.numpy()
1291
+
1292
+ test.assertEqual(a.shape, shape)
1293
+ test.assertEqual(a.dtype, mattype)
1294
+ test.assertEqual(na.shape, npshape)
1295
+ test.assertEqual(na.dtype, nptype)
1296
+ assert_np_equal(na, np.full(a.size * mattype._length_, 42, dtype=nptype).reshape(npshape))
1297
+
1298
+ # fill with 1d numpy array and specific dtype
1299
+ if wptype != wp.bool:
1300
+ fill_arr1d = np.arange(mattype._length_, dtype=nptype)
1301
+ else:
1302
+ fill_arr1d = np.ones(mattype._length_, dtype=nptype)
1303
+ a = wp.full(shape, fill_arr1d, dtype=mattype, device=device)
1304
+ na = a.numpy()
1305
+
1306
+ test.assertEqual(a.shape, shape)
1307
+ test.assertEqual(a.dtype, mattype)
1308
+ test.assertEqual(na.shape, npshape)
1309
+ test.assertEqual(na.dtype, nptype)
1310
+
1311
+ expected = np.tile(fill_arr1d, a.size).reshape(npshape)
1312
+ assert_np_equal(na, expected)
1313
+
1314
+ # fill with 2d numpy array and specific dtype
1315
+ fill_arr2d = fill_arr1d.reshape(mattype._shape_)
1316
+ a = wp.full(shape, fill_arr2d, dtype=mattype, device=device)
1317
+ na = a.numpy()
1318
+
1319
+ test.assertEqual(a.shape, shape)
1320
+ test.assertEqual(a.dtype, mattype)
1321
+ test.assertEqual(na.shape, npshape)
1322
+ test.assertEqual(na.dtype, nptype)
1323
+ assert_np_equal(na, expected)
1324
+
1325
+ # fill with 2d numpy array and automatically infer dtype
1326
+ a = wp.full(shape, fill_arr2d, device=device)
1327
+ na = a.numpy()
1328
+
1329
+ test.assertEqual(a.shape, shape)
1330
+ test.assertTrue(wp.types.types_equal(a.dtype, mattype))
1331
+ test.assertEqual(na.shape, npshape)
1332
+ test.assertEqual(na.dtype, nptype)
1333
+ assert_np_equal(na, expected)
1334
+
1335
+ # fill with flat list and specific dtype
1336
+ fill_list1d = list(fill_arr1d)
1337
+ a = wp.full(shape, fill_list1d, dtype=mattype, device=device)
1338
+ na = a.numpy()
1339
+
1340
+ test.assertEqual(a.shape, shape)
1341
+ test.assertEqual(a.dtype, mattype)
1342
+ test.assertEqual(na.shape, npshape)
1343
+ test.assertEqual(na.dtype, nptype)
1344
+ assert_np_equal(na, expected)
1345
+
1346
+ # fill with nested list and specific dtype
1347
+ fill_list2d = [list(row) for row in fill_arr2d]
1348
+ a = wp.full(shape, fill_list2d, dtype=mattype, device=device)
1349
+ na = a.numpy()
1350
+
1351
+ test.assertEqual(a.shape, shape)
1352
+ test.assertEqual(a.dtype, mattype)
1353
+ test.assertEqual(na.shape, npshape)
1354
+ test.assertEqual(na.dtype, nptype)
1355
+ assert_np_equal(na, expected)
1356
+
1357
+ mat_lists = [
1358
+ # square matrices
1359
+ [[1, 2], [3, 4]],
1360
+ [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
1361
+ [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]],
1362
+ # non-square matrices
1363
+ [[1, 2, 3, 4], [5, 6, 7, 8]],
1364
+ [[1, 2], [3, 4], [5, 6], [7, 8]],
1365
+ ]
1366
+
1367
+ # fill with nested lists and automatically infer dtype
1368
+ for fill_list in mat_lists:
1369
+ num_rows = len(fill_list)
1370
+ num_cols = len(fill_list[0])
1371
+ npshape = (*shape, num_rows, num_cols)
1372
+
1373
+ a = wp.full(shape, fill_list, device=device)
1374
+ na = a.numpy()
1375
+
1376
+ test.assertEqual(a.shape, shape)
1377
+
1378
+ # check that the inferred dtype is a correctly shaped matrix
1379
+ # Note that we cannot guarantee the scalar type, because it depends on numpy and may vary by platform
1380
+ # (e.g. int64 on Linux and int32 on Windows).
1381
+ test.assertEqual(a.dtype._wp_generic_type_str_, "mat_t")
1382
+ test.assertEqual(a.dtype._shape_, (num_rows, num_cols))
1383
+
1384
+ expected = np.tile(np.array(fill_list).flatten(), a.size).reshape(npshape)
1385
+ assert_np_equal(na, expected)
1386
+
1387
+
1388
+ def test_full_struct(test, device):
1389
+ dim = 4
1390
+
1391
+ for ndim in range(1, 5):
1392
+ shape = (dim,) * ndim
1393
+
1394
+ s = FillStruct()
1395
+
1396
+ # fill with default struct (should be zeros)
1397
+ a = wp.full(shape, s, dtype=FillStruct, device=device)
1398
+ na = a.numpy()
1399
+
1400
+ test.assertEqual(a.shape, shape)
1401
+ test.assertEqual(a.dtype, FillStruct)
1402
+ test.assertEqual(na.shape, shape)
1403
+ test.assertEqual(na.dtype, FillStruct.numpy_dtype())
1404
+ assert_np_equal(na, np.zeros(a.size, dtype=FillStruct.numpy_dtype()))
1405
+
1406
+ # scalars
1407
+ s.i1 = -17
1408
+ s.i2 = 42
1409
+ s.i4 = 99
1410
+ s.i8 = 101
1411
+ s.f2 = -1.25
1412
+ s.f4 = 13.37
1413
+ s.f8 = 0.125
1414
+ # vectors
1415
+ s.v2 = [21, 22]
1416
+ s.v3 = [31, 32, 33]
1417
+ s.v4 = [41, 42, 43, 44]
1418
+ s.v5 = [51, 52, 53, 54, 55]
1419
+ # matrices
1420
+ s.m2 = [[61, 62]] * 2
1421
+ s.m3 = [[71, 72, 73]] * 3
1422
+ s.m4 = [[81, 82, 83, 84]] * 4
1423
+ s.m5 = [[91, 92, 93, 94, 95]] * 5
1424
+ # arrays
1425
+ s.a1 = wp.zeros((2,) * 1, dtype=float, device=device)
1426
+ s.a2 = wp.zeros((2,) * 2, dtype=float, device=device)
1427
+ s.a3 = wp.zeros((2,) * 3, dtype=float, device=device)
1428
+ s.a4 = wp.zeros((2,) * 4, dtype=float, device=device)
1429
+
1430
+ # fill with initialized struct and explicit dtype
1431
+ a = wp.full(shape, s, dtype=FillStruct, device=device)
1432
+ na = a.numpy()
1433
+
1434
+ test.assertEqual(a.shape, shape)
1435
+ test.assertEqual(a.dtype, FillStruct)
1436
+ test.assertEqual(na.shape, shape)
1437
+ test.assertEqual(na.dtype, FillStruct.numpy_dtype())
1438
+
1439
+ expected = np.empty(shape, dtype=FillStruct.numpy_dtype())
1440
+ expected.fill(s.numpy_value())
1441
+ assert_np_equal(na, expected)
1442
+
1443
+ # fill with initialized struct and automatically inferred dtype
1444
+ a = wp.full(shape, s, device=device)
1445
+ na = a.numpy()
1446
+
1447
+ test.assertEqual(a.shape, shape)
1448
+ test.assertEqual(a.dtype, FillStruct)
1449
+ test.assertEqual(na.shape, shape)
1450
+ test.assertEqual(na.dtype, FillStruct.numpy_dtype())
1451
+ assert_np_equal(na, expected)
615
1452
 
616
1453
 
617
1454
  def test_round_trip(test, device):
1455
+ rng = np.random.default_rng(123)
618
1456
  dim_x = 4
619
1457
 
620
1458
  for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
621
- a_np = np.random.randn(dim_x).astype(nptype)
1459
+ a_np = rng.standard_normal(size=dim_x).astype(nptype)
622
1460
  a = wp.array(a_np, device=device)
623
1461
  test.assertEqual(a.dtype, wptype)
624
1462
 
625
1463
  assert_np_equal(a.numpy(), a_np)
626
1464
 
627
- v_np = np.random.randn(dim_x, 3).astype(nptype)
1465
+ v_np = rng.standard_normal(size=(dim_x, 3)).astype(nptype)
628
1466
  v = wp.array(v_np, dtype=wp.types.vector(3, wptype), device=device)
629
1467
 
630
1468
  assert_np_equal(v.numpy(), v_np)
631
1469
 
632
1470
 
633
- def test_large_arrays_slow(test, device):
634
- # The goal of this test is to use arrays just large enough to know
635
- # if there's a flaw in handling arrays with more than 2**31-1 elements
636
- # Unfortunately, it takes a long time to run so it won't be run automatically
637
- # without changes to support how frequently a test may be run
638
- total_elements = 2**31 + 8
1471
+ def test_empty_array(test, device):
1472
+ # Test whether common operations work with empty (zero-sized) arrays
1473
+ # without throwing exceptions.
1474
+
1475
+ def test_empty_ops(ndim, nrows, ncols, wptype, nptype):
1476
+ shape = (0,) * ndim
1477
+ dtype_shape = ()
1478
+
1479
+ if wptype in wp.types.scalar_types:
1480
+ # scalar, vector, or matrix
1481
+ if ncols > 0:
1482
+ if nrows > 0:
1483
+ wptype = wp.types.matrix((nrows, ncols), wptype)
1484
+ else:
1485
+ wptype = wp.types.vector(ncols, wptype)
1486
+ dtype_shape = wptype._shape_
1487
+ fill_value = wptype(42)
1488
+ else:
1489
+ # struct
1490
+ fill_value = wptype()
1491
+
1492
+ # create a zero-sized array
1493
+ a = wp.empty(shape, dtype=wptype, device=device, requires_grad=True)
1494
+
1495
+ test.assertEqual(a.ptr, None)
1496
+ test.assertEqual(a.size, 0)
1497
+ test.assertEqual(a.shape, shape)
1498
+ test.assertEqual(a.grad.ptr, None)
1499
+ test.assertEqual(a.grad.size, 0)
1500
+ test.assertEqual(a.grad.shape, shape)
1501
+
1502
+ # all of these methods should succeed with zero-sized arrays
1503
+ a.zero_()
1504
+ a.fill_(fill_value)
1505
+ b = a.flatten()
1506
+ b = a.reshape((0,))
1507
+ b = a.transpose()
1508
+ b = a.contiguous()
1509
+
1510
+ b = wp.empty_like(a)
1511
+ b = wp.zeros_like(a)
1512
+ b = wp.full_like(a, fill_value)
1513
+ b = wp.clone(a)
1514
+
1515
+ wp.copy(a, b)
1516
+ a.assign(b)
1517
+
1518
+ na = a.numpy()
1519
+ test.assertEqual(na.size, 0)
1520
+ test.assertEqual(na.shape, (*shape, *dtype_shape))
1521
+ test.assertEqual(na.dtype, nptype)
1522
+
1523
+ test.assertEqual(a.list(), [])
1524
+
1525
+ for ndim in range(1, 5):
1526
+ # test with scalars, vectors, and matrices
1527
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
1528
+ # scalars
1529
+ test_empty_ops(ndim, 0, 0, wptype, nptype)
639
1530
 
640
- # 1-D to 4-D arrays: test zero_, fill_, then zero_ for scalar data types:
641
- for total_dims in range(1, 5):
642
- dim_x = math.ceil(total_elements ** (1 / total_dims))
643
- shape_tuple = tuple([dim_x] * total_dims)
1531
+ for ncols in [2, 3, 4, 5]:
1532
+ # vectors
1533
+ test_empty_ops(ndim, 0, ncols, wptype, nptype)
1534
+ # square matrices
1535
+ test_empty_ops(ndim, ncols, ncols, wptype, nptype)
644
1536
 
645
- for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
646
- a1 = wp.zeros(shape_tuple, dtype=wptype, device=device)
647
- assert_np_equal(a1.numpy(), np.zeros_like(a1.numpy()))
1537
+ # non-square matrices
1538
+ test_empty_ops(ndim, 2, 3, wptype, nptype)
1539
+ test_empty_ops(ndim, 3, 2, wptype, nptype)
1540
+ test_empty_ops(ndim, 3, 4, wptype, nptype)
1541
+ test_empty_ops(ndim, 4, 3, wptype, nptype)
648
1542
 
649
- a1.fill_(127)
650
- assert_np_equal(a1.numpy(), 127 * np.ones_like(a1.numpy()))
1543
+ # test with structs
1544
+ test_empty_ops(ndim, 0, 0, FillStruct, FillStruct.numpy_dtype())
651
1545
 
652
- a1.zero_()
653
- assert_np_equal(a1.numpy(), np.zeros_like(a1.numpy()))
654
1546
 
1547
+ def test_empty_from_numpy(test, device):
1548
+ # Test whether wrapping an empty (zero-sized) numpy array works correctly
655
1549
 
656
- def test_large_arrays_fast(test, device):
657
- # A truncated version of test_large_arrays_slow meant to catch basic errors
658
- total_elements = 2**31 + 8
1550
+ def test_empty_from_data(ndim, nrows, ncols, wptype, nptype):
1551
+ shape = (0,) * ndim
1552
+ dtype_shape = ()
659
1553
 
660
- nptype = np.dtype(np.int8)
661
- wptype = wp.types.np_dtype_to_warp_type[nptype]
1554
+ if ncols > 0:
1555
+ if nrows > 0:
1556
+ wptype = wp.types.matrix((nrows, ncols), wptype)
1557
+ else:
1558
+ wptype = wp.types.vector(ncols, wptype)
1559
+ dtype_shape = wptype._shape_
662
1560
 
663
- a1 = wp.zeros((total_elements,), dtype=wptype, device=device)
664
- assert_np_equal(a1.numpy(), np.zeros_like(a1.numpy()))
1561
+ npshape = (*shape, *dtype_shape)
665
1562
 
666
- a1.fill_(127)
667
- assert_np_equal(a1.numpy(), 127 * np.ones_like(a1.numpy()))
1563
+ na = np.empty(npshape, dtype=nptype)
1564
+ a = wp.array(na, dtype=wptype, device=device)
1565
+ test.assertEqual(a.size, 0)
1566
+ test.assertEqual(a.shape, shape)
1567
+
1568
+ for ndim in range(1, 5):
1569
+ # test with scalars, vectors, and matrices
1570
+ for nptype, wptype in wp.types.np_dtype_to_warp_type.items():
1571
+ # scalars
1572
+ test_empty_from_data(ndim, 0, 0, wptype, nptype)
1573
+
1574
+ for ncols in [2, 3, 4, 5]:
1575
+ # vectors
1576
+ test_empty_from_data(ndim, 0, ncols, wptype, nptype)
1577
+ # square matrices
1578
+ test_empty_from_data(ndim, ncols, ncols, wptype, nptype)
1579
+
1580
+ # non-square matrices
1581
+ test_empty_from_data(ndim, 2, 3, wptype, nptype)
1582
+ test_empty_from_data(ndim, 3, 2, wptype, nptype)
1583
+ test_empty_from_data(ndim, 3, 4, wptype, nptype)
1584
+ test_empty_from_data(ndim, 4, 3, wptype, nptype)
668
1585
 
669
- a1.zero_()
670
- assert_np_equal(a1.numpy(), np.zeros_like(a1.numpy()))
1586
+
1587
+ def test_empty_from_list(test, device):
1588
+ # Test whether creating an array from an empty Python list works correctly
1589
+
1590
+ def test_empty_from_data(nrows, ncols, wptype):
1591
+ if ncols > 0:
1592
+ if nrows > 0:
1593
+ wptype = wp.types.matrix((nrows, ncols), wptype)
1594
+ else:
1595
+ wptype = wp.types.vector(ncols, wptype)
1596
+
1597
+ a = wp.array([], dtype=wptype, device=device)
1598
+ test.assertEqual(a.size, 0)
1599
+ test.assertEqual(a.shape, (0,))
1600
+
1601
+ # test with scalars, vectors, and matrices
1602
+ for wptype in wp.types.scalar_types:
1603
+ # scalars
1604
+ test_empty_from_data(0, 0, wptype)
1605
+
1606
+ for ncols in [2, 3, 4, 5]:
1607
+ # vectors
1608
+ test_empty_from_data(0, ncols, wptype)
1609
+ # square matrices
1610
+ test_empty_from_data(ncols, ncols, wptype)
1611
+
1612
+ # non-square matrices
1613
+ test_empty_from_data(2, 3, wptype)
1614
+ test_empty_from_data(3, 2, wptype)
1615
+ test_empty_from_data(3, 4, wptype)
1616
+ test_empty_from_data(4, 3, wptype)
1617
+
1618
+
1619
+ def test_to_list_scalar(test, device):
1620
+ dim = 3
1621
+ fill_value = 42
1622
+
1623
+ for ndim in range(1, 5):
1624
+ shape = (dim,) * ndim
1625
+
1626
+ for wptype in wp.types.scalar_types:
1627
+ a = wp.full(shape, fill_value, dtype=wptype, device=device)
1628
+ l = a.list()
1629
+
1630
+ test.assertEqual(len(l), a.size)
1631
+ test.assertTrue(all(x == fill_value for x in l))
1632
+
1633
+
1634
+ def test_to_list_vector(test, device):
1635
+ dim = 3
1636
+
1637
+ for ndim in range(1, 5):
1638
+ shape = (dim,) * ndim
1639
+
1640
+ for veclen in [2, 3, 4, 5]:
1641
+ for wptype in wp.types.scalar_types:
1642
+ vectype = wp.types.vector(veclen, wptype)
1643
+ fill_value = vectype(42)
1644
+
1645
+ a = wp.full(shape, fill_value, dtype=vectype, device=device)
1646
+ l = a.list()
1647
+
1648
+ test.assertEqual(len(l), a.size)
1649
+ test.assertTrue(all(x == fill_value for x in l))
1650
+
1651
+
1652
+ def test_to_list_matrix(test, device):
1653
+ dim = 3
1654
+
1655
+ for ndim in range(1, 5):
1656
+ shape = (dim,) * ndim
1657
+
1658
+ for wptype in wp.types.scalar_types:
1659
+ matrix_types = [
1660
+ # square matrices
1661
+ wp.types.matrix((2, 2), wptype),
1662
+ wp.types.matrix((3, 3), wptype),
1663
+ wp.types.matrix((4, 4), wptype),
1664
+ wp.types.matrix((5, 5), wptype),
1665
+ # non-square matrices
1666
+ wp.types.matrix((2, 3), wptype),
1667
+ wp.types.matrix((3, 2), wptype),
1668
+ wp.types.matrix((3, 4), wptype),
1669
+ wp.types.matrix((4, 3), wptype),
1670
+ ]
1671
+
1672
+ for mattype in matrix_types:
1673
+ fill_value = mattype(42)
1674
+
1675
+ a = wp.full(shape, fill_value, dtype=mattype, device=device)
1676
+ l = a.list()
1677
+
1678
+ test.assertEqual(len(l), a.size)
1679
+ test.assertTrue(all(x == fill_value for x in l))
1680
+
1681
+
1682
+ def test_to_list_struct(test, device):
1683
+ @wp.struct
1684
+ class Inner:
1685
+ h: wp.float16
1686
+ v: wp.vec3
1687
+
1688
+ @wp.struct
1689
+ class ListStruct:
1690
+ i: int
1691
+ f: float
1692
+ h: wp.float16
1693
+ vi: wp.vec2i
1694
+ vf: wp.vec3f
1695
+ vh: wp.vec4h
1696
+ mi: wp.types.matrix((2, 2), int)
1697
+ mf: wp.types.matrix((3, 3), float)
1698
+ mh: wp.types.matrix((4, 4), wp.float16)
1699
+ inner: Inner
1700
+ a1: wp.array(dtype=int)
1701
+ a2: wp.array2d(dtype=float)
1702
+ a3: wp.array3d(dtype=wp.float16)
1703
+ bool: wp.bool
1704
+
1705
+ dim = 3
1706
+
1707
+ s = ListStruct()
1708
+ s.i = 42
1709
+ s.f = 2.5
1710
+ s.h = -1.25
1711
+ s.vi = wp.vec2i(1, 2)
1712
+ s.vf = wp.vec3f(0.1, 0.2, 0.3)
1713
+ s.vh = wp.vec4h(1.0, 2.0, 3.0, 4.0)
1714
+ s.mi = [[1, 2], [3, 4]]
1715
+ s.mf = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
1716
+ s.mh = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
1717
+ s.inner = Inner()
1718
+ s.inner.h = 1.5
1719
+ s.inner.v = [1, 2, 3]
1720
+ s.a1 = wp.empty(1, dtype=int, device=device)
1721
+ s.a2 = wp.empty((1, 1), dtype=float, device=device)
1722
+ s.a3 = wp.empty((1, 1, 1), dtype=wp.float16, device=device)
1723
+ s.bool = True
1724
+
1725
+ for ndim in range(1, 5):
1726
+ shape = (dim,) * ndim
1727
+
1728
+ a = wp.full(shape, s, dtype=ListStruct, device=device)
1729
+ l = a.list()
1730
+
1731
+ for i in range(a.size):
1732
+ test.assertEqual(l[i].i, s.i)
1733
+ test.assertEqual(l[i].f, s.f)
1734
+ test.assertEqual(l[i].h, s.h)
1735
+ test.assertEqual(l[i].vi, s.vi)
1736
+ test.assertEqual(l[i].vf, s.vf)
1737
+ test.assertEqual(l[i].vh, s.vh)
1738
+ test.assertEqual(l[i].mi, s.mi)
1739
+ test.assertEqual(l[i].mf, s.mf)
1740
+ test.assertEqual(l[i].mh, s.mh)
1741
+ test.assertEqual(l[i].bool, s.bool)
1742
+ test.assertEqual(l[i].inner.h, s.inner.h)
1743
+ test.assertEqual(l[i].inner.v, s.inner.v)
1744
+ test.assertEqual(l[i].a1.dtype, s.a1.dtype)
1745
+ test.assertEqual(l[i].a1.ndim, s.a1.ndim)
1746
+ test.assertEqual(l[i].a2.dtype, s.a2.dtype)
1747
+ test.assertEqual(l[i].a2.ndim, s.a2.ndim)
1748
+ test.assertEqual(l[i].a3.dtype, s.a3.dtype)
1749
+ test.assertEqual(l[i].a3.ndim, s.a3.ndim)
671
1750
 
672
1751
 
673
1752
  @wp.kernel
@@ -692,30 +1771,28 @@ def test_array_to_bool(test, device):
692
1771
 
693
1772
  wp.launch(kernel_array_to_bool, dim=1, inputs=[None, arr], device=device)
694
1773
 
1774
+
695
1775
  @wp.struct
696
1776
  class InputStruct:
697
-
698
1777
  param1: int
699
1778
  param2: float
700
1779
  param3: wp.vec3
701
1780
  param4: wp.array(dtype=float)
702
1781
 
1782
+
703
1783
  @wp.struct
704
1784
  class OutputStruct:
705
-
706
1785
  param1: int
707
1786
  param2: float
708
1787
  param3: wp.vec3
709
1788
 
710
1789
 
711
1790
  @wp.kernel
712
- def struct_array_kernel(inputs: wp.array(dtype=InputStruct),
713
- outputs: wp.array(dtype=OutputStruct)):
714
-
1791
+ def struct_array_kernel(inputs: wp.array(dtype=InputStruct), outputs: wp.array(dtype=OutputStruct)):
715
1792
  tid = wp.tid()
716
1793
 
717
1794
  wp.expect_eq(inputs[tid].param1, tid)
718
- wp.expect_eq(inputs[tid].param2, float(tid*tid))
1795
+ wp.expect_eq(inputs[tid].param2, float(tid * tid))
719
1796
 
720
1797
  wp.expect_eq(inputs[tid].param3[0], 1.0)
721
1798
  wp.expect_eq(inputs[tid].param3[1], 2.0)
@@ -725,34 +1802,31 @@ def struct_array_kernel(inputs: wp.array(dtype=InputStruct),
725
1802
  wp.expect_eq(inputs[tid].param4[1], 2.0)
726
1803
  wp.expect_eq(inputs[tid].param4[2], 3.0)
727
1804
 
728
-
729
1805
  o = OutputStruct()
730
1806
  o.param1 = inputs[tid].param1
731
1807
  o.param2 = inputs[tid].param2
732
1808
  o.param3 = inputs[tid].param3
733
-
1809
+
734
1810
  outputs[tid] = o
735
1811
 
736
1812
 
737
1813
  def test_array_of_structs(test, device):
738
-
739
1814
  num_items = 10
740
1815
 
741
1816
  l = []
742
1817
  for i in range(num_items):
743
-
744
1818
  s = InputStruct()
745
1819
  s.param1 = i
746
- s.param2 = float(i*i)
1820
+ s.param2 = float(i * i)
747
1821
  s.param3 = wp.vec3(1.0, 2.0, 3.0)
748
1822
  s.param4 = wp.array([1.0, 2.0, 3.0], dtype=float, device=device)
749
-
1823
+
750
1824
  l.append(s)
751
1825
 
752
1826
  # initialize array from list of structs
753
1827
  inputs = wp.array(l, dtype=InputStruct, device=device)
754
1828
  outputs = wp.zeros(num_items, dtype=OutputStruct, device=device)
755
-
1829
+
756
1830
  # pass to our compute kernel
757
1831
  wp.launch(struct_array_kernel, dim=num_items, inputs=[inputs, outputs], device=device)
758
1832
 
@@ -761,11 +1835,15 @@ def test_array_of_structs(test, device):
761
1835
  out_cptr = outputs.to("cpu").cptr()
762
1836
 
763
1837
  for i in range(num_items):
764
-
765
1838
  test.assertEqual(out_numpy[i][0], l[i].param1)
766
1839
  test.assertEqual(out_numpy[i][1], l[i].param2)
767
1840
  assert_np_equal(out_numpy[i][2], np.array(l[i].param3))
768
1841
 
1842
+ # test named slices of numpy structured array
1843
+ test.assertEqual(out_numpy["param1"][i], l[i].param1)
1844
+ test.assertEqual(out_numpy["param2"][i], l[i].param2)
1845
+ assert_np_equal(out_numpy["param3"][i], np.array(l[i].param3))
1846
+
769
1847
  test.assertEqual(out_list[i].param1, l[i].param1)
770
1848
  test.assertEqual(out_list[i].param2, l[i].param2)
771
1849
  test.assertEqual(out_list[i].param3, l[i].param3)
@@ -777,75 +1855,283 @@ def test_array_of_structs(test, device):
777
1855
 
778
1856
  @wp.struct
779
1857
  class GradStruct:
780
-
781
1858
  param1: int
782
1859
  param2: float
783
1860
  param3: wp.vec3
784
1861
 
1862
+
785
1863
  @wp.kernel
786
- def test_array_of_structs_grad_kernel(inputs: wp.array(dtype=GradStruct),
787
- loss: wp.array(dtype=float)):
788
-
1864
+ def test_array_of_structs_grad_kernel(inputs: wp.array(dtype=GradStruct), loss: wp.array(dtype=float)):
789
1865
  tid = wp.tid()
790
1866
 
791
- wp.atomic_add(loss, 0, inputs[tid].param2*2.0)
1867
+ wp.atomic_add(loss, 0, inputs[tid].param2 * 2.0)
792
1868
 
793
- def test_array_of_structs_grad(test, device):
794
1869
 
1870
+ def test_array_of_structs_grad(test, device):
795
1871
  num_items = 10
796
1872
 
797
1873
  l = []
798
1874
  for i in range(num_items):
799
-
800
1875
  g = GradStruct()
801
1876
  g.param2 = float(i)
802
-
1877
+
803
1878
  l.append(g)
804
1879
 
805
1880
  a = wp.array(l, dtype=GradStruct, device=device, requires_grad=True)
806
1881
  loss = wp.zeros(1, dtype=float, device=device, requires_grad=True)
807
-
1882
+
808
1883
  with wp.Tape() as tape:
809
-
810
1884
  wp.launch(test_array_of_structs_grad_kernel, dim=num_items, inputs=[a, loss], device=device)
811
-
1885
+
812
1886
  tape.backward(loss)
813
1887
 
814
- grads = a.grad.list()
815
- for i in range(num_items):
816
- test.assertEqual(grads[i].param2, 2.0)
1888
+ grads = a.grad.numpy()
1889
+ assert_np_equal(grads["param2"], np.full(num_items, 2.0, dtype=np.float32))
1890
+
1891
+
1892
+ @wp.struct
1893
+ class NumpyStruct:
1894
+ x: int
1895
+ v: wp.vec3
1896
+
1897
+
1898
+ def test_array_of_structs_from_numpy(test, device):
1899
+ num_items = 10
1900
+
1901
+ na = np.zeros(num_items, dtype=NumpyStruct.numpy_dtype())
1902
+ na["x"] = 17
1903
+ na["v"] = (1, 2, 3)
1904
+
1905
+ a = wp.array(data=na, dtype=NumpyStruct, device=device)
1906
+
1907
+ assert_np_equal(a.numpy(), na)
1908
+
1909
+
1910
+ def test_array_of_structs_roundtrip(test, device):
1911
+ num_items = 10
1912
+
1913
+ value = NumpyStruct()
1914
+ value.x = 17
1915
+ value.v = wp.vec3(1.0, 2.0, 3.0)
1916
+
1917
+ # create Warp structured array
1918
+ a = wp.full(num_items, value, device=device)
1919
+
1920
+ # convert to NumPy structured array
1921
+ na = a.numpy()
1922
+
1923
+ expected = np.zeros(num_items, dtype=NumpyStruct.numpy_dtype())
1924
+ expected["x"] = value.x
1925
+ expected["v"] = value.v
1926
+
1927
+ assert_np_equal(na, expected)
1928
+
1929
+ # modify a field
1930
+ na["x"] = 42
1931
+
1932
+ # convert back to Warp array
1933
+ a = wp.from_numpy(na, NumpyStruct, device=device)
1934
+
1935
+ expected["x"] = 42
1936
+
1937
+ assert_np_equal(a.numpy(), expected)
1938
+
817
1939
 
1940
+ def test_array_from_numpy(test, device):
1941
+ arr = np.array((1.0, 2.0, 3.0), dtype=float)
818
1942
 
1943
+ result = wp.from_numpy(arr)
1944
+ expected = wp.array((1.0, 2.0, 3.0), dtype=wp.float32, shape=(3,))
1945
+ assert_np_equal(result.numpy(), expected.numpy())
819
1946
 
820
- def register(parent):
821
- devices = get_test_devices()
1947
+ result = wp.from_numpy(arr, dtype=wp.vec3)
1948
+ expected = wp.array(((1.0, 2.0, 3.0),), dtype=wp.vec3, shape=(1,))
1949
+ assert_np_equal(result.numpy(), expected.numpy())
822
1950
 
823
- class TestArray(parent):
824
- pass
825
-
826
- add_function_test(TestArray, "test_shape", test_shape, devices=devices)
827
- add_function_test(TestArray, "test_flatten", test_flatten, devices=devices)
828
- add_function_test(TestArray, "test_reshape", test_reshape, devices=devices)
829
- add_function_test(TestArray, "test_slicing", test_slicing, devices=devices)
830
- add_function_test(TestArray, "test_transpose", test_transpose, devices=devices)
831
- add_function_test(TestArray, "test_view", test_view, devices=devices)
1951
+ # --------------------------------------------------------------------------
832
1952
 
833
- add_function_test(TestArray, "test_1d_array", test_1d, devices=devices)
834
- add_function_test(TestArray, "test_2d_array", test_2d, devices=devices)
835
- add_function_test(TestArray, "test_3d_array", test_3d, devices=devices)
836
- add_function_test(TestArray, "test_4d_array", test_4d, devices=devices)
837
- add_function_test(TestArray, "test_4d_array_transposed", test_4d_transposed, devices=devices)
838
- add_function_test(TestArray, "test_lower_bound", test_lower_bound, devices=devices)
839
- add_function_test(TestArray, "test_fill_zero", test_fill_zero, devices=devices)
840
- add_function_test(TestArray, "test_round_trip", test_round_trip, devices=devices)
841
- add_function_test(TestArray, "test_large_arrays_fast", test_large_arrays_fast, devices=devices)
842
- add_function_test(TestArray, "test_array_to_bool", test_array_to_bool, devices=devices)
843
- add_function_test(TestArray, "test_array_of_structs", test_array_of_structs, devices=devices)
844
- add_function_test(TestArray, "test_array_of_structs_grad", test_array_of_structs_grad, devices=devices)
1953
+ arr = np.array(((1.0, 2.0, 3.0), (4.0, 5.0, 6.0)), dtype=float)
845
1954
 
846
- return TestArray
1955
+ result = wp.from_numpy(arr)
1956
+ expected = wp.array(((1.0, 2.0, 3.0), (4.0, 5.0, 6.0)), dtype=wp.vec3, shape=(2,))
1957
+ assert_np_equal(result.numpy(), expected.numpy())
1958
+
1959
+ result = wp.from_numpy(arr, dtype=wp.float32)
1960
+ expected = wp.array(((1.0, 2.0, 3.0), (4.0, 5.0, 6.0)), dtype=wp.float32, shape=(2, 3))
1961
+ assert_np_equal(result.numpy(), expected.numpy())
1962
+
1963
+ result = wp.from_numpy(arr, dtype=wp.float32, shape=(6,))
1964
+ expected = wp.array((1.0, 2.0, 3.0, 4.0, 5.0, 6.0), dtype=wp.float32, shape=(6,))
1965
+ assert_np_equal(result.numpy(), expected.numpy())
1966
+
1967
+ # --------------------------------------------------------------------------
1968
+
1969
+ arr = np.array(
1970
+ (
1971
+ (
1972
+ (1.0, 2.0, 3.0, 4.0),
1973
+ (2.0, 3.0, 4.0, 5.0),
1974
+ (3.0, 4.0, 5.0, 6.0),
1975
+ (4.0, 5.0, 6.0, 7.0),
1976
+ ),
1977
+ (
1978
+ (2.0, 3.0, 4.0, 5.0),
1979
+ (3.0, 4.0, 5.0, 6.0),
1980
+ (4.0, 5.0, 6.0, 7.0),
1981
+ (5.0, 6.0, 7.0, 8.0),
1982
+ ),
1983
+ ),
1984
+ dtype=float,
1985
+ )
1986
+
1987
+ result = wp.from_numpy(arr)
1988
+ expected = wp.array(
1989
+ (
1990
+ (
1991
+ (1.0, 2.0, 3.0, 4.0),
1992
+ (2.0, 3.0, 4.0, 5.0),
1993
+ (3.0, 4.0, 5.0, 6.0),
1994
+ (4.0, 5.0, 6.0, 7.0),
1995
+ ),
1996
+ (
1997
+ (2.0, 3.0, 4.0, 5.0),
1998
+ (3.0, 4.0, 5.0, 6.0),
1999
+ (4.0, 5.0, 6.0, 7.0),
2000
+ (5.0, 6.0, 7.0, 8.0),
2001
+ ),
2002
+ ),
2003
+ dtype=wp.mat44,
2004
+ shape=(2,),
2005
+ )
2006
+ assert_np_equal(result.numpy(), expected.numpy())
2007
+
2008
+ result = wp.from_numpy(arr, dtype=wp.float32)
2009
+ expected = wp.array(
2010
+ (
2011
+ (
2012
+ (1.0, 2.0, 3.0, 4.0),
2013
+ (2.0, 3.0, 4.0, 5.0),
2014
+ (3.0, 4.0, 5.0, 6.0),
2015
+ (4.0, 5.0, 6.0, 7.0),
2016
+ ),
2017
+ (
2018
+ (2.0, 3.0, 4.0, 5.0),
2019
+ (3.0, 4.0, 5.0, 6.0),
2020
+ (4.0, 5.0, 6.0, 7.0),
2021
+ (5.0, 6.0, 7.0, 8.0),
2022
+ ),
2023
+ ),
2024
+ dtype=wp.float32,
2025
+ shape=(2, 4, 4),
2026
+ )
2027
+ assert_np_equal(result.numpy(), expected.numpy())
2028
+
2029
+ result = wp.from_numpy(arr, dtype=wp.vec4)
2030
+ expected = wp.array(
2031
+ (
2032
+ (1.0, 2.0, 3.0, 4.0),
2033
+ (2.0, 3.0, 4.0, 5.0),
2034
+ (3.0, 4.0, 5.0, 6.0),
2035
+ (4.0, 5.0, 6.0, 7.0),
2036
+ (2.0, 3.0, 4.0, 5.0),
2037
+ (3.0, 4.0, 5.0, 6.0),
2038
+ (4.0, 5.0, 6.0, 7.0),
2039
+ (5.0, 6.0, 7.0, 8.0),
2040
+ ),
2041
+ dtype=wp.vec4,
2042
+ shape=(8,),
2043
+ )
2044
+ assert_np_equal(result.numpy(), expected.numpy())
2045
+
2046
+ result = wp.from_numpy(arr, dtype=wp.float32, shape=(32,))
2047
+ expected = wp.array(
2048
+ (
2049
+ 1.0,
2050
+ 2.0,
2051
+ 3.0,
2052
+ 4.0,
2053
+ 2.0,
2054
+ 3.0,
2055
+ 4.0,
2056
+ 5.0,
2057
+ 3.0,
2058
+ 4.0,
2059
+ 5.0,
2060
+ 6.0,
2061
+ 4.0,
2062
+ 5.0,
2063
+ 6.0,
2064
+ 7.0,
2065
+ 2.0,
2066
+ 3.0,
2067
+ 4.0,
2068
+ 5.0,
2069
+ 3.0,
2070
+ 4.0,
2071
+ 5.0,
2072
+ 6.0,
2073
+ 4.0,
2074
+ 5.0,
2075
+ 6.0,
2076
+ 7.0,
2077
+ 5.0,
2078
+ 6.0,
2079
+ 7.0,
2080
+ 8.0,
2081
+ ),
2082
+ dtype=wp.float32,
2083
+ shape=(32,),
2084
+ )
2085
+ assert_np_equal(result.numpy(), expected.numpy())
2086
+
2087
+
2088
+ devices = get_test_devices()
2089
+
2090
+
2091
+ class TestArray(unittest.TestCase):
2092
+ pass
2093
+
2094
+
2095
+ add_function_test(TestArray, "test_shape", test_shape, devices=devices)
2096
+ add_function_test(TestArray, "test_flatten", test_flatten, devices=devices)
2097
+ add_function_test(TestArray, "test_reshape", test_reshape, devices=devices)
2098
+ add_function_test(TestArray, "test_slicing", test_slicing, devices=devices)
2099
+ add_function_test(TestArray, "test_transpose", test_transpose, devices=devices)
2100
+ add_function_test(TestArray, "test_view", test_view, devices=devices)
2101
+
2102
+ add_function_test(TestArray, "test_1d_array", test_1d, devices=devices)
2103
+ add_function_test(TestArray, "test_2d_array", test_2d, devices=devices)
2104
+ add_function_test(TestArray, "test_3d_array", test_3d, devices=devices)
2105
+ add_function_test(TestArray, "test_4d_array", test_4d, devices=devices)
2106
+ add_function_test(TestArray, "test_4d_array_transposed", test_4d_transposed, devices=devices)
2107
+
2108
+ add_function_test(TestArray, "test_fill_scalar", test_fill_scalar, devices=devices)
2109
+ add_function_test(TestArray, "test_fill_vector", test_fill_vector, devices=devices)
2110
+ add_function_test(TestArray, "test_fill_matrix", test_fill_matrix, devices=devices)
2111
+ add_function_test(TestArray, "test_fill_struct", test_fill_struct, devices=devices)
2112
+ add_function_test(TestArray, "test_fill_slices", test_fill_slices, devices=devices)
2113
+ add_function_test(TestArray, "test_full_scalar", test_full_scalar, devices=devices)
2114
+ add_function_test(TestArray, "test_full_vector", test_full_vector, devices=devices)
2115
+ add_function_test(TestArray, "test_full_matrix", test_full_matrix, devices=devices)
2116
+ add_function_test(TestArray, "test_full_struct", test_full_struct, devices=devices)
2117
+ add_function_test(TestArray, "test_empty_array", test_empty_array, devices=devices)
2118
+ add_function_test(TestArray, "test_empty_from_numpy", test_empty_from_numpy, devices=devices)
2119
+ add_function_test(TestArray, "test_empty_from_list", test_empty_from_list, devices=devices)
2120
+ add_function_test(TestArray, "test_to_list_scalar", test_to_list_scalar, devices=devices)
2121
+ add_function_test(TestArray, "test_to_list_vector", test_to_list_vector, devices=devices)
2122
+ add_function_test(TestArray, "test_to_list_matrix", test_to_list_matrix, devices=devices)
2123
+ add_function_test(TestArray, "test_to_list_struct", test_to_list_struct, devices=devices)
2124
+
2125
+ add_function_test(TestArray, "test_lower_bound", test_lower_bound, devices=devices)
2126
+ add_function_test(TestArray, "test_round_trip", test_round_trip, devices=devices)
2127
+ add_function_test(TestArray, "test_array_to_bool", test_array_to_bool, devices=devices)
2128
+ add_function_test(TestArray, "test_array_of_structs", test_array_of_structs, devices=devices)
2129
+ add_function_test(TestArray, "test_array_of_structs_grad", test_array_of_structs_grad, devices=devices)
2130
+ add_function_test(TestArray, "test_array_of_structs_from_numpy", test_array_of_structs_from_numpy, devices=devices)
2131
+ add_function_test(TestArray, "test_array_of_structs_roundtrip", test_array_of_structs_roundtrip, devices=devices)
2132
+ add_function_test(TestArray, "test_array_from_numpy", test_array_from_numpy, devices=devices)
847
2133
 
848
2134
 
849
2135
  if __name__ == "__main__":
850
- c = register(unittest.TestCase)
2136
+ wp.build.clear_kernel_cache()
851
2137
  unittest.main(verbosity=2)