warp-lang 1.1.0__py3-none-manylinux2014_aarch64.whl → 1.2.1__py3-none-manylinux2014_aarch64.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/bin/warp-clang.so +0 -0
- warp/bin/warp.so +0 -0
- warp/build.py +10 -37
- warp/build_dll.py +2 -2
- warp/builtins.py +274 -6
- warp/codegen.py +51 -4
- warp/config.py +2 -2
- warp/constants.py +4 -0
- warp/context.py +422 -203
- warp/examples/benchmarks/benchmark_api.py +0 -2
- warp/examples/benchmarks/benchmark_cloth_warp.py +0 -1
- warp/examples/benchmarks/benchmark_launches.py +0 -2
- warp/examples/core/example_dem.py +0 -2
- warp/examples/core/example_fluid.py +0 -2
- warp/examples/core/example_graph_capture.py +0 -2
- warp/examples/core/example_marching_cubes.py +0 -2
- warp/examples/core/example_mesh.py +0 -2
- warp/examples/core/example_mesh_intersect.py +0 -2
- warp/examples/core/example_nvdb.py +0 -2
- warp/examples/core/example_raycast.py +0 -2
- warp/examples/core/example_raymarch.py +0 -2
- warp/examples/core/example_render_opengl.py +0 -2
- warp/examples/core/example_sph.py +0 -2
- warp/examples/core/example_torch.py +0 -3
- warp/examples/core/example_wave.py +0 -2
- warp/examples/fem/example_apic_fluid.py +140 -115
- warp/examples/fem/example_burgers.py +262 -0
- warp/examples/fem/example_convection_diffusion.py +0 -2
- warp/examples/fem/example_convection_diffusion_dg.py +0 -2
- warp/examples/fem/example_deformed_geometry.py +0 -2
- warp/examples/fem/example_diffusion.py +0 -2
- warp/examples/fem/example_diffusion_3d.py +5 -4
- warp/examples/fem/example_diffusion_mgpu.py +0 -2
- warp/examples/fem/example_mixed_elasticity.py +0 -2
- warp/examples/fem/example_navier_stokes.py +0 -2
- warp/examples/fem/example_stokes.py +0 -2
- warp/examples/fem/example_stokes_transfer.py +0 -2
- warp/examples/optim/example_bounce.py +0 -2
- warp/examples/optim/example_cloth_throw.py +0 -2
- warp/examples/optim/example_diffray.py +0 -2
- warp/examples/optim/example_drone.py +0 -2
- warp/examples/optim/example_inverse_kinematics.py +0 -2
- warp/examples/optim/example_inverse_kinematics_torch.py +0 -2
- warp/examples/optim/example_spring_cage.py +0 -2
- warp/examples/optim/example_trajectory.py +0 -2
- warp/examples/optim/example_walker.py +0 -2
- warp/examples/sim/example_cartpole.py +0 -2
- warp/examples/sim/example_cloth.py +0 -2
- warp/examples/sim/example_granular.py +0 -2
- warp/examples/sim/example_granular_collision_sdf.py +0 -2
- warp/examples/sim/example_jacobian_ik.py +0 -2
- warp/examples/sim/example_particle_chain.py +0 -2
- warp/examples/sim/example_quadruped.py +0 -2
- warp/examples/sim/example_rigid_chain.py +0 -2
- warp/examples/sim/example_rigid_contact.py +0 -2
- warp/examples/sim/example_rigid_force.py +0 -2
- warp/examples/sim/example_rigid_gyroscopic.py +0 -2
- warp/examples/sim/example_rigid_soft_contact.py +0 -2
- warp/examples/sim/example_soft_body.py +0 -2
- warp/fem/__init__.py +1 -0
- warp/fem/cache.py +3 -1
- warp/fem/geometry/__init__.py +1 -0
- warp/fem/geometry/element.py +4 -0
- warp/fem/geometry/grid_3d.py +0 -4
- warp/fem/geometry/nanogrid.py +455 -0
- warp/fem/integrate.py +63 -9
- warp/fem/space/__init__.py +43 -158
- warp/fem/space/basis_space.py +34 -0
- warp/fem/space/collocated_function_space.py +1 -1
- warp/fem/space/grid_2d_function_space.py +13 -132
- warp/fem/space/grid_3d_function_space.py +16 -154
- warp/fem/space/hexmesh_function_space.py +37 -134
- warp/fem/space/nanogrid_function_space.py +202 -0
- warp/fem/space/quadmesh_2d_function_space.py +12 -119
- warp/fem/space/restriction.py +4 -1
- warp/fem/space/shape/__init__.py +77 -0
- warp/fem/space/shape/cube_shape_function.py +5 -15
- warp/fem/space/tetmesh_function_space.py +6 -76
- warp/fem/space/trimesh_2d_function_space.py +6 -76
- warp/native/array.h +12 -3
- warp/native/builtin.h +48 -5
- warp/native/bvh.cpp +14 -10
- warp/native/bvh.cu +23 -15
- warp/native/bvh.h +1 -0
- warp/native/clang/clang.cpp +2 -1
- warp/native/crt.cpp +11 -1
- warp/native/crt.h +18 -1
- warp/native/exports.h +187 -0
- warp/native/mat.h +47 -0
- warp/native/mesh.cpp +1 -1
- warp/native/mesh.cu +1 -2
- warp/native/nanovdb/GridHandle.h +366 -0
- warp/native/nanovdb/HostBuffer.h +590 -0
- warp/native/nanovdb/NanoVDB.h +3999 -2157
- warp/native/nanovdb/PNanoVDB.h +936 -99
- warp/native/quat.h +28 -1
- warp/native/rand.h +5 -1
- warp/native/vec.h +45 -1
- warp/native/volume.cpp +335 -103
- warp/native/volume.cu +39 -13
- warp/native/volume.h +725 -303
- warp/native/volume_builder.cu +381 -360
- warp/native/volume_builder.h +16 -1
- warp/native/volume_impl.h +61 -0
- warp/native/warp.cu +8 -2
- warp/native/warp.h +15 -7
- warp/render/render_opengl.py +191 -52
- warp/sim/integrator_featherstone.py +10 -3
- warp/sim/integrator_xpbd.py +16 -22
- warp/sparse.py +89 -27
- warp/stubs.py +83 -0
- warp/tests/assets/test_index_grid.nvdb +0 -0
- warp/tests/aux_test_dependent.py +0 -2
- warp/tests/aux_test_grad_customs.py +0 -2
- warp/tests/aux_test_reference.py +0 -2
- warp/tests/aux_test_reference_reference.py +0 -2
- warp/tests/aux_test_square.py +0 -2
- warp/tests/disabled_kinematics.py +0 -2
- warp/tests/test_adam.py +0 -2
- warp/tests/test_arithmetic.py +0 -36
- warp/tests/test_array.py +9 -11
- warp/tests/test_array_reduce.py +0 -2
- warp/tests/test_async.py +0 -2
- warp/tests/test_atomic.py +0 -2
- warp/tests/test_bool.py +58 -50
- warp/tests/test_builtins_resolution.py +0 -2
- warp/tests/test_bvh.py +0 -2
- warp/tests/test_closest_point_edge_edge.py +0 -1
- warp/tests/test_codegen.py +0 -4
- warp/tests/test_compile_consts.py +130 -10
- warp/tests/test_conditional.py +0 -2
- warp/tests/test_copy.py +0 -2
- warp/tests/test_ctypes.py +6 -8
- warp/tests/test_dense.py +0 -2
- warp/tests/test_devices.py +0 -2
- warp/tests/test_dlpack.py +9 -11
- warp/tests/test_examples.py +42 -39
- warp/tests/test_fabricarray.py +0 -3
- warp/tests/test_fast_math.py +0 -2
- warp/tests/test_fem.py +75 -54
- warp/tests/test_fp16.py +0 -2
- warp/tests/test_func.py +0 -2
- warp/tests/test_generics.py +27 -2
- warp/tests/test_grad.py +147 -8
- warp/tests/test_grad_customs.py +0 -2
- warp/tests/test_hash_grid.py +1 -3
- warp/tests/test_import.py +0 -2
- warp/tests/test_indexedarray.py +0 -2
- warp/tests/test_intersect.py +0 -2
- warp/tests/test_jax.py +0 -2
- warp/tests/test_large.py +11 -9
- warp/tests/test_launch.py +0 -2
- warp/tests/test_lerp.py +10 -54
- warp/tests/test_linear_solvers.py +3 -5
- warp/tests/test_lvalue.py +0 -2
- warp/tests/test_marching_cubes.py +0 -2
- warp/tests/test_mat.py +0 -2
- warp/tests/test_mat_lite.py +0 -2
- warp/tests/test_mat_scalar_ops.py +0 -2
- warp/tests/test_math.py +0 -2
- warp/tests/test_matmul.py +35 -37
- warp/tests/test_matmul_lite.py +29 -31
- warp/tests/test_mempool.py +0 -2
- warp/tests/test_mesh.py +0 -3
- warp/tests/test_mesh_query_aabb.py +0 -2
- warp/tests/test_mesh_query_point.py +0 -2
- warp/tests/test_mesh_query_ray.py +0 -2
- warp/tests/test_mlp.py +0 -2
- warp/tests/test_model.py +0 -2
- warp/tests/test_module_hashing.py +111 -0
- warp/tests/test_modules_lite.py +0 -3
- warp/tests/test_multigpu.py +0 -2
- warp/tests/test_noise.py +0 -4
- warp/tests/test_operators.py +0 -2
- warp/tests/test_options.py +0 -2
- warp/tests/test_peer.py +0 -2
- warp/tests/test_pinned.py +0 -2
- warp/tests/test_print.py +0 -2
- warp/tests/test_quat.py +0 -2
- warp/tests/test_rand.py +41 -5
- warp/tests/test_reload.py +0 -10
- warp/tests/test_rounding.py +0 -2
- warp/tests/test_runlength_encode.py +0 -2
- warp/tests/test_sim_grad.py +0 -2
- warp/tests/test_sim_kinematics.py +0 -2
- warp/tests/test_smoothstep.py +0 -2
- warp/tests/test_snippet.py +0 -2
- warp/tests/test_sparse.py +0 -2
- warp/tests/test_spatial.py +0 -2
- warp/tests/test_special_values.py +362 -0
- warp/tests/test_streams.py +0 -2
- warp/tests/test_struct.py +0 -2
- warp/tests/test_tape.py +0 -2
- warp/tests/test_torch.py +0 -2
- warp/tests/test_transient_module.py +0 -2
- warp/tests/test_types.py +0 -2
- warp/tests/test_utils.py +0 -2
- warp/tests/test_vec.py +0 -2
- warp/tests/test_vec_lite.py +0 -2
- warp/tests/test_vec_scalar_ops.py +0 -2
- warp/tests/test_verify_fp.py +0 -2
- warp/tests/test_volume.py +237 -13
- warp/tests/test_volume_write.py +86 -3
- warp/tests/unittest_serial.py +10 -9
- warp/tests/unittest_suites.py +6 -2
- warp/tests/unittest_utils.py +2 -171
- warp/tests/unused_test_misc.py +0 -2
- warp/tests/walkthrough_debug.py +1 -1
- warp/thirdparty/unittest_parallel.py +37 -40
- warp/types.py +526 -85
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/METADATA +61 -31
- warp_lang-1.2.1.dist-info/RECORD +359 -0
- warp/examples/fem/example_convection_diffusion_dg0.py +0 -204
- warp/native/nanovdb/PNanoVDBWrite.h +0 -295
- warp_lang-1.1.0.dist-info/RECORD +0 -352
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/WHEEL +0 -0
- {warp_lang-1.1.0.dist-info → warp_lang-1.2.1.dist-info}/top_level.txt +0 -0
warp/native/volume_builder.h
CHANGED
|
@@ -10,8 +10,23 @@ struct BuildGridParams {
|
|
|
10
10
|
char name[256] = "";
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
template<>
|
|
14
|
+
struct BuildGridParams<nanovdb::ValueIndex> {
|
|
15
|
+
double voxel_size = 1.0;
|
|
16
|
+
nanovdb::ValueIndex background_value;
|
|
17
|
+
nanovdb::Vec3d translation{0.0, 0.0, 0.0};
|
|
18
|
+
char name[256] = "";
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
template<>
|
|
22
|
+
struct BuildGridParams<nanovdb::ValueOnIndex> {
|
|
23
|
+
double voxel_size = 1.0;
|
|
24
|
+
nanovdb::Vec3d translation{0.0, 0.0, 0.0};
|
|
25
|
+
char name[256] = "";
|
|
26
|
+
};
|
|
27
|
+
|
|
13
28
|
template <typename BuildT>
|
|
14
|
-
void
|
|
29
|
+
void build_grid_from_points(nanovdb::Grid<nanovdb::NanoTree<BuildT>> *&out_grid,
|
|
15
30
|
size_t &out_grid_size,
|
|
16
31
|
const void *points,
|
|
17
32
|
size_t num_points,
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
|
|
9
|
+
#pragma once
|
|
10
|
+
|
|
11
|
+
#include "volume.h"
|
|
12
|
+
|
|
13
|
+
// Helper functions for cpp/cu files, not to be exposed to user kernels
|
|
14
|
+
|
|
15
|
+
namespace wp
|
|
16
|
+
{
|
|
17
|
+
|
|
18
|
+
namespace volume
|
|
19
|
+
{
|
|
20
|
+
|
|
21
|
+
inline CUDA_CALLABLE pnanovdb_leaf_handle_t get_leaf(const pnanovdb_buf_t buf, const uint32_t leaf_id)
|
|
22
|
+
{
|
|
23
|
+
const pnanovdb_tree_handle_t tree = get_tree(buf);
|
|
24
|
+
const uint64_t first_leaf_offset = pnanovdb_tree_get_node_offset_leaf(buf, tree);
|
|
25
|
+
const uint32_t leaf_stride = PNANOVDB_GRID_TYPE_GET(get_grid_type(buf), leaf_size);
|
|
26
|
+
return {pnanovdb_address_offset64(tree.address, first_leaf_offset + uint64_t(leaf_id) * leaf_stride)};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
inline CUDA_CALLABLE pnanovdb_coord_t leaf_origin(const pnanovdb_buf_t buf, const pnanovdb_leaf_handle_t leaf)
|
|
30
|
+
{
|
|
31
|
+
pnanovdb_coord_t origin = pnanovdb_leaf_get_bbox_min(buf, leaf);
|
|
32
|
+
// mask out last three bits corresponding to voxel coordinates within leaf
|
|
33
|
+
constexpr uint32_t MASK = (1u << 3u) - 1u;
|
|
34
|
+
origin.x &= ~MASK;
|
|
35
|
+
origin.y &= ~MASK;
|
|
36
|
+
origin.z &= ~MASK;
|
|
37
|
+
return origin;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
inline CUDA_CALLABLE uint64_t leaf_voxel_index(const pnanovdb_buf_t buf, const uint32_t leaf_id,
|
|
41
|
+
const pnanovdb_coord_t &ijk)
|
|
42
|
+
{
|
|
43
|
+
const uint32_t grid_type = get_grid_type(buf);
|
|
44
|
+
|
|
45
|
+
const pnanovdb_leaf_handle_t leaf = get_leaf(buf, leaf_id);
|
|
46
|
+
const pnanovdb_address_t value_address = pnanovdb_leaf_get_value_address(grid_type, buf, leaf, &ijk);
|
|
47
|
+
return volume::get_grid_voxel_index(grid_type, buf, value_address, ijk) - 1;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
inline CUDA_CALLABLE pnanovdb_coord_t leaf_offset_to_local_coord(uint32_t offset)
|
|
51
|
+
{
|
|
52
|
+
pnanovdb_coord_t coord;
|
|
53
|
+
coord.x = (offset >> 6) & 7;
|
|
54
|
+
coord.y = (offset >> 3) & 7;
|
|
55
|
+
coord.z = (offset >> 0) & 7;
|
|
56
|
+
return coord;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
} // namespace volume
|
|
60
|
+
|
|
61
|
+
} // namespace wp
|
warp/native/warp.cu
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
#include <iterator>
|
|
19
19
|
#include <list>
|
|
20
20
|
#include <map>
|
|
21
|
+
#include <string>
|
|
21
22
|
#include <unordered_map>
|
|
22
23
|
#include <unordered_set>
|
|
23
24
|
#include <vector>
|
|
@@ -2536,7 +2537,7 @@ size_t cuda_compile_program(const char* cuda_src, int arch, const char* include_
|
|
|
2536
2537
|
std::vector<const char*> opts;
|
|
2537
2538
|
opts.push_back(arch_opt);
|
|
2538
2539
|
opts.push_back(include_opt);
|
|
2539
|
-
opts.push_back("--std=c++
|
|
2540
|
+
opts.push_back("--std=c++17");
|
|
2540
2541
|
|
|
2541
2542
|
if (debug)
|
|
2542
2543
|
{
|
|
@@ -2864,7 +2865,12 @@ void* cuda_graphics_register_gl_buffer(void* context, uint32_t gl_buffer, unsign
|
|
|
2864
2865
|
ContextGuard guard(context);
|
|
2865
2866
|
|
|
2866
2867
|
CUgraphicsResource *resource = new CUgraphicsResource;
|
|
2867
|
-
check_cu(cuGraphicsGLRegisterBuffer_f(resource, gl_buffer, flags));
|
|
2868
|
+
bool success = check_cu(cuGraphicsGLRegisterBuffer_f(resource, gl_buffer, flags));
|
|
2869
|
+
if (!success)
|
|
2870
|
+
{
|
|
2871
|
+
delete resource;
|
|
2872
|
+
return NULL;
|
|
2873
|
+
}
|
|
2868
2874
|
|
|
2869
2875
|
return resource;
|
|
2870
2876
|
}
|
warp/native/warp.h
CHANGED
|
@@ -97,20 +97,28 @@ extern "C"
|
|
|
97
97
|
const void* a, const void* b, const void* c, void* d, float alpha, float beta,
|
|
98
98
|
bool row_major_a, bool row_major_b, bool allow_tf32x3_arith, int batch_count);
|
|
99
99
|
|
|
100
|
-
WP_API uint64_t volume_create_host(void* buf, uint64_t size);
|
|
101
|
-
WP_API void
|
|
102
|
-
WP_API void
|
|
100
|
+
WP_API uint64_t volume_create_host(void* buf, uint64_t size, bool copy, bool owner);
|
|
101
|
+
WP_API void volume_get_tiles_host(uint64_t id, void* buf);
|
|
102
|
+
WP_API void volume_get_voxels_host(uint64_t id, void* buf);
|
|
103
103
|
WP_API void volume_destroy_host(uint64_t id);
|
|
104
104
|
|
|
105
|
-
WP_API uint64_t volume_create_device(void* context, void* buf, uint64_t size);
|
|
105
|
+
WP_API uint64_t volume_create_device(void* context, void* buf, uint64_t size, bool copy, bool owner);
|
|
106
|
+
WP_API void volume_get_tiles_device(uint64_t id, void* buf);
|
|
107
|
+
WP_API void volume_get_voxels_device(uint64_t id, void* buf);
|
|
108
|
+
WP_API void volume_destroy_device(uint64_t id);
|
|
109
|
+
|
|
106
110
|
WP_API uint64_t volume_f_from_tiles_device(void* context, void* points, int num_points, float voxel_size, float bg_value, float tx, float ty, float tz, bool points_in_world_space);
|
|
107
111
|
WP_API uint64_t volume_v_from_tiles_device(void* context, void* points, int num_points, float voxel_size, float bg_value_x, float bg_value_y, float bg_value_z, float tx, float ty, float tz, bool points_in_world_space);
|
|
108
112
|
WP_API uint64_t volume_i_from_tiles_device(void* context, void* points, int num_points, float voxel_size, int bg_value, float tx, float ty, float tz, bool points_in_world_space);
|
|
109
|
-
WP_API
|
|
110
|
-
WP_API
|
|
111
|
-
WP_API void volume_destroy_device(uint64_t id);
|
|
113
|
+
WP_API uint64_t volume_index_from_tiles_device(void* context, void* points, int num_points, float voxel_size, float tx, float ty, float tz, bool points_in_world_space);
|
|
114
|
+
WP_API uint64_t volume_from_active_voxels_device(void* context, void* points, int num_points, float voxel_size, float tx, float ty, float tz, bool points_in_world_space);
|
|
112
115
|
|
|
116
|
+
WP_API void volume_get_buffer_info(uint64_t id, void** buf, uint64_t* size);
|
|
113
117
|
WP_API void volume_get_voxel_size(uint64_t id, float* dx, float* dy, float* dz);
|
|
118
|
+
WP_API void volume_get_tile_and_voxel_count(uint64_t id, uint32_t& tile_count, uint64_t& voxel_count);
|
|
119
|
+
WP_API const char* volume_get_grid_info(uint64_t id, uint64_t *grid_size, uint32_t *grid_index, uint32_t *grid_count, float translation[3], float transform[9], char type_str[16]);
|
|
120
|
+
WP_API uint32_t volume_get_blind_data_count(uint64_t id);
|
|
121
|
+
WP_API const char* volume_get_blind_data_info(uint64_t id, uint32_t data_index, void** buf, uint64_t* value_count, uint32_t* value_size, char type_str[16]);
|
|
114
122
|
|
|
115
123
|
WP_API uint64_t marching_cubes_create_device(void* context);
|
|
116
124
|
WP_API void marching_cubes_destroy_device(uint64_t id);
|
warp/render/render_opengl.py
CHANGED
|
@@ -469,6 +469,24 @@ def copy_rgb_frame(
|
|
|
469
469
|
output_img[v, w, 2] = b / 255.0
|
|
470
470
|
|
|
471
471
|
|
|
472
|
+
@wp.kernel
|
|
473
|
+
def copy_rgb_frame_uint8(
|
|
474
|
+
input_img: wp.array(dtype=wp.uint8),
|
|
475
|
+
width: int,
|
|
476
|
+
height: int,
|
|
477
|
+
# outputs
|
|
478
|
+
output_img: wp.array(dtype=wp.uint8, ndim=3),
|
|
479
|
+
):
|
|
480
|
+
w, v = wp.tid()
|
|
481
|
+
pixel = v * width + w
|
|
482
|
+
pixel *= 3
|
|
483
|
+
# flip vertically (OpenGL coordinates start at bottom)
|
|
484
|
+
v = height - v - 1
|
|
485
|
+
output_img[v, w, 0] = input_img[pixel + 0]
|
|
486
|
+
output_img[v, w, 1] = input_img[pixel + 1]
|
|
487
|
+
output_img[v, w, 2] = input_img[pixel + 2]
|
|
488
|
+
|
|
489
|
+
|
|
472
490
|
@wp.kernel
|
|
473
491
|
def copy_depth_frame(
|
|
474
492
|
input_img: wp.array(dtype=wp.float32),
|
|
@@ -519,6 +537,34 @@ def copy_rgb_frame_tiles(
|
|
|
519
537
|
output_img[tile, y, x, 2] = b / 255.0
|
|
520
538
|
|
|
521
539
|
|
|
540
|
+
@wp.kernel
|
|
541
|
+
def copy_rgb_frame_tiles_uint8(
|
|
542
|
+
input_img: wp.array(dtype=wp.uint8),
|
|
543
|
+
positions: wp.array(dtype=int, ndim=2),
|
|
544
|
+
screen_width: int,
|
|
545
|
+
screen_height: int,
|
|
546
|
+
tile_height: int,
|
|
547
|
+
# outputs
|
|
548
|
+
output_img: wp.array(dtype=wp.uint8, ndim=4),
|
|
549
|
+
):
|
|
550
|
+
tile, x, y = wp.tid()
|
|
551
|
+
p = positions[tile]
|
|
552
|
+
qx = x + p[0]
|
|
553
|
+
qy = y + p[1]
|
|
554
|
+
pixel = qy * screen_width + qx
|
|
555
|
+
# flip vertically (OpenGL coordinates start at bottom)
|
|
556
|
+
y = tile_height - y - 1
|
|
557
|
+
if qx >= screen_width or qy >= screen_height:
|
|
558
|
+
output_img[tile, y, x, 0] = wp.uint8(0)
|
|
559
|
+
output_img[tile, y, x, 1] = wp.uint8(0)
|
|
560
|
+
output_img[tile, y, x, 2] = wp.uint8(0)
|
|
561
|
+
return # prevent out-of-bounds access
|
|
562
|
+
pixel *= 3
|
|
563
|
+
output_img[tile, y, x, 0] = input_img[pixel + 0]
|
|
564
|
+
output_img[tile, y, x, 1] = input_img[pixel + 1]
|
|
565
|
+
output_img[tile, y, x, 2] = input_img[pixel + 2]
|
|
566
|
+
|
|
567
|
+
|
|
522
568
|
@wp.kernel
|
|
523
569
|
def copy_depth_frame_tiles(
|
|
524
570
|
input_img: wp.array(dtype=wp.float32),
|
|
@@ -577,6 +623,34 @@ def copy_rgb_frame_tile(
|
|
|
577
623
|
output_img[tile, y, x, 2] = b / 255.0
|
|
578
624
|
|
|
579
625
|
|
|
626
|
+
@wp.kernel
|
|
627
|
+
def copy_rgb_frame_tile_uint8(
|
|
628
|
+
input_img: wp.array(dtype=wp.uint8),
|
|
629
|
+
offset_x: int,
|
|
630
|
+
offset_y: int,
|
|
631
|
+
screen_width: int,
|
|
632
|
+
screen_height: int,
|
|
633
|
+
tile_height: int,
|
|
634
|
+
# outputs
|
|
635
|
+
output_img: wp.array(dtype=wp.uint8, ndim=4),
|
|
636
|
+
):
|
|
637
|
+
tile, x, y = wp.tid()
|
|
638
|
+
qx = x + offset_x
|
|
639
|
+
qy = y + offset_y
|
|
640
|
+
pixel = qy * screen_width + qx
|
|
641
|
+
# flip vertically (OpenGL coordinates start at bottom)
|
|
642
|
+
y = tile_height - y - 1
|
|
643
|
+
if qx >= screen_width or qy >= screen_height:
|
|
644
|
+
output_img[tile, y, x, 0] = wp.uint8(0)
|
|
645
|
+
output_img[tile, y, x, 1] = wp.uint8(0)
|
|
646
|
+
output_img[tile, y, x, 2] = wp.uint8(0)
|
|
647
|
+
return # prevent out-of-bounds access
|
|
648
|
+
pixel *= 3
|
|
649
|
+
output_img[tile, y, x, 0] = input_img[pixel + 0]
|
|
650
|
+
output_img[tile, y, x, 1] = input_img[pixel + 1]
|
|
651
|
+
output_img[tile, y, x, 2] = input_img[pixel + 2]
|
|
652
|
+
|
|
653
|
+
|
|
580
654
|
def check_gl_error():
|
|
581
655
|
from pyglet import gl
|
|
582
656
|
|
|
@@ -860,7 +934,7 @@ class OpenGLRenderer:
|
|
|
860
934
|
|
|
861
935
|
def __init__(
|
|
862
936
|
self,
|
|
863
|
-
title="Warp
|
|
937
|
+
title="Warp",
|
|
864
938
|
scaling=1.0,
|
|
865
939
|
fps=60,
|
|
866
940
|
up_axis="Y",
|
|
@@ -881,11 +955,57 @@ class OpenGLRenderer:
|
|
|
881
955
|
render_depth=False,
|
|
882
956
|
axis_scale=1.0,
|
|
883
957
|
vsync=False,
|
|
884
|
-
headless=
|
|
958
|
+
headless=None,
|
|
885
959
|
enable_backface_culling=True,
|
|
886
960
|
enable_mouse_interaction=True,
|
|
887
961
|
enable_keyboard_interaction=True,
|
|
888
962
|
):
|
|
963
|
+
"""
|
|
964
|
+
Args:
|
|
965
|
+
|
|
966
|
+
title (str): The window title.
|
|
967
|
+
scaling (float): The scaling factor for the scene.
|
|
968
|
+
fps (int): The target frames per second.
|
|
969
|
+
up_axis (str): The up axis of the scene. Can be "X", "Y", or "Z".
|
|
970
|
+
screen_width (int): The width of the window.
|
|
971
|
+
screen_height (int): The height of the window.
|
|
972
|
+
near_plane (float): The near clipping plane.
|
|
973
|
+
far_plane (float): The far clipping plane.
|
|
974
|
+
camera_fov (float): The camera field of view in degrees.
|
|
975
|
+
camera_pos (tuple): The initial camera position.
|
|
976
|
+
camera_front (tuple): The initial camera front direction.
|
|
977
|
+
camera_up (tuple): The initial camera up direction.
|
|
978
|
+
background_color (tuple): The background color of the scene.
|
|
979
|
+
draw_grid (bool): Whether to draw a grid indicating the ground plane.
|
|
980
|
+
draw_sky (bool): Whether to draw a sky sphere.
|
|
981
|
+
draw_axis (bool): Whether to draw the coordinate system axes.
|
|
982
|
+
show_info (bool): Whether to overlay rendering information.
|
|
983
|
+
render_wireframe (bool): Whether to render scene shapes as wireframes.
|
|
984
|
+
render_depth (bool): Whether to show the depth buffer instead of the RGB image.
|
|
985
|
+
axis_scale (float): The scale of the coordinate system axes being rendered (only if ``draw_axis`` is True).
|
|
986
|
+
vsync (bool): Whether to enable vertical synchronization.
|
|
987
|
+
headless (bool): Whether to run in headless mode (no window is created). If None, the value is determined by the Pyglet configuration defined in ``pyglet.options["headless"]``.
|
|
988
|
+
enable_backface_culling (bool): Whether to enable backface culling.
|
|
989
|
+
enable_mouse_interaction (bool): Whether to enable mouse interaction.
|
|
990
|
+
enable_keyboard_interaction (bool): Whether to enable keyboard interaction.
|
|
991
|
+
|
|
992
|
+
Note:
|
|
993
|
+
|
|
994
|
+
:class:`OpenGLRenderer` requires Pyglet (version >= 2.0, known to work on 2.0.7) to be installed.
|
|
995
|
+
|
|
996
|
+
Headless rendering is supported via EGL on UNIX operating systems. To enable headless rendering, set the following pyglet options before importing ``warp.render``:
|
|
997
|
+
|
|
998
|
+
.. code-block:: python
|
|
999
|
+
|
|
1000
|
+
import pyglet
|
|
1001
|
+
|
|
1002
|
+
pyglet.options["headless"] = True
|
|
1003
|
+
|
|
1004
|
+
import warp.render
|
|
1005
|
+
|
|
1006
|
+
# OpenGLRenderer is instantiated with headless=True by default
|
|
1007
|
+
renderer = warp.render.OpenGLRenderer()
|
|
1008
|
+
"""
|
|
889
1009
|
try:
|
|
890
1010
|
import pyglet
|
|
891
1011
|
|
|
@@ -917,10 +1037,15 @@ class OpenGLRenderer:
|
|
|
917
1037
|
self.window = pyglet.window.Window(
|
|
918
1038
|
width=screen_width, height=screen_height, caption=title, resizable=True, vsync=vsync, visible=not headless
|
|
919
1039
|
)
|
|
1040
|
+
if headless is None:
|
|
1041
|
+
self.headless = pyglet.options.get("headless", False)
|
|
1042
|
+
else:
|
|
1043
|
+
self.headless = headless
|
|
920
1044
|
self.app = pyglet.app
|
|
921
1045
|
|
|
922
|
-
|
|
923
|
-
|
|
1046
|
+
if not headless:
|
|
1047
|
+
# making window current opengl rendering context
|
|
1048
|
+
self.window.switch_to()
|
|
924
1049
|
|
|
925
1050
|
self.screen_width, self.screen_height = self.window.get_framebuffer_size()
|
|
926
1051
|
|
|
@@ -1011,15 +1136,16 @@ class OpenGLRenderer:
|
|
|
1011
1136
|
self._frame_fbo = None
|
|
1012
1137
|
self._frame_pbo = None
|
|
1013
1138
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1139
|
+
if not headless:
|
|
1140
|
+
self.window.push_handlers(on_draw=self._draw)
|
|
1141
|
+
self.window.push_handlers(on_resize=self._window_resize_callback)
|
|
1142
|
+
self.window.push_handlers(on_key_press=self._key_press_callback)
|
|
1017
1143
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1144
|
+
self._key_handler = pyglet.window.key.KeyStateHandler()
|
|
1145
|
+
self.window.push_handlers(self._key_handler)
|
|
1020
1146
|
|
|
1021
|
-
|
|
1022
|
-
|
|
1147
|
+
self.window.on_mouse_scroll = self._scroll_callback
|
|
1148
|
+
self.window.on_mouse_drag = self._mouse_drag_callback
|
|
1023
1149
|
|
|
1024
1150
|
gl.glClearColor(*self.background_color, 1)
|
|
1025
1151
|
gl.glEnable(gl.GL_DEPTH_TEST)
|
|
@@ -1232,20 +1358,21 @@ class OpenGLRenderer:
|
|
|
1232
1358
|
width=400,
|
|
1233
1359
|
)
|
|
1234
1360
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1361
|
+
if not headless:
|
|
1362
|
+
# set up our own event handling so we can synchronously render frames
|
|
1363
|
+
# by calling update() in a loop
|
|
1364
|
+
from pyglet.window import Window
|
|
1238
1365
|
|
|
1239
|
-
|
|
1366
|
+
Window._enable_event_queue = False
|
|
1240
1367
|
|
|
1241
|
-
|
|
1242
|
-
|
|
1368
|
+
self.window.switch_to()
|
|
1369
|
+
self.window.dispatch_pending_events()
|
|
1243
1370
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1371
|
+
platform_event_loop = self.app.platform_event_loop
|
|
1372
|
+
platform_event_loop.start()
|
|
1246
1373
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1374
|
+
# start event loop
|
|
1375
|
+
self.app.event_loop.dispatch_event("on_enter")
|
|
1249
1376
|
|
|
1250
1377
|
@property
|
|
1251
1378
|
def paused(self):
|
|
@@ -1266,8 +1393,9 @@ class OpenGLRenderer:
|
|
|
1266
1393
|
def clear(self):
|
|
1267
1394
|
from pyglet import gl
|
|
1268
1395
|
|
|
1269
|
-
self.
|
|
1270
|
-
|
|
1396
|
+
if not self.headless:
|
|
1397
|
+
self.app.event_loop.dispatch_event("on_exit")
|
|
1398
|
+
self.app.platform_event_loop.stop()
|
|
1271
1399
|
|
|
1272
1400
|
if self._instance_transform_gl_buffer is not None:
|
|
1273
1401
|
try:
|
|
@@ -1334,7 +1462,8 @@ class OpenGLRenderer:
|
|
|
1334
1462
|
"""
|
|
1335
1463
|
Set up tiled rendering where the render buffer is split into multiple tiles that can visualize
|
|
1336
1464
|
different shape instances of the scene with different view and projection matrices.
|
|
1337
|
-
See
|
|
1465
|
+
See :meth:`get_pixels` which allows to retrieve the pixels of for each tile.
|
|
1466
|
+
See :meth:`update_tile` which allows to update the shape instances, projection matrix, view matrix, tile size, or tile position for a given tile.
|
|
1338
1467
|
|
|
1339
1468
|
:param instances: A list of lists of shape instance ids. Each list of shape instance ids
|
|
1340
1469
|
will be rendered into a separate tile.
|
|
@@ -1516,7 +1645,7 @@ class OpenGLRenderer:
|
|
|
1516
1645
|
)
|
|
1517
1646
|
|
|
1518
1647
|
if gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) != gl.GL_FRAMEBUFFER_COMPLETE:
|
|
1519
|
-
print("Framebuffer is not complete!")
|
|
1648
|
+
print("Framebuffer is not complete!", flush=True)
|
|
1520
1649
|
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
|
|
1521
1650
|
sys.exit(1)
|
|
1522
1651
|
|
|
@@ -1590,9 +1719,21 @@ class OpenGLRenderer:
|
|
|
1590
1719
|
def camera_up(self, value):
|
|
1591
1720
|
self.update_view_matrix(cam_up=value)
|
|
1592
1721
|
|
|
1593
|
-
def
|
|
1722
|
+
def compute_view_matrix(self, cam_pos, cam_front, cam_up):
|
|
1594
1723
|
from pyglet.math import Mat4, Vec3
|
|
1595
1724
|
|
|
1725
|
+
model = np.array(self._model_matrix).reshape((4, 4))
|
|
1726
|
+
cp = model @ np.array([*cam_pos / self._scaling, 1.0])
|
|
1727
|
+
cf = model @ np.array([*cam_front / self._scaling, 1.0])
|
|
1728
|
+
up = model @ np.array([*cam_up / self._scaling, 0.0])
|
|
1729
|
+
cp = Vec3(*cp[:3])
|
|
1730
|
+
cf = Vec3(*cf[:3])
|
|
1731
|
+
up = Vec3(*up[:3])
|
|
1732
|
+
return np.array(Mat4.look_at(cp, cp + cf, up), dtype=np.float32)
|
|
1733
|
+
|
|
1734
|
+
def update_view_matrix(self, cam_pos=None, cam_front=None, cam_up=None, stiffness=1.0):
|
|
1735
|
+
from pyglet.math import Vec3
|
|
1736
|
+
|
|
1596
1737
|
if cam_pos is not None:
|
|
1597
1738
|
self._camera_pos = self._camera_pos * (1.0 - stiffness) + Vec3(*cam_pos) * stiffness
|
|
1598
1739
|
if cam_front is not None:
|
|
@@ -1600,22 +1741,16 @@ class OpenGLRenderer:
|
|
|
1600
1741
|
if cam_up is not None:
|
|
1601
1742
|
self._camera_up = self._camera_up * (1.0 - stiffness) + Vec3(*cam_up) * stiffness
|
|
1602
1743
|
|
|
1603
|
-
|
|
1604
|
-
cp = model @ np.array([*self._camera_pos / self._scaling, 1.0])
|
|
1605
|
-
cf = model @ np.array([*self._camera_front / self._scaling, 1.0])
|
|
1606
|
-
up = model @ np.array([*self._camera_up / self._scaling, 0.0])
|
|
1607
|
-
cp = Vec3(*cp[:3])
|
|
1608
|
-
cf = Vec3(*cf[:3])
|
|
1609
|
-
up = Vec3(*up[:3])
|
|
1610
|
-
self._view_matrix = np.array(Mat4.look_at(cp, cp + cf, up))
|
|
1744
|
+
self._view_matrix = self.compute_view_matrix(self._camera_pos, self._camera_front, self._camera_up)
|
|
1611
1745
|
|
|
1612
|
-
|
|
1746
|
+
@staticmethod
|
|
1747
|
+
def compute_model_matrix(camera_axis: int, scaling: float):
|
|
1613
1748
|
if camera_axis == 0:
|
|
1614
|
-
return np.array((0, 0, scaling, 0, scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, 0, 1))
|
|
1749
|
+
return np.array((0, 0, scaling, 0, scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, 0, 1), dtype=np.float32)
|
|
1615
1750
|
elif camera_axis == 2:
|
|
1616
|
-
return np.array((-scaling, 0, 0, 0, 0, 0, scaling, 0, 0, scaling, 0, 0, 0, 0, 0, 1))
|
|
1751
|
+
return np.array((-scaling, 0, 0, 0, 0, 0, scaling, 0, 0, scaling, 0, 0, 0, 0, 0, 1), dtype=np.float32)
|
|
1617
1752
|
|
|
1618
|
-
return np.array((scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, 1))
|
|
1753
|
+
return np.array((scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, scaling, 0, 0, 0, 0, 1), dtype=np.float32)
|
|
1619
1754
|
|
|
1620
1755
|
def update_model_matrix(self, model_matrix: Optional[Mat44] = None):
|
|
1621
1756
|
from pyglet import gl
|
|
@@ -1684,8 +1819,8 @@ class OpenGLRenderer:
|
|
|
1684
1819
|
self._last_time = self.clock_time
|
|
1685
1820
|
self._frame_speed = update_duration * 100.0
|
|
1686
1821
|
|
|
1687
|
-
|
|
1688
|
-
|
|
1822
|
+
if not self.headless:
|
|
1823
|
+
self.app.platform_event_loop.step(self._frame_dt * 1e-3)
|
|
1689
1824
|
|
|
1690
1825
|
if not self.skip_rendering:
|
|
1691
1826
|
self._skip_frame_counter += 1
|
|
@@ -1705,13 +1840,17 @@ class OpenGLRenderer:
|
|
|
1705
1840
|
update = 1.0 / update_duration
|
|
1706
1841
|
self._fps_render = (1.0 - self._fps_alpha) * self._fps_render + self._fps_alpha * update
|
|
1707
1842
|
|
|
1708
|
-
self.
|
|
1843
|
+
if not self.headless:
|
|
1844
|
+
self.app.event_loop._redraw_windows(self._frame_dt * 1e-3)
|
|
1845
|
+
else:
|
|
1846
|
+
self._draw()
|
|
1709
1847
|
|
|
1710
1848
|
def _draw(self):
|
|
1711
1849
|
from pyglet import gl
|
|
1712
1850
|
|
|
1713
|
-
|
|
1714
|
-
|
|
1851
|
+
if not self.headless:
|
|
1852
|
+
# catch key hold events
|
|
1853
|
+
self._process_inputs()
|
|
1715
1854
|
|
|
1716
1855
|
if self.enable_backface_culling:
|
|
1717
1856
|
gl.glEnable(gl.GL_CULL_FACE)
|
|
@@ -1860,7 +1999,9 @@ Instances: {len(self._instances)}"""
|
|
|
1860
1999
|
|
|
1861
2000
|
for i, viewport in enumerate(self._tile_viewports):
|
|
1862
2001
|
projection_matrix_ptr = arr_pointer(self._tile_projection_matrices[i])
|
|
1863
|
-
view_matrix_ptr = arr_pointer(
|
|
2002
|
+
view_matrix_ptr = arr_pointer(
|
|
2003
|
+
self._tile_view_matrices[i] if self._tile_view_matrices[i] is not None else self._view_matrix
|
|
2004
|
+
)
|
|
1864
2005
|
|
|
1865
2006
|
gl.glViewport(*viewport)
|
|
1866
2007
|
if self.draw_grid:
|
|
@@ -2289,7 +2430,7 @@ Instances: {len(self._instances)}"""
|
|
|
2289
2430
|
self.clear()
|
|
2290
2431
|
self.app.event_loop.exit()
|
|
2291
2432
|
|
|
2292
|
-
def get_pixels(self, target_image: wp.array, split_up_tiles=True, mode="rgb"):
|
|
2433
|
+
def get_pixels(self, target_image: wp.array, split_up_tiles=True, mode="rgb", use_uint8=False):
|
|
2293
2434
|
"""
|
|
2294
2435
|
Read the pixels from the frame buffer (RGB or depth are supported) into the given array.
|
|
2295
2436
|
|
|
@@ -2302,6 +2443,7 @@ Instances: {len(self._instances)}"""
|
|
|
2302
2443
|
target_image (array): The array to read the pixels into. Must have float32 as dtype and be on a CUDA device.
|
|
2303
2444
|
split_up_tiles (bool): Whether to split up the viewport into tiles, see :meth:`setup_tiled_rendering`.
|
|
2304
2445
|
mode (str): can be either "rgb" or "depth"
|
|
2446
|
+
use_uint8 (bool): Whether to use uint8 as dtype in RGB mode for the target_image array and return values in the range [0, 255]. Otherwise, float32 is assumed as dtype with values in the range [0, 1].
|
|
2305
2447
|
|
|
2306
2448
|
Returns:
|
|
2307
2449
|
bool: Whether the pixels were successfully read.
|
|
@@ -2328,7 +2470,7 @@ Instances: {len(self._instances)}"""
|
|
|
2328
2470
|
self._tile_width,
|
|
2329
2471
|
channels,
|
|
2330
2472
|
)
|
|
2331
|
-
), f"Shape of `target_image` array does not match {self.num_tiles} x {self.
|
|
2473
|
+
), f"Shape of `target_image` array does not match {self.num_tiles} x {self._tile_height} x {self._tile_width} x {channels}"
|
|
2332
2474
|
else:
|
|
2333
2475
|
assert target_image.shape == (
|
|
2334
2476
|
self.screen_height,
|
|
@@ -2355,9 +2497,7 @@ Instances: {len(self._instances)}"""
|
|
|
2355
2497
|
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
|
2356
2498
|
gl.glBindBuffer(gl.GL_PIXEL_PACK_BUFFER, 0)
|
|
2357
2499
|
|
|
2358
|
-
pbo_buffer = wp.RegisteredGLBuffer(
|
|
2359
|
-
int(self._frame_pbo.value), self._device, wp.RegisteredGLBuffer.WRITE_DISCARD
|
|
2360
|
-
)
|
|
2500
|
+
pbo_buffer = wp.RegisteredGLBuffer(int(self._frame_pbo.value), self._device, wp.RegisteredGLBuffer.READ_ONLY)
|
|
2361
2501
|
screen_size = self.screen_height * self.screen_width
|
|
2362
2502
|
if mode == "rgb":
|
|
2363
2503
|
img = pbo_buffer.map(dtype=wp.uint8, shape=(screen_size * channels))
|
|
@@ -2368,7 +2508,7 @@ Instances: {len(self._instances)}"""
|
|
|
2368
2508
|
positions = wp.array(self._tile_viewports, ndim=2, dtype=wp.int32, device=target_image.device)
|
|
2369
2509
|
if mode == "rgb":
|
|
2370
2510
|
wp.launch(
|
|
2371
|
-
copy_rgb_frame_tiles,
|
|
2511
|
+
copy_rgb_frame_tiles_uint8 if use_uint8 else copy_rgb_frame_tiles,
|
|
2372
2512
|
dim=(self.num_tiles, self._tile_width, self._tile_height),
|
|
2373
2513
|
inputs=[img, positions, self.screen_width, self.screen_height, self._tile_height],
|
|
2374
2514
|
outputs=[target_image],
|
|
@@ -2393,7 +2533,7 @@ Instances: {len(self._instances)}"""
|
|
|
2393
2533
|
else:
|
|
2394
2534
|
if mode == "rgb":
|
|
2395
2535
|
wp.launch(
|
|
2396
|
-
copy_rgb_frame,
|
|
2536
|
+
copy_rgb_frame_uint8 if use_uint8 else copy_rgb_frame,
|
|
2397
2537
|
dim=(self.screen_width, self.screen_height),
|
|
2398
2538
|
inputs=[img, self.screen_width, self.screen_height],
|
|
2399
2539
|
outputs=[target_image],
|
|
@@ -3213,5 +3353,4 @@ Instances: {len(self._instances)}"""
|
|
|
3213
3353
|
|
|
3214
3354
|
|
|
3215
3355
|
if __name__ == "__main__":
|
|
3216
|
-
wp.init()
|
|
3217
3356
|
renderer = OpenGLRenderer()
|
|
@@ -1288,6 +1288,7 @@ def dense_solve(
|
|
|
1288
1288
|
n: int,
|
|
1289
1289
|
L_start: int,
|
|
1290
1290
|
b_start: int,
|
|
1291
|
+
A: wp.array(dtype=float),
|
|
1291
1292
|
L: wp.array(dtype=float),
|
|
1292
1293
|
b: wp.array(dtype=float),
|
|
1293
1294
|
# outputs
|
|
@@ -1303,13 +1304,14 @@ def adj_dense_solve(
|
|
|
1303
1304
|
n: int,
|
|
1304
1305
|
L_start: int,
|
|
1305
1306
|
b_start: int,
|
|
1307
|
+
A: wp.array(dtype=float),
|
|
1306
1308
|
L: wp.array(dtype=float),
|
|
1307
1309
|
b: wp.array(dtype=float),
|
|
1308
1310
|
# outputs
|
|
1309
1311
|
x: wp.array(dtype=float),
|
|
1310
1312
|
tmp: wp.array(dtype=float),
|
|
1311
1313
|
):
|
|
1312
|
-
if not tmp or not wp.adjoint[x] or not wp.adjoint[L]:
|
|
1314
|
+
if not tmp or not wp.adjoint[x] or not wp.adjoint[A] or not wp.adjoint[L]:
|
|
1313
1315
|
return
|
|
1314
1316
|
for i in range(n):
|
|
1315
1317
|
tmp[b_start + i] = 0.0
|
|
@@ -1324,12 +1326,17 @@ def adj_dense_solve(
|
|
|
1324
1326
|
for j in range(n):
|
|
1325
1327
|
wp.adjoint[L][L_start + dense_index(n, i, j)] += -tmp[b_start + i] * x[b_start + j]
|
|
1326
1328
|
|
|
1329
|
+
for i in range(n):
|
|
1330
|
+
for j in range(n):
|
|
1331
|
+
wp.adjoint[A][L_start + dense_index(n, i, j)] += -tmp[b_start + i] * x[b_start + j]
|
|
1332
|
+
|
|
1327
1333
|
|
|
1328
1334
|
@wp.kernel
|
|
1329
1335
|
def eval_dense_solve_batched(
|
|
1330
1336
|
L_start: wp.array(dtype=int),
|
|
1331
1337
|
L_dim: wp.array(dtype=int),
|
|
1332
1338
|
b_start: wp.array(dtype=int),
|
|
1339
|
+
A: wp.array(dtype=float),
|
|
1333
1340
|
L: wp.array(dtype=float),
|
|
1334
1341
|
b: wp.array(dtype=float),
|
|
1335
1342
|
# outputs
|
|
@@ -1338,7 +1345,7 @@ def eval_dense_solve_batched(
|
|
|
1338
1345
|
):
|
|
1339
1346
|
batch = wp.tid()
|
|
1340
1347
|
|
|
1341
|
-
dense_solve(L_dim[batch], L_start[batch], b_start[batch], L, b, x, tmp)
|
|
1348
|
+
dense_solve(L_dim[batch], L_start[batch], b_start[batch], A, L, b, x, tmp)
|
|
1342
1349
|
|
|
1343
1350
|
|
|
1344
1351
|
@wp.kernel
|
|
@@ -1509,7 +1516,6 @@ class FeatherstoneIntegrator(Integrator):
|
|
|
1509
1516
|
self.L = wp.zeros_like(self.H)
|
|
1510
1517
|
|
|
1511
1518
|
if model.body_count:
|
|
1512
|
-
# TODO use requires_grad here?
|
|
1513
1519
|
self.body_I_m = wp.empty(
|
|
1514
1520
|
(model.body_count,), dtype=wp.spatial_matrix, device=model.device, requires_grad=model.requires_grad
|
|
1515
1521
|
)
|
|
@@ -1859,6 +1865,7 @@ class FeatherstoneIntegrator(Integrator):
|
|
|
1859
1865
|
self.articulation_H_start,
|
|
1860
1866
|
self.articulation_H_rows,
|
|
1861
1867
|
self.articulation_dof_start,
|
|
1868
|
+
self.H,
|
|
1862
1869
|
self.L,
|
|
1863
1870
|
state_aug.joint_tau,
|
|
1864
1871
|
],
|