use super::{
ActivationDescriptor, ConvolutionDescriptor, DropoutDescriptor, FilterDescriptor,
NormalizationDescriptor, PoolingDescriptor, RnnDescriptor,
};
use crate::cuda::CudaDeviceMemory;
use crate::ffi::*;
use num::traits::*;
#[derive(Debug, Copy, Clone)]
pub enum DataType {
Float,
Double,
Half,
}
pub trait DataTypeInfo {
fn cudnn_data_type() -> DataType;
fn size() -> usize;
}
impl DataTypeInfo for f32 {
fn cudnn_data_type() -> DataType {
DataType::Float
}
fn size() -> usize {
4_usize
}
}
impl DataTypeInfo for f64 {
fn cudnn_data_type() -> DataType {
DataType::Double
}
fn size() -> usize {
8_usize
}
}
#[allow(missing_debug_implementations, missing_copy_implementations)]
pub struct ConvolutionConfig {
forward_algo: cudnnConvolutionFwdAlgo_t,
backward_filter_algo: cudnnConvolutionBwdFilterAlgo_t,
backward_data_algo: cudnnConvolutionBwdDataAlgo_t,
forward_workspace_size: usize,
backward_filter_workspace_size: usize,
backward_data_workspace_size: usize,
conv_desc: ConvolutionDescriptor,
filter_desc: FilterDescriptor,
}
impl ConvolutionConfig {
#[allow(clippy::too_many_arguments)]
pub fn new(
algo_fwd: cudnnConvolutionFwdAlgo_t,
workspace_size_fwd: usize,
algo_filter_bwd: cudnnConvolutionBwdFilterAlgo_t,
workspace_filter_size_bwd: usize,
algo_data_bwd: cudnnConvolutionBwdDataAlgo_t,
workspace_data_size_bwd: usize,
conv_desc: ConvolutionDescriptor,
filter_desc: FilterDescriptor,
) -> ConvolutionConfig {
ConvolutionConfig {
forward_algo: algo_fwd,
forward_workspace_size: workspace_size_fwd,
backward_filter_algo: algo_filter_bwd,
backward_filter_workspace_size: workspace_filter_size_bwd,
backward_data_algo: algo_data_bwd,
backward_data_workspace_size: workspace_data_size_bwd,
conv_desc,
filter_desc,
}
}
pub fn largest_workspace_size(&self) -> usize {
if self.backward_data_workspace_size() >= self.backward_filter_workspace_size()
&& self.backward_data_workspace_size() >= self.forward_workspace_size()
{
self.backward_data_workspace_size()
} else if self.backward_filter_workspace_size() >= self.backward_data_workspace_size()
&& self.backward_filter_workspace_size() >= self.forward_workspace_size()
{
self.backward_filter_workspace_size()
} else {
self.forward_workspace_size()
}
}
pub fn forward_algo(&self) -> &cudnnConvolutionFwdAlgo_t {
&self.forward_algo
}
pub fn forward_workspace_size(&self) -> usize {
self.forward_workspace_size
}
pub fn backward_filter_algo(&self) -> &cudnnConvolutionBwdFilterAlgo_t {
&self.backward_filter_algo
}
pub fn backward_filter_workspace_size(&self) -> usize {
self.backward_filter_workspace_size
}
pub fn backward_data_algo(&self) -> &cudnnConvolutionBwdDataAlgo_t {
&self.backward_data_algo
}
pub fn backward_data_workspace_size(&self) -> usize {
self.backward_data_workspace_size
}
pub fn conv_desc(&self) -> &ConvolutionDescriptor {
&self.conv_desc
}
pub fn filter_desc(&self) -> &FilterDescriptor {
&self.filter_desc
}
}
#[allow(missing_debug_implementations, missing_copy_implementations)]
pub struct NormalizationConfig {
lrn_desc: NormalizationDescriptor,
}
impl NormalizationConfig {
pub fn new(lrn_desc: NormalizationDescriptor) -> NormalizationConfig {
NormalizationConfig { lrn_desc }
}
pub fn lrn_desc(&self) -> &NormalizationDescriptor {
&self.lrn_desc
}
}
#[allow(missing_debug_implementations, missing_copy_implementations)]
pub struct PoolingConfig {
pooling_avg_desc: PoolingDescriptor,
pooling_max_desc: PoolingDescriptor,
}
impl PoolingConfig {
pub fn new(
pooling_avg_desc: PoolingDescriptor,
pooling_max_desc: PoolingDescriptor,
) -> PoolingConfig {
PoolingConfig {
pooling_avg_desc,
pooling_max_desc,
}
}
pub fn pooling_avg_desc(&self) -> &PoolingDescriptor {
&self.pooling_avg_desc
}
pub fn pooling_max_desc(&self) -> &PoolingDescriptor {
&self.pooling_max_desc
}
}
#[allow(missing_debug_implementations, missing_copy_implementations)]
pub struct ActivationConfig {
activation_sigmoid_desc: ActivationDescriptor,
activation_relu_desc: ActivationDescriptor,
activation_clipped_relu_desc: ActivationDescriptor,
activation_tanh_desc: ActivationDescriptor,
}
impl ActivationConfig {
pub fn new(
activation_sigmoid_desc: ActivationDescriptor,
activation_relu_desc: ActivationDescriptor,
activation_clipped_relu_desc: ActivationDescriptor,
activation_tanh_desc: ActivationDescriptor,
) -> ActivationConfig {
ActivationConfig {
activation_sigmoid_desc,
activation_relu_desc,
activation_clipped_relu_desc,
activation_tanh_desc,
}
}
pub fn activation_sigmoid_desc(&self) -> &ActivationDescriptor {
&self.activation_sigmoid_desc
}
pub fn activation_relu_desc(&self) -> &ActivationDescriptor {
&self.activation_relu_desc
}
pub fn activation_clipped_relu_desc(&self) -> &ActivationDescriptor {
&self.activation_clipped_relu_desc
}
pub fn activation_tanh_desc(&self) -> &ActivationDescriptor {
&self.activation_tanh_desc
}
}
#[allow(missing_debug_implementations, missing_copy_implementations)]
#[derive(Debug)]
pub struct DropoutConfig {
dropout_desc: DropoutDescriptor,
reserve_space: CudaDeviceMemory,
}
impl DropoutConfig {
pub fn new(dropout_desc: DropoutDescriptor, reserve: CudaDeviceMemory) -> DropoutConfig {
DropoutConfig {
dropout_desc,
reserve_space: reserve,
}
}
pub fn dropout_desc(&self) -> &DropoutDescriptor {
&self.dropout_desc
}
pub fn take_mem(self) -> CudaDeviceMemory {
self.reserve_space
}
pub fn reserved_space(&self) -> &CudaDeviceMemory {
&self.reserve_space
}
}
#[allow(missing_debug_implementations, missing_copy_implementations)]
pub struct RnnConfig {
rnn_desc: RnnDescriptor,
pub hidden_size: ::libc::c_int,
pub num_layers: ::libc::c_int,
pub sequence_length: ::libc::c_int,
dropout_desc: cudnnDropoutDescriptor_t,
input_mode: cudnnRNNInputMode_t,
direction_mode: cudnnDirectionMode_t,
rnn_mode: cudnnRNNMode_t,
algo: cudnnRNNAlgo_t,
data_type: cudnnDataType_t,
workspace_size: usize,
training_reserve_size: usize,
training_reserve: CudaDeviceMemory,
}
impl RnnConfig {
#[allow(clippy::too_many_arguments)]
pub fn new(
rnn_desc: RnnDescriptor,
hidden_size: i32,
num_layers: i32,
sequence_length: i32,
dropout_desc: cudnnDropoutDescriptor_t,
input_mode: cudnnRNNInputMode_t,
direction_mode: cudnnDirectionMode_t,
rnn_mode: cudnnRNNMode_t,
algo: cudnnRNNAlgo_t,
data_type: cudnnDataType_t,
workspace_size: usize,
training_reserve_size: usize,
training_reserve: CudaDeviceMemory,
) -> RnnConfig {
RnnConfig {
rnn_desc,
hidden_size,
num_layers,
sequence_length,
dropout_desc,
input_mode,
direction_mode,
rnn_mode,
algo,
data_type,
workspace_size,
training_reserve_size,
training_reserve,
}
}
pub fn rnn_workspace_size(&self) -> usize {
self.workspace_size
}
pub fn largest_workspace_size(&self) -> usize {
self.rnn_workspace_size()
}
pub fn training_reserve_size(&self) -> usize {
self.training_reserve_size
}
pub fn training_reserve(&self) -> &CudaDeviceMemory {
&self.training_reserve
}
pub fn rnn_desc(&self) -> &RnnDescriptor {
&self.rnn_desc
}
pub fn sequence_length(&self) -> &i32 {
&self.sequence_length
}
}
#[allow(missing_debug_implementations, missing_copy_implementations)]
pub struct ScalParams<T>
where
T: Float + DataTypeInfo,
{
pub a: T,
pub b: T,
}
impl<T> Default for ScalParams<T>
where
T: Float + Zero + One + DataTypeInfo,
{
fn default() -> ScalParams<T> {
ScalParams {
a: One::one(),
b: Zero::zero(),
}
}
}