riciii7/FastAPI-Batik-GAN
0
1# Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.2#3# NVIDIA CORPORATION and its licensors retain all intellectual property4# and proprietary rights in and to this software, related documentation5# and any modifications thereto. Any use, reproduction, disclosure or6# distribution of this software and related documentation without an express7# license agreement from NVIDIA CORPORATION is strictly prohibited.8 9"""Fused multiply-add, with slightly faster gradients than `torch.addcmul()`."""10 11import torch12 13#----------------------------------------------------------------------------14 15def fma(a, b, c): # => a * b + c16 return _FusedMultiplyAdd.apply(a, b, c)17 18#----------------------------------------------------------------------------19 20class _FusedMultiplyAdd(torch.autograd.Function): # a * b + c21 @staticmethod22 def forward(ctx, a, b, c): # pylint: disable=arguments-differ23 out = torch.addcmul(c, a, b)24 ctx.save_for_backward(a, b)25 ctx.c_shape = c.shape26 return out27 28 @staticmethod29 def backward(ctx, dout): # pylint: disable=arguments-differ30 a, b = ctx.saved_tensors31 c_shape = ctx.c_shape32 da = None33 db = None34 dc = None35 36 if ctx.needs_input_grad[0]:37 da = _unbroadcast(dout * b, a.shape)38 39 if ctx.needs_input_grad[1]:40 db = _unbroadcast(dout * a, b.shape)41 42 if ctx.needs_input_grad[2]:43 dc = _unbroadcast(dout, c_shape)44 45 return da, db, dc46 47#----------------------------------------------------------------------------48 49def _unbroadcast(x, shape):50 extra_dims = x.ndim - len(shape)51 assert extra_dims >= 052 dim = [i for i in range(x.ndim) if x.shape[i] > 1 and (i < extra_dims or shape[i - extra_dims] == 1)]53 if len(dim):54 x = x.sum(dim=dim, keepdim=True)55 if extra_dims:56 x = x.reshape(-1, *x.shape[extra_dims+1:])57 assert x.shape == shape58 return x59 60#----------------------------------------------------------------------------61 