Interpolations.jl works for this, too, although with a bit more overhead than in-place calculation:
julia> using Interpolations
julia> v = rand(3, 3, 3);
julia> itp = linear_interpolation(axes(v), v);
julia> [Interpolations.gradient(itp, idx...) for idx in knots(itp)]
3×3×3 Array{StaticArraysCore.SVector{3, Float64}, 3}:
[:, :, 1] =
[0.0217651, 0.081234, 0.245227] [0.422528, 0.50527, 0.237876] [-0.336426, 0.50527, -0.153063]
[-0.140606, 0.481997, 0.47315] [-0.205345, -0.253683, -0.562774] [-0.184544, -0.253683, -0.330334]
[-0.140606, 0.417258, 0.815596] [-0.205345, -0.232882, -0.0649707] [-0.184544, -0.232882, 0.0365438]
[:, :, 2] =
[0.249688, 0.0738826, 0.347969] [-0.378122, 0.114332, -0.0942331] [-0.513697, 0.114332, -0.253928]
[0.201841, -0.553927, 0.189845] [0.292458, -0.0212431, 0.726295] [0.182334, -0.0212431, 0.368639]
[0.201841, -0.463309, 0.0285594] [0.292458, -0.131368, 0.152346] [0.182334, -0.131368, 0.292275]
[:, :, 3] =
[0.0915639, -0.368319, 0.347969] [0.442407, -0.0453636, -0.0942331] [0.10887, -0.0453636, -0.253928]
[0.0405551, -0.0174767, 0.189845] [-0.281491, -0.3789, 0.726295] [0.105971, -0.3789, 0.368639]
[0.0405551, -0.339523, 0.0285594] [-0.281491, 0.00856203, 0.152346] [0.105971, 0.00856203, 0.292275]