| // |
| // This confidential and proprietary software may be used only as |
| // authorised by a licensing agreement from ARM Limited |
| // (C) COPYRIGHT 2020-2023 ARM Limited |
| // ALL RIGHTS RESERVED |
| // The entire notice above must be reproduced on all authorised |
| // copies and copies may only be made to the extent permitted |
| // by a licensing agreement from ARM Limited. |
| |
| === Elementwise Unary Operators |
| |
| ==== ABS |
| |
| Elementwise absolute value operation |
| |
| include::{generated}/operators/ABS.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|+infinity|+infinity|+0|+0|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| if (is_floating_point(in_out_t) && value1 == -0.0) { |
| value1 = 0.0; |
| } |
| if (static_cast<int32_t>(value1) < 0.0) { |
| value1 = apply_sub_s<in_out_t>(0, value1); |
| } |
| tensor_write<in_out_t>(output, shape, index, value1); |
| } |
| ---- |
| |
| ==== BITWISE_NOT |
| |
| Elementwise bitwise NOT of input tensor. |
| |
| include::{generated}/operators/BITWISE_NOT.adoc[] |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| in_out_t result = ~value1; |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== CEIL |
| |
| Elementwise ceiling operation |
| |
| include::{generated}/operators/CEIL.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|-infinity|+infinity|-0|+0|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| in_out_t result = apply_ceil<in_out_t>(value1); |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== CLZ |
| |
| Elementwise count leading zeros operation |
| |
| include::{generated}/operators/CLZ.adoc[] |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| in_out_t result = count_leading_zeros(value1); |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== EXP |
| |
| Elementwise e to the x operation |
| |
| include::{generated}/operators/EXP.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|+0|+infinity|1|1|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| in_out_t result = apply_exp<in_out_t>(value1); |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== FLOOR |
| |
| Elementwise floor operation |
| |
| include::{generated}/operators/FLOOR.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|-infinity|+infinity|-0|+0|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| in_out_t result = apply_floor<in_out_t>(value1); |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== LOG |
| |
| Elementwise natural logarithm operation |
| |
| include::{generated}/operators/LOG.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|NaN|+infinity|-infinity|-infinity|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| in_out_t result = apply_log<in_out_t>(value1); |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== LOGICAL_NOT |
| |
| Elementwise logical NOT of input. |
| |
| include::{generated}/operators/LOGICAL_NOT.adoc[] |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index); |
| in_out_t result = !value1; |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== NEGATE |
| |
| Elementwise negation operation |
| |
| include::{generated}/operators/NEGATE.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|+infinity|-infinity|+0|-0|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| ERROR_IF(in_out_t != i8_t && input1_zp != 0) // Zero point only for int8_t |
| ERROR_IF(in_out_t != i8_t && output_zp != 0) // Zero point only for int8_t |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape, index); |
| acc_t value = apply_sub_s<acc_t>(sign_extend<acc_t>(value1), |
| sign_extend<acc_t>(input1_zp)); |
| value = apply_sub_s<acc_t>(0, value); |
| value = apply_add_s<acc_t>(value, sign_extend<acc_t>(output_zp)); |
| in_out_t result = truncate<in_out_t>(apply_clip_s<acc_t>(value, |
| minimum_s<in_out_t>, |
| maximum_s<in_out_t>)); |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== RECIPROCAL |
| |
| Elementwise reciprocal operation. For integer operation, a TABLE should be used with the appropriate ranges. |
| |
| include::{generated}/operators/RECIPROCAL.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|-0|+0|-infinity|+infinity|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index); |
| in_out_t result = 1.0 / value1; |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |
| |
| ==== RSQRT |
| |
| Elementwise reciprocal square root operation. For integer operation, a TABLE should be used with the appropriate ranges. |
| |
| include::{generated}/operators/RSQRT.adoc[] |
| |
| *Floating-point behavior:* |
| |=== |
| |Input|-infinity|+infinity|-0|+0|NaN |
| |
| |Output|NaN|+0|-infinity|+infinity|NaN |
| |=== |
| |
| [source,c++] |
| ---- |
| for_each(index in shape) { |
| in_out_t value1 = tensor_read<in_out_t>(input1, shape1, index); |
| in_out_t result; |
| if (value1 < 0) { |
| result = NaN; |
| } |
| else { |
| result = 1.0 / apply_sqrt<in_out_t>(value1); |
| } |
| tensor_write<in_out_t>(output, shape, index, result); |
| } |
| ---- |