class_docstr: Create Precision Plugin for IPEX BFloat16.
docstr: Bf16 optimizer step.
docstr_tok: ["Bf16","optimizer","step","."]
code: def optimizer_step(
      self,
      model: Union["pl.LightningModule", Module],
      optimizer: Optimizer,
      optimizer_idx: int,
      closure: Callable[[], Any],
      **kwargs: Any,
  ) -> Any:
      """Bf16 optimizer step."""
      if compare_version(
          "intel_extension_for_pytorch", operator.lt, "1.13.100"
      ):
          from intel_extension_for_pytorch.optim._optimizer_utils import (
              IPEX_FUSED_OPTIMIZER_LIST,
          )
      else:
          from intel_extension_for_pytorch.optim._optimizer_utils import (
              IPEX_FUSED_OPTIMIZER_LIST_CPU as IPEX_FUSED_OPTIMIZER_LIST,
          )
      """Hook to run the optimizer step."""
      if type(optimizer) in IPEX_FUSED_OPTIMIZER_LIST:
          return super().optimizer_step(
              model, optimizer, optimizer_idx, closure, **kwargs
          )
  
      if isinstance(model, pl.LightningModule):
          closure = partial(
              self._wrap_closure,
              model,
              optimizer,
              optimizer_idx,
              closure,
          )
  
      # Only `torch.optim.LBFGS`  need to reevaluate closure multiple times
      # in optimizer.step(...) now.
      if isinstance(optimizer, LBFGS):
          invalidInputError(
              False,
              "IPEX BFloat16 and the LBFGS optimizer are not compatible "
              f"(optimizer {optimizer_idx}",
              "Hint: Set 'use_ipex' to False or not set 'precision' to 'bf16'"
              " if LBFGS optimizer is necessary",
          )
  
      # Detect custom optimzer
      if type(optimizer).__name__ not in dir(torch.optim):
          warning(
              "Seems like you are using a custom optimizer,"
              "please make sure that 'optimizer.step(closure)'"
              " does not need to be called in training stage"
          )
  
      # For optimizer not in IPEX_FUSED_OPTIMIZER_LIST,
      # `closure()` needs to be called to backward the loss to avoid `.grad` being None
      closure_result = closure()
      optimizer.step(**kwargs)
  
      return closure_result
  
imports: import operator
  from contextlib import contextmanager
  from functools import partial
  from logging import warning
  from typing import Any, Union, Callable
  import torch
  from torch.nn import Module
  from torch.optim import Optimizer, LBFGS
  import pytorch_lightning
  from pytorch_lightning.strategies import SingleDeviceStrategy
  from pytorch_lightning.accelerators.accelerator import Accelerator
  from pytorch_lightning.plugins.precision import PrecisionPlugin
  from bigdl.nano.utils.common import compare_version
  from bigdl.nano.utils.common import invalidInputError
  from bigdl.nano.deps.ipex.ipex_api import ipex_optimize
label_desc: Use image node_id 2 for calling the IPEXBF16Precision obj's underlying member method code with example usage: obj.optimizer_step(model, optimizer, optimizer_idx, closure) and returns: closure_result, super