NVIDIA / NVIDIA/warp

[QUESTION] Is it possible to compute intermediary gradients while a `wp.Tape()` object is recording the operations?

Open
#875 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

question
Dominant language
Python
Stars
7.1k
Forks
624
Avg merge
3d 17h
Merged PRs (30d)
5

Description

Hi, I'm attempting to write a simulator for a mass-spring system that calculates the elastic energy of the system in it's current state, and using the gradient, calculates the internal forces of the system and updates it's state for the next frame.

I would like to add a wp.Tape() object that captures all the operations within a simulation step, so that I can compute gradients of the loss with respect to my simulation parameters. The below code is an example of what I'm trying to do:

def train_step():
    with wp.ScopedCapture() as capture:
        with wp.Tape() as self.tape:
            step()
            calculate_loss()
        self.tape.backward(self.loss)

def calculate_loss():
    wp.launch(
        compute_track_loss,
        dim=self.num_original_points,
        inputs=[
            self.wp_x,
            wp_current_object_points,
            wp_current_object_motions_valid,
            num_valid_motions
        ],
        outputs=[self.loss],
    )

def step():
    for i in range(num_substeps):
        with wp.Tape() as tape:
            wp.launch(
                kernel=eval_energy,
                dim=self.n_springs,
                inputs=[
                    self.wp_x,
                    self.wp_v,
                    num_object_points,
                    wp_springs,
                    wp_rest_lengths,
                    wp_spring_k,
                    wp_strain,
                    wp_damping,
                ],
                outputs=[elastic_energies]
            )

        # Calculate elastic forces from energy
        tape.backward(elastic_energies)
        elastic_force = -1.0 * tape.gradients[self.wp_x]

        wp.launch(
            kernel=update_positions_and_velocities,
            dim=self.num_object_points,
            inputs=[
                self.wp_x,
                wp_v_before_ground,
                wp_collide_elas,
                wp_collide_fric,
                dt,
                reverse_factor,
            ],
            outputs=[self.wp_x_next, self.wp_v_next],
        )

The issue I'm having is that I cannot start recording a tape within another active tape, yet I need to compute the gradient of elastic energy with respect to position in order to get force and complete the simulation step. Is there any workarounds for what I'm trying to do?

Thank you.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the nested wp.Tape() usage in step() and the outer wp.Tape() in train_step(), then read the Warp Tape and ScopedCapture documentation for supported nesting or gradient accumulation. Reproduce the example with a minimal simulation step; done means documenting a supported workaround or confirming that this nesting is unsupported.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
machine-learning
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.