Skip to content

Commit

Permalink
Merge branch 'ershi/1.4.2-rc.3' into 'release-1.4'
Browse files Browse the repository at this point in the history
Changes for 1.4.2-rc.3

See merge request omniverse/warp!848
  • Loading branch information
shi-eric committed Nov 7, 2024
2 parents f45f865 + 7fcf0b6 commit ebd934e
Show file tree
Hide file tree
Showing 27 changed files with 226 additions and 134 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
- Fix kernel compile error when printing structs.
- Fix an incorrect user function being sometimes resolved when multiple overloads are available with array parameters with different `dtype` values.
- Fix error being raised when static and dynamic for-loops are written in sequence with the same iteration variable names ([GH-331](https://github.com/NVIDIA/warp/issues/331)).
- Fix an issue with the `Texture Write` node, used in the Mandelbrot Omniverse sample, sometimes erroring out in multi-GPU environments.
- Code generation of in-place multiplication and division operations (regression introduced in a69d061)([GH-342](https://github.com/NVIDIA/warp/issues/342)).

## [1.4.1] - 2024-10-15

Expand Down
2 changes: 1 addition & 1 deletion VERSION.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.4.2-rc.2
1.4.2-rc.3
28 changes: 28 additions & 0 deletions docs/modules/differentiability.rst
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,34 @@ Warp uses a source-code transformation approach to auto-differentiation.
In this approach, the backwards pass must keep a record of intermediate values computed during the forward pass.
This imposes some restrictions on what kernels can do if they are to remain differentiable.

In-Place Math Operations
^^^^^^^^^^^^^^^^^^^^^^^^

In-place addition and subtraction can be used in kernels participating in the backward pass, e.g.

.. code-block:: python
@wp.kernel
def inplace(a: wp.array(dtype=float), b: wp.array(dtype=float)):
i = wp.tid()
a[i] -= b[i]
a = wp.full(10, value=10.0, dtype=float, requires_grad=True)
b = wp.full(10, value=2.0, dtype=float, requires_grad=True)
with wp.Tape() as tape:
wp.launch(inplace, a.shape, inputs=[a, b])
tape.backward(grads={a: wp.ones_like(a)})
print(a.grad) # [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
print(b.grad) # [-1. -1. -1. -1. -1. -1. -1. -1. -1. -1.]
In-place multiplication and division are *not* supported and incorrect results will be obtained in the backward pass.
A warning will be emitted during code generation if ``wp.config.verbose = True``.

Dynamic Loops
^^^^^^^^^^^^^
Currently, dynamic loops are not replayed or unrolled in the backward pass, meaning intermediate values that are
Expand Down
2 changes: 1 addition & 1 deletion exts/omni.warp.core/config/extension.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
# Semantic Versioning is used: https://semver.org/
version = "1.4.2-rc.2"
version = "1.4.2-rc.3"
authors = ["NVIDIA"]
title = "Warp Core"
description="The core Warp Python module"
Expand Down
4 changes: 3 additions & 1 deletion exts/omni.warp.core/docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CHANGELOG

## [1.4.2-rc.2] - 2024-11-01
## [1.4.2-rc.3] - 2024-11-01

### Changed

Expand All @@ -13,6 +13,8 @@
- Fix kernel compile error when printing structs.
- Fix an incorrect user function being sometimes resolved when multiple overloads are available with array parameters with different `dtype` values.
- Fix error being raised when static and dynamic for-loops are written in sequence with the same iteration variable names ([GH-331](https://github.com/NVIDIA/warp/issues/331)).
- Fix an issue with the `Texture Write` node, used in the Mandelbrot Omniverse sample, sometimes erroring out in multi-GPU environments.
- Code generation of in-place multiplication and division operations (regression introduced in a69d061)([GH-342](https://github.com/NVIDIA/warp/issues/342)).

## [1.4.1] - 2024-10-15

Expand Down
4 changes: 2 additions & 2 deletions exts/omni.warp/config/extension.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
# Semantic Versioning is used: https://semver.org/
version = "1.4.2-rc.2"
version = "1.4.2-rc.3"
authors = ["NVIDIA"]
title = "Warp"
description="Warp OmniGraph Nodes and Sample Scenes"
Expand Down Expand Up @@ -35,7 +35,7 @@ exclude = ["Ogn*Database.py", "*/ogn*"]
"omni.timeline" = {}
"omni.ui" = {optional = true}
"omni.usd" = {}
"omni.warp.core" = {version = "1.4.2-rc.2", exact = true}
"omni.warp.core" = {version = "1.4.2-rc.3", exact = true}

[[python.module]]
name = "omni.warp._extension"
Expand Down
4 changes: 3 additions & 1 deletion exts/omni.warp/docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CHANGELOG

## [1.4.2-rc.2] - 2024-11-01
## [1.4.2-rc.3] - 2024-11-01

### Changed

Expand All @@ -13,6 +13,8 @@
- Fix kernel compile error when printing structs.
- Fix an incorrect user function being sometimes resolved when multiple overloads are available with array parameters with different `dtype` values.
- Fix error being raised when static and dynamic for-loops are written in sequence with the same iteration variable names ([GH-331](https://github.com/NVIDIA/warp/issues/331)).
- Fix an issue with the `Texture Write` node, used in the Mandelbrot Omniverse sample, sometimes erroring out in multi-GPU environments.
- Code generation of in-place multiplication and division operations (regression introduced in a69d061)([GH-342](https://github.com/NVIDIA/warp/issues/342)).

## [1.4.1] - 2024-10-15

Expand Down
14 changes: 7 additions & 7 deletions exts/omni.warp/omni/warp/nodes/_impl/OgnClothSimulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def update_collider(
db: OgnClothSimulateDatabase,
) -> None:
"""Updates the collider state."""
state = db.internal_state
state = db.per_instance_state

points = omni.warp.nodes.mesh_get_points(db.inputs.collider)
xform = omni.warp.nodes.bundle_get_world_xform(db.inputs.collider)
Expand Down Expand Up @@ -397,7 +397,7 @@ def update_cloth(
db: OgnClothSimulateDatabase,
) -> None:
"""Updates the cloth state."""
state = db.internal_state
state = db.per_instance_state

xform = omni.warp.nodes.bundle_get_world_xform(db.inputs.cloth)

Expand Down Expand Up @@ -425,7 +425,7 @@ def update_cloth(

def step(db: OgnClothSimulateDatabase) -> None:
"""Steps through the simulation."""
state = db.internal_state
state = db.per_instance_state

sim_dt = state.sim_dt / db.inputs.substepCount

Expand Down Expand Up @@ -461,7 +461,7 @@ def step(db: OgnClothSimulateDatabase) -> None:

def simulate(db: OgnClothSimulateDatabase) -> None:
"""Simulates the cloth at the current time."""
state = db.internal_state
state = db.per_instance_state

if USE_GRAPH:
wp.capture_launch(state.graph)
Expand All @@ -474,7 +474,7 @@ def compute(db: OgnClothSimulateDatabase, device: wp.context.Device) -> None:
if not db.inputs.cloth.valid or not db.outputs.cloth.valid:
return

state = db.internal_state
state = db.per_instance_state

if not db.inputs.enabled:
# Pass through the data.
Expand Down Expand Up @@ -633,10 +633,10 @@ def compute(db: OgnClothSimulateDatabase) -> None:
compute(db, device)
except Exception:
db.log_error(traceback.format_exc())
db.internal_state.is_valid = False
db.per_instance_state.is_valid = False
return

db.internal_state.is_valid = True
db.per_instance_state.is_valid = True

# Fire the execution for the downstream nodes.
db.outputs.execOut = og.ExecutionAttributeState.ENABLED
2 changes: 1 addition & 1 deletion exts/omni.warp/omni/warp/nodes/_impl/OgnFixedTime.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def compute(db) -> bool:
"""Compute the outputs from the current input"""

timeline = omni.timeline.get_timeline_interface()
context = db.internal_state
context = db.per_instance_state

if not context.initialized:
context.time = db.inputs.start
Expand Down
6 changes: 3 additions & 3 deletions exts/omni.warp/omni/warp/nodes/_impl/OgnGridCreate.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def compute(db: OgnGridCreateDatabase) -> None:
if not db.outputs.mesh.valid:
return

state = db.internal_state
state = db.per_instance_state

if state.is_valid and not state.attr_tracking.have_attrs_changed(db):
return
Expand Down Expand Up @@ -105,10 +105,10 @@ def compute(db: OgnGridCreateDatabase) -> None:
compute(db)
except Exception:
db.log_error(traceback.format_exc())
db.internal_state.is_valid = False
db.per_instance_state.is_valid = False
return

db.internal_state.is_valid = True
db.per_instance_state.is_valid = True

# Fire the execution for the downstream nodes.
db.outputs.execOut = og.ExecutionAttributeState.ENABLED
20 changes: 10 additions & 10 deletions exts/omni.warp/omni/warp/nodes/_impl/OgnKernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,38 +151,38 @@ def compute(db: OgnKernelDatabase, device: wp.context.Device) -> None:

# Ensure that our internal state is correctly initialized.
timeline = omni.timeline.get_timeline_interface()
if db.internal_state.needs_initialization(db, timeline.is_stopped()):
if not db.internal_state.initialize(db, len(kernel_shape)):
if db.per_instance_state.needs_initialization(db, timeline.is_stopped()):
if not db.per_instance_state.initialize(db, len(kernel_shape)):
return

db.internal_state.is_valid = True
db.per_instance_state.is_valid = True

# Exit early if there are no outputs defined.
if not db.internal_state.attr_infos[ATTR_PORT_TYPE_OUTPUT]:
if not db.per_instance_state.attr_infos[ATTR_PORT_TYPE_OUTPUT]:
return

# Retrieve the inputs and outputs argument values to pass to the kernel.
inputs, outputs = get_kernel_args(
db.inputs,
db.outputs,
db.internal_state.attr_infos,
db.internal_state.kernel_module,
db.per_instance_state.attr_infos,
db.per_instance_state.kernel_module,
kernel_shape,
)

# Ensure that all array input values are valid.
validate_input_arrays(db.node, db.internal_state.attr_infos, inputs)
validate_input_arrays(db.node, db.per_instance_state.attr_infos, inputs)

# Launch the kernel.
wp.launch(
db.internal_state.kernel_module.compute,
db.per_instance_state.kernel_module.compute,
dim=kernel_shape,
inputs=[inputs],
outputs=[outputs],
)

# Write the output values to the node's attributes.
write_output_attrs(db.outputs, db.internal_state.attr_infos, outputs)
write_output_attrs(db.outputs, db.per_instance_state.attr_infos, outputs)


# Node Entry Point
Expand Down Expand Up @@ -222,7 +222,7 @@ def compute(db: OgnKernelDatabase) -> None:
with wp.ScopedDevice(device):
compute(db, device)
except Exception:
db.internal_state.is_valid = False
db.per_instance_state.is_valid = False
db.log_error(traceback.format_exc())
wp.config.quiet = True
return
Expand Down
6 changes: 3 additions & 3 deletions exts/omni.warp/omni/warp/nodes/_impl/OgnMeshFromVolume.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def compute(db: OgnMeshFromVolumeDatabase) -> None:
if not db.inputs.data.memory or db.inputs.data.shape[0] == 0:
return

state = db.internal_state
state = db.per_instance_state

# Initialize the internal state if it hasn't been already.
if state.needs_initialization(db):
Expand Down Expand Up @@ -210,10 +210,10 @@ def compute(db: OgnMeshFromVolumeDatabase) -> None:
compute(db)
except Exception:
db.log_error(traceback.format_exc())
db.internal_state.is_valid = False
db.per_instance_state.is_valid = False
return

db.internal_state.is_valid = True
db.per_instance_state.is_valid = True

# Fire the execution for the downstream nodes.
db.outputs.execOut = og.ExecutionAttributeState.ENABLED
8 changes: 4 additions & 4 deletions exts/omni.warp/omni/warp/nodes/_impl/OgnParticlesFromMesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def spawn_particles(db: OgnParticlesFromMeshDatabase) -> Tuple[wp.array, int]:
kernel=sample_mesh_kernel,
dim=dims,
inputs=[
db.internal_state.mesh.id,
db.per_instance_state.mesh.id,
extent[0],
db.inputs.maxPoints,
db.inputs.minSdf,
Expand Down Expand Up @@ -224,7 +224,7 @@ def compute(db: OgnParticlesFromMeshDatabase) -> None:
if not db.inputs.mesh.valid or not db.outputs.particles.valid:
return

state = db.internal_state
state = db.per_instance_state

# Initialize the internal state if it hasn't been already.
if state.needs_initialization(db):
Expand Down Expand Up @@ -307,10 +307,10 @@ def compute(db: OgnParticlesFromMeshDatabase) -> None:
compute(db)
except Exception:
db.log_error(traceback.format_exc())
db.internal_state.is_valid = False
db.per_instance_state.is_valid = False
return

db.internal_state.is_valid = True
db.per_instance_state.is_valid = True

# Fire the execution for the downstream nodes.
db.outputs.execOut = og.ExecutionAttributeState.ENABLED
14 changes: 7 additions & 7 deletions exts/omni.warp/omni/warp/nodes/_impl/OgnParticlesSimulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def update_collider(
db: OgnParticlesSimulateDatabase,
) -> None:
"""Updates the collider state."""
state = db.internal_state
state = db.per_instance_state

points = omni.warp.nodes.mesh_get_points(db.inputs.collider)
xform = omni.warp.nodes.bundle_get_world_xform(db.inputs.collider)
Expand Down Expand Up @@ -398,7 +398,7 @@ def update_particles(
db: OgnParticlesSimulateDatabase,
) -> None:
"""Updates the particles state."""
state = db.internal_state
state = db.per_instance_state

xform = omni.warp.nodes.bundle_get_world_xform(db.inputs.particles)

Expand Down Expand Up @@ -426,7 +426,7 @@ def update_particles(

def step(db: OgnParticlesSimulateDatabase) -> None:
"""Steps through the simulation."""
state = db.internal_state
state = db.per_instance_state

sim_dt = state.sim_dt / db.inputs.substepCount

Expand All @@ -448,7 +448,7 @@ def step(db: OgnParticlesSimulateDatabase) -> None:

def simulate(db: OgnParticlesSimulateDatabase) -> None:
"""Simulates the particles at the current time."""
state = db.internal_state
state = db.per_instance_state

state.model.particle_grid.build(
state.state_0.particle_q,
Expand All @@ -466,7 +466,7 @@ def compute(db: OgnParticlesSimulateDatabase, device: wp.context.Device) -> None
if not db.inputs.particles.valid or not db.outputs.particles.valid:
return

state = db.internal_state
state = db.per_instance_state

if not db.inputs.enabled:
# Pass through the data.
Expand Down Expand Up @@ -556,10 +556,10 @@ def compute(db: OgnParticlesSimulateDatabase) -> None:
compute(db, device)
except Exception:
db.log_error(traceback.format_exc())
db.internal_state.is_valid = False
db.per_instance_state.is_valid = False
return

db.internal_state.is_valid = True
db.per_instance_state.is_valid = True

# Fire the execution for the downstream nodes.
db.outputs.execOut = og.ExecutionAttributeState.ENABLED
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def compute(db: OgnSampleOceanDeformDatabase) -> None:
if not db.inputs.mesh.valid or not db.outputs.mesh.valid:
return

state = db.internal_state
state = db.per_instance_state

amplitude = max(0.0001, min(1000.0, db.inputs.amplitude))
direction = db.inputs.direction % 6.28318530718
Expand Down
Loading

0 comments on commit ebd934e

Please sign in to comment.