warp-lang 0.11.0__py3-none-manylinux2014_x86_64.whl → 1.0.0__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.

Potentially problematic release.


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

Files changed (170) hide show
  1. warp/__init__.py +8 -0
  2. warp/bin/warp-clang.so +0 -0
  3. warp/bin/warp.so +0 -0
  4. warp/build.py +7 -6
  5. warp/build_dll.py +70 -79
  6. warp/builtins.py +10 -6
  7. warp/codegen.py +51 -19
  8. warp/config.py +7 -8
  9. warp/constants.py +3 -0
  10. warp/context.py +948 -245
  11. warp/dlpack.py +198 -113
  12. warp/examples/assets/bunny.usd +0 -0
  13. warp/examples/assets/cartpole.urdf +110 -0
  14. warp/examples/assets/crazyflie.usd +0 -0
  15. warp/examples/assets/cube.usda +42 -0
  16. warp/examples/assets/nv_ant.xml +92 -0
  17. warp/examples/assets/nv_humanoid.xml +183 -0
  18. warp/examples/assets/quadruped.urdf +268 -0
  19. warp/examples/assets/rocks.nvdb +0 -0
  20. warp/examples/assets/rocks.usd +0 -0
  21. warp/examples/assets/sphere.usda +56 -0
  22. warp/examples/assets/torus.usda +105 -0
  23. warp/examples/benchmarks/benchmark_api.py +383 -0
  24. warp/examples/benchmarks/benchmark_cloth.py +279 -0
  25. warp/examples/benchmarks/benchmark_cloth_cupy.py +88 -0
  26. warp/examples/benchmarks/benchmark_cloth_jax.py +100 -0
  27. warp/examples/benchmarks/benchmark_cloth_numba.py +142 -0
  28. warp/examples/benchmarks/benchmark_cloth_numpy.py +77 -0
  29. warp/examples/benchmarks/benchmark_cloth_pytorch.py +86 -0
  30. warp/examples/benchmarks/benchmark_cloth_taichi.py +112 -0
  31. warp/examples/benchmarks/benchmark_cloth_warp.py +146 -0
  32. warp/examples/benchmarks/benchmark_launches.py +295 -0
  33. warp/examples/core/example_dem.py +221 -0
  34. warp/examples/core/example_fluid.py +267 -0
  35. warp/examples/core/example_graph_capture.py +129 -0
  36. warp/examples/core/example_marching_cubes.py +177 -0
  37. warp/examples/core/example_mesh.py +154 -0
  38. warp/examples/core/example_mesh_intersect.py +193 -0
  39. warp/examples/core/example_nvdb.py +169 -0
  40. warp/examples/core/example_raycast.py +89 -0
  41. warp/examples/core/example_raymarch.py +178 -0
  42. warp/examples/core/example_render_opengl.py +141 -0
  43. warp/examples/core/example_sph.py +389 -0
  44. warp/examples/core/example_torch.py +181 -0
  45. warp/examples/core/example_wave.py +249 -0
  46. warp/examples/fem/bsr_utils.py +380 -0
  47. warp/examples/fem/example_apic_fluid.py +391 -0
  48. warp/examples/fem/example_convection_diffusion.py +168 -0
  49. warp/examples/fem/example_convection_diffusion_dg.py +209 -0
  50. warp/examples/fem/example_convection_diffusion_dg0.py +194 -0
  51. warp/examples/fem/example_deformed_geometry.py +159 -0
  52. warp/examples/fem/example_diffusion.py +173 -0
  53. warp/examples/fem/example_diffusion_3d.py +152 -0
  54. warp/examples/fem/example_diffusion_mgpu.py +214 -0
  55. warp/examples/fem/example_mixed_elasticity.py +222 -0
  56. warp/examples/fem/example_navier_stokes.py +243 -0
  57. warp/examples/fem/example_stokes.py +192 -0
  58. warp/examples/fem/example_stokes_transfer.py +249 -0
  59. warp/examples/fem/mesh_utils.py +109 -0
  60. warp/examples/fem/plot_utils.py +287 -0
  61. warp/examples/optim/example_bounce.py +248 -0
  62. warp/examples/optim/example_cloth_throw.py +210 -0
  63. warp/examples/optim/example_diffray.py +535 -0
  64. warp/examples/optim/example_drone.py +850 -0
  65. warp/examples/optim/example_inverse_kinematics.py +169 -0
  66. warp/examples/optim/example_inverse_kinematics_torch.py +170 -0
  67. warp/examples/optim/example_spring_cage.py +234 -0
  68. warp/examples/optim/example_trajectory.py +201 -0
  69. warp/examples/sim/example_cartpole.py +128 -0
  70. warp/examples/sim/example_cloth.py +184 -0
  71. warp/examples/sim/example_granular.py +113 -0
  72. warp/examples/sim/example_granular_collision_sdf.py +185 -0
  73. warp/examples/sim/example_jacobian_ik.py +213 -0
  74. warp/examples/sim/example_particle_chain.py +106 -0
  75. warp/examples/sim/example_quadruped.py +179 -0
  76. warp/examples/sim/example_rigid_chain.py +191 -0
  77. warp/examples/sim/example_rigid_contact.py +176 -0
  78. warp/examples/sim/example_rigid_force.py +126 -0
  79. warp/examples/sim/example_rigid_gyroscopic.py +97 -0
  80. warp/examples/sim/example_rigid_soft_contact.py +124 -0
  81. warp/examples/sim/example_soft_body.py +178 -0
  82. warp/fabric.py +29 -20
  83. warp/fem/cache.py +0 -1
  84. warp/fem/dirichlet.py +0 -2
  85. warp/fem/integrate.py +0 -1
  86. warp/jax.py +45 -0
  87. warp/jax_experimental.py +339 -0
  88. warp/native/builtin.h +12 -0
  89. warp/native/bvh.cu +18 -18
  90. warp/native/clang/clang.cpp +8 -3
  91. warp/native/cuda_util.cpp +94 -5
  92. warp/native/cuda_util.h +35 -6
  93. warp/native/cutlass_gemm.cpp +1 -1
  94. warp/native/cutlass_gemm.cu +4 -1
  95. warp/native/error.cpp +66 -0
  96. warp/native/error.h +27 -0
  97. warp/native/mesh.cu +2 -2
  98. warp/native/reduce.cu +4 -4
  99. warp/native/runlength_encode.cu +2 -2
  100. warp/native/scan.cu +2 -2
  101. warp/native/sparse.cu +0 -1
  102. warp/native/temp_buffer.h +2 -2
  103. warp/native/warp.cpp +95 -60
  104. warp/native/warp.cu +1053 -218
  105. warp/native/warp.h +49 -32
  106. warp/optim/linear.py +33 -16
  107. warp/render/render_opengl.py +202 -101
  108. warp/render/render_usd.py +82 -40
  109. warp/sim/__init__.py +13 -4
  110. warp/sim/articulation.py +4 -5
  111. warp/sim/collide.py +320 -175
  112. warp/sim/import_mjcf.py +25 -30
  113. warp/sim/import_urdf.py +94 -63
  114. warp/sim/import_usd.py +51 -36
  115. warp/sim/inertia.py +3 -2
  116. warp/sim/integrator.py +233 -0
  117. warp/sim/integrator_euler.py +447 -469
  118. warp/sim/integrator_featherstone.py +1991 -0
  119. warp/sim/integrator_xpbd.py +1420 -640
  120. warp/sim/model.py +765 -487
  121. warp/sim/particles.py +2 -1
  122. warp/sim/render.py +35 -13
  123. warp/sim/utils.py +222 -11
  124. warp/stubs.py +8 -0
  125. warp/tape.py +16 -1
  126. warp/tests/aux_test_grad_customs.py +23 -0
  127. warp/tests/test_array.py +190 -1
  128. warp/tests/test_async.py +656 -0
  129. warp/tests/test_bool.py +50 -0
  130. warp/tests/test_dlpack.py +164 -11
  131. warp/tests/test_examples.py +166 -74
  132. warp/tests/test_fem.py +8 -1
  133. warp/tests/test_generics.py +15 -5
  134. warp/tests/test_grad.py +1 -1
  135. warp/tests/test_grad_customs.py +172 -12
  136. warp/tests/test_jax.py +254 -0
  137. warp/tests/test_large.py +29 -6
  138. warp/tests/test_launch.py +25 -0
  139. warp/tests/test_linear_solvers.py +20 -3
  140. warp/tests/test_matmul.py +61 -16
  141. warp/tests/test_matmul_lite.py +13 -13
  142. warp/tests/test_mempool.py +186 -0
  143. warp/tests/test_multigpu.py +3 -0
  144. warp/tests/test_options.py +16 -2
  145. warp/tests/test_peer.py +137 -0
  146. warp/tests/test_print.py +3 -1
  147. warp/tests/test_quat.py +23 -0
  148. warp/tests/test_sim_kinematics.py +97 -0
  149. warp/tests/test_snippet.py +126 -3
  150. warp/tests/test_streams.py +108 -79
  151. warp/tests/test_torch.py +16 -8
  152. warp/tests/test_utils.py +32 -27
  153. warp/tests/test_verify_fp.py +65 -0
  154. warp/tests/test_volume.py +1 -1
  155. warp/tests/unittest_serial.py +2 -0
  156. warp/tests/unittest_suites.py +12 -0
  157. warp/tests/unittest_utils.py +14 -7
  158. warp/thirdparty/unittest_parallel.py +15 -3
  159. warp/torch.py +10 -8
  160. warp/types.py +363 -246
  161. warp/utils.py +143 -19
  162. warp_lang-1.0.0.dist-info/LICENSE.md +126 -0
  163. warp_lang-1.0.0.dist-info/METADATA +394 -0
  164. {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/RECORD +167 -86
  165. warp/sim/optimizer.py +0 -138
  166. warp_lang-0.11.0.dist-info/LICENSE.md +0 -36
  167. warp_lang-0.11.0.dist-info/METADATA +0 -238
  168. /warp/tests/{walkthough_debug.py → walkthrough_debug.py} +0 -0
  169. {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/WHEEL +0 -0
  170. {warp_lang-0.11.0.dist-info → warp_lang-1.0.0.dist-info}/top_level.txt +0 -0
warp/dlpack.py CHANGED
@@ -5,6 +5,9 @@
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
+ # Python specification for DLpack:
9
+ # https://dmlc.github.io/dlpack/latest/python_spec.html
10
+
8
11
  import warp
9
12
  import ctypes
10
13
 
@@ -14,77 +17,104 @@ from warp.thirdparty.dlpack import (
14
17
  DLDeviceType,
15
18
  DLDataType,
16
19
  DLDataTypeCode,
17
- DLTensor,
18
20
  _c_str_dltensor,
19
21
  )
20
22
 
21
- ctypes.pythonapi.PyMem_RawMalloc.restype = ctypes.c_void_p
22
- ctypes.pythonapi.PyMem_RawFree.argtypes = [ctypes.c_void_p]
23
+ _c_str_used_dltensor = b"used_dltensor"
23
24
 
24
- ctypes.pythonapi.PyCapsule_New.restype = ctypes.py_object
25
- ctypes.pythonapi.PyCapsule_New.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p]
25
+ PyMem_RawMalloc = ctypes.pythonapi.PyMem_RawMalloc
26
+ PyMem_RawMalloc.argtypes = [ctypes.c_size_t]
27
+ PyMem_RawMalloc.restype = ctypes.c_void_p
26
28
 
27
- ctypes.pythonapi.PyCapsule_IsValid.restype = ctypes.c_int
28
- ctypes.pythonapi.PyCapsule_IsValid.argtypes = [ctypes.py_object, ctypes.c_char_p]
29
+ PyMem_RawFree = ctypes.pythonapi.PyMem_RawFree
30
+ PyMem_RawFree.argtypes = [ctypes.c_void_p]
31
+ PyMem_RawFree.restype = None
29
32
 
30
- ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
31
- ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p]
33
+ Py_IncRef = ctypes.pythonapi.Py_IncRef
34
+ Py_IncRef.argtypes = [ctypes.py_object]
35
+ Py_IncRef.restype = None
32
36
 
37
+ Py_DecRef = ctypes.pythonapi.Py_DecRef
38
+ Py_DecRef.argtypes = [ctypes.py_object]
39
+ Py_DecRef.restype = None
33
40
 
34
- class _Holder:
35
- def __init__(self, wp_array) -> None:
36
- self.wp_array = wp_array
41
+ PyCapsule_Destructor = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
37
42
 
38
- def _as_manager_ctx(self) -> ctypes.c_void_p:
39
- py_obj = ctypes.py_object(self)
40
- py_obj_ptr = ctypes.pointer(py_obj)
41
- ctypes.pythonapi.Py_IncRef(py_obj)
42
- ctypes.pythonapi.Py_IncRef(ctypes.py_object(py_obj_ptr))
43
- return ctypes.cast(py_obj_ptr, ctypes.c_void_p)
43
+ PyCapsule_New = ctypes.pythonapi.PyCapsule_New
44
+ PyCapsule_New.argtypes = [ctypes.c_void_p, ctypes.c_char_p, PyCapsule_Destructor]
45
+ PyCapsule_New.restype = ctypes.py_object
44
46
 
47
+ PyCapsule_IsValid = ctypes.pythonapi.PyCapsule_IsValid
48
+ PyCapsule_IsValid.argtypes = [ctypes.py_object, ctypes.c_char_p]
49
+ PyCapsule_IsValid.restype = ctypes.c_int
45
50
 
46
- @ctypes.CFUNCTYPE(None, ctypes.c_void_p)
47
- def _warp_array_deleter(handle: ctypes.c_void_p) -> None:
48
- """A function to deallocate the memory of a Warp array."""
51
+ PyCapsule_GetPointer = ctypes.pythonapi.PyCapsule_GetPointer
52
+ PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p]
53
+ PyCapsule_GetPointer.restype = ctypes.c_void_p
54
+
55
+ PyCapsule_SetName = ctypes.pythonapi.PyCapsule_SetName
56
+ PyCapsule_SetName.argtypes = [ctypes.py_object, ctypes.c_char_p]
57
+ PyCapsule_SetName.restype = ctypes.c_int
58
+
59
+
60
+ class _DLPackTensorHolder:
61
+ """Class responsible for deleting DLManagedTensor memory after ownership is transferred from a capsule."""
49
62
 
50
- dl_managed_tensor = DLManagedTensor.from_address(handle)
51
- py_obj_ptr = ctypes.cast(dl_managed_tensor.manager_ctx, ctypes.POINTER(ctypes.py_object))
52
- py_obj = py_obj_ptr.contents
53
- ctypes.pythonapi.Py_DecRef(py_obj)
54
- ctypes.pythonapi.Py_DecRef(ctypes.py_object(py_obj_ptr))
55
- ctypes.pythonapi.PyMem_RawFree(handle)
63
+ def __init__(self, mem_ptr):
64
+ self.mem_ptr = mem_ptr
65
+
66
+ def __del__(self):
67
+ managed_tensor = DLManagedTensor.from_address(self.mem_ptr)
68
+ if managed_tensor.deleter:
69
+ managed_tensor.deleter(self.mem_ptr)
56
70
 
57
71
 
58
72
  @ctypes.CFUNCTYPE(None, ctypes.c_void_p)
59
- def _warp_pycapsule_deleter(handle: ctypes.c_void_p) -> None:
60
- """A function to deallocate a pycapsule that wraps a Warp array."""
73
+ def _dlpack_tensor_deleter(managed_ptr) -> None:
74
+ """A function to deallocate a DLManagedTensor."""
61
75
 
62
- pycapsule: ctypes.py_object = ctypes.cast(handle, ctypes.py_object)
63
- if ctypes.pythonapi.PyCapsule_IsValid(pycapsule, _c_str_dltensor):
64
- dl_managed_tensor = ctypes.pythonapi.PyCapsule_GetPointer(pycapsule, _c_str_dltensor)
65
- _warp_array_deleter(dl_managed_tensor)
66
- ctypes.pythonapi.PyCapsule_SetDestructor(pycapsule, None)
76
+ managed_tensor = DLManagedTensor.from_address(managed_ptr)
67
77
 
78
+ # unreference the source array
79
+ manager = ctypes.cast(managed_tensor.manager_ctx, ctypes.py_object)
80
+ ctypes.pythonapi.Py_DecRef(manager)
68
81
 
69
- def device_to_dlpack(wp_device) -> DLDevice:
70
- d = warp.get_device(wp_device)
71
-
72
- if d.is_cpu:
73
- device_type = DLDeviceType.kDLCPU
74
- device_id = 0
75
- elif d.is_cuda:
76
- device_type = DLDeviceType.kDLCUDA
77
- device_id = d.ordinal
78
- else:
79
- raise RuntimeError("Unhandled device type converting to dlpack")
82
+ # free the DLManagedTensor memory, including shape and strides
83
+ PyMem_RawFree(ctypes.c_void_p(managed_ptr))
84
+
85
+
86
+ @PyCapsule_Destructor
87
+ def _dlpack_capsule_deleter(ptr) -> None:
88
+ """Destructor for a capsule holding a DLManagedTensor."""
89
+
90
+ capsule = ctypes.cast(ptr, ctypes.py_object)
80
91
 
92
+ if ctypes.pythonapi.PyCapsule_IsValid(capsule, _c_str_dltensor):
93
+ managed_ptr = ctypes.pythonapi.PyCapsule_GetPointer(capsule, _c_str_dltensor)
94
+ managed_tensor = DLManagedTensor.from_address(managed_ptr)
95
+ if managed_tensor.deleter:
96
+ managed_tensor.deleter(managed_ptr)
97
+
98
+
99
+ def _device_to_dlpack(wp_device: warp.context.Device) -> DLDevice:
81
100
  dl_device = DLDevice()
82
- dl_device.device_type = device_type
83
- dl_device.device_id = device_id
101
+
102
+ if wp_device.is_cpu:
103
+ dl_device.device_type = DLDeviceType.kDLCPU
104
+ dl_device.device_id = 0
105
+ elif wp_device.is_cuda:
106
+ dl_device.device_type = DLDeviceType.kDLCUDA
107
+ dl_device.device_id = wp_device.ordinal
108
+ else:
109
+ raise RuntimeError(f"Invalid device type converting to dlpack: {wp_device}")
84
110
 
85
111
  return dl_device
86
112
 
87
113
 
114
+ def device_to_dlpack(wp_device) -> DLDevice:
115
+ return _device_to_dlpack(warp.get_device(wp_device))
116
+
117
+
88
118
  def dtype_to_dlpack(wp_dtype) -> DLDataType:
89
119
  if wp_dtype == warp.int8:
90
120
  return (DLDataTypeCode.kDLInt, 8, 1)
@@ -149,13 +179,15 @@ def dtype_from_dlpack(dl_dtype):
149
179
 
150
180
 
151
181
  def device_from_dlpack(dl_device):
182
+ assert warp.context.runtime is not None, "Warp not initialized, call wp.init() before use"
183
+
152
184
  if dl_device.device_type.value == DLDeviceType.kDLCPU or dl_device.device_type.value == DLDeviceType.kDLCUDAHost:
153
- return "cpu"
185
+ return warp.context.runtime.cpu_device
154
186
  elif (
155
187
  dl_device.device_type.value == DLDeviceType.kDLCUDA
156
188
  or dl_device.device_type.value == DLDeviceType.kDLCUDAManaged
157
189
  ):
158
- return f"cuda:{dl_device.device_id}"
190
+ return warp.context.runtime.cuda_devices[dl_device.device_id]
159
191
  else:
160
192
  raise RuntimeError(f"Unknown device type from dlpack: {dl_device.device_type.value}")
161
193
 
@@ -167,39 +199,29 @@ def shape_to_dlpack(shape):
167
199
 
168
200
  def strides_to_dlpack(strides, dtype):
169
201
  # convert from byte count to element count
170
- s = []
171
- for i in range(len(strides)):
172
- s.append(int(int(strides[i]) / int(warp.types.type_size_in_bytes(dtype))))
173
-
174
- a = (ctypes.c_int64 * len(strides))(*s)
202
+ ndim = len(strides)
203
+ a = (ctypes.c_int64 * ndim)()
204
+ dtype_size = warp.types.type_size_in_bytes(dtype)
205
+ for i in range(ndim):
206
+ a[i] = strides[i] // dtype_size
175
207
  return a
176
208
 
177
209
 
178
210
  def to_dlpack(wp_array: warp.array):
179
211
  """Convert a Warp array to another type of dlpack compatible array.
180
212
 
181
- Parameters
182
- ----------
183
- np_array : np.ndarray
184
- The source numpy array that will be converted.
213
+ Args:
214
+ wp_array: The source Warp array that will be converted.
185
215
 
186
- Returns
187
- -------
188
- pycapsule : PyCapsule
189
- A pycapsule containing a DLManagedTensor that can be converted
190
- to other array formats without copying the underlying memory.
216
+ Returns:
217
+ A capsule containing a DLManagedTensor that can be converted
218
+ to another array type without copying the underlying memory.
191
219
  """
192
220
 
193
221
  # DLPack does not support structured arrays
194
222
  if isinstance(wp_array.dtype, warp.codegen.Struct):
195
223
  raise RuntimeError("Cannot convert structured Warp arrays to DLPack.")
196
224
 
197
- holder = _Holder(wp_array)
198
-
199
- # allocate DLManagedTensor
200
- size = ctypes.c_size_t(ctypes.sizeof(DLManagedTensor))
201
- dl_managed_tensor = DLManagedTensor.from_address(ctypes.pythonapi.PyMem_RawMalloc(size))
202
-
203
225
  # handle vector types
204
226
  if hasattr(wp_array.dtype, "_wp_scalar_type_"):
205
227
  # vector type, flatten the dimensions into one tuple
@@ -215,33 +237,60 @@ def to_dlpack(wp_array: warp.array):
215
237
  target_shape = wp_array.shape
216
238
  target_strides = wp_array.strides
217
239
 
218
- # store the shape and stride arrays with the holder to prevent them from getting deallocated
219
- holder._shape = shape_to_dlpack(target_shape)
220
- holder._strides = strides_to_dlpack(target_strides, target_dtype)
221
-
222
240
  if wp_array.pinned:
223
- dl_device = DLDeviceType.kDLCUDAHost
241
+ dl_device = DLDevice()
242
+ dl_device.device_type = DLDeviceType.kDLCUDAHost
243
+ dl_device.device_id = 0
244
+ else:
245
+ dl_device = _device_to_dlpack(wp_array.device)
246
+
247
+ # allocate DLManagedTensor, shape, and strides together
248
+ managed_tensor_size = ctypes.sizeof(DLManagedTensor)
249
+ padding = managed_tensor_size & 7
250
+ shape_size = target_ndim * 8
251
+ mem_size = managed_tensor_size + padding + 2 * shape_size
252
+ mem_ptr = PyMem_RawMalloc(mem_size)
253
+ assert mem_ptr, "Failed to allocate memory for DLManagedTensor"
254
+
255
+ # set managed tensor attributes
256
+ managed_tensor = DLManagedTensor.from_address(mem_ptr)
257
+ managed_tensor.dl_tensor.data = wp_array.ptr
258
+ managed_tensor.dl_tensor.device = dl_device
259
+ managed_tensor.dl_tensor.ndim = target_ndim
260
+ managed_tensor.dl_tensor.dtype = dtype_to_dlpack(target_dtype)
261
+ managed_tensor.dl_tensor.byte_offset = 0
262
+
263
+ # shape
264
+ shape_offset = managed_tensor_size + padding
265
+ shape_ptr = ctypes.cast(mem_ptr + shape_offset, ctypes.POINTER(ctypes.c_int64))
266
+ for i in range(target_ndim):
267
+ shape_ptr[i] = target_shape[i]
268
+ managed_tensor.dl_tensor.shape = shape_ptr
269
+
270
+ # strides, if not contiguous
271
+ if wp_array.is_contiguous:
272
+ managed_tensor.dl_tensor.strides = None
224
273
  else:
225
- dl_device = device_to_dlpack(wp_array.device)
226
-
227
- # set Tensor attributes
228
- dl_managed_tensor.dl_tensor.data = wp_array.ptr
229
- dl_managed_tensor.dl_tensor.device = dl_device
230
- dl_managed_tensor.dl_tensor.ndim = target_ndim
231
- dl_managed_tensor.dl_tensor.dtype = dtype_to_dlpack(target_dtype)
232
- dl_managed_tensor.dl_tensor.shape = holder._shape
233
- dl_managed_tensor.dl_tensor.strides = holder._strides
234
- dl_managed_tensor.dl_tensor.byte_offset = 0
235
- dl_managed_tensor.manager_ctx = holder._as_manager_ctx()
236
- dl_managed_tensor.deleter = _warp_array_deleter
237
-
238
- pycapsule = ctypes.pythonapi.PyCapsule_New(
239
- ctypes.byref(dl_managed_tensor),
274
+ stride_offset = shape_offset + shape_size
275
+ stride_ptr = ctypes.cast(mem_ptr + stride_offset, ctypes.POINTER(ctypes.c_int64))
276
+ dtype_size = warp.types.type_size_in_bytes(target_dtype)
277
+ for i in range(target_ndim):
278
+ stride_ptr[i] = target_strides[i] // dtype_size
279
+ managed_tensor.dl_tensor.strides = stride_ptr
280
+
281
+ # DLManagedTensor holds a reference to the source array
282
+ managed_tensor.manager_ctx = id(wp_array)
283
+ Py_IncRef(wp_array)
284
+
285
+ managed_tensor.deleter = _dlpack_tensor_deleter
286
+
287
+ capsule = PyCapsule_New(
288
+ ctypes.byref(managed_tensor),
240
289
  _c_str_dltensor,
241
- _warp_pycapsule_deleter,
290
+ _dlpack_capsule_deleter,
242
291
  )
243
292
 
244
- return pycapsule
293
+ return capsule
245
294
 
246
295
 
247
296
  def dtype_is_compatible(dl_dtype, wp_dtype):
@@ -272,35 +321,28 @@ def dtype_is_compatible(dl_dtype, wp_dtype):
272
321
  raise RuntimeError(f"Unsupported dlpack dtype {(str(dl_dtype.type_code), dl_dtype.bits)}")
273
322
 
274
323
 
275
- def from_dlpack(pycapsule, dtype=None) -> warp.array:
276
- """Convert a dlpack tensor into a numpy array without copying.
324
+ def _from_dlpack(capsule, dtype=None) -> warp.array:
325
+ """Convert a DLPack capsule into a Warp array without copying.
277
326
 
278
- Parameters
279
- ----------
280
- pycapsule : PyCapsule
281
- A pycapsule wrapping a dlpack tensor that will be converted.
327
+ Args:
328
+ capsule: A DLPack capsule wrapping an external array or tensor.
329
+ dtype: An optional Warp data type to interpret the source data.
282
330
 
283
- Returns
284
- -------
285
- np_array : np.ndarray
286
- A new numpy array that uses the same underlying memory as the input
287
- pycapsule.
331
+ Returns:
332
+ A new Warp array that uses the same underlying memory as the input capsule.
288
333
  """
289
334
 
290
- assert ctypes.pythonapi.PyCapsule_IsValid(pycapsule, _c_str_dltensor)
291
- dl_managed_tensor = ctypes.pythonapi.PyCapsule_GetPointer(pycapsule, _c_str_dltensor)
292
- dl_managed_tensor_ptr = ctypes.cast(dl_managed_tensor, ctypes.POINTER(DLManagedTensor))
293
- dl_managed_tensor = dl_managed_tensor_ptr.contents
335
+ assert PyCapsule_IsValid(capsule, _c_str_dltensor), "Invalid capsule"
336
+ mem_ptr = PyCapsule_GetPointer(capsule, _c_str_dltensor)
337
+ managed_tensor = DLManagedTensor.from_address(mem_ptr)
294
338
 
295
- dlt = dl_managed_tensor.dl_tensor
296
- assert isinstance(dlt, DLTensor)
339
+ dlt = managed_tensor.dl_tensor
297
340
 
298
341
  device = device_from_dlpack(dlt.device)
299
-
300
342
  pinned = dlt.device.device_type.value == DLDeviceType.kDLCUDAHost
301
-
302
343
  shape = tuple(dlt.shape[dim] for dim in range(dlt.ndim))
303
344
 
345
+ # strides, if not contiguous
304
346
  itemsize = dlt.dtype.bits // 8
305
347
  if dlt.strides:
306
348
  strides = tuple(dlt.strides[dim] * itemsize for dim in range(dlt.ndim))
@@ -348,10 +390,53 @@ def from_dlpack(pycapsule, dtype=None) -> warp.array:
348
390
  raise RuntimeError(f"Incompatible data types: {dlt.dtype} and {dtype}")
349
391
 
350
392
  a = warp.types.array(
351
- ptr=dlt.data, dtype=dtype, shape=shape, strides=strides, copy=False, owner=False, device=device, pinned=pinned
393
+ ptr=dlt.data, dtype=dtype, shape=shape, strides=strides, copy=False, device=device, pinned=pinned
352
394
  )
353
395
 
354
- # keep a reference to the capsule so it doesn't get deleted
355
- a._pycapsule = pycapsule
396
+ # take ownership of the DLManagedTensor
397
+ a._dlpack_tensor_holder = _DLPackTensorHolder(mem_ptr)
398
+
399
+ # rename the capsule so that it no longer owns the DLManagedTensor
400
+ PyCapsule_SetName(capsule, _c_str_used_dltensor)
356
401
 
357
402
  return a
403
+
404
+
405
+ def from_dlpack(source, dtype=None) -> warp.array:
406
+ """Convert a source array or DLPack capsule into a Warp array without copying.
407
+
408
+ Args:
409
+ source: A DLPack-compatible array or PyCapsule
410
+ dtype: An optional Warp data type to interpret the source data.
411
+
412
+ Returns:
413
+ A new Warp array that uses the same underlying memory as the input
414
+ pycapsule.
415
+ """
416
+
417
+ # See https://data-apis.org/array-api/2022.12/API_specification/generated/array_api.array.__dlpack__.html
418
+
419
+ if hasattr(source, "__dlpack__"):
420
+ device_type, device_id = source.__dlpack_device__()
421
+ # Check if the source lives on a CUDA device
422
+ if device_type in (DLDeviceType.kDLCUDA, DLDeviceType.kDLCUDAManaged):
423
+ # Assume that the caller will use the array on its device's current stream.
424
+ # Note that we pass 1 for the null stream, per DLPack spec.
425
+ cuda_stream = warp.get_cuda_device(device_id).stream.cuda_stream or 1
426
+ elif device_type == DLDeviceType.kDLCPU:
427
+ # No stream sync for CPU arrays.
428
+ cuda_stream = None
429
+ elif device_type == DLDeviceType.kDLCUDAHost:
430
+ # For pinned memory, we sync with the current CUDA device's stream.
431
+ # Note that we pass 1 for the null stream, per DLPack spec.
432
+ cuda_stream = warp.get_cuda_device().stream.cuda_stream or 1
433
+ else:
434
+ raise TypeError("Unsupported source device")
435
+
436
+ capsule = source.__dlpack__(stream=cuda_stream)
437
+
438
+ else:
439
+ # legacy behaviour, assume source is a capsule
440
+ capsule = source
441
+
442
+ return _from_dlpack(capsule, dtype=dtype)
Binary file
@@ -0,0 +1,110 @@
1
+ <?xml version="1.0"?>
2
+ <robot name="cartpole">
3
+
4
+ <link name="slider">
5
+ <visual>
6
+ <geometry>
7
+ <box size="0.03 8 0.03"/>
8
+ </geometry>
9
+ <material name="slider_mat">
10
+ <color rgba="0.9 0.6 0.2 1"/>
11
+ </material>
12
+ </visual>
13
+ <collision>
14
+ <geometry>
15
+ <box size="0.03 8 0.03"/>
16
+ </geometry>
17
+ </collision>
18
+ </link>
19
+
20
+ <joint name="slider_to_cart" type="prismatic">
21
+ <axis xyz="0 1 0"/>
22
+ <origin xyz="0 0 0"/>
23
+ <parent link="slider"/>
24
+ <child link="cart"/>
25
+ <limit effort="1000.0" lower="-4" upper="4" velocity="100"/>
26
+ </joint>
27
+
28
+ <link name="cart">
29
+ <visual>
30
+ <geometry>
31
+ <box size="0.2 0.25 0.2"/>
32
+ </geometry>
33
+ <material name="cart_mat">
34
+ <color rgba="0.3 0.5 0.7 1"/>
35
+ </material>
36
+ </visual>
37
+ <collision>
38
+ <geometry>
39
+ <box size="0.2 0.25 0.2"/>
40
+ </geometry>
41
+ </collision>
42
+ <inertial>
43
+ <mass value="1"/>
44
+ <inertia ixx="0.1" ixy="0.0" ixz="0.0" iyy="0.1" iyz="0.0" izz="0.1"/>
45
+ </inertial>
46
+ </link>
47
+
48
+ <joint name="cart_to_pole1" type="continuous">
49
+ <axis xyz="1 0 0"/>
50
+ <origin xyz="0.12 0 0"/>
51
+ <parent link="cart"/>
52
+ <child link="pole1"/>
53
+ <limit effort="1000.0" velocity="8"/>
54
+ </joint>
55
+
56
+ <link name="pole1">
57
+ <visual>
58
+ <geometry>
59
+ <box size="0.04 0.06 1.0"/>
60
+ </geometry>
61
+ <origin xyz="0 0 0.47"/>
62
+ <material name="pole_mat">
63
+ <color rgba="0.1 0.1 0.3 1"/>
64
+ </material>
65
+ </visual>
66
+ <collision>
67
+ <geometry>
68
+ <box size="0.04 0.06 1.0"/>
69
+ </geometry>
70
+ <origin xyz="0 0 0.47"/>
71
+ </collision>
72
+ <inertial>
73
+ <origin xyz="0 0 0.47"/>
74
+ <mass value="0.25"/>
75
+ <inertia ixx="0.1" ixy="0.0" ixz="0.0" iyy="0.1" iyz="0.0" izz="0.1"/>
76
+ </inertial>
77
+ </link>
78
+
79
+ <link name="pole2">
80
+ <visual>
81
+ <geometry>
82
+ <box size="0.04 0.06 1.0"/>
83
+ </geometry>
84
+ <origin xyz="0 0 0.47"/>
85
+ <material name="pole_mat">
86
+ <color rgba="0.1 0.1 0.3 1"/>
87
+ </material>
88
+ </visual>
89
+ <collision>
90
+ <geometry>
91
+ <box size="0.04 0.06 1.0"/>
92
+ </geometry>
93
+ <origin xyz="0 0 0.47"/>
94
+ </collision>
95
+ <inertial>
96
+ <origin xyz="0 0 0.47"/>
97
+ <mass value="0.25"/>
98
+ <inertia ixx="0.1" ixy="0.0" ixz="0.0" iyy="0.1" iyz="0.0" izz="0.1"/>
99
+ </inertial>
100
+ </link>
101
+
102
+ <joint name="pole1_to_pole2" type="continuous">
103
+ <axis xyz="1 0 0"/>
104
+ <origin xyz="0.0 0 1.0"/>
105
+ <parent link="pole1"/>
106
+ <child link="pole2"/>
107
+ <limit effort="1000.0" velocity="8"/>
108
+ </joint>
109
+
110
+ </robot>
Binary file
@@ -0,0 +1,42 @@
1
+ #usda 1.0
2
+ (
3
+ doc = "Blender v2.92.0"
4
+ metersPerUnit = 1
5
+ upAxis = "Z"
6
+ defaultPrim = "Cube"
7
+ )
8
+
9
+ def Xform "Cube"
10
+ {
11
+ matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
12
+ uniform token[] xformOpOrder = ["xformOp:transform"]
13
+
14
+ def Mesh "Cube_001"
15
+ {
16
+ int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
17
+ int[] faceVertexIndices = [1, 2, 0, 3, 6, 2, 7, 4, 6, 5, 0, 4, 6, 0, 2, 3, 5, 7, 1, 3, 2, 3, 7, 6, 7, 5, 4, 5, 1, 0, 6, 4, 0, 3, 1, 5]
18
+ normal3f[] normals = [(-1, 0, 0), (-1, 0, 0), (-1, 0, 0), (0, 1, -0), (0, 1, -0), (0, 1, -0), (1, 0, -0), (1, 0, -0), (1, 0, -0), (0, -1, 0), (0, -1, 0), (0, -1, 0), (0, 0, -1), (0, 0, -1), (0, 0, -1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (-1, 0, 0), (-1, 0, 0), (-1, 0, 0), (0, 1, -0), (0, 1, -0), (0, 1, -0), (1, 0, 0), (1, 0, 0), (1, 0, 0), (0, -1, 0), (0, -1, 0), (0, -1, 0), (0, 0, -1), (0, 0, -1), (0, 0, -1), (0, -0, 1), (0, -0, 1), (0, -0, 1)] (
19
+ interpolation = "faceVarying"
20
+ )
21
+ point3f[] points = [(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]
22
+ uniform token subdivisionScheme = "none"
23
+ }
24
+ }
25
+
26
+ def Xform "Camera"
27
+ {
28
+ matrix4d xformOp:transform = ( (0.6859206557273865, 0.7276763319969177, 0, 0), (-0.32401347160339355, 0.305420845746994, 0.8953956365585327, 0), (0.6515582203865051, -0.6141703724861145, 0.44527140259742737, 0), (7.358891487121582, -6.925790786743164, 4.958309173583984, 1) )
29
+ uniform token[] xformOpOrder = ["xformOp:transform"]
30
+
31
+ def Camera "Camera"
32
+ {
33
+ float2 clippingRange = (0.1, 100)
34
+ float focalLength = 50
35
+ float horizontalAperture = 36
36
+ float horizontalApertureOffset = 0
37
+ token projection = "perspective"
38
+ float verticalAperture = 20.25
39
+ float verticalApertureOffset = 0
40
+ }
41
+ }
42
+
@@ -0,0 +1,92 @@
1
+ <mujoco model="ant">
2
+ <custom>
3
+ <numeric data="0.0 0.0 0.55 1.0 0.0 0.0 0.0 0.0 1.0 0.0 -1.0 0.0 -1.0 0.0 1.0" name="init_qpos"/>
4
+ </custom>
5
+
6
+ <default>
7
+ <joint armature="0.01" damping="0.1" limited="true"/>
8
+ <geom condim="3" density="5.0" friction="1.5 0.1 0.1" margin="0.01" rgba="0.97 0.38 0.06 1"/>
9
+ </default>
10
+
11
+ <compiler inertiafromgeom="true" angle="degree"/>
12
+
13
+ <option timestep="0.016" iterations="50" tolerance="1e-10" solver="Newton" jacobian="dense" cone="pyramidal"/>
14
+
15
+ <size nconmax="50" njmax="200" nstack="10000"/>
16
+ <visual>
17
+ <map force="0.1" zfar="30"/>
18
+ <rgba haze="0.15 0.25 0.35 1"/>
19
+ <quality shadowsize="2048"/>
20
+ <global offwidth="800" offheight="800"/>
21
+ </visual>
22
+
23
+ <asset>
24
+ <texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="512"/>
25
+ <texture name="texplane" type="2d" builtin="checker" rgb1=".2 .3 .4" rgb2=".1 0.15 0.2" width="512" height="512" mark="cross" markrgb=".8 .8 .8"/>
26
+ <texture name="texgeom" type="cube" builtin="flat" mark="cross" width="127" height="1278"
27
+ rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1" random="0.01"/>
28
+
29
+ <material name="matplane" reflectance="0.3" texture="texplane" texrepeat="1 1" texuniform="true"/>
30
+ <material name="matgeom" texture="texgeom" texuniform="true" rgba="0.8 0.6 .4 1"/>
31
+ </asset>
32
+
33
+ <worldbody>
34
+ <geom name="floor" pos="0 0 0" size="0 0 .25" type="plane" material="matplane" condim="3"/>
35
+
36
+ <light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1" castshadow="false"/>
37
+ <light mode="targetbodycom" target="torso" directional="false" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 0 4.0" dir="0 0 -1"/>
38
+
39
+ <body name="torso" pos="0 0 0.75">
40
+ <geom name="torso_geom" pos="0 0 0" size="0.25" type="sphere"/>
41
+ <geom fromto="0.0 0.0 0.0 0.2 0.2 0.0" name="aux_1_geom" size="0.08" type="capsule" rgba=".999 .2 .1 1"/>
42
+ <geom fromto="0.0 0.0 0.0 -0.2 0.2 0.0" name="aux_2_geom" size="0.08" type="capsule"/>
43
+ <geom fromto="0.0 0.0 0.0 -0.2 -0.2 0.0" name="aux_3_geom" size="0.08" type="capsule"/>
44
+ <geom fromto="0.0 0.0 0.0 0.2 -0.2 0.0" name="aux_4_geom" size="0.08" type="capsule" rgba=".999 .2 .02 1"/>
45
+
46
+ <joint armature="0" damping="0" limited="false" margin="0.01" name="root" pos="0 0 0" type="free"/>
47
+ <body name="front_left_leg" pos="0.2 0.2 0">
48
+ <joint axis="0 0 1" name="hip_1" pos="0.0 0.0 0.0" range="-40 40" type="hinge"/>
49
+ <geom fromto="0.0 0.0 0.0 0.2 0.2 0.0" name="left_leg_geom" size="0.08" type="capsule" rgba=".999 .2 .1 1"/>
50
+ <body pos="0.2 0.2 0" name="front_left_foot">
51
+ <joint axis="-1 1 0" name="ankle_1" pos="0.0 0.0 0.0" range="30 100" type="hinge"/>
52
+ <geom fromto="0.0 0.0 0.0 0.4 0.4 0.0" name="left_ankle_geom" size="0.08" type="capsule" rgba=".999 .2 .1 1"/>
53
+ </body>
54
+ </body>
55
+ <body name="front_right_leg" pos="-0.2 0.2 0">
56
+ <joint axis="0 0 1" name="hip_2" pos="0.0 0.0 0.0" range="-40 40" type="hinge"/>
57
+ <geom fromto="0.0 0.0 0.0 -0.2 0.2 0.0" name="right_leg_geom" size="0.08" type="capsule"/>
58
+ <body pos="-0.2 0.2 0" name="front_right_foot">
59
+ <joint axis="1 1 0" name="ankle_2" pos="0.0 0.0 0.0" range="-100 -30" type="hinge"/>
60
+ <geom fromto="0.0 0.0 0.0 -0.4 0.4 0.0" name="right_ankle_geom" size="0.08" type="capsule"/>
61
+ </body>
62
+ </body>
63
+ <body name="left_back_leg" pos="-0.2 -0.2 0">
64
+ <joint axis="0 0 1" name="hip_3" pos="0.0 0.0 0.0" range="-40 40" type="hinge"/>
65
+ <geom fromto="0.0 0.0 0.0 -0.2 -0.2 0.0" name="back_leg_geom" size="0.08" type="capsule"/>
66
+ <body pos="-0.2 -0.2 0" name="left_back_foot">
67
+ <joint axis="-1 1 0" name="ankle_3" pos="0.0 0.0 0.0" range="-100 -30" type="hinge"/>
68
+ <geom fromto="0.0 0.0 0.0 -0.4 -0.4 0.0" name="third_ankle_geom" size="0.08" type="capsule"/>
69
+ </body>
70
+ </body>
71
+ <body name="right_back_leg" pos="0.2 -0.2 0">
72
+ <joint axis="0 0 1" name="hip_4" pos="0.0 0.0 0.0" range="-40 40" type="hinge"/>
73
+ <geom fromto="0.0 0.0 0.0 0.2 -0.2 0.0" name="rightback_leg_geom" size="0.08" type="capsule" rgba=".999 .2 .1 1"/>
74
+ <body pos="0.2 -0.2 0" name="right_back_foot">
75
+ <joint axis="1 1 0" name="ankle_4" pos="0.0 0.0 0.0" range="30 100" type="hinge"/>
76
+ <geom fromto="0.0 0.0 0.0 0.4 -0.4 0.0" name="fourth_ankle_geom" size="0.08" type="capsule" rgba=".999 .2 .1 1"/>
77
+ </body>
78
+ </body>
79
+ </body>
80
+ </worldbody>
81
+
82
+ <actuator>
83
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="hip_4" gear="15"/>
84
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="ankle_4" gear="15"/>
85
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="hip_1" gear="15"/>
86
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="ankle_1" gear="15"/>
87
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="hip_2" gear="15"/>
88
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="ankle_2" gear="15"/>
89
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="hip_3" gear="15"/>
90
+ <motor ctrllimited="true" ctrlrange="-1.0 1.0" joint="ankle_3" gear="15"/>
91
+ </actuator>
92
+ </mujoco>