class_docstr: Quantized counterpart of the nn.Conv2d module that applies QuantNoise during training.
  
  Args:
      - standard nn.Conv2d parameters
      - p: amount of noise to inject (0 = no quantization, 1 = quantize all the weights)
      - bits: number of bits
      - method: choose among {"tensor", "histogram", "channel"}
      - update_step: recompute scale and zero_point every update_steps iterations
  
  Remarks:
      - We use the straight-thgourh estimator so that the gradients
        back-propagate nicely in the network, this is implemented with
        the detach() trick
      - Parameters scale and zero_point are recomputed every update_step
        forward pass to reduce the overhead
      - At test time, the weights are fully quantized
class_docstr_tok: ["Quantized","counterpart","of","the","nn.Conv2d","module","that","applies","QuantNoise","during","training",".","Args",":","-","standard","nn.Conv2d","parameters","-","p",":","amount","of","noise","to","inject","(","0","=","no","quantization",",","1","=","quantize","all","the","weights",")","-","bits",":","number","of","bits","-","method",":","choose","among","{","``","tensor","''",",","``","histogram","''",",","``","channel","''","}","-","update_step",":","recompute","scale","and","zero_point","every","update_steps","iterations","Remarks",":","-","We","use","the","straight-thgourh","estimator","so","that","the","gradients","back-propagate","nicely","in","the","network",",","this","is","implemented","with","the","detach","(",")","trick","-","Parameters","scale","and","zero_point","are","recomputed","every","update_step","forward","pass","to","reduce","the","overhead","-","At","test","time",",","the","weights","are","fully","quantized"]
code: def forward(self, input):
      # train with QuantNoise and evaluate the fully quantized network
      p = self.p if self.training else 1
  
      # update parameters every 100 iterations
      if self.counter % self.update_step == 0:
          self.scale = None
          self.zero_point = None
      self.counter += 1
  
      # quantize weight
      weight_quantized, self.scale, self.zero_point = emulate_int(
          self.weight.detach(),
          bits=self.bits,
          method=self.method,
          scale=self.scale,
          zero_point=self.zero_point,
      )
  
      # mask to apply noise
      mask = torch.zeros_like(self.weight)
      mask.bernoulli_(1 - p)
      noise = (weight_quantized - self.weight).masked_fill(
          mask.bool(), 0
      )
  
      # using straight-through estimator (STE)
      clamp_low = -self.scale * self.zero_point
      clamp_high = self.scale * (2**self.bits - 1 - self.zero_point)
      weight = (
          torch.clamp(self.weight, clamp_low.item(), clamp_high.item())
          + noise.detach()
      )
  
      # return output
      output = self._conv_forward(input, weight)
      return output
  
file_path: fairseq/fairseq/modules/quantization/scalar/modules/qconv.py
imports: import torch
  import torch.nn.functional
  from torch.nn.modules.conv import _ConvNd
  from torch.nn.modules.utils import _pair
  from ..ops import emulate_int
label_desc: Use image node_id 3 for calling the IntConv2d obj's underlying member method code with example usage: obj.forward(input) and returns: output