//  [python]
def forward(self, x, time, mask, x_self_cond = None, **kwargs):
        if self.self_condition:
            x_self_cond = default(x_self_cond, lambda: torch.zeros_like(x))
            x = torch.cat((x_self_cond, x), dim = 1)
        sigma = time.reshape(-1, 1, 1, 1)
        eps = 1e-4
        c_skip1 = 1 - sigma
        c_skip2 = torch.sqrt(sigma)
        # c_out = sigma * self.sigma_data / (sigma ** 2 + self.sigma_data ** 2).sqrt()
        c_out1 = sigma / torch.sqrt(sigma ** 2 + 1)
        c_out2 = torch.sqrt(1 - sigma) / torch.sqrt(sigma ** 2 + 1)
        c_in = 1

        x_clone = x.clone()
        x = c_in * x
        # mask = torch.cat([], dim=1)
        hm = self.init_conv_mask(mask)
        # if self.cond_pe:
        #     m = self.cond_pos_embedding(m)
        x = self.init_conv(torch.cat([x, F.interpolate(hm[0], size=x.shape[-2:], mode="bilinear")], dim=1))
        r = x.clone()

        t = self.time_mlp(torch.log(time)/4)

        h = []
        h2 = []
        for i, layer in enumerate(self.projects):
            # print(hm[i].shape)
            hm[i] = layer(hm[i])
        hm2 = []
        for i in range(len(hm)):
            hm2.append(hm[i].clone())
        # hm = []
        # hm2 = []
        for i, ((block1, block2, attn, downsample), relation_layer) \
                in enumerate(zip(self.downs, self.relation_layers_down)):
            x = block1(x, t)
            h.append(x)
            h2.append(x.clone())
            # m = m_block(m, t)
            # hm.append(m)
            # hm2.append(m.clone())

            x = relation_layer(hm[i], x)

            x = block2(x, t)
            x = attn(x)
            h.append(x)
            h2.append(x.clone())

            x = downsample(x)
            # m = m_downsample(m)


        # x = x + F.interpolate(hm[-1], size=x.shape[2:], mode="bilinear", align_corners=True)
        x = self.mid_block1(x, t)
        x = self.mid_attn(x)
        x = self.mid_block2(x, t)
        x1 = x + self.decouple1(x)
        x2 = x + self.decouple2(x)

        x = x1
        for (block1, block2, attn, upsample), relation_layer in zip(self.ups, self.relation_layers_up):
            x = torch.cat((x, h.pop()), dim = 1)
            x = block1(x, t)
            x = relation_layer(hm.pop(), x)
            x = torch.cat((x, h.pop()), dim = 1)
            x = block2(x, t)
            x = attn(x)
            x = upsample(x)

        x1 = torch.cat((x, r), dim=1)
        x1 = self.final_res_block(x1, t)
        x1 = self.final_conv(x1)

        x = x2
        for (block1, block2, attn, upsample), relation_layer in zip(self.ups2, self.relation_layers_up2):
            x = torch.cat((x, h2.pop()), dim = 1)
            x = block1(x, t)
            x = relation_layer(hm2.pop(), x)
            x = torch.cat((x, h2.pop()), dim = 1)
            x = block2(x, t)
            x = attn(x)
            x = upsample(x)

        x2 = torch.cat((x, r), dim=1)
        x2 = self.final_res_block2(x2, t)
        x2 = self.final_conv2(x2)
        # sigma = time.reshape(x1.shape[0], *((1,) * (len(x1.shape) - 1)))
        # scale_C = torch.exp(sigma)
        x1 = c_skip1 * x_clone + c_out1 * x1
        x2 = c_skip2 * x_clone + c_out2 * x2
        return x1, x2