code: def layer_register(log_shape=False, use_scope=True):
      """
      Args:
          log_shape (bool): log input/output shape of this layer
          use_scope (bool or None):
              Whether to call this layer with an extra first argument as variable scope.
              When set to None, it can be called either with or without
              the scope name argument, depend on whether the first argument
              is string or not.
  
      Returns:
          A decorator used to register a layer.
  
      Example:
  
      .. code-block:: python
  
          @layer_register(use_scope=True)
          def add10(x):
              return x + tf.get_variable('W', shape=[10])
  
          # use it:
          output = add10('layer_name', input)  # the function will be called under variable scope "layer_name".
      """
  
      def wrapper(func):
          @wraps(func)
          def wrapped_func(*args, **kwargs):
              assert args[0] is not None, args
              if use_scope:
                  name, inputs = args[0], args[1]
                  args = args[
                      1:
                  ]  # actual positional args used to call func
                  assert isinstance(name, six.string_types), (
                      'First argument for "{}" should be a string. '.format(
                          func.__name__
                      )
                      + "Did you forget to specify the name of the layer?"
                  )
              else:
                  assert not log_shape
                  if isinstance(args[0], six.string_types):
                      if use_scope is False:
                          logger.warn(
                              "Please call layer {} without the first scope name argument, "
                              "or register the layer with use_scope=None to allow calling it "
                              "with scope names.".format(func.__name__)
                          )
                      name, inputs = args[0], args[1]
                      args = args[
                          1:
                      ]  # actual positional args used to call func
                  else:
                      inputs = args[0]
                      name = None
              if not (
                  isinstance(inputs, (tf.Tensor, tf.Variable))
                  or (
                      isinstance(inputs, (list, tuple))
                      and isinstance(
                          inputs[0], (tf.Tensor, tf.Variable)
                      )
                  )
              ):
                  raise ValueError(
                      "Invalid inputs to layer: " + str(inputs)
                  )
  
              # use kwargs from current argument scope
              actual_args = copy.copy(get_arg_scope()[func.__name__])
              # explicit kwargs overwrite argscope
              actual_args.update(kwargs)
              # if six.PY3:
              #     # explicit positional args also override argscope. only work in PY3
              #     posargmap = inspect.signature(func).bind_partial(*args).arguments
              #     for k in six.iterkeys(posargmap):
              #         if k in actual_args:
              #             del actual_args[k]
  
              if name is not None:  # use scope
                  with tfv1.variable_scope(name) as scope:
                      # this name is only used to surpress logging, doesn't hurt to do some heuristics
                      scope_name = re.sub(
                          "tower[0-9]+/", "", scope.name
                      )
                      do_log_shape = (
                          log_shape and scope_name not in _LAYER_LOGGED
                      )
                      if do_log_shape:
                          _SHAPE_LOGGER.push_inputs(
                              scope.name, get_shape_str(inputs)
                          )
  
                      # run the actual function
                      outputs = func(*args, **actual_args)
  
                      if do_log_shape:
                          _SHAPE_LOGGER.push_outputs(
                              scope.name, get_shape_str(outputs)
                          )
                          _LAYER_LOGGED.add(scope_name)
              else:
                  # run the actual function
                  outputs = func(*args, **actual_args)
              return outputs
  
          wrapped_func.use_scope = use_scope
          wrapped_func.__argscope_enabled__ = True
          _register(func.__name__, wrapped_func)
          return wrapped_func
  
      return wrapper
  
file_path: tensorpack/tensorpack/models/registry.py
imports: import copy
  import re
  import collections
  from functools import wraps
  import six
  import tensorflow
  from ..compat import tfv1
  from ..tfutils.argscope import get_arg_scope
  from ..tfutils.model_utils import get_shape_str
  from ..utils import logger
label_desc: Use image node_id 4 for calling a global function with example usage: layer_register(log_shape, use_scope) and returns: wrapper, wrapped_func, outputs