code: def monkeypatch(
      module: _torch.nn.Module,
      device: _typing.Optional[_torch.device] = None,
      copy_initial_weights: bool = True,
      track_higher_grads: bool = True,
  ) -> _MonkeyPatchBase:
      r"""Create a monkey-patched stateless version of a module.
  
      This function produces a monkey-patched version of a module, and returns a
      copy of its parameters for use as fast weights. Where the original module
      or any of its submodules have state (e.g. batch norm), this will be copied
      too, but further updates (e.g. during inner loop training) will cause these
      to diverge without changing the state of the original module.
  
      Args:
          module: a ``torch.nn.Module`` subclass instance.
          device (optional): a device to cast the fast weights and state to.
          copy_initial_weights: if True, the weights of the patched module are
              copied to form the initial weights of the patched module, and thus
              are not part of the gradient tape when unrolling the patched module.
              If this is set to False, the actual module weights will be the
              initial weights of the patched module. This is useful when doing
              MAML, for example.
          track_higher_grads: if True, during unrolled optimization the graph be
              retained, and the fast weights will bear grad funcs, so as to permit
              backpropagation through the optimization process. Setting this to
              False allows ``monkeypatch`` to be used in "test mode", without
              potentially tracking higher order gradients. This can be useful when
              running the training loop at test time, e.g. in k-shot learning
              experiments, without incurring a significant memory overhead.
  
      Returns:
          ``fmodule``: a "stateless" version of the original module, for which calls
          to forward take the additional kwarg-only parameter ``params``, which
          should be a list of torch tensors requiring gradients, ideally
          provided by this function (see below) or by an update step from one
          of the optimizers in ``higher.optim``.
      """
  
      def encapsulator(
          fmodule: _MonkeyPatchBase, module: _torch.nn.Module
      ) -> None:
          if copy_initial_weights:
              params = _utils.get_func_params(module, device=device)
          else:
              params = [
                  p.clone() if device is None else p.clone().to(device)
                  for p in module.parameters()
              ]
          buffer_sync(module, fmodule, device)
          fmodule.update_params(params)
  
      fmodule = make_functional(module, encapsulator=encapsulator)
      fmodule.track_higher_grads = track_higher_grads
  
      return fmodule
  
imports: import abc
  from collections import OrderedDict
  from contextlib import contextmanager
  import typing
  import weakref
  import warnings
  import torch
  from .None import utils
label_desc: Use image node_id 7 for calling a global function with example usage: monkeypatch(module, device, copy_initial_weights, track_higher_grads) and returns: fmodule