It looks to me like its just dequantizing, adding together, and then requantizing:
import torch

x = torch.randn(10,10)
y = torch.randn(10,10)

#arbitrary scales and zero_points
zp_x = 1
zp_y = 2
zp_z = 3

s_x = .1
s_y = .2
s_z = .3

#quantize tensors
xq = torch.quantize_per_tensor(x, s_x, zp_x, torch.qint8)
yq = torch.quantize_per_tensor(y, s_y, zp_y, torch.qint8)

#setup add operation
add_op = torch.nn.quantized.QFunctional()
add_op.scale = s_z
add_op.zero_point = zp_z

zq_qfunc = add_op.add(xq,yq)
print("QFunctional output", zq_qfunc)

#manually do operation
xdq = xq.dequantize()
ydq = yq.dequantize()

#add together
zdq = xdq+ydq

#requantize
zq_manual = torch.quantize_per_tensor(zdq, s_z, zp_z, torch.qint8)

print("Manual output", zq_manual)

print("difference", zq_manual.int_repr()-zq_qfunc.int_repr())


You can get the specifics about the quant/dequant process formulas here: Quantization API Reference — PyTorch master documentation