// Copyright (c) 2023 CINN Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include "paddle/cinn/adt/adapter_dynamic_tensor.h" #include "paddle/cinn/adt/adapter_tensor.h" #include "paddle/cinn/adt/adt.h" #include "paddle/cinn/adt/arithmetic.h" #include "paddle/cinn/adt/equation_value.h" #include "paddle/cinn/adt/logical.h" #include "paddle/cinn/adt/schedule_descriptor.h" #include "paddle/cinn/adt/schedule_mesh.h" #include "paddle/cinn/adt/tags.h" #include "paddle/cinn/adt/tree.h" namespace pir { class Operation; } namespace cinn { namespace adt { // Offset = Int64 using Offset = std::int64_t; class GlobalMemoryType final { public: bool operator==(const GlobalMemoryType& global_memory_type) const { return this == &global_memory_type; } }; inline std::size_t GetHashValueImpl(const GlobalMemoryType&) { static GlobalMemoryType global_memory_type; return reinterpret_cast(&global_memory_type); } class SharedMemoryType final { public: bool operator==(const SharedMemoryType& shared_memory_type) const { return this == &shared_memory_type; } }; inline std::size_t GetHashValueImpl(const SharedMemoryType&) { static SharedMemoryType shared_memory_type; return reinterpret_cast(&shared_memory_type); } // MemoryType = GlobalMemoryType | SharedMemoryType DEFINE_ADT_UNION(MemoryType, GlobalMemoryType, SharedMemoryType); OVERLOAD_OPERATOR_EQ_NE(MemoryType, UnionEqual); OVERRIDE_UNION_GET_HASH_VALUE(MemoryType); // TempStorage = (Name, Offset, MemoryType) class TempStorage final : public Tuple { public: using Tuple::Tuple; }; OVERLOAD_OPERATOR_EQ_NE(TempStorage, TupleEqual); inline std::size_t GetHashValueImpl(const TempStorage& temp_storage) { const auto& [var_name, offset, memory_type] = temp_storage.tuple(); std::size_t hash_value = std::hash()(var_name); hash_value = hash_combine(hash_value, offset); hash_value = hash_combine(hash_value, GetHashValue(memory_type)); return hash_value; } // Tensor = adapter::Tensor | adapter::DynamicTensor | TempStorage DEFINE_ADT_UNION(Tensor, adapter::Tensor, adapter::DynamicTensor, TempStorage); OVERRIDE_UNION_GET_HASH_VALUE(Tensor); OVERLOAD_OPERATOR_EQ_NE(Tensor, UnionEqual); // Op = const pir::Operation* // | tReduceInit // | tReduceAcc DEFINE_ADT_UNION(Op, const ::pir::Operation*, tReduceInit, tReduceAcc); using Arg = Tensor; // OpStmt = (Op, In [Arg], Out [Arg]) class OpStmt final : public Tuple>, tOut>> { public: using Tuple>, tOut>>::Tuple; bool operator==(const OpStmt& other) const { return &this->tuple() == &other.tuple(); } }; inline std::size_t GetHashValue(const OpStmt& op_stmt_node) { return reinterpret_cast(&op_stmt_node.tuple()); } using LoopIterators = List; // MapStmt T = ([Iterator], [T]) template class MapStmt final : public Tuple> { public: using value_type = LoopIterators; using Tuple>::Tuple; }; // Stmt = OpStmt | MapStmt Stmt using Stmt = Tree; template class Store final : public Tuple { public: using Tuple::Tuple; }; template class Load final : public Tuple { public: using Tuple::Tuple; }; // OpCall T = (Op, [T]) template class OpCall final : public Tuple> { public: using Tuple>::Tuple; }; // OpExpr = Tree OpCall (Load Tensor) using OpExpr = Tree>; // OpExprStmt = Store Tensor OpExpr using OpExprStmt = Store; using InlineStmt = Tree; using TensorIndexExpr = Value; using TensorIndexExpr4TensorT = std::function; using TensorIteratorExpr = Value; using TensorIteratorExpr4TensorT = std::function(const Tensor&)>; using LoopDescriptor4LoopIteratorT = std::function; // AnchoredMapStmt = (MapStmt Stmt, ScheduleMesh, tAnchor Tensor, // TensorIndexExpr4TensorT, TensorIteratorExpr4TensorT, // LoopDescriptor4LoopIteratorT) class AnchoredMapStmt final : public Tuple, ScheduleMesh, tAnchor, TensorIndexExpr4TensorT, TensorIteratorExpr4TensorT, LoopDescriptor4LoopIteratorT> { public: using Tuple, ScheduleMesh, tAnchor, TensorIndexExpr4TensorT, TensorIteratorExpr4TensorT, LoopDescriptor4LoopIteratorT>::Tuple; TensorIndexExpr GetTensorIndexExpr(const Tensor& tensor) const { const auto& TensorIndexExpr4Tensor = std::get<3>(tuple()); return TensorIndexExpr4Tensor(tensor); } }; DEFINE_ADT_UNION(GenericDim, SymbolicDim, std::int64_t); using KernelCondition = Logical>; template class ConditionalAnchoredMapStmt : public Tuple, tTrue, tFalse> { public: using Tuple, tTrue, tFalse>::Tuple; }; using KernelBody = Tree; // Kernel = (KernelBody, In [Tensor], Out [Tensor]) class Kernel final : public Tuple, tIn>, tOut>> { public: using Tuple, tIn>, tOut>>:: Tuple; }; // MapExpr = Kernel; using MapExpr = Kernel; } // namespace adt } // namespace cinn namespace std { template <> struct hash { std::size_t operator()(const cinn::adt::Tensor& tensor) const { return cinn::adt::GetHashValue(tensor); } }; template <> struct hash { std::size_t operator()(const cinn::adt::OpStmt& op_stmt_node) const { return cinn::adt::GetHashValue(op_stmt_node); } }; } // namespace std