// Copyright Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT /** * */ #pragma once #include #include #include #include #include #include #include #include namespace rocRoller { namespace Operations { struct E_Unary { explicit E_Unary(OperationTag a); E_Unary(const std::initializer_list&); std::string toString() const; OperationTag getTag() const; void setTag(OperationTag tag); std::unordered_set getOutputs() const; std::unordered_set getInputs() const; virtual std::string name() const { return ""; } OperationTag dest; OperationTag a; auto operator<=>(E_Unary const&) const = default; }; // Macro for declaring a new Unary XOp #define MAKE_UNARY_XOP(FUNC) \ struct FUNC : public E_Unary \ { \ explicit FUNC(OperationTag a) \ : E_Unary(a) \ { \ } \ FUNC(const std::initializer_list& args) \ : E_Unary(args) \ { \ } \ std::string name() const override \ { \ return #FUNC; \ } \ }; MAKE_UNARY_XOP(E_Neg) MAKE_UNARY_XOP(E_Abs) MAKE_UNARY_XOP(E_Not) MAKE_UNARY_XOP(E_RandomNumber) struct E_Cvt : public E_Unary { E_Cvt(OperationTag a, rocRoller::DataType destType) : E_Unary(a) , destType(destType) { } E_Cvt(const std::initializer_list& args, rocRoller::DataType destType) : E_Unary(args) , destType(destType) { } std::string name() const override { return "E_Cvt"; } rocRoller::DataType destType; }; struct E_Binary { E_Binary(OperationTag a, OperationTag b); E_Binary(const std::initializer_list&); std::string toString() const; OperationTag getTag() const; void setTag(OperationTag tag); std::unordered_set getOutputs() const; std::unordered_set getInputs() const; virtual std::string name() const { return ""; } OperationTag dest; OperationTag a; OperationTag b; auto operator<=>(E_Binary const&) const = default; }; // Macro for defining a new binary XOp #define MAKE_BINARY_XOP(FUNC) \ struct FUNC : public E_Binary \ { \ FUNC(OperationTag a, OperationTag b) \ : E_Binary(a, b) \ { \ } \ FUNC(const std::initializer_list& args) \ : E_Binary(args) \ { \ } \ std::string name() const override \ { \ return #FUNC; \ } \ }; struct E_StochasticRoundingCvt : public E_Binary { E_StochasticRoundingCvt(OperationTag data, OperationTag seed, rocRoller::DataType destType) : E_Binary(data, seed) , destType(destType) { } E_StochasticRoundingCvt(const std::initializer_list& args, rocRoller::DataType destType) : E_Binary(args) , destType(destType) { } std::string name() const override { return "E_StochasticRoundingCvt"; } rocRoller::DataType destType; }; MAKE_BINARY_XOP(E_Add) MAKE_BINARY_XOP(E_Sub) MAKE_BINARY_XOP(E_Mul) MAKE_BINARY_XOP(E_Div) MAKE_BINARY_XOP(E_And) MAKE_BINARY_XOP(E_Or) MAKE_BINARY_XOP(E_GreaterThan) struct E_Ternary { E_Ternary(OperationTag a, OperationTag b, OperationTag c); E_Ternary(const std::initializer_list&); std::string toString() const; OperationTag getTag() const; void setTag(OperationTag tag); std::unordered_set getOutputs() const; std::unordered_set getInputs() const; virtual std::string name() const { return ""; } OperationTag dest; OperationTag a; OperationTag b; OperationTag c; auto operator<=>(E_Ternary const&) const = default; }; // Macro for defining a new ternary XOp #define MAKE_TERNARY_XOP(FUNC) \ struct FUNC : public E_Ternary \ { \ FUNC(OperationTag a, OperationTag b, OperationTag c) \ : E_Ternary(a, b, c) \ { \ } \ FUNC(const std::initializer_list& args) \ : E_Ternary(args) \ { \ } \ std::string name() const override \ { \ return #FUNC; \ } \ }; MAKE_TERNARY_XOP(E_Conditional) class T_Execute : public BaseOperation { public: T_Execute() = delete; explicit T_Execute(OperationTag starting_tag); std::unordered_set getInputs() const; std::unordered_set getOutputs() const; OperationTag addXOp(std::shared_ptr); template OperationTag addXOp(T&& op); OperationTag getNextTag() const; std::string toString() const; std::vector> getXOps() const { return m_xops; } bool operator==(T_Execute const&) const; private: template friend struct rocRoller::Serialization::MappingTraits; std::vector> m_xops; std::unordered_set m_inputs; std::unordered_set m_outputs; OperationTag m_nextTag; }; template concept CUnaryXOp = requires() { requires std::derived_from; }; template concept CBinaryXOp = requires() { requires std::derived_from; }; template concept CTernaryXOp = requires() { requires std::derived_from; }; } } #include