diff --git a/include/fused_kernel/core/execution_model/operation_model/batch_operations.h b/include/fused_kernel/core/execution_model/operation_model/batch_operations.h index e6ff8cb8..6dd25ffa 100644 --- a/include/fused_kernel/core/execution_model/operation_model/batch_operations.h +++ b/include/fused_kernel/core/execution_model/operation_model/batch_operations.h @@ -116,7 +116,7 @@ namespace fk { using OutputArrayType = std::array, IOpType::Operation::BATCH>; OutputArrayType resultingArray{}; for (int i = 0; i < IOpType::Operation::BATCH; i++) { - if constexpr (IOpType::template is) { + if constexpr (IOpType::template is || IOpType::template is) { resultingArray[i] = Operation::build(std::forward(batchIOp).params.opData[i]); } else { static_assert(IOpType::template is, "IOpType must be ReadType or WriteType"); @@ -162,25 +162,20 @@ namespace fk { Implements build(const ParamsType& params) */ template + requires(isCompleteOperation) struct BatchRead { - static_assert(isCompleteOperation, - "The IOp passed as template parameter is not a complete operation"); + using Operation = Op; + static constexpr size_t BATCH = BATCH_; + static constexpr PlanePolicy PP = PlanePolicy::PROCESS_ALL; private: using SelfType = BatchRead; + using Parent = ReadOperation, typename Op::OutputType, + static_cast(Operation::THREAD_FUSION), SelfType, + Operation::IS_FUSED_OP>; public: FK_STATIC_STRUCT(BatchRead, SelfType) - using Operation = Op; - static constexpr size_t BATCH = BATCH_; - static constexpr PlanePolicy PP = PlanePolicy::PROCESS_ALL; - - using ParamsType = BatchReadParams; - using ReadDataType = typename Operation::ReadDataType; - using InstanceType = ReadType; - using OutputType = typename Operation::OutputType; - using OperationDataType = OperationData; - using InstantiableType = Read; - static constexpr bool IS_FUSED_OP = Operation::IS_FUSED_OP; - static constexpr bool THREAD_FUSION = Operation::THREAD_FUSION; + DECLARE_READ_PARENT_BASIC FK_HOST_DEVICE_FUSE uint num_elems_x(const Point thread, const OperationDataType& opData) { return Operation::num_elems_x(thread, opData.params.opData[thread.z]); @@ -198,10 +193,6 @@ namespace fk { return opData.params.activeThreads; } - template - FK_HOST_DEVICE_FUSE auto exec(const Point thread, const OperationDataType& opData) { - return exec(thread, opData.params); - } template FK_HOST_DEVICE_FUSE auto exec(const Point thread, const ParamsType& params) { if constexpr (THREAD_FUSION) { @@ -210,34 +201,23 @@ namespace fk { return Operation::exec(thread, params.opData[thread.z]); } } - FK_HOST_FUSE InstantiableType build(const OperationDataType& opData) { - return InstantiableType{ opData }; - } - FK_HOST_FUSE InstantiableType build(const ParamsType& params) { - return InstantiableType{ {params} }; - } }; template + requires(isCompleteOperation) struct BatchRead { - static_assert(isCompleteOperation, - "The IOp passed as template parameter is not a complete operation"); - private: - using SelfType = BatchRead; - public: - FK_STATIC_STRUCT(BatchRead, SelfType) using Operation = Op; static constexpr size_t BATCH = BATCH_; static constexpr PlanePolicy PP = PlanePolicy::CONDITIONAL_WITH_DEFAULT; - - using ParamsType = BatchReadParams; - using ReadDataType = typename Operation::ReadDataType; - using InstanceType = ReadType; - using OutputType = typename Operation::OutputType; - using OperationDataType = OperationData; - using InstantiableType = Read; - static constexpr bool IS_FUSED_OP = Operation::IS_FUSED_OP; - static constexpr bool THREAD_FUSION = false; + private: + using SelfType = BatchRead; + using Parent = ReadOperation, + typename Op::OutputType, + static_cast(Operation::THREAD_FUSION), SelfType, false>; + public: + FK_STATIC_STRUCT(BatchRead, SelfType) + DECLARE_READ_PARENT_BASIC FK_HOST_DEVICE_FUSE uint num_elems_x(const Point thread, const OperationDataType& opData) { return Operation::num_elems_x(thread, opData.params.opData[thread.z]); @@ -254,11 +234,6 @@ namespace fk { FK_HOST_DEVICE_FUSE ActiveThreads getActiveThreads(const OperationDataType& opData) { return opData.params.activeThreads; } - - template - FK_HOST_DEVICE_FUSE auto exec(const Point thread, const OperationDataType& opData) { - return exec(thread, opData.params); - } template FK_HOST_DEVICE_FUSE auto exec(const Point thread, const ParamsType& params) { if (params.usedPlanes <= thread.z) { @@ -271,13 +246,6 @@ namespace fk { } } } - - FK_HOST_FUSE InstantiableType build(const OperationDataType& opData) { - return InstantiableType{ opData }; - } - FK_HOST_FUSE InstantiableType build(const ParamsType& params) { - return InstantiableType{ {params} }; - } }; /* @@ -286,23 +254,19 @@ namespace fk { ParamsType = BatchReadParams */ template + requires(isIncompleteReadBackOperation) struct BatchRead> { - private: - using SelfType = BatchRead>; - public: - FK_STATIC_STRUCT(BatchRead, SelfType) using Operation = Op; static constexpr size_t BATCH = BATCH_; static constexpr PlanePolicy PP = PlanePolicy::PROCESS_ALL; - - using ParamsType = BatchReadParams; - using ReadDataType = typename Operation::ReadDataType; - using InstanceType = ReadType; - using OutputType = typename Operation::OutputType; - using OperationDataType = OperationData; - using InstantiableType = Read; - static constexpr bool IS_FUSED_OP = Operation::IS_FUSED_OP; - static constexpr bool THREAD_FUSION = Operation::THREAD_FUSION; + private: + using SelfType = BatchRead>; + using Parent = IncompleteReadBackOperation, NullType, + typename Operation::OutputType, SelfType>; + public: + FK_STATIC_STRUCT(BatchRead, SelfType) + DECLARE_INCOMPLETEREADBACK_PARENT_BASIC FK_HOST_DEVICE_FUSE uint num_elems_x(const Point thread, const OperationDataType& opData) { return Operation::num_elems_x(thread, opData.params.opData[thread.z]); @@ -319,13 +283,6 @@ namespace fk { FK_HOST_DEVICE_FUSE ActiveThreads getActiveThreads(const OperationDataType& opData) { return opData.params.activeThreads; } - - FK_HOST_FUSE InstantiableType build(const OperationDataType& opData) { - return InstantiableType{ opData }; - } - FK_HOST_FUSE InstantiableType build(const ParamsType& params) { - return InstantiableType{ {params} }; - } }; /* @@ -334,23 +291,19 @@ namespace fk { ParamsType = BatchReadParams */ template + requires(isIncompleteReadBackOperation) struct BatchRead> { - private: - using SelfType = BatchRead>; - public: - FK_STATIC_STRUCT(BatchRead, SelfType) using Operation = Op; static constexpr size_t BATCH = BATCH_; static constexpr PlanePolicy PP = PlanePolicy::CONDITIONAL_WITH_DEFAULT; - - using ParamsType = BatchReadParams; - using ReadDataType = typename Operation::ReadDataType; - using InstanceType = ReadType; - using OutputType = typename Operation::OutputType; - using OperationDataType = OperationData; - using InstantiableType = Read; - static constexpr bool IS_FUSED_OP = Operation::IS_FUSED_OP; - static constexpr bool THREAD_FUSION = false; + private: + using SelfType = BatchRead>; + using Parent = IncompleteReadBackOperation, NullType, + typename Operation::OutputType, SelfType>; + public: + FK_STATIC_STRUCT(BatchRead, SelfType) + DECLARE_INCOMPLETEREADBACK_PARENT_BASIC FK_HOST_DEVICE_FUSE uint num_elems_x(const Point thread, const OperationDataType& opData) { return Operation::num_elems_x(thread, opData.params.opData[thread.z]); @@ -367,13 +320,6 @@ namespace fk { FK_HOST_DEVICE_FUSE ActiveThreads getActiveThreads(const OperationDataType& opData) { return opData.params.activeThreads; } - - FK_HOST_FUSE InstantiableType build(const OperationDataType& opData) { - return InstantiableType{ opData }; - } - FK_HOST_FUSE InstantiableType build(const ParamsType& params) { - return InstantiableType{ {params} }; - } }; /* @@ -420,7 +366,11 @@ namespace fk { paramsStore.opData[i] = iOps[i]; } - return BatchReadType::build(paramsStore); + if constexpr (isCompleteOperation) { + return BatchReadType::build(paramsStore); + } else { + return BatchReadType::build(paramsStore, typename BatchReadType::BackIOp{}); + } } }; @@ -453,7 +403,11 @@ namespace fk { paramsStore.opData[i] = iOps[i]; } - return BatchReadType::build(paramsStore); + if constexpr (isCompleteOperation) { + return BatchReadType::build(paramsStore); + } else { + return BatchReadType::build(paramsStore, typename BatchReadType::BackIOp{}); + } } }; // ##################### END BATCH_READ ##################### diff --git a/include/fused_kernel/core/execution_model/operation_model/operation_data.h b/include/fused_kernel/core/execution_model/operation_model/operation_data.h index 8a397b3d..f105f672 100644 --- a/include/fused_kernel/core/execution_model/operation_model/operation_data.h +++ b/include/fused_kernel/core/execution_model/operation_model/operation_data.h @@ -75,24 +75,53 @@ namespace fk { constexpr bool hasParamsArray = hasParams_v && std::is_array_v; + template + constexpr bool hasParamsAndBackIOpNoArray = + hasParamsAndBackIOp_v && !std::is_array_v && + !std::is_array_v; + + template + constexpr bool hasParamsAndBackIOpArray = + hasParamsAndBackIOp_v && std::is_array_v && + std::is_array_v; + // OperationData implementations - template + template struct OperationData; using ParamsTypes = TypeList; using ParamsAndBackIOpTypes = TypeList; template - struct OperationData>> { + requires (one_of_v) + struct OperationData { FK_HOST_DEVICE_CNST OperationData() {}; - FK_HOST_DEVICE_CNST OperationData(const typename Operation::ParamsType ¶ms_) : params(params_) {} + FK_HOST_DEVICE_CNST OperationData(const typename Operation::ParamsType ¶ms_) + requires(hasParamsNoArray) : params(params_) {} + FK_HOST_DEVICE_CNST OperationData(const typename Operation::ParamsType& params_) + requires(hasParamsArray) : params{} { + for (size_t i = 0; i < std::extent_v; ++i) { + params[i] = params_[i]; + } + } typename Operation::ParamsType params{}; }; template - struct OperationData>> { + requires (one_of_v) + struct OperationData { FK_HOST_DEVICE_CNST OperationData() {}; - FK_HOST_DEVICE_CNST OperationData(const typename Operation::ParamsType& params_, const typename Operation::BackIOp& backIOp_) : params(params_), backIOp(backIOp_) {} + FK_HOST_DEVICE_CNST OperationData(const typename Operation::ParamsType& params_, const typename Operation::BackIOp& backIOp_) + requires (hasParamsAndBackIOpNoArray) : params(params_), backIOp(backIOp_) {} + FK_HOST_DEVICE_CNST OperationData(const typename Operation::ParamsType& params_, const typename Operation::BackIOp& backIOp_) + requires (hasParamsAndBackIOpArray) : params{}, backIOp{} { + for (size_t i = 0; i < std::extent_v; ++i) { + params[i] = params_[i]; + } + for (size_t i = 0; i < std::extent_v; ++i) { + backIOp[i] = backIOp_[i]; + } + } typename Operation::ParamsType params{}; typename Operation::BackIOp backIOp{}; }; diff --git a/include/fused_kernel/core/execution_model/operation_model/operation_types.h b/include/fused_kernel/core/execution_model/operation_model/operation_types.h index 89648ec6..de725191 100644 --- a/include/fused_kernel/core/execution_model/operation_model/operation_types.h +++ b/include/fused_kernel/core/execution_model/operation_model/operation_types.h @@ -170,6 +170,9 @@ namespace fk { template constexpr bool isCompleteOperation = IsCompleteOperation::value; + template + constexpr bool isIncompleteReadBackOperation = opIs; + template struct is_fused_operation_ : std::false_type {};