warp-lang 1.0.0b2__py3-none-win_amd64.whl → 1.0.0b6__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.
- docs/conf.py +17 -5
- examples/env/env_ant.py +1 -1
- examples/env/env_cartpole.py +1 -1
- examples/env/env_humanoid.py +1 -1
- examples/env/env_usd.py +4 -1
- examples/env/environment.py +8 -9
- examples/example_dem.py +34 -33
- examples/example_diffray.py +364 -337
- examples/example_fluid.py +32 -23
- examples/example_jacobian_ik.py +97 -93
- examples/example_marching_cubes.py +6 -16
- examples/example_mesh.py +6 -16
- examples/example_mesh_intersect.py +16 -14
- examples/example_nvdb.py +14 -16
- examples/example_raycast.py +14 -13
- examples/example_raymarch.py +16 -23
- examples/example_render_opengl.py +19 -10
- examples/example_sim_cartpole.py +82 -78
- examples/example_sim_cloth.py +45 -48
- examples/example_sim_fk_grad.py +51 -44
- examples/example_sim_fk_grad_torch.py +47 -40
- examples/example_sim_grad_bounce.py +108 -133
- examples/example_sim_grad_cloth.py +99 -113
- examples/example_sim_granular.py +5 -6
- examples/{example_sim_sdf_shape.py → example_sim_granular_collision_sdf.py} +37 -26
- examples/example_sim_neo_hookean.py +51 -55
- examples/example_sim_particle_chain.py +4 -4
- examples/example_sim_quadruped.py +126 -81
- examples/example_sim_rigid_chain.py +54 -61
- examples/example_sim_rigid_contact.py +66 -70
- examples/example_sim_rigid_fem.py +3 -3
- examples/example_sim_rigid_force.py +1 -1
- examples/example_sim_rigid_gyroscopic.py +3 -4
- examples/example_sim_rigid_kinematics.py +28 -39
- examples/example_sim_trajopt.py +112 -110
- examples/example_sph.py +9 -8
- examples/example_wave.py +7 -7
- examples/fem/bsr_utils.py +30 -17
- examples/fem/example_apic_fluid.py +85 -69
- examples/fem/example_convection_diffusion.py +97 -93
- examples/fem/example_convection_diffusion_dg.py +142 -149
- examples/fem/example_convection_diffusion_dg0.py +141 -136
- examples/fem/example_deformed_geometry.py +146 -0
- examples/fem/example_diffusion.py +115 -84
- examples/fem/example_diffusion_3d.py +116 -86
- examples/fem/example_diffusion_mgpu.py +102 -79
- examples/fem/example_mixed_elasticity.py +139 -100
- examples/fem/example_navier_stokes.py +175 -162
- examples/fem/example_stokes.py +143 -111
- examples/fem/example_stokes_transfer.py +186 -157
- examples/fem/mesh_utils.py +59 -97
- examples/fem/plot_utils.py +138 -17
- tools/ci/publishing/build_nodes_info.py +54 -0
- warp/__init__.py +4 -3
- warp/__init__.pyi +1 -0
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +5 -3
- warp/build_dll.py +29 -9
- warp/builtins.py +836 -492
- warp/codegen.py +864 -553
- warp/config.py +3 -1
- warp/context.py +389 -172
- warp/fem/__init__.py +24 -6
- warp/fem/cache.py +318 -25
- warp/fem/dirichlet.py +7 -3
- warp/fem/domain.py +14 -0
- warp/fem/field/__init__.py +30 -38
- warp/fem/field/field.py +149 -0
- warp/fem/field/nodal_field.py +244 -138
- warp/fem/field/restriction.py +8 -6
- warp/fem/field/test.py +127 -59
- warp/fem/field/trial.py +117 -60
- warp/fem/geometry/__init__.py +5 -1
- warp/fem/geometry/deformed_geometry.py +271 -0
- warp/fem/geometry/element.py +24 -1
- warp/fem/geometry/geometry.py +86 -14
- warp/fem/geometry/grid_2d.py +112 -54
- warp/fem/geometry/grid_3d.py +134 -65
- warp/fem/geometry/hexmesh.py +953 -0
- warp/fem/geometry/partition.py +85 -33
- warp/fem/geometry/quadmesh_2d.py +532 -0
- warp/fem/geometry/tetmesh.py +451 -115
- warp/fem/geometry/trimesh_2d.py +197 -92
- warp/fem/integrate.py +534 -268
- warp/fem/operator.py +58 -31
- warp/fem/polynomial.py +11 -0
- warp/fem/quadrature/__init__.py +1 -1
- warp/fem/quadrature/pic_quadrature.py +150 -58
- warp/fem/quadrature/quadrature.py +209 -57
- warp/fem/space/__init__.py +230 -53
- warp/fem/space/basis_space.py +489 -0
- warp/fem/space/collocated_function_space.py +105 -0
- warp/fem/space/dof_mapper.py +49 -2
- warp/fem/space/function_space.py +90 -39
- warp/fem/space/grid_2d_function_space.py +149 -496
- warp/fem/space/grid_3d_function_space.py +173 -538
- warp/fem/space/hexmesh_function_space.py +352 -0
- warp/fem/space/partition.py +129 -76
- warp/fem/space/quadmesh_2d_function_space.py +369 -0
- warp/fem/space/restriction.py +46 -34
- warp/fem/space/shape/__init__.py +15 -0
- warp/fem/space/shape/cube_shape_function.py +738 -0
- warp/fem/space/shape/shape_function.py +103 -0
- warp/fem/space/shape/square_shape_function.py +611 -0
- warp/fem/space/shape/tet_shape_function.py +567 -0
- warp/fem/space/shape/triangle_shape_function.py +429 -0
- warp/fem/space/tetmesh_function_space.py +132 -1039
- warp/fem/space/topology.py +295 -0
- warp/fem/space/trimesh_2d_function_space.py +104 -742
- warp/fem/types.py +13 -11
- warp/fem/utils.py +335 -60
- warp/native/array.h +120 -34
- warp/native/builtin.h +101 -72
- warp/native/bvh.cpp +73 -325
- warp/native/bvh.cu +406 -23
- warp/native/bvh.h +22 -40
- warp/native/clang/clang.cpp +1 -0
- warp/native/crt.h +2 -0
- warp/native/cuda_util.cpp +8 -3
- warp/native/cuda_util.h +1 -0
- warp/native/exports.h +1522 -1243
- warp/native/intersect.h +19 -4
- warp/native/intersect_adj.h +8 -8
- warp/native/mat.h +76 -17
- warp/native/mesh.cpp +33 -108
- warp/native/mesh.cu +114 -18
- warp/native/mesh.h +395 -40
- warp/native/noise.h +272 -329
- warp/native/quat.h +51 -8
- warp/native/rand.h +44 -34
- warp/native/reduce.cpp +1 -1
- warp/native/sparse.cpp +4 -4
- warp/native/sparse.cu +163 -155
- warp/native/spatial.h +2 -2
- warp/native/temp_buffer.h +18 -14
- warp/native/vec.h +103 -21
- warp/native/warp.cpp +2 -1
- warp/native/warp.cu +28 -3
- warp/native/warp.h +4 -3
- warp/render/render_opengl.py +261 -109
- warp/sim/__init__.py +1 -2
- warp/sim/articulation.py +385 -185
- warp/sim/import_mjcf.py +59 -48
- warp/sim/import_urdf.py +15 -15
- warp/sim/import_usd.py +174 -102
- warp/sim/inertia.py +17 -18
- warp/sim/integrator_xpbd.py +4 -3
- warp/sim/model.py +330 -250
- warp/sim/render.py +1 -1
- warp/sparse.py +625 -152
- warp/stubs.py +341 -309
- warp/tape.py +9 -6
- warp/tests/__main__.py +3 -6
- warp/tests/assets/curlnoise_golden.npy +0 -0
- warp/tests/assets/pnoise_golden.npy +0 -0
- warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
- warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
- warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
- warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
- warp/tests/aux_test_unresolved_func.py +14 -0
- warp/tests/aux_test_unresolved_symbol.py +14 -0
- warp/tests/disabled_kinematics.py +239 -0
- warp/tests/run_coverage_serial.py +31 -0
- warp/tests/test_adam.py +103 -106
- warp/tests/test_arithmetic.py +94 -74
- warp/tests/test_array.py +82 -101
- warp/tests/test_array_reduce.py +57 -23
- warp/tests/test_atomic.py +64 -28
- warp/tests/test_bool.py +22 -12
- warp/tests/test_builtins_resolution.py +1292 -0
- warp/tests/test_bvh.py +18 -18
- warp/tests/test_closest_point_edge_edge.py +54 -57
- warp/tests/test_codegen.py +165 -134
- warp/tests/test_compile_consts.py +28 -20
- warp/tests/test_conditional.py +108 -24
- warp/tests/test_copy.py +10 -12
- warp/tests/test_ctypes.py +112 -88
- warp/tests/test_dense.py +21 -14
- warp/tests/test_devices.py +98 -0
- warp/tests/test_dlpack.py +75 -75
- warp/tests/test_examples.py +237 -0
- warp/tests/test_fabricarray.py +22 -24
- warp/tests/test_fast_math.py +15 -11
- warp/tests/test_fem.py +1034 -124
- warp/tests/test_fp16.py +23 -16
- warp/tests/test_func.py +187 -86
- warp/tests/test_generics.py +194 -49
- warp/tests/test_grad.py +123 -181
- warp/tests/test_grad_customs.py +176 -0
- warp/tests/test_hash_grid.py +35 -34
- warp/tests/test_import.py +10 -23
- warp/tests/test_indexedarray.py +24 -25
- warp/tests/test_intersect.py +18 -9
- warp/tests/test_large.py +141 -0
- warp/tests/test_launch.py +14 -41
- warp/tests/test_lerp.py +64 -65
- warp/tests/test_lvalue.py +493 -0
- warp/tests/test_marching_cubes.py +12 -13
- warp/tests/test_mat.py +517 -2898
- warp/tests/test_mat_lite.py +115 -0
- warp/tests/test_mat_scalar_ops.py +2889 -0
- warp/tests/test_math.py +103 -9
- warp/tests/test_matmul.py +304 -69
- warp/tests/test_matmul_lite.py +410 -0
- warp/tests/test_mesh.py +60 -22
- warp/tests/test_mesh_query_aabb.py +21 -25
- warp/tests/test_mesh_query_point.py +111 -22
- warp/tests/test_mesh_query_ray.py +12 -24
- warp/tests/test_mlp.py +30 -22
- warp/tests/test_model.py +92 -89
- warp/tests/test_modules_lite.py +39 -0
- warp/tests/test_multigpu.py +88 -114
- warp/tests/test_noise.py +12 -11
- warp/tests/test_operators.py +16 -20
- warp/tests/test_options.py +11 -11
- warp/tests/test_pinned.py +17 -18
- warp/tests/test_print.py +32 -11
- warp/tests/test_quat.py +275 -129
- warp/tests/test_rand.py +18 -16
- warp/tests/test_reload.py +38 -34
- warp/tests/test_rounding.py +50 -43
- warp/tests/test_runlength_encode.py +168 -20
- warp/tests/test_smoothstep.py +9 -11
- warp/tests/test_snippet.py +143 -0
- warp/tests/test_sparse.py +261 -63
- warp/tests/test_spatial.py +276 -243
- warp/tests/test_streams.py +110 -85
- warp/tests/test_struct.py +268 -63
- warp/tests/test_tape.py +39 -21
- warp/tests/test_torch.py +90 -86
- warp/tests/test_transient_module.py +10 -12
- warp/tests/test_types.py +363 -0
- warp/tests/test_utils.py +451 -0
- warp/tests/test_vec.py +354 -2050
- warp/tests/test_vec_lite.py +73 -0
- warp/tests/test_vec_scalar_ops.py +2099 -0
- warp/tests/test_volume.py +418 -376
- warp/tests/test_volume_write.py +124 -134
- warp/tests/unittest_serial.py +35 -0
- warp/tests/unittest_suites.py +291 -0
- warp/tests/unittest_utils.py +342 -0
- warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
- warp/tests/{test_debug.py → walkthough_debug.py} +3 -17
- warp/thirdparty/appdirs.py +36 -45
- warp/thirdparty/unittest_parallel.py +589 -0
- warp/types.py +622 -211
- warp/utils.py +54 -393
- warp_lang-1.0.0b6.dist-info/METADATA +238 -0
- warp_lang-1.0.0b6.dist-info/RECORD +409 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
- examples/example_cache_management.py +0 -40
- examples/example_multigpu.py +0 -54
- examples/example_struct.py +0 -65
- examples/fem/example_stokes_transfer_3d.py +0 -210
- warp/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/fem/field/discrete_field.py +0 -80
- warp/fem/space/nodal_function_space.py +0 -233
- warp/tests/test_all.py +0 -223
- warp/tests/test_array_scan.py +0 -60
- warp/tests/test_base.py +0 -208
- warp/tests/test_unresolved_func.py +0 -7
- warp/tests/test_unresolved_symbol.py +0 -7
- warp_lang-1.0.0b2.dist-info/METADATA +0 -26
- warp_lang-1.0.0b2.dist-info/RECORD +0 -380
- /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
- /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
- /warp/tests/{test_square.py → aux_test_square.py} +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.0.0b2.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# Copyright (c) 2022 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
|
+
|
|
8
|
+
import ctypes
|
|
9
|
+
import ctypes.util
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
import unittest
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
import warp as wp
|
|
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
|
+
|
|
26
|
+
# default test mode (see get_test_devices())
|
|
27
|
+
# "basic" - only run on CPU and first GPU device
|
|
28
|
+
# "unique" - run on CPU and all unique GPU arches
|
|
29
|
+
# "all" - run on all devices
|
|
30
|
+
test_mode = "unique"
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
if sys.platform == "win32":
|
|
34
|
+
LIBC = ctypes.CDLL("ucrtbase.dll")
|
|
35
|
+
else:
|
|
36
|
+
LIBC = ctypes.CDLL(ctypes.util.find_library("c"))
|
|
37
|
+
except OSError:
|
|
38
|
+
print("Failed to load the standard C library")
|
|
39
|
+
LIBC = None
|
|
40
|
+
|
|
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
|
+
|
|
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
|
+
"""
|
|
76
|
+
if mode is None:
|
|
77
|
+
global test_mode
|
|
78
|
+
mode = test_mode
|
|
79
|
+
|
|
80
|
+
devices = []
|
|
81
|
+
|
|
82
|
+
# only run on CPU and first GPU device
|
|
83
|
+
if mode == "basic":
|
|
84
|
+
if wp.is_cpu_available():
|
|
85
|
+
devices.append(wp.get_device("cpu"))
|
|
86
|
+
if wp.is_cuda_available():
|
|
87
|
+
devices.append(wp.get_device("cuda:0"))
|
|
88
|
+
|
|
89
|
+
# run on CPU and all unique GPU arches
|
|
90
|
+
elif mode == "unique":
|
|
91
|
+
if wp.is_cpu_available():
|
|
92
|
+
devices.append(wp.get_device("cpu"))
|
|
93
|
+
|
|
94
|
+
devices.extend(get_unique_cuda_test_devices())
|
|
95
|
+
|
|
96
|
+
# run on all devices
|
|
97
|
+
elif mode == "all":
|
|
98
|
+
devices = wp.get_devices()
|
|
99
|
+
|
|
100
|
+
return devices
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# redirects and captures all stdout output (including from C-libs)
|
|
104
|
+
class StdOutCapture:
|
|
105
|
+
def begin(self):
|
|
106
|
+
# Flush the stream buffers managed by libc.
|
|
107
|
+
# This is needed at the moment due to Carbonite not flushing the logs
|
|
108
|
+
# being printed out when extensions are starting up.
|
|
109
|
+
if LIBC is not None:
|
|
110
|
+
LIBC.fflush(None)
|
|
111
|
+
|
|
112
|
+
# save original
|
|
113
|
+
self.saved = sys.stdout
|
|
114
|
+
self.target = os.dup(self.saved.fileno())
|
|
115
|
+
|
|
116
|
+
# create temporary capture stream
|
|
117
|
+
import io
|
|
118
|
+
import tempfile
|
|
119
|
+
|
|
120
|
+
self.tempfile = io.TextIOWrapper(
|
|
121
|
+
tempfile.TemporaryFile(buffering=0), encoding="utf-8", errors="replace", newline="", write_through=True
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
os.dup2(self.tempfile.fileno(), self.saved.fileno())
|
|
125
|
+
|
|
126
|
+
sys.stdout = self.tempfile
|
|
127
|
+
|
|
128
|
+
def end(self):
|
|
129
|
+
os.dup2(self.target, self.saved.fileno())
|
|
130
|
+
os.close(self.target)
|
|
131
|
+
|
|
132
|
+
self.tempfile.seek(0)
|
|
133
|
+
res = self.tempfile.buffer.read()
|
|
134
|
+
self.tempfile.close()
|
|
135
|
+
|
|
136
|
+
sys.stdout = self.saved
|
|
137
|
+
|
|
138
|
+
return str(res.decode("utf-8"))
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class CheckOutput:
|
|
142
|
+
def __init__(self, test):
|
|
143
|
+
self.test = test
|
|
144
|
+
|
|
145
|
+
def __enter__(self):
|
|
146
|
+
# wp.force_load()
|
|
147
|
+
|
|
148
|
+
self.capture = StdOutCapture()
|
|
149
|
+
self.capture.begin()
|
|
150
|
+
|
|
151
|
+
def __exit__(self, exc_type, exc_value, traceback):
|
|
152
|
+
# ensure any stdout output is flushed
|
|
153
|
+
wp.synchronize()
|
|
154
|
+
|
|
155
|
+
s = self.capture.end()
|
|
156
|
+
if s != "":
|
|
157
|
+
print(s.rstrip())
|
|
158
|
+
|
|
159
|
+
# fail if test produces unexpected output (e.g.: from wp.expect_eq() builtins)
|
|
160
|
+
# we allow strings starting of the form "Module xxx load on device xxx"
|
|
161
|
+
# for lazy loaded modules
|
|
162
|
+
if s != "" and not s.startswith("Module"):
|
|
163
|
+
self.test.fail(f"Unexpected output:\n'{s.rstrip()}'")
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def assert_array_equal(result: wp.array, expect: wp.array):
|
|
167
|
+
np.testing.assert_equal(result.numpy(), expect.numpy())
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def assert_np_equal(result, expect, tol=0.0):
|
|
171
|
+
a = result.flatten()
|
|
172
|
+
b = expect.flatten()
|
|
173
|
+
|
|
174
|
+
if tol == 0.0:
|
|
175
|
+
if not (a == b).all():
|
|
176
|
+
raise AssertionError(f"Unexpected result, got: {a} expected: {b}")
|
|
177
|
+
|
|
178
|
+
else:
|
|
179
|
+
delta = a - b
|
|
180
|
+
err = np.max(np.abs(delta))
|
|
181
|
+
if err > tol:
|
|
182
|
+
raise AssertionError(
|
|
183
|
+
f"Maximum expected error exceeds tolerance got: {a}, expected: {b}, with err: {err} > {tol}"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# if check_output is True any output to stdout will be treated as an error
|
|
188
|
+
def create_test_func(func, device, check_output, **kwargs):
|
|
189
|
+
# pass args to func
|
|
190
|
+
def test_func(self):
|
|
191
|
+
if check_output:
|
|
192
|
+
with CheckOutput(self):
|
|
193
|
+
func(self, device, **kwargs)
|
|
194
|
+
else:
|
|
195
|
+
func(self, device, **kwargs)
|
|
196
|
+
|
|
197
|
+
return test_func
|
|
198
|
+
|
|
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
|
+
|
|
205
|
+
def sanitize_identifier(s):
|
|
206
|
+
"""replace all non-identifier characters with '_'"""
|
|
207
|
+
|
|
208
|
+
s = str(s)
|
|
209
|
+
if s.isidentifier():
|
|
210
|
+
return s
|
|
211
|
+
else:
|
|
212
|
+
import re
|
|
213
|
+
|
|
214
|
+
return re.sub(r"\W|^(?=\d)", "_", s)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def add_function_test(cls, name, func, devices=None, check_output=True, **kwargs):
|
|
218
|
+
if devices is None:
|
|
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
|
+
)
|
|
231
|
+
else:
|
|
232
|
+
setattr(cls, name + "_" + sanitize_identifier(devices), create_test_func(func, devices, check_output, **kwargs))
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def add_kernel_test(cls, kernel, dim, name=None, expect=None, inputs=None, devices=None):
|
|
236
|
+
def test_func(self, device):
|
|
237
|
+
args = []
|
|
238
|
+
if inputs:
|
|
239
|
+
args.extend(inputs)
|
|
240
|
+
|
|
241
|
+
if expect:
|
|
242
|
+
# allocate outputs to match results
|
|
243
|
+
result = wp.array(expect, dtype=int, device=device)
|
|
244
|
+
output = wp.zeros_like(result)
|
|
245
|
+
|
|
246
|
+
args.append(output)
|
|
247
|
+
|
|
248
|
+
# force load so that we don't generate any log output during launch
|
|
249
|
+
kernel.module.load(device)
|
|
250
|
+
|
|
251
|
+
with CheckOutput(self):
|
|
252
|
+
wp.launch(kernel, dim=dim, inputs=args, device=device)
|
|
253
|
+
|
|
254
|
+
# check output values
|
|
255
|
+
if expect:
|
|
256
|
+
assert_array_equal(output, result)
|
|
257
|
+
|
|
258
|
+
if name is None:
|
|
259
|
+
name = kernel.key
|
|
260
|
+
|
|
261
|
+
# device is required for kernel tests, so use all devices if none were given
|
|
262
|
+
if devices is None:
|
|
263
|
+
devices = get_test_devices()
|
|
264
|
+
|
|
265
|
+
# register test func with class for the given devices
|
|
266
|
+
for d in devices:
|
|
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)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
# helper that first calls the test function to generate all kernel permutations
|
|
275
|
+
# so that compilation is done in one-shot instead of per-test
|
|
276
|
+
def add_function_test_register_kernel(cls, name, func, devices=None, **kwargs):
|
|
277
|
+
func(None, None, **kwargs, register_kernels=True)
|
|
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
|
-
|
|
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
|
|
67
|
+
def example_breakpoint(n: int):
|
|
71
68
|
a = int(0)
|
|
72
69
|
|
|
73
70
|
for i in range(0, n):
|
|
@@ -83,17 +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
|
-
wp.build.clear_kernel_cache()
|
|
91
|
-
|
|
92
|
-
add_kernel_test(TestDebug, name="test_breakpoint", kernel=test_breakpoint, dim=1, inputs=[10], devices=["cpu"])
|
|
93
|
-
|
|
94
|
-
return TestDebug
|
|
95
|
-
|
|
96
|
-
|
|
97
83
|
if __name__ == "__main__":
|
|
98
|
-
|
|
99
|
-
|
|
84
|
+
wp.build.clear_kernel_cache()
|
|
85
|
+
wp.launch(example_breakpoint, dim=1, inputs=[10], device="cpu")
|
warp/thirdparty/appdirs.py
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
1
|
# -*- coding: utf-8 -*-
|
|
3
2
|
# Copyright (c) 2005-2010 ActiveState Software Inc.
|
|
4
3
|
# Copyright (c) 2013 Eddy Petrișor
|
|
5
4
|
|
|
6
5
|
"""Utilities for determining application-specific dirs.
|
|
7
6
|
|
|
8
|
-
See <
|
|
7
|
+
See <https://github.com/ActiveState/appdirs> for details and usage.
|
|
9
8
|
"""
|
|
10
9
|
# Dev Notes:
|
|
11
10
|
# - MSDN on where to store app data files:
|
|
12
11
|
# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120
|
|
13
12
|
# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html
|
|
14
|
-
# - XDG spec for Un*x:
|
|
13
|
+
# - XDG spec for Un*x: https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
|
|
15
14
|
|
|
16
15
|
__version__ = "1.4.4"
|
|
17
16
|
__version_info__ = tuple(int(segment) for segment in __version__.split("."))
|
|
@@ -77,7 +76,7 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False):
|
|
|
77
76
|
if system == "win32":
|
|
78
77
|
if appauthor is None:
|
|
79
78
|
appauthor = appname
|
|
80
|
-
const =
|
|
79
|
+
const = "CSIDL_APPDATA" if roaming else "CSIDL_LOCAL_APPDATA"
|
|
81
80
|
path = os.path.normpath(_get_win_folder(const))
|
|
82
81
|
if appname:
|
|
83
82
|
if appauthor is not False:
|
|
@@ -184,15 +183,19 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False):
|
|
|
184
183
|
for a discussion of issues.
|
|
185
184
|
|
|
186
185
|
Typical user config directories are:
|
|
187
|
-
Mac OS X:
|
|
186
|
+
Mac OS X: ~/Library/Preferences/<AppName>
|
|
188
187
|
Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined
|
|
189
188
|
Win *: same as user_data_dir
|
|
190
189
|
|
|
191
190
|
For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME.
|
|
192
191
|
That means, by default "~/.config/<AppName>".
|
|
193
192
|
"""
|
|
194
|
-
if system
|
|
193
|
+
if system == "win32":
|
|
195
194
|
path = user_data_dir(appname, appauthor, None, roaming)
|
|
195
|
+
elif system == "darwin":
|
|
196
|
+
path = os.path.expanduser("~/Library/Preferences/")
|
|
197
|
+
if appname:
|
|
198
|
+
path = os.path.join(path, appname)
|
|
196
199
|
else:
|
|
197
200
|
path = os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
|
|
198
201
|
if appname:
|
|
@@ -232,10 +235,14 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False)
|
|
|
232
235
|
|
|
233
236
|
WARNING: Do not use this on Windows. See the Vista-Fail note above for why.
|
|
234
237
|
"""
|
|
235
|
-
if system
|
|
238
|
+
if system == "win32":
|
|
236
239
|
path = site_data_dir(appname, appauthor)
|
|
237
240
|
if appname and version:
|
|
238
241
|
path = os.path.join(path, version)
|
|
242
|
+
elif system == "darwin":
|
|
243
|
+
path = os.path.expanduser("/Library/Preferences")
|
|
244
|
+
if appname:
|
|
245
|
+
path = os.path.join(path, appname)
|
|
239
246
|
else:
|
|
240
247
|
# XDG default for $XDG_CONFIG_DIRS
|
|
241
248
|
# only first, if multipath is False
|
|
@@ -466,35 +473,6 @@ def _get_win_folder_from_registry(csidl_name):
|
|
|
466
473
|
return dir
|
|
467
474
|
|
|
468
475
|
|
|
469
|
-
def _get_win_folder_with_pywin32(csidl_name):
|
|
470
|
-
from win32com.shell import shellcon, shell
|
|
471
|
-
|
|
472
|
-
dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
|
|
473
|
-
# Try to make this a unicode path because SHGetFolderPath does
|
|
474
|
-
# not return unicode strings when there is unicode data in the
|
|
475
|
-
# path.
|
|
476
|
-
try:
|
|
477
|
-
dir = unicode(dir)
|
|
478
|
-
|
|
479
|
-
# Downgrade to short path name if have highbit chars. See
|
|
480
|
-
# <http://bugs.activestate.com/show_bug.cgi?id=85099>.
|
|
481
|
-
has_high_char = False
|
|
482
|
-
for c in dir:
|
|
483
|
-
if ord(c) > 255:
|
|
484
|
-
has_high_char = True
|
|
485
|
-
break
|
|
486
|
-
if has_high_char:
|
|
487
|
-
try:
|
|
488
|
-
import win32api
|
|
489
|
-
|
|
490
|
-
dir = win32api.GetShortPathName(dir)
|
|
491
|
-
except ImportError:
|
|
492
|
-
pass
|
|
493
|
-
except UnicodeError:
|
|
494
|
-
pass
|
|
495
|
-
return dir
|
|
496
|
-
|
|
497
|
-
|
|
498
476
|
def _get_win_folder_with_ctypes(csidl_name):
|
|
499
477
|
import ctypes
|
|
500
478
|
|
|
@@ -549,23 +527,36 @@ def _get_win_folder_with_jna(csidl_name):
|
|
|
549
527
|
return dir
|
|
550
528
|
|
|
551
529
|
|
|
530
|
+
def _get_win_folder_from_environ(csidl_name):
|
|
531
|
+
env_var_name = {
|
|
532
|
+
"CSIDL_APPDATA": "APPDATA",
|
|
533
|
+
"CSIDL_COMMON_APPDATA": "ALLUSERSPROFILE",
|
|
534
|
+
"CSIDL_LOCAL_APPDATA": "LOCALAPPDATA",
|
|
535
|
+
}[csidl_name]
|
|
536
|
+
|
|
537
|
+
return os.environ[env_var_name]
|
|
538
|
+
|
|
539
|
+
|
|
552
540
|
if system == "win32":
|
|
553
541
|
try:
|
|
554
|
-
import
|
|
555
|
-
|
|
556
|
-
_get_win_folder = _get_win_folder_with_pywin32
|
|
542
|
+
from ctypes import windll
|
|
557
543
|
except ImportError:
|
|
558
544
|
try:
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
_get_win_folder = _get_win_folder_with_ctypes
|
|
545
|
+
import com.sun.jna
|
|
562
546
|
except ImportError:
|
|
563
547
|
try:
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
548
|
+
if PY3:
|
|
549
|
+
import winreg as _winreg
|
|
550
|
+
else:
|
|
551
|
+
import _winreg
|
|
567
552
|
except ImportError:
|
|
553
|
+
_get_win_folder = _get_win_folder_from_environ
|
|
554
|
+
else:
|
|
568
555
|
_get_win_folder = _get_win_folder_from_registry
|
|
556
|
+
else:
|
|
557
|
+
_get_win_folder = _get_win_folder_with_jna
|
|
558
|
+
else:
|
|
559
|
+
_get_win_folder = _get_win_folder_with_ctypes
|
|
569
560
|
|
|
570
561
|
|
|
571
562
|
# ---- self test code
|