warp-lang 1.0.0b5__py3-none-manylinux2014_x86_64.whl → 1.0.0b6__py3-none-manylinux2014_x86_64.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.
Files changed (187) hide show
  1. docs/conf.py +3 -4
  2. examples/env/env_ant.py +1 -1
  3. examples/env/env_cartpole.py +1 -1
  4. examples/env/env_humanoid.py +1 -1
  5. examples/example_dem.py +28 -26
  6. examples/example_diffray.py +37 -30
  7. examples/example_fluid.py +7 -3
  8. examples/example_jacobian_ik.py +1 -1
  9. examples/example_mesh_intersect.py +10 -7
  10. examples/example_nvdb.py +3 -3
  11. examples/example_render_opengl.py +19 -10
  12. examples/example_sim_cartpole.py +9 -5
  13. examples/example_sim_cloth.py +29 -25
  14. examples/example_sim_fk_grad.py +2 -2
  15. examples/example_sim_fk_grad_torch.py +3 -3
  16. examples/example_sim_grad_bounce.py +11 -8
  17. examples/example_sim_grad_cloth.py +12 -9
  18. examples/example_sim_granular.py +2 -2
  19. examples/example_sim_granular_collision_sdf.py +13 -13
  20. examples/example_sim_neo_hookean.py +3 -3
  21. examples/example_sim_particle_chain.py +2 -2
  22. examples/example_sim_quadruped.py +8 -5
  23. examples/example_sim_rigid_chain.py +8 -5
  24. examples/example_sim_rigid_contact.py +13 -10
  25. examples/example_sim_rigid_fem.py +2 -2
  26. examples/example_sim_rigid_gyroscopic.py +2 -2
  27. examples/example_sim_rigid_kinematics.py +1 -1
  28. examples/example_sim_trajopt.py +3 -2
  29. examples/fem/example_apic_fluid.py +5 -7
  30. examples/fem/example_diffusion_mgpu.py +18 -16
  31. warp/__init__.py +3 -2
  32. warp/bin/warp.so +0 -0
  33. warp/build_dll.py +29 -9
  34. warp/builtins.py +206 -7
  35. warp/codegen.py +58 -38
  36. warp/config.py +3 -1
  37. warp/context.py +234 -128
  38. warp/fem/__init__.py +2 -2
  39. warp/fem/cache.py +2 -1
  40. warp/fem/field/nodal_field.py +18 -17
  41. warp/fem/geometry/hexmesh.py +11 -6
  42. warp/fem/geometry/quadmesh_2d.py +16 -12
  43. warp/fem/geometry/tetmesh.py +19 -8
  44. warp/fem/geometry/trimesh_2d.py +18 -7
  45. warp/fem/integrate.py +341 -196
  46. warp/fem/quadrature/__init__.py +1 -1
  47. warp/fem/quadrature/pic_quadrature.py +138 -53
  48. warp/fem/quadrature/quadrature.py +81 -9
  49. warp/fem/space/__init__.py +1 -1
  50. warp/fem/space/basis_space.py +169 -51
  51. warp/fem/space/grid_2d_function_space.py +2 -2
  52. warp/fem/space/grid_3d_function_space.py +2 -2
  53. warp/fem/space/hexmesh_function_space.py +2 -2
  54. warp/fem/space/partition.py +9 -6
  55. warp/fem/space/quadmesh_2d_function_space.py +2 -2
  56. warp/fem/space/shape/cube_shape_function.py +27 -15
  57. warp/fem/space/shape/square_shape_function.py +29 -18
  58. warp/fem/space/tetmesh_function_space.py +2 -2
  59. warp/fem/space/topology.py +10 -0
  60. warp/fem/space/trimesh_2d_function_space.py +2 -2
  61. warp/fem/utils.py +10 -5
  62. warp/native/array.h +49 -8
  63. warp/native/builtin.h +31 -14
  64. warp/native/cuda_util.cpp +8 -3
  65. warp/native/cuda_util.h +1 -0
  66. warp/native/exports.h +1177 -1108
  67. warp/native/intersect.h +4 -4
  68. warp/native/intersect_adj.h +8 -8
  69. warp/native/mat.h +65 -6
  70. warp/native/mesh.h +126 -5
  71. warp/native/quat.h +28 -4
  72. warp/native/vec.h +76 -14
  73. warp/native/warp.cu +1 -6
  74. warp/render/render_opengl.py +261 -109
  75. warp/sim/import_mjcf.py +13 -7
  76. warp/sim/import_urdf.py +14 -14
  77. warp/sim/inertia.py +17 -18
  78. warp/sim/model.py +67 -67
  79. warp/sim/render.py +1 -1
  80. warp/sparse.py +6 -6
  81. warp/stubs.py +19 -81
  82. warp/tape.py +1 -1
  83. warp/tests/__main__.py +3 -6
  84. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  85. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  86. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  87. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  88. warp/tests/aux_test_unresolved_func.py +14 -0
  89. warp/tests/aux_test_unresolved_symbol.py +14 -0
  90. warp/tests/{test_kinematics.py → disabled_kinematics.py} +10 -12
  91. warp/tests/run_coverage_serial.py +31 -0
  92. warp/tests/test_adam.py +102 -106
  93. warp/tests/test_arithmetic.py +39 -40
  94. warp/tests/test_array.py +46 -48
  95. warp/tests/test_array_reduce.py +25 -19
  96. warp/tests/test_atomic.py +62 -26
  97. warp/tests/test_bool.py +16 -11
  98. warp/tests/test_builtins_resolution.py +1292 -0
  99. warp/tests/test_bvh.py +9 -12
  100. warp/tests/test_closest_point_edge_edge.py +53 -57
  101. warp/tests/test_codegen.py +164 -134
  102. warp/tests/test_compile_consts.py +13 -19
  103. warp/tests/test_conditional.py +30 -32
  104. warp/tests/test_copy.py +9 -12
  105. warp/tests/test_ctypes.py +90 -98
  106. warp/tests/test_dense.py +20 -14
  107. warp/tests/test_devices.py +34 -35
  108. warp/tests/test_dlpack.py +74 -75
  109. warp/tests/test_examples.py +215 -97
  110. warp/tests/test_fabricarray.py +15 -21
  111. warp/tests/test_fast_math.py +14 -11
  112. warp/tests/test_fem.py +280 -97
  113. warp/tests/test_fp16.py +19 -15
  114. warp/tests/test_func.py +177 -194
  115. warp/tests/test_generics.py +71 -77
  116. warp/tests/test_grad.py +83 -32
  117. warp/tests/test_grad_customs.py +7 -9
  118. warp/tests/test_hash_grid.py +6 -10
  119. warp/tests/test_import.py +9 -23
  120. warp/tests/test_indexedarray.py +19 -21
  121. warp/tests/test_intersect.py +15 -9
  122. warp/tests/test_large.py +17 -19
  123. warp/tests/test_launch.py +14 -17
  124. warp/tests/test_lerp.py +63 -63
  125. warp/tests/test_lvalue.py +84 -35
  126. warp/tests/test_marching_cubes.py +9 -13
  127. warp/tests/test_mat.py +388 -3004
  128. warp/tests/test_mat_lite.py +9 -12
  129. warp/tests/test_mat_scalar_ops.py +2889 -0
  130. warp/tests/test_math.py +10 -11
  131. warp/tests/test_matmul.py +104 -100
  132. warp/tests/test_matmul_lite.py +72 -98
  133. warp/tests/test_mesh.py +35 -32
  134. warp/tests/test_mesh_query_aabb.py +18 -25
  135. warp/tests/test_mesh_query_point.py +39 -23
  136. warp/tests/test_mesh_query_ray.py +9 -21
  137. warp/tests/test_mlp.py +8 -9
  138. warp/tests/test_model.py +89 -93
  139. warp/tests/test_modules_lite.py +15 -25
  140. warp/tests/test_multigpu.py +87 -114
  141. warp/tests/test_noise.py +10 -12
  142. warp/tests/test_operators.py +14 -21
  143. warp/tests/test_options.py +10 -11
  144. warp/tests/test_pinned.py +16 -18
  145. warp/tests/test_print.py +16 -20
  146. warp/tests/test_quat.py +121 -88
  147. warp/tests/test_rand.py +12 -13
  148. warp/tests/test_reload.py +27 -32
  149. warp/tests/test_rounding.py +7 -10
  150. warp/tests/test_runlength_encode.py +105 -106
  151. warp/tests/test_smoothstep.py +8 -9
  152. warp/tests/test_snippet.py +13 -22
  153. warp/tests/test_sparse.py +30 -29
  154. warp/tests/test_spatial.py +179 -174
  155. warp/tests/test_streams.py +100 -107
  156. warp/tests/test_struct.py +98 -67
  157. warp/tests/test_tape.py +11 -17
  158. warp/tests/test_torch.py +89 -86
  159. warp/tests/test_transient_module.py +9 -12
  160. warp/tests/test_types.py +328 -50
  161. warp/tests/test_utils.py +217 -218
  162. warp/tests/test_vec.py +133 -2133
  163. warp/tests/test_vec_lite.py +8 -11
  164. warp/tests/test_vec_scalar_ops.py +2099 -0
  165. warp/tests/test_volume.py +391 -382
  166. warp/tests/test_volume_write.py +122 -135
  167. warp/tests/unittest_serial.py +35 -0
  168. warp/tests/unittest_suites.py +291 -0
  169. warp/tests/{test_base.py → unittest_utils.py} +138 -25
  170. warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
  171. warp/tests/{test_debug.py → walkthough_debug.py} +2 -15
  172. warp/thirdparty/unittest_parallel.py +257 -54
  173. warp/types.py +119 -98
  174. warp/utils.py +14 -0
  175. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/METADATA +2 -1
  176. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/RECORD +182 -178
  177. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
  178. warp/tests/test_all.py +0 -239
  179. warp/tests/test_conditional_unequal_types_kernels.py +0 -14
  180. warp/tests/test_coverage.py +0 -38
  181. warp/tests/test_unresolved_func.py +0 -7
  182. warp/tests/test_unresolved_symbol.py +0 -7
  183. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  184. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  185. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  186. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
  187. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
@@ -9,15 +9,25 @@ import ctypes
9
9
  import ctypes.util
10
10
  import os
11
11
  import sys
12
+ import unittest
12
13
 
13
14
  import numpy as np
15
+
14
16
  import warp as wp
15
17
 
18
+ try:
19
+ import pxr # noqa: F401
20
+
21
+ USD_AVAILABLE = True
22
+ except ImportError as e:
23
+ USD_AVAILABLE = False
24
+ print(f"Skipping USD tests for reason: {e}")
25
+
16
26
  # default test mode (see get_test_devices())
17
27
  # "basic" - only run on CPU and first GPU device
18
28
  # "unique" - run on CPU and all unique GPU arches
19
29
  # "all" - run on all devices
20
- test_mode = "basic"
30
+ test_mode = "unique"
21
31
 
22
32
  try:
23
33
  if sys.platform == "win32":
@@ -29,7 +39,40 @@ except OSError:
29
39
  LIBC = None
30
40
 
31
41
 
42
+ def get_unique_cuda_test_devices(mode=None):
43
+ """Returns a list of unique CUDA devices according to the CUDA arch.
44
+
45
+ If ``mode`` is ``None``, the ``global test_mode`` value will be used and
46
+ this list will be a subset of the devices returned from ``get_test_devices()``.
47
+ """
48
+
49
+ if mode is None:
50
+ global test_mode
51
+ mode = test_mode
52
+
53
+ if mode == "basic":
54
+ cuda_devices = [wp.get_device("cuda:0")]
55
+ else:
56
+ cuda_devices = wp.get_cuda_devices()
57
+
58
+ unique_cuda_devices = {}
59
+ for d in cuda_devices:
60
+ if d.arch not in unique_cuda_devices:
61
+ unique_cuda_devices[d.arch] = d
62
+
63
+ return list(unique_cuda_devices.values())
64
+
65
+
32
66
  def get_test_devices(mode=None):
67
+ """Returns a list of devices based on the mode selected.
68
+
69
+ Args:
70
+ mode (str, optional): The testing mode to specify which devices to include. If not provided or ``None``, the
71
+ ``global test_mode`` value will be used.
72
+ "basic" (default): Returns the CPU and the first GPU device when available.
73
+ "unique": Returns the CPU and all unique GPU architectures.
74
+ "all": Returns all available devices.
75
+ """
33
76
  if mode is None:
34
77
  global test_mode
35
78
  mode = test_mode
@@ -48,14 +91,7 @@ def get_test_devices(mode=None):
48
91
  if wp.is_cpu_available():
49
92
  devices.append(wp.get_device("cpu"))
50
93
 
51
- cuda_devices = wp.get_cuda_devices()
52
-
53
- unique_cuda_devices = {}
54
- for d in cuda_devices:
55
- if d.arch not in unique_cuda_devices:
56
- unique_cuda_devices[d.arch] = d
57
-
58
- devices.extend(list(unique_cuda_devices.values()))
94
+ devices.extend(get_unique_cuda_test_devices())
59
95
 
60
96
  # run on all devices
61
97
  elif mode == "all":
@@ -78,7 +114,8 @@ class StdOutCapture:
78
114
  self.target = os.dup(self.saved.fileno())
79
115
 
80
116
  # create temporary capture stream
81
- import io, tempfile
117
+ import io
118
+ import tempfile
82
119
 
83
120
  self.tempfile = io.TextIOWrapper(
84
121
  tempfile.TemporaryFile(buffering=0), encoding="utf-8", errors="replace", newline="", write_through=True
@@ -126,12 +163,8 @@ class CheckOutput:
126
163
  self.test.fail(f"Unexpected output:\n'{s.rstrip()}'")
127
164
 
128
165
 
129
- def assert_array_equal(result, expect):
130
- a = result.numpy()
131
- b = expect.numpy()
132
-
133
- if (a == b).all() == False:
134
- raise AssertionError(f"Unexpected result, got: {a} expected: {b}")
166
+ def assert_array_equal(result: wp.array, expect: wp.array):
167
+ np.testing.assert_equal(result.numpy(), expect.numpy())
135
168
 
136
169
 
137
170
  def assert_np_equal(result, expect, tol=0.0):
@@ -139,7 +172,7 @@ def assert_np_equal(result, expect, tol=0.0):
139
172
  b = expect.flatten()
140
173
 
141
174
  if tol == 0.0:
142
- if (a == b).all() == False:
175
+ if not (a == b).all():
143
176
  raise AssertionError(f"Unexpected result, got: {a} expected: {b}")
144
177
 
145
178
  else:
@@ -153,7 +186,6 @@ def assert_np_equal(result, expect, tol=0.0):
153
186
 
154
187
  # if check_output is True any output to stdout will be treated as an error
155
188
  def create_test_func(func, device, check_output, **kwargs):
156
-
157
189
  # pass args to func
158
190
  def test_func(self):
159
191
  if check_output:
@@ -165,6 +197,11 @@ def create_test_func(func, device, check_output, **kwargs):
165
197
  return test_func
166
198
 
167
199
 
200
+ def skip_test_func(self):
201
+ # A function to use so we can tell unittest that the test was skipped.
202
+ self.skipTest("No suitable devices to run the test.")
203
+
204
+
168
205
  def sanitize_identifier(s):
169
206
  """replace all non-identifier characters with '_'"""
170
207
 
@@ -174,15 +211,25 @@ def sanitize_identifier(s):
174
211
  else:
175
212
  import re
176
213
 
177
- return re.sub("\W|^(?=\d)", "_", s)
214
+ return re.sub(r"\W|^(?=\d)", "_", s)
178
215
 
179
216
 
180
217
  def add_function_test(cls, name, func, devices=None, check_output=True, **kwargs):
181
218
  if devices is None:
182
219
  setattr(cls, name, create_test_func(func, None, check_output, **kwargs))
220
+ elif isinstance(devices, list):
221
+ if not devices:
222
+ # No devices to run this test
223
+ setattr(cls, name, skip_test_func)
224
+ else:
225
+ for device in devices:
226
+ setattr(
227
+ cls,
228
+ name + "_" + sanitize_identifier(device),
229
+ create_test_func(func, device, check_output, **kwargs),
230
+ )
183
231
  else:
184
- for device in devices:
185
- setattr(cls, name + "_" + sanitize_identifier(device), create_test_func(func, device, check_output, **kwargs))
232
+ setattr(cls, name + "_" + sanitize_identifier(devices), create_test_func(func, devices, check_output, **kwargs))
186
233
 
187
234
 
188
235
  def add_kernel_test(cls, kernel, dim, name=None, expect=None, inputs=None, devices=None):
@@ -217,13 +264,79 @@ def add_kernel_test(cls, kernel, dim, name=None, expect=None, inputs=None, devic
217
264
 
218
265
  # register test func with class for the given devices
219
266
  for d in devices:
220
- # use a lambda to forward the device to the inner test function
221
- test_lambda = lambda test, device=d: test_func(test, device)
222
- setattr(cls, name + "_" + sanitize_identifier(d), test_lambda)
267
+ # use a function to forward the device to the inner test function
268
+ def test_func_wrapper(test, device=d):
269
+ test_func(test, device)
270
+
271
+ setattr(cls, name + "_" + sanitize_identifier(d), test_func_wrapper)
223
272
 
224
273
 
225
- # helper that first calls the test function to generate all kernel permuations
274
+ # helper that first calls the test function to generate all kernel permutations
226
275
  # so that compilation is done in one-shot instead of per-test
227
276
  def add_function_test_register_kernel(cls, name, func, devices=None, **kwargs):
228
277
  func(None, None, **kwargs, register_kernels=True)
229
278
  add_function_test(cls, name, func, devices=devices, **kwargs)
279
+
280
+
281
+ class TeamCityTestResult(unittest.TextTestResult):
282
+ """This class will report each test result to TeamCity"""
283
+
284
+ def __init__(self, stream, descriptions, verbosity):
285
+ super(TeamCityTestResult, self).__init__(stream, descriptions, verbosity)
286
+
287
+ def addSuccess(self, test):
288
+ super(TeamCityTestResult, self).addSuccess(test)
289
+ self.reportSuccess(test)
290
+
291
+ def addError(self, test, err):
292
+ super(TeamCityTestResult, self).addError(test, err)
293
+ self.reportFailure(test)
294
+
295
+ def addFailure(self, test, err):
296
+ super(TeamCityTestResult, self).addFailure(test, err)
297
+ self.reportFailure(test)
298
+
299
+ def addSkip(self, test, reason):
300
+ super(TeamCityTestResult, self).addSkip(test, reason)
301
+
302
+ def addExpectedFailure(self, test, err):
303
+ super(TeamCityTestResult, self).addExpectedFailure(test, err)
304
+ self.reportSuccess(test)
305
+
306
+ def addUnexpectedSuccess(self, test):
307
+ super(TeamCityTestResult, self).addUnexpectedSuccess(test)
308
+ self.reportFailure(test)
309
+
310
+ def reportSuccess(self, test):
311
+ test_id = test.id()
312
+ print(f"##teamcity[testStarted name='{test_id}']")
313
+ print(f"##teamcity[testFinished name='{test_id}']")
314
+
315
+ def reportFailure(self, test):
316
+ test_id = test.id()
317
+ print(f"##teamcity[testStarted name='{test_id}']")
318
+ print(f"##teamcity[testFailed name='{test_id}']")
319
+ print(f"##teamcity[testFinished name='{test_id}']")
320
+
321
+
322
+ class TeamCityTestRunner(unittest.TextTestRunner):
323
+ """Test runner that will report test results to TeamCity if running in TeamCity"""
324
+
325
+ def __init__(self, **kwargs):
326
+ self.running_in_teamcity = os.environ.get("TEAMCITY_VERSION") is not None
327
+ if self.running_in_teamcity:
328
+ kwargs["resultclass"] = TeamCityTestResult
329
+ super(TeamCityTestRunner, self).__init__(**kwargs)
330
+
331
+ def run(self, test, name):
332
+ if self.running_in_teamcity:
333
+ print(f"##teamcity[testSuiteStarted name='{name}']")
334
+
335
+ result = super(TeamCityTestRunner, self).run(test)
336
+
337
+ if self.running_in_teamcity:
338
+ print(f"##teamcity[testSuiteFinished name='{name}']")
339
+ if not result.wasSuccessful():
340
+ print("##teamcity[buildStatus status='FAILURE']")
341
+
342
+ return result
@@ -1,8 +1,17 @@
1
- import warp as wp
1
+ # Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved.
2
+ # NVIDIA CORPORATION and its licensors retain all intellectual property
3
+ # and proprietary rights in and to this software, related documentation
4
+ # and any modifications thereto. Any use, reproduction, disclosure or
5
+ # distribution of this software and related documentation without an express
6
+ # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
+
2
8
  import numpy as np
3
9
 
10
+ import warp as wp
11
+
4
12
  wp.init()
5
13
 
14
+
6
15
  @wp.kernel
7
16
  def arange(out: wp.array(dtype=int)):
8
17
  tid = wp.tid()
@@ -28,7 +37,7 @@ for i in range(5):
28
37
 
29
38
  graph = wp.capture_end()
30
39
 
31
- #---------------------------------------
40
+ # ---------------------------------------
32
41
 
33
42
  ref = np.arange(0, n, dtype=int)
34
43
  wp.capture_launch(graph)
@@ -37,7 +46,7 @@ for i in range(5):
37
46
  print(arrays[i].numpy())
38
47
 
39
48
 
40
- #---------------------------------------
49
+ # ---------------------------------------
41
50
 
42
51
  n = 16
43
52
  arrays = []
@@ -49,7 +58,7 @@ for i in range(5):
49
58
  for i in range(5):
50
59
  cmd.set_dim(n)
51
60
  cmd.set_param(arrays[i])
52
-
61
+
53
62
  cmd.update_graph()
54
63
 
55
64
 
@@ -60,4 +69,3 @@ ref = np.arange(0, n, dtype=int)
60
69
 
61
70
  for i in range(5):
62
71
  print(arrays[i].numpy())
63
-
@@ -49,10 +49,7 @@
49
49
  #
50
50
  ####################################################################################################
51
51
 
52
- import unittest
53
-
54
52
  import warp as wp
55
- from warp.tests.test_base import *
56
53
 
57
54
  # The init() function prints the directory of the kernel cache which contains the .cpp files
58
55
  # generated from Warp kernels. You can put breakpoints in these C++ files through Visual Studio Code,
@@ -67,7 +64,7 @@ assert wp.context.runtime.core.is_debug_enabled(), "Warp must be built in debug
67
64
 
68
65
 
69
66
  @wp.kernel
70
- def test_breakpoint(n: int):
67
+ def example_breakpoint(n: int):
71
68
  a = int(0)
72
69
 
73
70
  for i in range(0, n):
@@ -83,16 +80,6 @@ def test_breakpoint(n: int):
83
80
  wp.expect_eq(a, 5)
84
81
 
85
82
 
86
- def register(parent):
87
- class TestDebug(parent):
88
- pass
89
-
90
- add_kernel_test(TestDebug, name="test_breakpoint", kernel=test_breakpoint, dim=1, inputs=[10], devices=["cpu"])
91
-
92
- return TestDebug
93
-
94
-
95
83
  if __name__ == "__main__":
96
84
  wp.build.clear_kernel_cache()
97
- _ = register(unittest.TestCase)
98
- unittest.main(verbosity=2, failfast=True)
85
+ wp.launch(example_breakpoint, dim=1, inputs=[10], device="cpu")