class_docstr: Learner for PPO.
docstr: Does a learner step and logs the results.
  
  One learner step consists of (possibly multiple) epochs of PPO updates on
  a batch of NxT steps collected by the actors.
docstr_tok: ["Does","a","learner","step","and","logs","the","results",".","One","learner","step","consists","of","(","possibly","multiple",")","epochs","of","PPO","updates","on","a","batch","of","NxT","steps","collected","by","the","actors","."]
code: def step(self):
      """Does a learner step and logs the results.
  
      One learner step consists of (possibly multiple) epochs of PPO updates on
      a batch of NxT steps collected by the actors.
      """
      sample = next(self._iterator)
      self._state, results = self._full_update_step(self._state, sample)
      self._cached_state = get_from_first_device(
          self._state, as_numpy=True
      )
  
      # Update our counts and record it.
      counts = self._counter.increment(
          steps=self.num_epochs * self.num_minibatches
      )
  
      # Snapshot and attempt to write logs.
      if self._num_full_update_steps % self.metrics_logging_period == 0:
          results = jax.tree_util.tree_map(jnp.mean, results)
          self._logger.write({**results, **counts})
  
      self._num_full_update_steps += 1
  
imports: from typing import Dict, Iterator, List, NamedTuple, Optional, Tuple
  import acme
  from acme import types
  from acme.agents.jax.ppo import networks
  from acme.agents.jax.ppo import normalization
  from acme.jax import networks
  from acme.jax.utils import get_from_first_device
  from acme.utils import counting
  from acme.utils import loggers
  import jax
  import jax.numpy
  import optax
  import reverb
  import rlax
label_desc: Use image node_id 2 for calling the PPOLearner obj's underlying member method code with example usage: obj.step() without return types