diff --git a/build_tools/math/README.md b/build_tools/math/README.md index f885c308d8..52f736ecb2 100644 --- a/build_tools/math/README.md +++ b/build_tools/math/README.md @@ -31,7 +31,7 @@ following requirements: - Python 3.11 or newer - mpmath 1.3 or newer -- functional_algorithms 0.14.1 or newer +- functional_algorithms 0.15.0 or newer that can be installed via pypi: diff --git a/build_tools/math/generate_ChloDecompositionPatternsMath.py b/build_tools/math/generate_ChloDecompositionPatternsMath.py index 59d2dee441..3a470e7003 100644 --- a/build_tools/math/generate_ChloDecompositionPatternsMath.py +++ b/build_tools/math/generate_ChloDecompositionPatternsMath.py @@ -100,6 +100,7 @@ def main(kind="CHLO"): ("StableHLO_Log1pOp", "complex_log1p", ("z:complex",)), ("StableHLO_SqrtOp", "complex_sqrt", ("z:complex",)), ("StableHLO_LogOp", "complex_log", ("z:complex",)), + ("StableHLO_ExpOp", "complex_exp", ("z:complex",)), ]: if not chloname.startswith(kind): continue diff --git a/build_tools/math/generate_tests.py b/build_tools/math/generate_tests.py index b8c5bec4b9..ad0853278a 100644 --- a/build_tools/math/generate_tests.py +++ b/build_tools/math/generate_tests.py @@ -68,6 +68,10 @@ dict(name="acosh", mpmath_name="arccosh"), dict(name="atanh", mpmath_name="arctanh"), dict(name="square", mpmath_name="square"), + dict(name="exponential", + mpmath_name="exp", + namespace="stablehlo", + passes="--stablehlo-complex-math-expander"), dict(name="log_plus_one", mpmath_name="log1p", namespace="stablehlo", diff --git a/stablehlo/tests/math/exponential_complex128.mlir b/stablehlo/tests/math/exponential_complex128.mlir new file mode 100644 index 0000000000..6e76a2ec52 --- /dev/null +++ b/stablehlo/tests/math/exponential_complex128.mlir @@ -0,0 +1,19 @@ +// RUN: stablehlo-opt --stablehlo-complex-math-expander %s | stablehlo-translate --interpret +// This file is generated, see build_tools/math/README.md for more information. +module @exponential_complex128 { + func.func private @samples() -> tensor<169xcomplex> { + %0 = stablehlo.constant dense<"0x000000000000F0FF000000000000F0FFFFFFFFFFFFFFEFFF000000000000F0FFFEFFFFFFFFFFEFFF000000000000F0FF000000000000F8BF000000000000F0FF000000000000FC9F000000000000F0FF0100000000000080000000000000F0FF0000000000000000000000000000F0FF0100000000000000000000000000F0FF000000000000FC1F000000000000F0FF000000000000F83F000000000000F0FFFEFFFFFFFFFFEF7F000000000000F0FFFFFFFFFFFFFFEF7F000000000000F0FF000000000000F07F000000000000F0FF000000000000F0FFFFFFFFFFFFFFEFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFEFFFFEFFFFFFFFFFEFFFFFFFFFFFFFFFEFFF000000000000F8BFFFFFFFFFFFFFEFFF000000000000FC9FFFFFFFFFFFFFEFFF0100000000000080FFFFFFFFFFFFEFFF0000000000000000FFFFFFFFFFFFEFFF0100000000000000FFFFFFFFFFFFEFFF000000000000FC1FFFFFFFFFFFFFEFFF000000000000F83FFFFFFFFFFFFFEFFFFEFFFFFFFFFFEF7FFFFFFFFFFFFFEFFFFFFFFFFFFFFFEF7FFFFFFFFFFFFFEFFF000000000000F07FFFFFFFFFFFFFEFFF000000000000F0FFFEFFFFFFFFFFEFFFFFFFFFFFFFFFEFFFFEFFFFFFFFFFEFFFFEFFFFFFFFFFEFFFFEFFFFFFFFFFEFFF000000000000F8BFFEFFFFFFFFFFEFFF000000000000FC9FFEFFFFFFFFFFEFFF0100000000000080FEFFFFFFFFFFEFFF0000000000000000FEFFFFFFFFFFEFFF0100000000000000FEFFFFFFFFFFEFFF000000000000FC1FFEFFFFFFFFFFEFFF000000000000F83FFEFFFFFFFFFFEFFFFEFFFFFFFFFFEF7FFEFFFFFFFFFFEFFFFFFFFFFFFFFFEF7FFEFFFFFFFFFFEFFF000000000000F07FFEFFFFFFFFFFEFFF000000000000F0FF000000000000F8BFFFFFFFFFFFFFEFFF000000000000F8BFFEFFFFFFFFFFEFFF000000000000F8BF000000000000F8BF000000000000F8BF000000000000FC9F000000000000F8BF0100000000000080000000000000F8BF0000000000000000000000000000F8BF0100000000000000000000000000F8BF000000000000FC1F000000000000F8BF000000000000F83F000000000000F8BFFEFFFFFFFFFFEF7F000000000000F8BFFFFFFFFFFFFFEF7F000000000000F8BF000000000000F07F000000000000F8BF000000000000F0FF000000000000FC9FFFFFFFFFFFFFEFFF000000000000FC9FFEFFFFFFFFFFEFFF000000000000FC9F000000000000F8BF000000000000FC9F000000000000FC9F000000000000FC9F0100000000000080000000000000FC9F0000000000000000000000000000FC9F0100000000000000000000000000FC9F000000000000FC1F000000000000FC9F000000000000F83F000000000000FC9FFEFFFFFFFFFFEF7F000000000000FC9FFFFFFFFFFFFFEF7F000000000000FC9F000000000000F07F000000000000FC9F000000000000F0FF0100000000000080FFFFFFFFFFFFEFFF0100000000000080FEFFFFFFFFFFEFFF0100000000000080000000000000F8BF0100000000000080000000000000FC9F0100000000000080010000000000008001000000000000800000000000000000010000000000008001000000000000000100000000000080000000000000FC1F0100000000000080000000000000F83F0100000000000080FEFFFFFFFFFFEF7F0100000000000080FFFFFFFFFFFFEF7F0100000000000080000000000000F07F0100000000000080000000000000F0FF0000000000000000FFFFFFFFFFFFEFFF0000000000000000FEFFFFFFFFFFEFFF0000000000000000000000000000F8BF0000000000000000000000000000FC9F0000000000000000010000000000008000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000FC1F0000000000000000000000000000F83F0000000000000000FEFFFFFFFFFFEF7F0000000000000000FFFFFFFFFFFFEF7F0000000000000000000000000000F07F0000000000000000000000000000F0FF0100000000000000FFFFFFFFFFFFEFFF0100000000000000FEFFFFFFFFFFEFFF0100000000000000000000000000F8BF0100000000000000000000000000FC9F0100000000000000010000000000008001000000000000000000000000000000010000000000000001000000000000000100000000000000000000000000FC1F0100000000000000000000000000F83F0100000000000000FEFFFFFFFFFFEF7F0100000000000000FFFFFFFFFFFFEF7F0100000000000000000000000000F07F0100000000000000000000000000F0FF000000000000FC1FFFFFFFFFFFFFEFFF000000000000FC1FFEFFFFFFFFFFEFFF000000000000FC1F000000000000F8BF000000000000FC1F000000000000FC9F000000000000FC1F0100000000000080000000000000FC1F0000000000000000000000000000FC1F0100000000000000000000000000FC1F000000000000FC1F000000000000FC1F000000000000F83F000000000000FC1FFEFFFFFFFFFFEF7F000000000000FC1FFFFFFFFFFFFFEF7F000000000000FC1F000000000000F07F000000000000FC1F000000000000F0FF000000000000F83FFFFFFFFFFFFFEFFF000000000000F83FFEFFFFFFFFFFEFFF000000000000F83F000000000000F8BF000000000000F83F000000000000FC9F000000000000F83F0100000000000080000000000000F83F0000000000000000000000000000F83F0100000000000000000000000000F83F000000000000FC1F000000000000F83F000000000000F83F000000000000F83FFEFFFFFFFFFFEF7F000000000000F83FFFFFFFFFFFFFEF7F000000000000F83F000000000000F07F000000000000F83F000000000000F0FFFEFFFFFFFFFFEF7FFFFFFFFFFFFFEFFFFEFFFFFFFFFFEF7FFEFFFFFFFFFFEFFFFEFFFFFFFFFFEF7F000000000000F8BFFEFFFFFFFFFFEF7F000000000000FC9FFEFFFFFFFFFFEF7F0100000000000080FEFFFFFFFFFFEF7F0000000000000000FEFFFFFFFFFFEF7F0100000000000000FEFFFFFFFFFFEF7F000000000000FC1FFEFFFFFFFFFFEF7F000000000000F83FFEFFFFFFFFFFEF7FFEFFFFFFFFFFEF7FFEFFFFFFFFFFEF7FFFFFFFFFFFFFEF7FFEFFFFFFFFFFEF7F000000000000F07FFEFFFFFFFFFFEF7F000000000000F0FFFFFFFFFFFFFFEF7FFFFFFFFFFFFFEFFFFFFFFFFFFFFFEF7FFEFFFFFFFFFFEFFFFFFFFFFFFFFFEF7F000000000000F8BFFFFFFFFFFFFFEF7F000000000000FC9FFFFFFFFFFFFFEF7F0100000000000080FFFFFFFFFFFFEF7F0000000000000000FFFFFFFFFFFFEF7F0100000000000000FFFFFFFFFFFFEF7F000000000000FC1FFFFFFFFFFFFFEF7F000000000000F83FFFFFFFFFFFFFEF7FFEFFFFFFFFFFEF7FFFFFFFFFFFFFEF7FFFFFFFFFFFFFEF7FFFFFFFFFFFFFEF7F000000000000F07FFFFFFFFFFFFFEF7F000000000000F0FF000000000000F07FFFFFFFFFFFFFEFFF000000000000F07FFEFFFFFFFFFFEFFF000000000000F07F000000000000F8BF000000000000F07F000000000000FC9F000000000000F07F0100000000000080000000000000F07F0000000000000000000000000000F07F0100000000000000000000000000F07F000000000000FC1F000000000000F07F000000000000F83F000000000000F07FFEFFFFFFFFFFEF7F000000000000F07FFFFFFFFFFFFFEF7F000000000000F07F000000000000F07F000000000000F07F"> : tensor<169xcomplex> + return %0 : tensor<169xcomplex> + } + func.func private @expected() -> tensor<169xcomplex> { + %0 = stablehlo.constant dense<"0x000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F00000000000000000000000000000000000000000000008000000000000000800000000000000080000000000000008070FB7467708FCCBF216B18E5C52352BF75ABCF2EE6FFEFBF974EB398FC5274BF75ABCF2EE6FFEFBF974EB398FC5274BF75ABCF2EE6FFEFBF974EB398FC5274BF75ABCF2EE6FFEFBF974EB398FC5274BF75ABCF2EE6FFEFBF974EB398FC5274BFBE3CC56F31ED11C0214025CB8AC596BF000000000000F0FF000000000000F0FF000000000000F0FF000000000000F0FF000000000000F0FF000000000000F0FF0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000800C300CC3886BB53F61593FDCFD79CABF8F30C5B4DFFFD73F8AEEC67736AAEDBF8F30C5B4DFFFD73F8AEEC67736AAEDBF8F30C5B4DFFFD73F8AEEC67736AAEDBF8F30C5B4DFFFD73F8AEEC67736AAEDBF8F30C5B4DFFFD73F8AEEC67736AAEDBF48DBADAABBE3FA3F705EA5CF5C9E10C0000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000080FA6C23AD9329903F999D1BAF367DCCBFA7F9C54FD51BB23F8B6D2C9B7AEBEFBFA7F9C54FD51BB23F8B6D2C9B7AEBEFBFA7F9C54FD51BB23F8B6D2C9B7AEBEFBFA7F9C54FD51BB23F8B6D2C9B7AEBEFBFA7F9C54FD51BB23F8B6D2C9B7AEBEFBFE84AB23E174AD43F1150D2E3C0E111C0000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000801D5C4B72878FCC3F9AF0018496FDD89F000000000000F03F000000000000FC9F000000000000F03F000000000000FC9F000000000000F03F000000000000FC9F000000000000F03F000000000000FC9F000000000000F03F000000000000FC9F41C54FE63FED114032990BD32F5F1FA0000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000801D5C4B72878FCC3F0000000000000080000000000000F03F0100000000000080000000000000F03F0100000000000080000000000000F03F0100000000000080000000000000F03F0100000000000080000000000000F03F010000000000008041C54FE63FED11400400000000000080000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D5C4B72878FCC3F0000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000F03F000000000000000041C54FE63FED11400000000000000000000000000000F07F0000000000000000000000000000F07F0000000000000000000000000000F07F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D5C4B72878FCC3F0000000000000000000000000000F03F0100000000000000000000000000F03F0100000000000000000000000000F03F0100000000000000000000000000F03F0100000000000000000000000000F03F010000000000000041C54FE63FED11400400000000000000000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D5C4B72878FCC3F9AF0018496FDD81F000000000000F03F000000000000FC1F000000000000F03F000000000000FC1F000000000000F03F000000000000FC1F000000000000F03F000000000000FC1F000000000000F03F000000000000FC1F41C54FE63FED114032990BD32F5F1F20000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FA6C23AD9329903F999D1BAF367DCC3FA7F9C54FD51BB23F8B6D2C9B7AEBEF3FA7F9C54FD51BB23F8B6D2C9B7AEBEF3FA7F9C54FD51BB23F8B6D2C9B7AEBEF3FA7F9C54FD51BB23F8B6D2C9B7AEBEF3FA7F9C54FD51BB23F8B6D2C9B7AEBEF3FE84AB23E174AD43F1150D2E3C0E11140000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C300CC3886BB53F61593FDCFD79CA3F8F30C5B4DFFFD73F8AEEC67736AAED3F8F30C5B4DFFFD73F8AEEC67736AAED3F8F30C5B4DFFFD73F8AEEC67736AAED3F8F30C5B4DFFFD73F8AEEC67736AAED3F8F30C5B4DFFFD73F8AEEC67736AAED3F48DBADAABBE3FA3F705EA5CF5C9E1040000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F00000000000000000000000000000000000000000000008000000000000000000000000000000080000000000000000070FB7467708FCCBF216B18E5C523523F75ABCF2EE6FFEFBF974EB398FC52743F75ABCF2EE6FFEFBF974EB398FC52743F75ABCF2EE6FFEFBF974EB398FC52743F75ABCF2EE6FFEFBF974EB398FC52743F75ABCF2EE6FFEFBF974EB398FC52743FBE3CC56F31ED11C0214025CB8AC5963F000000000000F0FF000000000000F07F000000000000F0FF000000000000F07F000000000000F0FF000000000000F07F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F000000000000F87F"> : tensor<169xcomplex> + return %0 : tensor<169xcomplex> + } + func.func public @main() { + %0 = call @samples() : () -> tensor<169xcomplex> + %1 = "stablehlo.exponential"(%0) : (tensor<169xcomplex>) -> tensor<169xcomplex> + %2 = call @expected() : () -> tensor<169xcomplex> + check.expect_close %1, %2, max_ulp_difference = 3 : tensor<169xcomplex>, tensor<169xcomplex> + func.return + } +} diff --git a/stablehlo/tests/math/exponential_complex64.mlir b/stablehlo/tests/math/exponential_complex64.mlir new file mode 100644 index 0000000000..0897c092e2 --- /dev/null +++ b/stablehlo/tests/math/exponential_complex64.mlir @@ -0,0 +1,19 @@ +// RUN: stablehlo-opt --stablehlo-complex-math-expander %s | stablehlo-translate --interpret +// This file is generated, see build_tools/math/README.md for more information. +module @exponential_complex64 { + func.func private @samples() -> tensor<169xcomplex> { + %0 = stablehlo.constant dense<"0x000080FF000080FFFFFF7FFF000080FFFEFF7FFF000080FF0000C0BF000080FF0000E09F000080FF01000080000080FF00000000000080FF01000000000080FF0000E01F000080FF0000C03F000080FFFEFF7F7F000080FFFFFF7F7F000080FF0000807F000080FF000080FFFFFF7FFFFFFF7FFFFFFF7FFFFEFF7FFFFFFF7FFF0000C0BFFFFF7FFF0000E09FFFFF7FFF01000080FFFF7FFF00000000FFFF7FFF01000000FFFF7FFF0000E01FFFFF7FFF0000C03FFFFF7FFFFEFF7F7FFFFF7FFFFFFF7F7FFFFF7FFF0000807FFFFF7FFF000080FFFEFF7FFFFFFF7FFFFEFF7FFFFEFF7FFFFEFF7FFF0000C0BFFEFF7FFF0000E09FFEFF7FFF01000080FEFF7FFF00000000FEFF7FFF01000000FEFF7FFF0000E01FFEFF7FFF0000C03FFEFF7FFFFEFF7F7FFEFF7FFFFFFF7F7FFEFF7FFF0000807FFEFF7FFF000080FF0000C0BFFFFF7FFF0000C0BFFEFF7FFF0000C0BF0000C0BF0000C0BF0000E09F0000C0BF010000800000C0BF000000000000C0BF010000000000C0BF0000E01F0000C0BF0000C03F0000C0BFFEFF7F7F0000C0BFFFFF7F7F0000C0BF0000807F0000C0BF000080FF0000E09FFFFF7FFF0000E09FFEFF7FFF0000E09F0000C0BF0000E09F0000E09F0000E09F010000800000E09F000000000000E09F010000000000E09F0000E01F0000E09F0000C03F0000E09FFEFF7F7F0000E09FFFFF7F7F0000E09F0000807F0000E09F000080FF01000080FFFF7FFF01000080FEFF7FFF010000800000C0BF010000800000E09F010000800100008001000080000000000100008001000000010000800000E01F010000800000C03F01000080FEFF7F7F01000080FFFF7F7F010000800000807F01000080000080FF00000000FFFF7FFF00000000FEFF7FFF000000000000C0BF000000000000E09F000000000100008000000000000000000000000001000000000000000000E01F000000000000C03F00000000FEFF7F7F00000000FFFF7F7F000000000000807F00000000000080FF01000000FFFF7FFF01000000FEFF7FFF010000000000C0BF010000000000E09F010000000100008001000000000000000100000001000000010000000000E01F010000000000C03F01000000FEFF7F7F01000000FFFF7F7F010000000000807F01000000000080FF0000E01FFFFF7FFF0000E01FFEFF7FFF0000E01F0000C0BF0000E01F0000E09F0000E01F010000800000E01F000000000000E01F010000000000E01F0000E01F0000E01F0000C03F0000E01FFEFF7F7F0000E01FFFFF7F7F0000E01F0000807F0000E01F000080FF0000C03FFFFF7FFF0000C03FFEFF7FFF0000C03F0000C0BF0000C03F0000E09F0000C03F010000800000C03F000000000000C03F010000000000C03F0000E01F0000C03F0000C03F0000C03FFEFF7F7F0000C03FFFFF7F7F0000C03F0000807F0000C03F000080FFFEFF7F7FFFFF7FFFFEFF7F7FFEFF7FFFFEFF7F7F0000C0BFFEFF7F7F0000E09FFEFF7F7F01000080FEFF7F7F00000000FEFF7F7F01000000FEFF7F7F0000E01FFEFF7F7F0000C03FFEFF7F7FFEFF7F7FFEFF7F7FFFFF7F7FFEFF7F7F0000807FFEFF7F7F000080FFFFFF7F7FFFFF7FFFFFFF7F7FFEFF7FFFFFFF7F7F0000C0BFFFFF7F7F0000E09FFFFF7F7F01000080FFFF7F7F00000000FFFF7F7F01000000FFFF7F7F0000E01FFFFF7F7F0000C03FFFFF7F7FFEFF7F7FFFFF7F7FFFFF7F7FFFFF7F7F0000807FFFFF7F7F000080FF0000807FFFFF7FFF0000807FFEFF7FFF0000807F0000C0BF0000807F0000E09F0000807F010000800000807F000000000000807F010000000000807F0000E01F0000807F0000C03F0000807FFEFF7F7F0000807FFFFF7F7F0000807F0000807F0000807F"> : tensor<169xcomplex> + return %0 : tensor<169xcomplex> + } + func.func private @expected() -> tensor<169xcomplex> { + %0 = stablehlo.constant dense<"0x0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000000000000000000000000000000000000000000000001BE7423E727BEE3D965F5A3FB399053F965F5A3FB399053F965F5A3FB399053F965F5A3FB399053F965F5A3FB399053FA0AB744059B015400000807F0000807F0000807F0000807F0000807F0000807F00000000000000000000008000000000000000800000000081242FBEABBB123ED13B44BF2C67243FD13B44BF2C67243FD13B44BF2C67243FD13B44BF2C67243FD13B44BF2C67243F54DD5BC067333840000080FF0000807F000080FF0000807F000080FF0000807F0000000000000000000000000000008000000000000000809D4C813CB5E963BEAADE903DD55B7FBFAADE903DD55B7FBFAADE903DD55B7FBFAADE903DD55B7FBFAADE903DD55B7FBFBA50A23E070E8FC00000807F000080FF0000807F000080FF0000807F000080FF0000000000000000000000000000008000000000000000803C7C643EB4ECC79E0000803F0000E09F0000803F0000E09F0000803F0000E09F0000803F0000E09F0000803F0000E09FFF698F407FF9FAA00000807F000080FF0000807F000080FF0000807F000080FF0000000000000000000000000000008000000000000000803C7C643E000000800000803F010000800000803F010000800000803F010000800000803F010000800000803F01000080FF698F40040000800000807F000080FF0000807F000080FF0000807F000080FF0000000000000000000000000000000000000000000000003C7C643E000000000000803F000000000000803F000000000000803F000000000000803F000000000000803F00000000FF698F40000000000000807F000000000000807F000000000000807F000000000000000000000000000000000000000000000000000000003C7C643E000000000000803F010000000000803F010000000000803F010000000000803F010000000000803F01000000FF698F40040000000000807F0000807F0000807F0000807F0000807F0000807F0000000000000000000000000000000000000000000000003C7C643EB4ECC71E0000803F0000E01F0000803F0000E01F0000803F0000E01F0000803F0000E01F0000803F0000E01FFF698F407FF9FA200000807F0000807F0000807F0000807F0000807F0000807F0000000000000000000000000000000000000000000000009D4C813CB5E9633EAADE903DD55B7F3FAADE903DD55B7F3FAADE903DD55B7F3FAADE903DD55B7F3FAADE903DD55B7F3FBA50A23E070E8F400000807F0000807F0000807F0000807F0000807F0000807F00000000000000000000008000000080000000800000008081242FBEABBB12BED13B44BF2C6724BFD13B44BF2C6724BFD13B44BF2C6724BFD13B44BF2C6724BFD13B44BF2C6724BF54DD5BC0673338C0000080FF000080FF000080FF000080FF000080FF000080FF0000000000000000000000000000008000000000000000801BE7423E727BEEBD965F5A3FB39905BF965F5A3FB39905BF965F5A3FB39905BF965F5A3FB39905BF965F5A3FB39905BFA0AB744059B015C00000807F000080FF0000807F000080FF0000807F000080FF0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F0000C07F"> : tensor<169xcomplex> + return %0 : tensor<169xcomplex> + } + func.func public @main() { + %0 = call @samples() : () -> tensor<169xcomplex> + %1 = "stablehlo.exponential"(%0) : (tensor<169xcomplex>) -> tensor<169xcomplex> + %2 = call @expected() : () -> tensor<169xcomplex> + check.expect_close %1, %2, max_ulp_difference = 3 : tensor<169xcomplex>, tensor<169xcomplex> + func.return + } +} diff --git a/stablehlo/tests/math/exponential_float32.mlir b/stablehlo/tests/math/exponential_float32.mlir new file mode 100644 index 0000000000..82f1465ac7 --- /dev/null +++ b/stablehlo/tests/math/exponential_float32.mlir @@ -0,0 +1,19 @@ +// RUN: stablehlo-opt --stablehlo-complex-math-expander %s | stablehlo-translate --interpret +// This file is generated, see build_tools/math/README.md for more information. +module @exponential_float32 { + func.func private @samples() -> tensor<169xf32> { + %0 = stablehlo.constant dense<"0x000080FFFFFF7FFFFEFF7FFF05E763FC88DAD5FA0BCE47F98EC1B9F711B52BF695A89DF4189C0FF39B8F81F11E83F3EFA17665EE246AD7ECA75D49EB2B51BBE9AE442DE831389FE6B42B11E5371F83E3BA12F5E13D0667E0C1F9D8DE44ED4ADDC7E0BCDB4AD42EDACDC7A0D850BB12D7D3AE84D557A2F6D3DA9568D25D89DAD0E07C4CCF6370BECDE66330CC6957A2CAED4A14C9703E86C7F331F8C576256AC4F918DCC27C0C4EC10000C0BF83F331BE06E7A3BC89DA15BB0CCE87B98FC1F9B712B56BB696A8DDB4199C4FB39C8FC1B11F8333B0A276A5AE256A17ADA85D89AB2C51FBA9AF446DA83238DFA6B52B51A5381FC3A3BB1235A23E06A7A0C2F9189F45ED8A9DC8E0FC9B4BD46E9ACEC7E09851BB5297D4AEC49558A23694DB95A8925E891A91E17C8C8F6470FE8DE763708C6A57E28AEE4A5489713EC687F43138867725AA84FA181C837D0C8E810100008000000000010000007D0C8E01FA181C037725AA04F4313806713EC607EE4A54096A57E20AE763700C6470FE0DE17C8C0F5E891A11DB95A81258A23614D4AEC41551BB5217CEC7E0184BD46E1AC8E0FC1B45ED8A1DC2F9181F3E06A720BB123522381FC323B52B51253238DF26AF446D282C51FB29A85D892B256A172DA276A52E1F8333309C8FC131199C4F3396A8DD3412B56B368FC1F9370CCE873989DA153B06E7A33C83F3313E0000C03F7C0C4E41F918DC4276256A44F331F845703E8647ED4A14496957A24AE663304C6370BE4DE07C4C4F5D89DA50DA95685257A2F653D3AE845550BB1257CDC7A0584AD42E5AC7E0BC5B44ED4A5DC1F9D85E3D066760BA12F561371F8363B42B116531389F66AE442D682B51BB69A75D496B246AD76CA176656E1E83F36F9B8F8171189C0F7395A89D7411B52B768EC1B9770BCE477988DAD57A05E7637CFEFF7F7FFFFF7F7F0000807F"> : tensor<169xf32> + return %0 : tensor<169xf32> + } + func.func private @expected() -> tensor<169xf32> { + %0 = stablehlo.constant dense<"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B15C2B363C7C643ECA29573FD0ED7A3F516A7F3F07EF7F3F0CFE7F3FC5FF7F3FF9FF7F3FFFFF7F3F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0000803F0300803F1D00803FFA00803F7D08803F034B803F3696823F2E4B983FFF698F408938BF480000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F0000807F"> : tensor<169xf32> + return %0 : tensor<169xf32> + } + func.func public @main() { + %0 = call @samples() : () -> tensor<169xf32> + %1 = "stablehlo.exponential"(%0) : (tensor<169xf32>) -> tensor<169xf32> + %2 = call @expected() : () -> tensor<169xf32> + check.expect_close %1, %2, max_ulp_difference = 3 : tensor<169xf32>, tensor<169xf32> + func.return + } +} diff --git a/stablehlo/tests/math/exponential_float64.mlir b/stablehlo/tests/math/exponential_float64.mlir new file mode 100644 index 0000000000..156c6b707d --- /dev/null +++ b/stablehlo/tests/math/exponential_float64.mlir @@ -0,0 +1,19 @@ +// RUN: stablehlo-opt --stablehlo-complex-math-expander %s | stablehlo-translate --interpret +// This file is generated, see build_tools/math/README.md for more information. +module @exponential_float64 { + func.func private @samples() -> tensor<169xf64> { + %0 = stablehlo.constant dense<"0x000000000000F0FFFFFFFFFFFFFFEFFFFEFFFFFFFFFFEFFF2A51BB12B52BD1FCC0F9189C8FC141FB56A276256A57B2F9EC4AD4AE44ED22F882F331381F8393F6189C8FC1F91804F5AE44ED4AD4AE74F343ED4AD4AE44E5F1D995A85D89DA55F06F3E06E76370C6EE05E763703E0637ED9B8FC1F9189CA7EB31381F83F33118EAC7E07C0CCEC788E85D89DA95A85DF9E6F231381F83F369E588DA95A85D89DAE31E83F331381F4BE2B42B51BB12B5BBE04AD4AE44ED4A2CDFE07C0CCEC7E09CDD76256A57A2760DDC0CCEC7E07C0C7EDAA176256A57A2EED8371F83F331385FD7CDC7E07C0CCECFD563703E06E76340D4F9189C8FC1F9B0D28FC1F9189C8F21D1256A57A2762592CFBB12B52B51BB02CE50BB12B52B5173CCE663703E06E7E3CA7C0CCEC7E07C54C912B52B51BB12C5C7A85D89DA95A835C63E06E763703EA6C4D4AE44ED4AD416C36A57A276256A87C1000000000000F8BF95A85D89DA9568BE2B51BB12B52BD9BCC1F9189C8FC149BB57A276256A57BAB9ED4AD4AE44ED2AB883F331381F839BB6199C8FC1F9180CB5AF44ED4AD4AE7CB344ED4AD4AE44EDB1DA95A85D89DA5DB0703E06E76370CEAE06E763703E063FAD9C8FC1F9189CAFAB32381F83F33120AAC8E07C0CCEC790A85E89DA95A85D01A7F331381F83F371A589DA95A85D89E2A31F83F331381F53A2B52B51BB12B5C3A04BD4AE44ED4A349FE17C0CCEC7E0A49D77256A57A276159C0DCEC7E07C0C869AA276256A57A2F698381F83F331386797CEC7E07C0CCED79564703E06E7634894FA189C8FC1F9B89290C1F9189C8F2991266A57A276259A8FBC12B52B51BB0A8E51BB12B52B517B8CE763703E06E7EB8A7D0CCEC7E07C5C8913B52B51BB12CD87A95D89DA95A83D863F06E763703EAE84D5AE44ED4AD41E836B57A276256A8F810100000000000080000000000000000001000000000000006B57A276256A8F01D5AE44ED4AD41E033F06E763703EAE04A95D89DA95A83D0613B52B51BB12CD077D0CCEC7E07C5C09E763703E06E7EB0A51BB12B52B517B0CBC12B52B51BB0A0E266A57A276259A0F90C1F9189C8F2911FA189C8FC1F9B81264703E06E7634814CEC7E07C0CCED715381F83F331386717A276256A57A2F6180DCEC7E07C0C861A77256A57A276151CE17C0CCEC7E0A41D4BD4AE44ED4A341FB52B51BB12B5C3201F83F331381F532289DA95A85D89E223F331381F83F371255E89DA95A85D0127C8E07C0CCEC7902832381F83F331202A9C8FC1F9189CAF2B06E763703E063F2D703E06E76370CE2EDA95A85D89DA5D3044ED4AD4AE44ED31AF44ED4AD4AE7C33199C8FC1F9180C3583F331381F839B36ED4AD4AE44ED2A3857A276256A57BA39C1F9189C8FC1493B2B51BB12B52BD93C95A85D89DA95683E000000000000F83F6A57A276256A8741D4AE44ED4AD416433E06E763703EA644A85D89DA95A8354612B52B51BB12C5477C0CCEC7E07C5449E663703E06E7E34A50BB12B52B51734CBB12B52B51BB024E256A57A27625924F8FC1F9189C8F2151F9189C8FC1F9B05263703E06E7634054CDC7E07C0CCECF55371F83F331385F57A176256A57A2EE580CCEC7E07C0C7E5A76256A57A2760D5CE07C0CCEC7E09C5D4AD4AE44ED4A2C5FB42B51BB12B5BB601E83F331381F4B6288DA95A85D89DA63F231381F83F369655D89DA95A85DF966C7E07C0CCEC7886831381F83F331186A9B8FC1F9189CA76B05E763703E06376D6F3E06E76370C66ED995A85D89DA557043ED4AD4AE44E571AE44ED4AD4AE7473189C8FC1F918047582F331381F839376EC4AD4AE44ED227856A276256A57B279C0F9189C8FC1417B2A51BB12B52BD17CFEFFFFFFFFFFEF7FFFFFFFFFFFFFEF7F000000000000F07F"> : tensor<169xf64> + return %0 : tensor<169xf64> + } + func.func private @expected() -> tensor<169xf64> { + %0 = stablehlo.constant dense<"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D5C4B72878FCC3F80256AE7FFFFEF3FF3FFFFFFFFFFEF3F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F000000000000F03F060000000000F03F49ED4A0C0000F03F41C54FE63FED1140000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F"> : tensor<169xf64> + return %0 : tensor<169xf64> + } + func.func public @main() { + %0 = call @samples() : () -> tensor<169xf64> + %1 = "stablehlo.exponential"(%0) : (tensor<169xf64>) -> tensor<169xf64> + %2 = call @expected() : () -> tensor<169xf64> + check.expect_close %1, %2, max_ulp_difference = 3 : tensor<169xf64>, tensor<169xf64> + func.return + } +} diff --git a/stablehlo/transforms/StablehloComplexMathExpanderPatterns.td b/stablehlo/transforms/StablehloComplexMathExpanderPatterns.td index 22e5dd4105..0ab485d5f5 100644 --- a/stablehlo/transforms/StablehloComplexMathExpanderPatterns.td +++ b/stablehlo/transforms/StablehloComplexMathExpanderPatterns.td @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ // -// This file is generated using functional_algorithms tool (0.14.1.dev0+ge22be68.d20241231). +// This file is generated using functional_algorithms tool (0.15.0). // See build_tools/math/README.md for more information. include "mlir/IR/OpBase.td" @@ -654,3 +654,66 @@ def LogOp_ComplexElementType_ComplexMathExpander: Pat<(StableHLO_LogOp ComplexEl (StableHLO_DivOp $mn, $mx)), $mn_over_mx))))), (StableHLO_Atan2Op $y, $x))>; + +// Exponential on complex inputs: +// +// exp(z) = exp(x) * (cos(y) + I * sin(y)) +// +// where z = x + I * y. +// +// Algorithm +// --------- +// +// While the above expression is accurate for a large part of the +// complex plane, there is two cases that require special attention. +// +// First, when `y == 0`, we'll define +// +// imag(exp(z)) = 0 +// +// that otherwise for overflowing `exp(x)` would evaluate to nan. +// +// Second, the overflow case `exp(x) -> inf` is compensated when `y` +// is close to the zeros of `cos(y)` or `sin(y)` and the real or +// imaginary parts of `exp(z)` ought to be finite. Therefore, for the +// `exp(x) -> inf` case, we'll use +// +// exp(z) = exp(x / 2) * (cos(y) + I * sin(y)) * exp(x / 2) +// +// Notice that for `y != 0`, neither `cos(y)` nor `sin(y)` is never +// zero on the set of floating point numbers. +// +def ExpOp_ComplexElementType_ComplexMathExpander: Pat<(StableHLO_ExpOp ComplexElementType:$z), + (StableHLO_ComplexOp + (StableHLO_SelectOp + (StableHLO_CompareOp:$eq_e_constant_posinf + (StableHLO_ExpOp:$e + (StableHLO_RealOp:$x $z)), + (StableHLO_ConstantLikePosInfValue $x), + StableHLO_ComparisonDirectionValue<"EQ">, + (STABLEHLO_DEFAULT_COMPARISON_TYPE)), + (StableHLO_MulOp + (StableHLO_MulOp + (StableHLO_ExpOp:$e2 + (StableHLO_MulOp + $x, + (StableHLO_ConstantLike<"0.5"> $x))), + (StableHLO_CosineOp:$cs + (StableHLO_ImagOp:$y $z))), + $e2), + (StableHLO_MulOp $e, $cs)), + (StableHLO_SelectOp + (StableHLO_CompareOp + $y, + (StableHLO_ConstantLike<"0">:$zero $x), + StableHLO_ComparisonDirectionValue<"EQ">, + (STABLEHLO_DEFAULT_COMPARISON_TYPE)), + $zero, + (StableHLO_SelectOp + $eq_e_constant_posinf, + (StableHLO_MulOp + (StableHLO_MulOp + $e2, + (StableHLO_SineOp:$sn $y)), + $e2), + (StableHLO_MulOp $e, $sn))))>;