Skip to content
This repository was archived by the owner on Mar 12, 2021. It is now read-only.

Add deterministic option #465

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/dnn/CUDNN.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ import NNlib

const libcudnn = Ref("libcudnn")

# control of deterministic
const deterministic = Ref(true)
isdeterministic() = deterministic[]
deterministic!(flag = true) = (deterministic[] = flag)

# core library
include("libcudnn_common.jl")
include("error.jl")
Expand Down
45 changes: 38 additions & 7 deletions src/dnn/nnlib.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,34 @@ function conv!(y::CuArray{T}, x::CuArray{T}, w::CuArray{T}, cdims::DenseConvDims
cudnnConvolutionForward(y, x, w, cdims, alpha=alpha, algo=algo)
end

# Reference for deterministic algo:
# https://docs.nvidia.com/deeplearning/sdk/cudnn-developer-guide/index.html#cudnnConvolutionBackwardFilter
function ∇conv_filter!(dw::CuArray{T}, x::CuArray{T}, dy::CuArray{T},
cdims::DenseConvDims; alpha=1, algo=0) where T<:CUDNNFloat
cdims::DenseConvDims; alpha=1, algo=isdeterministic() ? 1 : 0) where T<:CUDNNFloat
if isdeterministic()
if algo == 0
@warn "algorithm 0 (CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0) is not deterministic; algorithm 1 is used instead"
algo = 1
end
end

if version() < v"6"
all(x -> x == 1, dilation(cdims)) || error("Only dilation = 1 is supported in cuDNN version < 6")
end

cudnnConvolutionBackwardFilter(dw, x, dy, cdims, alpha=alpha, algo=algo)
end

# Reference for deterministic algo:
# https://docs.nvidia.com/deeplearning/sdk/cudnn-developer-guide/index.html#cudnnConvolutionBackwardData
function ∇conv_data!(dx::CuArray{T}, dy::CuArray{T}, w::CuArray{T},
cdims::DenseConvDims; alpha=1, algo=0) where T<:CUDNNFloat
cdims::DenseConvDims; alpha=1, algo=isdeterministic() ? 1 : 0) where T<:CUDNNFloat
if isdeterministic()
if algo == 0
@warn "algorithm 0 (CUDNN_CONVOLUTION_BWD_DATA_ALGO_0) is not deterministic; algorithm 1 is used instead"
end
end

if version() < v"6"
all(x -> x == 1, dilation(cdims)) || error("Only dilation = 1 is supported in cuDNN version < 6")
end
Expand All @@ -71,12 +88,26 @@ end
∇conv_bias!(db::CuArray{T}, dy::CuArray{T}; alpha=1, beta=0) where T<:CUDNNFloat =
cudnnConvolutionBackwardBias(db, dy, alpha=alpha, beta=beta)

maxpool!(y::CuArray{T}, x::CuArray{T}, pdims::PoolDims) where T<:CUDNNFloat =
cudnnPoolingForward(y, x, pdims; mode=0)
# Reference for deterministic mode:
# https://docs.nvidia.com/deeplearning/sdk/cudnn-developer-guide/index.html#cudnnPoolingMode_t
function maxpool!(y::CuArray{T}, x::CuArray{T}, pdims::PoolDims; mode=isdeterministic() ? 3 : 0) where T<:CUDNNFloat
if isdeterministic()
if model != 3
@warn "mode $mode is not deterministic; mode 3 (CUDNN_POOLING_MAX_DETERMINISTIC) is used instead"
end
end
return cudnnPoolingForward(y, x, pdims; mode=mode)
end

∇maxpool!(dx::CuArray{T}, dy::CuArray{T}, y::CuArray{T}, x::CuArray{T},
pdims::PoolDims) where T<:CUDNNFloat =
cudnnPoolingBackward(dx, dy, x, y, pdims, mode=0)
function ∇maxpool!(dx::CuArray{T}, dy::CuArray{T}, y::CuArray{T}, x::CuArray{T},
pdims::PoolDims, mode=isdeterministic() ? 3 : 0) where T<:CUDNNFloat
if isdeterministic()
if model != 3
@warn "mode $mode is not deterministic; mode 3 (CUDNN_POOLING_MAX_DETERMINISTIC) is used instead"
end
end
return cudnnPoolingBackward(dx, dy, x, y, pdims, mode=mode)
end

meanpool!(y::CuArray{T}, x::CuArray{T}, pdims::PoolDims) where T<:CUDNNFloat =
cudnnPoolingForward(y, x, pdims, mode=1)
Expand Down