| 42 | |
| 43 | template<typename OutT, typename InT> |
| 44 | void copyElemwise(Param<OutT> dst, CParam<InT> src, OutT default_value, |
| 45 | double factor) { |
| 46 | af::dim4 src_dims = src.dims(); |
| 47 | af::dim4 dst_dims = dst.dims(); |
| 48 | af::dim4 src_strides = src.strides(); |
| 49 | af::dim4 dst_strides = dst.strides(); |
| 50 | |
| 51 | data_t<InT> const* const src_ptr = src.get(); |
| 52 | data_t<OutT>* dst_ptr = dst.get(); |
| 53 | |
| 54 | dim_t trgt_l = std::min(dst_dims[3], src_dims[3]); |
| 55 | dim_t trgt_k = std::min(dst_dims[2], src_dims[2]); |
| 56 | dim_t trgt_j = std::min(dst_dims[1], src_dims[1]); |
| 57 | dim_t trgt_i = std::min(dst_dims[0], src_dims[0]); |
| 58 | |
| 59 | for (dim_t l = 0; l < dst_dims[3]; ++l) { |
| 60 | dim_t src_loff = l * src_strides[3]; |
| 61 | dim_t dst_loff = l * dst_strides[3]; |
| 62 | bool isLvalid = l < trgt_l; |
| 63 | |
| 64 | for (dim_t k = 0; k < dst_dims[2]; ++k) { |
| 65 | dim_t src_koff = k * src_strides[2]; |
| 66 | dim_t dst_koff = k * dst_strides[2]; |
| 67 | bool isKvalid = k < trgt_k; |
| 68 | |
| 69 | for (dim_t j = 0; j < dst_dims[1]; ++j) { |
| 70 | dim_t src_joff = j * src_strides[1]; |
| 71 | dim_t dst_joff = j * dst_strides[1]; |
| 72 | bool isJvalid = j < trgt_j; |
| 73 | |
| 74 | for (dim_t i = 0; i < dst_dims[0]; ++i) { |
| 75 | data_t<OutT> temp = default_value; |
| 76 | if (isLvalid && isKvalid && isJvalid && i < trgt_i) { |
| 77 | dim_t src_idx = |
| 78 | i * src_strides[0] + src_joff + src_koff + src_loff; |
| 79 | // The conversions here are necessary because the half |
| 80 | // type does not convert to complex automatically |
| 81 | temp = |
| 82 | compute_t<OutT>(compute_t<InT>(src_ptr[src_idx])) * |
| 83 | compute_t<OutT>(factor); |
| 84 | } |
| 85 | dim_t dst_idx = |
| 86 | i * dst_strides[0] + dst_joff + dst_koff + dst_loff; |
| 87 | dst_ptr[dst_idx] = temp; |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | template<typename OutT, typename InT> |
| 95 | struct CopyImpl { |