This is my custom convolution function (I modified conv2d() ) and I replaced all conv2d functions with this function in Alex-net.
but I found that parameters in Qilconv2d were not changed after backpropagation and grad was also None.
What is the problem in my source?
My custom convolution has 3 steps.

transformer (weight, inputs)
discretized  (weight, inputs)
F.conv2d()

import torch
import torch.nn as nn
import torch.nn.functional as F

import numpy as np
import copy
import time
import math
from torch.nn.modules.utils import _single, _pair, _triple
from torch.nn.modules.conv import _ConvNd


class RoundNoGradient(torch.autograd.Function):
	@staticmethod
	def forward(ctx, x):
		return x.round()
	
	@staticmethod
	def backward(ctx, g):
		return g 

class QilConv2d(_ConvNd):
	
	discretization_level = 32.0

	def __init__(self, in_channels, out_channels, kernel_size, stride=1,
				padding=0, dilation=1, groups=1,
				bias=True, padding_mode='zeros'):
		kernel_size = _pair(kernel_size)
		stride = _pair(stride)
		padding = _pair(padding)
		dilation = _pair(dilation)
		
		super(QilConv2d, self).__init__(
			in_channels, out_channels, kernel_size, stride, padding, dilation,
			False, _pair(0), groups, bias, padding_mode)

		# Qil parameters
		self.cw = nn.Parameter(torch.randn(1),requires_grad=True) 
		self.dw = nn.Parameter(torch.randn(1),requires_grad=True) 
		self.cx = nn.Parameter(torch.randn(1),requires_grad=True) 
		self.dx = nn.Parameter(torch.randn(1),requires_grad=True) 
#		self.gamma = nn.Parameter(torch.tensor(1.0)) 
		self.gamma = torch.tensor(1.0) 
	
	def transfomer_weights(self,weights):
		device = weights.device
		aw = (0.5 / self.dw)
		bw = (-0.5*self.cw / self.dw + 0.5)
		
		weights_t = torch.where( abs(weights) < self.cw - self.dw, weights - weights ,weights)
		weights_t = torch.where( abs(weights_t) > self.cw + self.dw,
									torch.sign(weights_t), weights_t)
		weights_t = torch.where( (abs(weights_t) >= self.cw - self.dw)&(abs(weights_t) <= self.cw + self.dw),
									(aw*abs(weights_t) + bw)**self.gamma  * weights_t.sign() , weights_t)
		return weights_t

	def transfomer_activation(self,x):
#		device = x.device
		ax,bx = (0.5 / self.dx) , (-0.5*self.cx / self.dx + 0.5)
		x_t = torch.where( x < self.cx - self.dx, x-x, x)
		x_t = torch.where( x_t > self.cx + self.dx,
				torch.sign(x_t), x_t )
		x_t = torch.where( ( x_t >= self.cx - self.dx ) & ( x_t <= self.cx + self.dx ),
							ax*x_t + bx, x_t)
		return x_t
	
	def discretizer(self,tensor):
		
		q_D = torch.pow(torch.tensor(2.0), torch.tensor(QilConv2d.discretization_level - 1)) 
		tensor_d = RoundNoGradient.apply( tensor * q_D) / q_D

		return tensor_d

	def params_print(self):
		print("\ncw : {}	dw : {} cx : {} dx : {} gamma : {} ".format(
			  self.cw, self.dw, self.cx, self.dx, self.gamma))

	def conv2d_forward(self, input, weight):
		if self.padding_mode == 'circular':
			expanded_padding = ((self.padding[1] + 1) // 2, self.padding[1] // 2,
								(self.padding[0] + 1) // 2, self.padding[0] // 2)
			return F.conv2d(F.pad(input, expanded_padding, mode='circular'),
							weight, self.bias, self.stride,
							_pair(0), self.dilation, self.groups)
		return F.conv2d(input, weight, self.bias, self.stride,
						self.padding, self.dilation, self.groups)

	def forward(self,input,Inference = False): 
		if not Inference:
			weight_t = self.transfomer_weights(self.weight)
			weight_qil = self.discretizer(weight_t)
		input_t = self.transfomer_activation(input)
		input_qil = self.discretizer(input_t)

		return self.conv2d_forward(input_qil,weight_qil)