| 70 | |
| 71 | template<af_op_t op> |
| 72 | static af_err af_unary(af_array *out, const af_array in) { |
| 73 | try { |
| 74 | const ArrayInfo &in_info = getInfo(in); |
| 75 | ARG_ASSERT(1, in_info.isReal()); |
| 76 | |
| 77 | af_dtype in_type = in_info.getType(); |
| 78 | af_array res; |
| 79 | |
| 80 | // Convert all inputs to floats / doubles |
| 81 | af_dtype type = implicit(in_type, f32); |
| 82 | if (in_type == f16) { type = f16; } |
| 83 | if (in_info.ndims() == 0) { return af_retain_array(out, in); } |
| 84 | |
| 85 | switch (type) { |
| 86 | case f16: res = unaryOp<half, op>(in); break; |
| 87 | case f32: res = unaryOp<float, op>(in); break; |
| 88 | case f64: res = unaryOp<double, op>(in); break; |
| 89 | default: TYPE_ERROR(1, in_type); break; |
| 90 | } |
| 91 | |
| 92 | std::swap(*out, res); |
| 93 | } |
| 94 | CATCHALL; |
| 95 | return AF_SUCCESS; |
| 96 | } |
| 97 | |
| 98 | template<af_op_t op> |
| 99 | static af_err af_unary_complex(af_array *out, const af_array in) { |