function fusedDepthwiseConv2d_({ x, filter, strides, pad, dataFormat = "NHWC", dilations = [
    1,
    1
], dimRoundingMode, bias, activation = "linear", preluActivationWeights, leakyreluAlpha }) {
    if ((0, _fusedUtil.shouldFuse)((0, _engine.ENGINE).state.gradientDepth, activation) === false) {
        let result = (0, _depthwiseConv2D.depthwiseConv2d)(x, filter, strides, pad, dataFormat, dilations, dimRoundingMode);
        if (bias != null) result = (0, _add.add)(result, bias);
        return (0, _fusedUtil.applyActivation)(result, activation, preluActivationWeights, leakyreluAlpha);
    }
    const $x = (0, _tensorUtilEnv.convertToTensor)(x, "x", "depthwiseConv2d", "float32");
    const $filter = (0, _tensorUtilEnv.convertToTensor)(filter, "filter", "depthwiseConv2d", "float32");
    let x4D = $x;
    let reshapedTo4D = false;
    if ($x.rank === 3) {
        reshapedTo4D = true;
        x4D = (0, _reshape.reshape)($x, [
            1,
            $x.shape[0],
            $x.shape[1],
            $x.shape[2]
        ]);
    }
    _util.assert(x4D.rank === 4, ()=>`Error in fused depthwiseConv2d: input must be rank 4, but got ` + `rank ${x4D.rank}.`);
    _util.assert($filter.rank === 4, ()=>`Error in fused depthwiseConv2d: filter must be rank 4, ` + `but got rank ${$filter.rank}.`);
    _util.assert(x4D.shape[3] === $filter.shape[2], ()=>`Error in fused depthwiseConv2d: number of input channels ` + `(${x4D.shape[3]}) must match the inChannels dimension in ` + `filter ${$filter.shape[2]}.`);
    if (dilations == null) dilations = [
        1,
        1
    ];
    _util.assert(_convUtil.eitherStridesOrDilationsAreOne(strides, dilations), ()=>"Error in fused depthwiseConv2d: Either strides or dilations must " + `be 1. Got strides ${strides} and dilations '${dilations}'`);
    _convUtil.checkPadOnDimRoundingMode("fused depthwiseConv2d", pad, dimRoundingMode);
    const convInfo = _convUtil.computeConv2DInfo(x4D.shape, $filter.shape, strides, dilations, pad, dimRoundingMode, true);
    let $bias;
    if (bias != null) {
        $bias = (0, _tensorUtilEnv.convertToTensor)(bias, "bias", "fused conv2d");
        [$bias] = (0, _tensorUtil.makeTypesMatch)($bias, $x);
        _broadcastUtil.assertAndGetBroadcastShape(convInfo.outShape, $bias.shape);
    }
    let $preluActivationWeights;
    if (preluActivationWeights != null) $preluActivationWeights = (0, _tensorUtilEnv.convertToTensor)(preluActivationWeights, "prelu weights", "fused depthwiseConv2d");
    const grad = (dy, saved)=>{
        _util.assert(_convUtil.tupleValuesAreOne(dilations), ()=>"Error in gradient of fused depthwiseConv2d: dilation rates " + `greater than 1 are not yet supported. Got dilations ` + `'${dilations}'`);
        const [$filter, x4D, y, bias] = saved;
        const dyActivation = (0, _fusedUtil.getFusedDyActivation)(dy, y, activation);
        const xDer = (0, _depthwiseConv2DNativeBackpropInput.depthwiseConv2dNativeBackpropInput)(x4D.shape, dyActivation, $filter, strides, pad, dilations, dimRoundingMode);
        const filterDer = (0, _depthwiseConv2DNativeBackpropFilter.depthwiseConv2dNativeBackpropFilter)(x4D, dyActivation, $filter.shape, strides, pad, dilations, dimRoundingMode);
        if (bias != null) {
            const biasDer = (0, _fusedUtil.getFusedBiasGradient)($bias, dyActivation);
            return [
                xDer,
                filterDer,
                biasDer
            ];
        }
        return [
            xDer,
            filterDer
        ];
    };
    const inputs = {
        x: x4D,
        filter: $filter,
        bias: $bias,
        preluActivationWeights: $preluActivationWeights
    };
    const attrs = {
        strides,
        pad,
        dataFormat,
        dilations,
        dimRoundingMode,
        activation,
        leakyreluAlpha
    };
    // Depending on the the params passed in we will have different number of
    // inputs and thus a a different number of elements in the gradient.
    if (bias == null) {
        const customOp = (0, _gradients.customGrad)((x4D, filter, save)=>{
            // tslint:disable-next-line: no-unnecessary-type-assertion
            let res = (0, _engine.ENGINE).runKernel((0, _kernelNames.FusedDepthwiseConv2D), inputs, attrs);
            save([
                filter,
                x4D,
                res
            ]);
            if (reshapedTo4D) // tslint:disable-next-line: no-unnecessary-type-assertion
            res = (0, _reshape.reshape)(res, [
                res.shape[1],
                res.shape[2],
                res.shape[3]
            ]);
            return {
                value: res,
                gradFunc: grad
            };
        });
        return customOp(x4D, $filter);
    } else {
        const customOpWithBias = (0, _gradients.customGrad)((x4D, filter, bias, save)=>{
            // tslint:disable-next-line: no-unnecessary-type-assertion
            let res = (0, _engine.ENGINE).runKernel((0, _kernelNames.FusedDepthwiseConv2D), inputs, attrs);
            save([
                filter,
                x4D,
                res,
                bias
            ]);
            if (reshapedTo4D) // tslint:disable-next-line: no-unnecessary-type-assertion
            res = (0, _reshape.reshape)(res, [
                res.shape[1],
                res.shape[2],
                res.shape[3]
            ]);
            return {
                value: res,
                gradFunc: grad
            };
        });
        return customOpWithBias(x4D, $filter, $bias);
    }
}
Computes depthwise 2D convolution, optionally fused with adding a
bias and applying an activation.

Given a 4D `input` array and a `filter` array of shape
`[filterHeight, filterWidth, inChannels, channelMultiplier]` containing
`inChannels` convolutional filters of depth 1, this op applies a
different filter to each input channel (expanding from 1 channel to
`channelMultiplier` channels for each), then concatenates the results
together. The output has `inChannels * channelMultiplier` channels.

See
[https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d](
    https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d)
for more details.

@param obj An object with the following properties:
@param x The input tensor, of rank 4 or rank 3, of shape
    `[batch, height, width, inChannels]`. If rank 3, batch of 1 is
assumed.
@param filter The filter tensor, rank 4, of shape
    `[filterHeight, filterWidth, inChannels, channelMultiplier]`.
@param strides The strides of the convolution: `[strideHeight,
strideWidth]`. If strides is a single number, then `strideHeight ==
strideWidth`.
@param pad The type of padding algorithm.
  - `same` and stride 1: output will be of same size as input,
      regardless of filter size.
  - `valid`: output will be smaller than input if filter is larger
      than 1x1.
  - For more info, see this guide:
    [https://www.tensorflow.org/api_docs/python/tf/nn/convolution](
         https://www.tensorflow.org/api_docs/python/tf/nn/convolution)
@param dilations The dilation rates: `[dilationHeight, dilationWidth]`
    in which we sample input values across the height and width dimensions
    in atrous convolution. Defaults to `[1, 1]`. If `rate` is a single
    number, then `dilationHeight == dilationWidth`. If it is greater than
    1, then all values of `strides` must be 1.
@param dataFormat: An optional string from: "NHWC", "NCHW". Defaults to
    "NHWC". Specify the data format of the input and output data. With the
    default format "NHWC", the data is stored in the order of: [batch,
    height, width, channels]. Only "NHWC" is currently supported.
@param dimRoundingMode A string from: 'ceil', 'round', 'floor'. If none is
    provided, it will default to truncate.
@param bias Tensor to be added to the result.
@param activation Name of activation kernel (defaults to `linear`).
@param preluActivationWeights Tensor of prelu weights to be applied as part
    of a `prelu` activation, typically the same shape as `x`.
@param leakyreluAlpha Optional. Alpha to be applied as part of a `leakyrelu`
    activation.