Backends/SiaNet.Backend.TensorSharp/Cpu/CpuMaxPoolingOps.cs
/// <summary>
/// Spatials the maximum pooling forward.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="output">The output.</param>
/// <param name="indices">The indices.</param>
/// <param name="cd">The cd.</param>
/// <param name="ceilMode">if set to <c>true</c> [ceil mode].</param>
/// <exception cref="ArgumentException">input must be a 4D tensor</exception>
/// <exception cref="InvalidOperationException">
/// input image is smaller than kernel size
/// or
/// pad should be smaller than half of the kernel size
/// </exception>
Spatials the maximum pooling forward.
Spatials the maximum pooling forward .
public static void SpatialMaxPoolingForward(NDArray input, NDArray output, NDArray indices, ConvolutionDesc2d cd, bool ceilMode)
        {
            if (input.DimensionCount != 4) throw new ArgumentException("input must be a 4D tensor");
            var dimw = 3;
            var dimh = 2;
            var dimc = 1;
            if (input.Shape[dimw] < cd.kW - cd.padW || input.Shape[dimh] < cd.kH - cd.padH)
                throw new InvalidOperationException("input image is smaller than kernel size");
            if (cd.padW > cd.kW / 2 || cd.padH > cd.kH / 2)
                throw new InvalidOperationException("pad should be smaller than half of the kernel size");
            var nbatch = input.Shape[0];
            var nslices = input.Shape[dimc];
            var iheight = input.Shape[dimh];
            var iwidth = input.Shape[dimw];
            long owidth;
            long oheight;
            if (ceilMode)
            {
                oheight = (long)(Math.Ceiling((float)(iheight - cd.kH + 2 * cd.padH) / cd.dH)) + 1;
                owidth = (long)(Math.Ceiling((float)(iwidth - cd.kW + 2 * cd.padW) / cd.dW)) + 1;
            }
            else
            {
                oheight = (long)(Math.Floor((float)(iheight - cd.kH + 2 * cd.padH) / cd.dH)) + 1;
                owidth = (long)(Math.Floor((float)(iwidth - cd.kW + 2 * cd.padW) / cd.dW)) + 1;
            }
            if (cd.padW != 0 || cd.padH != 0)
            {
                if ((oheight - 1) * cd.dH >= iheight + cd.padH)
                    --oheight;
                if ((owidth - 1) * cd.dW >= iwidth + cd.padW)
                    --owidth;
            }
            using (var inputContig = Ops.AsContiguous(input))
            {
                for (int i = 0; i < nbatch; ++i)
                {
                    using (var input_i = inputContig.Select(0, i))
                    using (var output_i = output.Select(0, i))
                    using (var indices_i = indices.Select(0, i))
                    {
                        IntPtr input_iPtr, output_iPtr, indices_iPtr;
                        using (NativeWrapper.BuildTensorRefPtr(input_i, out input_iPtr))
                        using (NativeWrapper.BuildTensorRefPtr(output_i, out output_iPtr))
                        using (NativeWrapper.BuildTensorRefPtr(indices_i, out indices_iPtr))
                        {
                            CpuOpsNative.TS_SpatialMaxPooling_updateOutput_frame(input_iPtr, output_iPtr, indices_iPtr,
                                nslices, iwidth, iheight,
                                owidth, oheight,
                                cd.kW, cd.kH, cd.dW, cd.dH, cd.padW, cd.padH);
                        }
                    }
                }
            }
        }
public static void SpatialMaxPoolingForward ( NDArray input , NDArray output , NDArray indices , ConvolutionDesc2d cd , bool ceilMode ) { if ( input . DimensionCount != 4 ) throw new ArgumentException ( " " ) ; var dimw = 3 ; var dimh = 2 ; var dimc = 1 ; if ( input . Shape [ dimw ] < cd . kW - cd . padW || input . Shape [ dimh ] < cd . kH - cd . padH ) throw new InvalidOperationException ( " " ) ; if ( cd . padW > cd . kW / 2 || cd . padH > cd . kH / 2 ) throw new InvalidOperationException ( " " ) ; var nbatch = input . Shape [ 0 ] ; var nslices = input . Shape [ dimc ] ; var iheight = input . Shape [ dimh ] ; var iwidth = input . Shape [ dimw ] ; long owidth ; long oheight ; if ( ceilMode ) { oheight = ( long ) ( Math . Ceiling ( ( float ) ( iheight - cd . kH + 2 * cd . padH ) / cd . dH ) ) + 1 ; owidth = ( long ) ( Math . Ceiling ( ( float ) ( iwidth - cd . kW + 2 * cd . padW ) / cd . dW ) ) + 1 ; } else { oheight = ( long ) ( Math . Floor ( ( float ) ( iheight - cd . kH + 2 * cd . padH ) / cd . dH ) ) + 1 ; owidth = ( long ) ( Math . Floor ( ( float ) ( iwidth - cd . kW + 2 * cd . padW ) / cd . dW ) ) + 1 ; } if ( cd . padW != 0 || cd . padH != 0 ) { if ( ( oheight - 1 ) * cd . dH >= iheight + cd . padH ) -- oheight ; if ( ( owidth - 1 ) * cd . dW >= iwidth + cd . padW ) -- owidth ; } using ( var inputContig = Ops . AsContiguous ( input ) ) { for ( int i = 0 ; i < nbatch ; ++ i ) { using ( var input_i = inputContig . Select ( 0 , i ) ) using ( var output_i = output . Select ( 0 , i ) ) using ( var indices_i = indices . Select ( 0 , i ) ) { IntPtr input_iPtr , output_iPtr , indices_iPtr ; using ( NativeWrapper . BuildTensorRefPtr ( input_i , out input_iPtr ) ) using ( NativeWrapper . BuildTensorRefPtr ( output_i , out output_iPtr ) ) using ( NativeWrapper . BuildTensorRefPtr ( indices_i , out indices_iPtr ) ) { CpuOpsNative . TS_SpatialMaxPooling_updateOutput_frame ( input_iPtr , output_iPtr , indices_iPtr , nslices , iwidth , iheight , owidth , oheight , cd . kW , cd . kH , cd . dW , cd . dH , cd . padW , cd . padH ) ; } } } } }
Spatials the maximum pooling forward.
Spatials the maximum pooling forward .
// ensure that the last pooling starts inside the image
input must be a 4D tensor
input must be a 4D tensor
input image is smaller than kernel size
or
pad should be smaller than half of the kernel size
input image is smaller than kernel size or pad should be smaller than half of the kernel size
input
NDArray
None
output
NDArray
None
indices
NDArray
None
cd
ConvolutionDesc2d
None
ceilMode
bool
if set to true
if set to true