# Copyright 2022 The Plenoptix Team. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ Sampler. """ import math import torch from torch import nn import pyrad_cuda class LLTMFunction(torch.autograd.Function): @staticmethod def forward(ctx, input, weights, bias, old_h, old_cell): outputs = pyrad_cuda.forward(input, weights, bias, old_h, old_cell) new_h, new_cell = outputs[:2] variables = outputs[1:] + [weights] ctx.save_for_backward(*variables) return new_h, new_cell @staticmethod def backward(ctx, grad_h, grad_cell): outputs = pyrad_cuda.backward(grad_h.contiguous(), grad_cell.contiguous(), *ctx.saved_variables) d_old_h, d_input, d_weights, d_bias, d_old_cell, d_gates = outputs return d_input, d_weights, d_bias, d_old_h, d_old_cell class Sampler(nn.Module): def __init__(self, input_features, state_size): super().__init__() self.input_features = input_features self.state_size = state_size self.weights = nn.Parameter(torch.Tensor(3 * state_size, input_features + state_size)) self.bias = nn.Parameter(torch.Tensor(1, 3 * state_size)) self.reset_parameters() def reset_parameters(self): stdv = 1.0 / math.sqrt(self.state_size) for weight in self.parameters(): weight.data.uniform_(-stdv, +stdv) def forward(self, input, state): return LLTMFunction.apply(input, self.weights, self.bias, *state)