| 412 | } |
| 413 | |
| 414 | af_err af_convolve2_gradient_nn( |
| 415 | af_array *out, const af_array incoming_gradient, |
| 416 | const af_array original_signal, const af_array original_filter, |
| 417 | const af_array convolved_output, const unsigned stride_dims, |
| 418 | const dim_t *strides, const unsigned padding_dims, const dim_t *paddings, |
| 419 | const unsigned dilation_dims, const dim_t *dilations, |
| 420 | af_conv_gradient_type grad_type) { |
| 421 | try { |
| 422 | const ArrayInfo &iinfo = getInfo(incoming_gradient); |
| 423 | const af::dim4 &iDims = iinfo.dims(); |
| 424 | |
| 425 | const ArrayInfo &sinfo = getInfo(original_signal); |
| 426 | af::dim4 sDims = sinfo.dims(); |
| 427 | |
| 428 | const ArrayInfo &finfo = getInfo(original_filter); |
| 429 | af::dim4 fDims = finfo.dims(); |
| 430 | |
| 431 | const ArrayInfo &oinfo = getInfo(convolved_output); |
| 432 | af::dim4 oDims = oinfo.dims(); |
| 433 | |
| 434 | DIM_ASSERT(1, iDims == oDims); |
| 435 | DIM_ASSERT(3, oDims[2] == fDims[3]); |
| 436 | DIM_ASSERT(3, oDims[3] == sDims[3]); |
| 437 | DIM_ASSERT(2, sDims[2] == fDims[2]); |
| 438 | |
| 439 | af_array output; |
| 440 | |
| 441 | af::dim4 stride(stride_dims, strides); |
| 442 | af::dim4 padding(padding_dims, paddings); |
| 443 | af::dim4 dilation(dilation_dims, dilations); |
| 444 | |
| 445 | size_t stride_ndims = stride.ndims(); |
| 446 | size_t padding_ndims = padding.ndims(); |
| 447 | size_t dilation_ndims = dilation.ndims(); |
| 448 | ARG_ASSERT(3, stride_ndims > 0 && stride_ndims <= 2); |
| 449 | ARG_ASSERT(5, padding_ndims >= 0 && padding_ndims <= 2); |
| 450 | ARG_ASSERT(7, dilation_ndims > 0 && dilation_ndims <= 2); |
| 451 | |
| 452 | af_dtype type = oinfo.getType(); |
| 453 | switch (type) { |
| 454 | case f32: |
| 455 | output = conv2GradCall<float>( |
| 456 | incoming_gradient, original_signal, original_filter, |
| 457 | convolved_output, stride, padding, dilation, grad_type); |
| 458 | break; |
| 459 | case f64: |
| 460 | output = conv2GradCall<double>( |
| 461 | incoming_gradient, original_signal, original_filter, |
| 462 | convolved_output, stride, padding, dilation, grad_type); |
| 463 | break; |
| 464 | case f16: |
| 465 | output = conv2GradCall<half>( |
| 466 | incoming_gradient, original_signal, original_filter, |
| 467 | convolved_output, stride, padding, dilation, grad_type); |
| 468 | break; |
| 469 | default: TYPE_ERROR(1, type); |
| 470 | } |
| 471 | // output array is pooled array |
no test coverage detected