class_docstr: Fake version of affine quantization
  
  gemmlowp style scale+shift quantization. See more details in
  https://github.com/google/gemmlowp/blob/master/doc/quantization.md.
  
  We DO NOT recommend affine quantization on weights for performance reason. There might be value to affine quantize
  activation as it can be cancelled by bias and comes with no performance penalty. This functionality is only added
  for experimental purpose.
class_docstr_tok: ["Fake","version","of","affine","quantization","gemmlowp","style","scale+shift","quantization",".","See","more","details","in","https",":","\/\/github.com\/google\/gemmlowp\/blob\/master\/doc\/quantization.md",".","We","DO","NOT","recommend","affine","quantization","on","weights","for","performance","reason",".","There","might","be","value","to","affine","quantize","activation","as","it","can","be","cancelled","by","bias","and","comes","with","no","performance","penalty",".","This","functionality","is","only","added","for","experimental","purpose","."]
docstr: As it will be only applied on activation with per tensor granularity, broadcast is not needed.
  
  Args:
      ctx: Pytorch convention.
      inputs: A Tensor of type float32.
      min_range: A float.
      max_range: A float.
      num_bits: An integer
  
  Returns:
      outputs: A Tensor of type output_dtype
docstr_tok: ["As","it","will","be","only","applied","on","activation","with","per","tensor","granularity",",","broadcast","is","not","needed",".","Args",":","ctx",":","Pytorch","convention",".","inputs",":","A","Tensor","of","type","float32",".","min_range",":","A","float",".","max_range",":","A","float",".","num_bits",":","An","integer","Returns",":","outputs",":","A","Tensor","of","type","output_dtype"]
code: def forward(ctx, inputs, min_range, max_range, num_bits=8):
      """
  
      As it will be only applied on activation with per tensor granularity, broadcast is not needed.
  
      Args:
          ctx: Pytorch convention.
          inputs: A Tensor of type float32.
          min_range: A float.
          max_range: A float.
          num_bits: An integer
  
      Returns:
          outputs: A Tensor of type output_dtype
      """
      logger.debug(
          "{} bits quantization on shape {} tensor.".format(
              num_bits, inputs.size()
          )
      )
      ctx.save_for_backward(inputs, min_range, max_range)
  
      step_size = (max_range - min_range) / (2.0**num_bits - 1)
  
      min_bound = -(2.0 ** (num_bits - 1))
      max_bound = 2.0 ** (num_bits - 1) - 1
  
      quant_zero = torch.round(min_range / step_size) - min_bound
      quantized = torch.round(inputs / step_size) - quant_zero
      quantized = torch.clamp(quantized, min_bound, max_bound)
  
      outputs = (quantized + quant_zero) * step_size
  
      return outputs
  
imports: import numpy
  import yaml
  import logging
  import torch
  from torch.autograd import Function
label_desc: Use image node_id 1 for calling the FakeAffineTensorQuantFunction obj's underlying member method code with example usage: obj.forward(ctx, inputs, min_range, max_range, num_bits) and returns: outputs