// Copyright © Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace hipdnn_frontend::detail { /// Queries the operation type directly via HIPDNN_ATTR_OPERATION_TYPE_EXT. /// Returns an error on failure — no fallback probing. [[nodiscard]] inline std::pair queryOperationType(hipdnnBackendDescriptor_t opDesc) { hipdnnOperationType_ext_t typeValue = HIPDNN_OPERATION_TYPE_NOT_SET_EXT; int64_t actualCount = 0; auto status = hipdnnBackend()->backendGetAttribute(opDesc, HIPDNN_ATTR_OPERATION_TYPE_EXT, HIPDNN_TYPE_OPERATION_TYPE_EXT, 1, &actualCount, &typeValue); if(status != HIPDNN_STATUS_SUCCESS) { std::array backendErrMsg{}; hipdnnBackend()->getLastErrorString(backendErrMsg.data(), backendErrMsg.size()); return {HIPDNN_OPERATION_TYPE_NOT_SET_EXT, {ErrorCode::HIPDNN_BACKEND_ERROR, std::string("Failed to query HIPDNN_ATTR_OPERATION_TYPE_EXT. Backend error: ") + backendErrMsg.data()}}; } return {typeValue, {}}; } /// Creates a frontend node of the appropriate type for the given backend operation type. /// /// @param opType The backend operation type from HIPDNN_ATTR_OPERATION_TYPE_EXT /// @param graphAttrs Graph-level attributes to associate with the created node /// @return A shared_ptr to the created INode, or an error if the type is unsupported [[nodiscard]] inline std::pair, Error> createNodeForType(hipdnnOperationType_ext_t opType, const graph::GraphAttributes& graphAttrs) { switch(opType) { case HIPDNN_OPERATION_TYPE_BATCHNORM_EXT: return {std::make_shared(graph::BatchnormAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_BATCHNORM_BACKWARD_EXT: return {std::make_shared(graph::BatchnormBackwardAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_BATCHNORM_INFERENCE_EXT: return {std::make_shared( graph::BatchnormInferenceAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_BATCHNORM_INFERENCE_VARIANCE_EXT: return {std::make_shared( graph::BatchnormInferenceAttributesVarianceExt{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_BLOCK_SCALE_DEQUANTIZE_EXT: return {std::make_shared( graph::BlockScaleDequantizeAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_BLOCK_SCALE_QUANTIZE_EXT: return {std::make_shared( graph::BlockScaleQuantizeAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_CONVOLUTION_BACKWARD_DATA_EXT: return { std::make_shared(graph::ConvDgradAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_CONVOLUTION_BACKWARD_WEIGHTS_EXT: return { std::make_shared(graph::ConvWgradAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_CONVOLUTION_FORWARD_EXT: return { std::make_shared(graph::ConvFpropAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_CUSTOM_OP_EXT: return {std::make_shared(graph::CustomOpAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_LAYERNORM_EXT: return {std::make_shared(graph::LayernormAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_MATMUL_EXT: return {std::make_shared(graph::MatmulAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_POINTWISE_EXT: return {std::make_shared(graph::PointwiseAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_REDUCTION_EXT: return {std::make_shared(graph::ReductionAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_RMSNORM_EXT: return {std::make_shared(graph::RMSNormAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_RMSNORM_BACKWARD_EXT: return {std::make_shared(graph::RMSNormBackwardAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_SDPA_BACKWARD_EXT: return {std::make_shared(graph::SdpaBackwardAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_SDPA_FORWARD_EXT: return {std::make_shared(graph::SdpaAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_RESAMPLE_FWD: return { std::make_shared(graph::ResampleFwdAttributes{}, graphAttrs), {}}; case HIPDNN_OPERATION_TYPE_LAYERNORM_BACKWARD_EXT: return {std::make_shared(graph::LayernormBackwardAttributes{}, graphAttrs), {}}; default: return {nullptr, {ErrorCode::HIPDNN_BACKEND_ERROR, "Unsupported operation type for graph lifting (type id: " + std::to_string(static_cast(opType)) + ")"}}; } } /// Unpacks a backend operation descriptor and returns a frontend node. /// /// Uses a two-phase approach: /// 1. Query the operation type via HIPDNN_ATTR_OPERATION_TYPE_EXT /// 2. Create the correct node type and unpack via virtual dispatch /// /// Errors are fail-fast: any failure during type query or unpacking returns /// immediately with a clear error message. /// /// @param opDesc The backend operation descriptor to unpack /// @param tensorMap A map from tensor UID to TensorAttributes for sharing tensors across operations /// @param graphAttrs Graph-level attributes to associate with the created node /// @return A shared_ptr to the created INode, or an error if unpacking fails [[nodiscard]] inline std::pair, Error> unpackOperation( hipdnnBackendDescriptor_t opDesc, std::unordered_map>& tensorMap, const graph::GraphAttributes& graphAttrs) { auto [opType, typeErr] = queryOperationType(opDesc); if(typeErr.is_bad()) { return {nullptr, {typeErr.code, std::string("Failed to determine operation type: ") + typeErr.get_message()}}; } auto [node, nodeErr] = createNodeForType(opType, graphAttrs); if(nodeErr.is_bad()) { return {nullptr, nodeErr}; } auto err = node->unpack_from_descriptor(opDesc, tensorMap); if(err.is_bad()) { return {nullptr, err}; } return {node, {}}; } } // namespace hipdnn_frontend::detail