warp-lang 1.7.0__py3-none-win_amd64.whl → 1.7.2__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.
- warp/autograd.py +12 -2
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +1 -1
- warp/builtins.py +103 -66
- warp/codegen.py +48 -27
- warp/config.py +1 -1
- warp/context.py +112 -49
- warp/examples/benchmarks/benchmark_cloth.py +1 -1
- warp/examples/distributed/example_jacobi_mpi.py +507 -0
- warp/fem/cache.py +1 -1
- warp/fem/field/field.py +11 -1
- warp/fem/field/nodal_field.py +36 -22
- warp/fem/geometry/adaptive_nanogrid.py +7 -3
- warp/fem/geometry/trimesh.py +4 -12
- warp/jax_experimental/custom_call.py +14 -2
- warp/jax_experimental/ffi.py +100 -67
- warp/native/builtin.h +91 -65
- warp/native/svd.h +59 -49
- warp/native/tile.h +55 -26
- warp/native/volume.cpp +2 -2
- warp/native/volume_builder.cu +33 -22
- warp/native/warp.cu +1 -1
- warp/render/render_opengl.py +41 -34
- warp/render/render_usd.py +96 -6
- warp/sim/collide.py +11 -9
- warp/sim/inertia.py +189 -156
- warp/sim/integrator_euler.py +3 -0
- warp/sim/integrator_xpbd.py +3 -0
- warp/sim/model.py +56 -31
- warp/sim/render.py +4 -0
- warp/sparse.py +1 -1
- warp/stubs.py +73 -25
- warp/tests/assets/torus.usda +1 -1
- warp/tests/cuda/test_streams.py +1 -1
- warp/tests/sim/test_collision.py +237 -206
- warp/tests/sim/test_inertia.py +161 -0
- warp/tests/sim/test_model.py +5 -3
- warp/tests/sim/{flaky_test_sim_grad.py → test_sim_grad.py} +1 -4
- warp/tests/sim/test_xpbd.py +399 -0
- warp/tests/test_array.py +8 -7
- warp/tests/test_atomic.py +181 -2
- warp/tests/test_builtins_resolution.py +38 -38
- warp/tests/test_codegen.py +24 -3
- warp/tests/test_examples.py +16 -6
- warp/tests/test_fem.py +93 -14
- warp/tests/test_func.py +1 -1
- warp/tests/test_mat.py +416 -119
- warp/tests/test_quat.py +321 -137
- warp/tests/test_struct.py +116 -0
- warp/tests/test_vec.py +320 -174
- warp/tests/tile/test_tile.py +27 -0
- warp/tests/tile/test_tile_load.py +124 -0
- warp/tests/unittest_suites.py +2 -5
- warp/types.py +107 -9
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/METADATA +41 -19
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/RECORD +60 -57
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/WHEEL +1 -1
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/licenses/LICENSE.md +0 -26
- {warp_lang-1.7.0.dist-info → warp_lang-1.7.2.dist-info}/top_level.txt +0 -0
warp/context.py
CHANGED
|
@@ -457,6 +457,24 @@ class Function:
|
|
|
457
457
|
return f"<Function {self.key}({inputs_str})>"
|
|
458
458
|
|
|
459
459
|
|
|
460
|
+
def get_builtin_type(return_type: type) -> type:
|
|
461
|
+
# The return_type might just be vector_t(length=3,dtype=wp.float32), so we've got to match that
|
|
462
|
+
# in the list of hard coded types so it knows it's returning one of them:
|
|
463
|
+
if hasattr(return_type, "_wp_generic_type_hint_"):
|
|
464
|
+
return_type_match = tuple(
|
|
465
|
+
x
|
|
466
|
+
for x in generic_vtypes
|
|
467
|
+
if x._wp_generic_type_hint_ == return_type._wp_generic_type_hint_
|
|
468
|
+
and x._wp_type_params_ == return_type._wp_type_params_
|
|
469
|
+
)
|
|
470
|
+
if not return_type_match:
|
|
471
|
+
raise RuntimeError("No match")
|
|
472
|
+
|
|
473
|
+
return return_type_match[0]
|
|
474
|
+
|
|
475
|
+
return return_type
|
|
476
|
+
|
|
477
|
+
|
|
460
478
|
def call_builtin(func: Function, *params: Any) -> Tuple[bool, Any]:
|
|
461
479
|
uses_non_warp_array_type = False
|
|
462
480
|
|
|
@@ -769,6 +787,12 @@ class Kernel:
|
|
|
769
787
|
|
|
770
788
|
return f"{self.key}_{hash_suffix}"
|
|
771
789
|
|
|
790
|
+
def __call__(self, *args, **kwargs):
|
|
791
|
+
# we implement this function only to ensure Kernel is a callable object
|
|
792
|
+
# so that we can document Warp kernels in the same way as Python functions
|
|
793
|
+
# annotated by @wp.kernel (see functools.update_wrapper())
|
|
794
|
+
raise NotImplementedError("Kernel.__call__() is not implemented, please use wp.launch() instead")
|
|
795
|
+
|
|
772
796
|
|
|
773
797
|
# ----------------------
|
|
774
798
|
|
|
@@ -1068,7 +1092,7 @@ def kernel(
|
|
|
1068
1092
|
# decorator to register struct, @struct
|
|
1069
1093
|
def struct(c: type):
|
|
1070
1094
|
m = get_module(c.__module__)
|
|
1071
|
-
s = warp.codegen.Struct(
|
|
1095
|
+
s = warp.codegen.Struct(key=warp.codegen.make_full_qualified_name(c), cls=c, module=m)
|
|
1072
1096
|
s = functools.update_wrapper(s, c)
|
|
1073
1097
|
return s
|
|
1074
1098
|
|
|
@@ -1439,6 +1463,24 @@ def register_api_function(
|
|
|
1439
1463
|
"""
|
|
1440
1464
|
function.group = group
|
|
1441
1465
|
function.hidden = hidden
|
|
1466
|
+
|
|
1467
|
+
# Update the docstring to mark these functions as being available from kernels and Python's runtime.
|
|
1468
|
+
assert function.__doc__.startswith("\n")
|
|
1469
|
+
leading_space_count = sum(1 for _ in itertools.takewhile(str.isspace, function.__doc__[1:]))
|
|
1470
|
+
assert leading_space_count % 4 == 0
|
|
1471
|
+
indent_level = leading_space_count // 4
|
|
1472
|
+
indent = " "
|
|
1473
|
+
function.__doc__ = (
|
|
1474
|
+
f"\n"
|
|
1475
|
+
f"{indent * indent_level}.. hlist::\n"
|
|
1476
|
+
f"{indent * (indent_level + 1)}:columns: 8\n"
|
|
1477
|
+
f"\n"
|
|
1478
|
+
f"{indent * (indent_level + 1)}* Kernel\n"
|
|
1479
|
+
f"{indent * (indent_level + 1)}* Python\n"
|
|
1480
|
+
f"{indent * (indent_level + 1)}* Differentiable\n"
|
|
1481
|
+
f"{function.__doc__}"
|
|
1482
|
+
)
|
|
1483
|
+
|
|
1442
1484
|
builtin_functions[function.key] = function
|
|
1443
1485
|
|
|
1444
1486
|
|
|
@@ -6504,12 +6546,46 @@ def type_str(t):
|
|
|
6504
6546
|
return t.__name__
|
|
6505
6547
|
|
|
6506
6548
|
|
|
6507
|
-
def
|
|
6549
|
+
def ctype_ret_str(t):
|
|
6550
|
+
return get_builtin_type(t).__name__
|
|
6551
|
+
|
|
6552
|
+
|
|
6553
|
+
def resolve_exported_function_sig(f):
|
|
6554
|
+
if not f.export or f.generic:
|
|
6555
|
+
return None
|
|
6556
|
+
|
|
6557
|
+
# only export simple types that don't use arrays or templated types
|
|
6558
|
+
if not f.is_simple():
|
|
6559
|
+
return None
|
|
6560
|
+
|
|
6561
|
+
# Runtime arguments that are to be passed to the function, not its template signature.
|
|
6562
|
+
if f.export_func is not None:
|
|
6563
|
+
func_args = f.export_func(f.input_types)
|
|
6564
|
+
else:
|
|
6565
|
+
func_args = f.input_types
|
|
6566
|
+
|
|
6567
|
+
# todo: construct a default value for each of the functions args
|
|
6568
|
+
# so we can generate the return type for overloaded functions
|
|
6569
|
+
return_type = f.value_func(func_args, None)
|
|
6570
|
+
|
|
6571
|
+
try:
|
|
6572
|
+
return_type_str = ctype_ret_str(return_type)
|
|
6573
|
+
except Exception:
|
|
6574
|
+
return None
|
|
6575
|
+
|
|
6576
|
+
if return_type_str.startswith("Tuple"):
|
|
6577
|
+
return None
|
|
6578
|
+
|
|
6579
|
+
return (func_args, return_type)
|
|
6580
|
+
|
|
6581
|
+
|
|
6582
|
+
def print_function(f, file, is_exported, noentry=False): # pragma: no cover
|
|
6508
6583
|
"""Writes a function definition to a file for use in reST documentation
|
|
6509
6584
|
|
|
6510
6585
|
Args:
|
|
6511
6586
|
f: The function being written
|
|
6512
6587
|
file: The file object for output
|
|
6588
|
+
is_exported: Whether the function is available in Python's runtime
|
|
6513
6589
|
noentry: If True, then the :noindex: and :nocontentsentry: directive
|
|
6514
6590
|
options will be added
|
|
6515
6591
|
|
|
@@ -6537,11 +6613,21 @@ def print_function(f, file, noentry=False): # pragma: no cover
|
|
|
6537
6613
|
print(" :nocontentsentry:", file=file)
|
|
6538
6614
|
print("", file=file)
|
|
6539
6615
|
|
|
6616
|
+
print(" .. hlist::", file=file)
|
|
6617
|
+
print(" :columns: 8", file=file)
|
|
6618
|
+
print("", file=file)
|
|
6619
|
+
print(" * Kernel", file=file)
|
|
6620
|
+
|
|
6621
|
+
if is_exported:
|
|
6622
|
+
print(" * Python", file=file)
|
|
6623
|
+
|
|
6624
|
+
if not f.missing_grad:
|
|
6625
|
+
print(" * Differentiable", file=file)
|
|
6626
|
+
|
|
6627
|
+
print("", file=file)
|
|
6628
|
+
|
|
6540
6629
|
if f.doc != "":
|
|
6541
|
-
|
|
6542
|
-
print(f" {f.doc}", file=file)
|
|
6543
|
-
else:
|
|
6544
|
-
print(f" {f.doc} [1]_", file=file)
|
|
6630
|
+
print(f" {f.doc}", file=file)
|
|
6545
6631
|
print("", file=file)
|
|
6546
6632
|
|
|
6547
6633
|
print(file=file)
|
|
@@ -6557,8 +6643,10 @@ def export_functions_rst(file): # pragma: no cover
|
|
|
6557
6643
|
".. functions:\n"
|
|
6558
6644
|
".. currentmodule:: warp\n"
|
|
6559
6645
|
"\n"
|
|
6560
|
-
"
|
|
6561
|
-
"
|
|
6646
|
+
"Built-Ins Reference\n"
|
|
6647
|
+
"===================\n"
|
|
6648
|
+
"This section lists the Warp types and functions available to use from Warp kernels and optionally also from the Warp Python runtime API.\n"
|
|
6649
|
+
"For a listing of the API that is exclusively intended to be used at the *Python Scope* and run inside the CPython interpreter, see the :doc:`runtime` section.\n"
|
|
6562
6650
|
)
|
|
6563
6651
|
|
|
6564
6652
|
print(header, file=file)
|
|
@@ -6603,9 +6691,12 @@ def export_functions_rst(file): # pragma: no cover
|
|
|
6603
6691
|
if hasattr(f, "overloads"):
|
|
6604
6692
|
# append all overloads to the group
|
|
6605
6693
|
for o in f.overloads:
|
|
6606
|
-
|
|
6694
|
+
sig = resolve_exported_function_sig(f)
|
|
6695
|
+
is_exported = sig is not None
|
|
6696
|
+
groups[f.group].append((o, is_exported))
|
|
6607
6697
|
else:
|
|
6608
|
-
|
|
6698
|
+
is_exported = False
|
|
6699
|
+
groups[f.group].append((f, is_exported))
|
|
6609
6700
|
|
|
6610
6701
|
# Keep track of what function and query types have been written
|
|
6611
6702
|
written_functions = set()
|
|
@@ -6624,7 +6715,7 @@ def export_functions_rst(file): # pragma: no cover
|
|
|
6624
6715
|
print(k, file=file)
|
|
6625
6716
|
print("---------------", file=file)
|
|
6626
6717
|
|
|
6627
|
-
for f in g:
|
|
6718
|
+
for f, is_exported in g:
|
|
6628
6719
|
if f.func:
|
|
6629
6720
|
# f is a Warp function written in Python, we can use autofunction
|
|
6630
6721
|
print(f".. autofunction:: {f.func.__module__}.{f.key}", file=file)
|
|
@@ -6637,15 +6728,11 @@ def export_functions_rst(file): # pragma: no cover
|
|
|
6637
6728
|
|
|
6638
6729
|
if f.key in written_functions:
|
|
6639
6730
|
# Add :noindex: + :nocontentsentry: since Sphinx gets confused
|
|
6640
|
-
print_function(f, file
|
|
6731
|
+
print_function(f, file, is_exported, noentry=True)
|
|
6641
6732
|
else:
|
|
6642
|
-
if print_function(f, file
|
|
6733
|
+
if print_function(f, file, is_exported):
|
|
6643
6734
|
written_functions.add(f.key)
|
|
6644
6735
|
|
|
6645
|
-
# footnotes
|
|
6646
|
-
print(".. rubric:: Footnotes", file=file)
|
|
6647
|
-
print(".. [1] Function gradients have not been implemented for backpropagation.", file=file)
|
|
6648
|
-
|
|
6649
6736
|
|
|
6650
6737
|
def export_stubs(file): # pragma: no cover
|
|
6651
6738
|
"""Generates stub file for auto-complete of builtin functions"""
|
|
@@ -6745,14 +6832,6 @@ def export_builtins(file: io.TextIOBase): # pragma: no cover
|
|
|
6745
6832
|
else:
|
|
6746
6833
|
return t.__name__
|
|
6747
6834
|
|
|
6748
|
-
def ctype_ret_str(t):
|
|
6749
|
-
if isinstance(t, int):
|
|
6750
|
-
return "int"
|
|
6751
|
-
elif isinstance(t, float):
|
|
6752
|
-
return "float"
|
|
6753
|
-
else:
|
|
6754
|
-
return t.__name__
|
|
6755
|
-
|
|
6756
6835
|
file.write("namespace wp {\n\n")
|
|
6757
6836
|
file.write('extern "C" {\n\n')
|
|
6758
6837
|
|
|
@@ -6760,40 +6839,24 @@ def export_builtins(file: io.TextIOBase): # pragma: no cover
|
|
|
6760
6839
|
if not hasattr(g, "overloads"):
|
|
6761
6840
|
continue
|
|
6762
6841
|
for f in g.overloads:
|
|
6763
|
-
|
|
6842
|
+
sig = resolve_exported_function_sig(f)
|
|
6843
|
+
if sig is None:
|
|
6764
6844
|
continue
|
|
6765
6845
|
|
|
6766
|
-
|
|
6767
|
-
# or templated types
|
|
6768
|
-
if not f.is_simple():
|
|
6769
|
-
continue
|
|
6770
|
-
|
|
6771
|
-
try:
|
|
6772
|
-
# todo: construct a default value for each of the functions args
|
|
6773
|
-
# so we can generate the return type for overloaded functions
|
|
6774
|
-
return_type = ctype_ret_str(f.value_func(None, None))
|
|
6775
|
-
except Exception:
|
|
6776
|
-
continue
|
|
6777
|
-
|
|
6778
|
-
if return_type.startswith("Tuple"):
|
|
6779
|
-
continue
|
|
6780
|
-
|
|
6781
|
-
# Runtime arguments that are to be passed to the function, not its template signature.
|
|
6782
|
-
if f.export_func is not None:
|
|
6783
|
-
func_args = f.export_func(f.input_types)
|
|
6784
|
-
else:
|
|
6785
|
-
func_args = f.input_types
|
|
6846
|
+
func_args, return_type = sig
|
|
6786
6847
|
|
|
6787
6848
|
args = ", ".join(f"{ctype_arg_str(v)} {k}" for k, v in func_args.items())
|
|
6788
6849
|
params = ", ".join(func_args.keys())
|
|
6789
6850
|
|
|
6851
|
+
return_str = ctype_ret_str(return_type)
|
|
6852
|
+
|
|
6790
6853
|
if args == "":
|
|
6791
|
-
file.write(f"WP_API void {f.mangled_name}({
|
|
6792
|
-
elif return_type
|
|
6854
|
+
file.write(f"WP_API void {f.mangled_name}({return_str}* ret) {{ *ret = wp::{f.key}({params}); }}\n")
|
|
6855
|
+
elif return_type is None:
|
|
6793
6856
|
file.write(f"WP_API void {f.mangled_name}({args}) {{ wp::{f.key}({params}); }}\n")
|
|
6794
6857
|
else:
|
|
6795
6858
|
file.write(
|
|
6796
|
-
f"WP_API void {f.mangled_name}({args}, {
|
|
6859
|
+
f"WP_API void {f.mangled_name}({args}, {return_str}* ret) {{ *ret = wp::{f.key}({params}); }}\n"
|
|
6797
6860
|
)
|
|
6798
6861
|
|
|
6799
6862
|
file.write('\n} // extern "C"\n\n')
|
|
@@ -160,7 +160,7 @@ def run_benchmark(mode, dim, timers, render=False):
|
|
|
160
160
|
stage = Usd.Stage.CreateNew("benchmark.usd")
|
|
161
161
|
stage.SetStartTimeCode(0.0)
|
|
162
162
|
stage.SetEndTimeCode(sim_duration * sim_fps)
|
|
163
|
-
stage.
|
|
163
|
+
stage.SetFramesPerSecond(sim_fps)
|
|
164
164
|
|
|
165
165
|
grid = UsdGeom.Mesh.Define(stage, "/root")
|
|
166
166
|
grid.GetPointsAttr().Set(cloth.positions, 0.0)
|