已关闭
完成第二部分修改,提交代码 #10842
chen-wei43创建于 5 天前关闭于 5 天前
完成第二部分修改,提交代码 #10842
已关闭
共 28 个文件变更+1585-897
| @@ -1017,6 +1017,73 @@ static int64_t GetPergroupSize(const gmm::GroupedMatmulParams &gmmParams, size_t | |||
| 1017 | return pergroupSize; | 1017 | return pergroupSize; |
| 1018 | } | 1018 | } |
| 1019 | 1019 | ||
| 1020 | +static aclnnStatus CheckAntiQuantPergroupSize(const gmm::GroupedMatmulParams &gmmParams, const char *opName, | ||
| 1021 | + const char *scenario) | ||
| 1022 | +{ | ||
| 1023 | + // check perGroupNum | ||
| 1024 | + auto antiquantScale0Shape = (*gmmParams.antiquantScaleOptional)[0]->GetViewShape(); | ||
| 1025 | + size_t antiquantScale0DimNum = antiquantScale0Shape.GetDimNum(); | ||
| 1026 | + auto w0Shape = (*gmmParams.weight)[0]->GetViewShape(); | ||
| 1027 | + size_t w0DimNum = w0Shape.GetDimNum(); | ||
| 1028 | + int64_t pergroupSize = GetPergroupSize(gmmParams, w0DimNum, w0Shape, antiquantScale0Shape); | ||
| 1029 | + CHECK_COND(!gmmParams.transposeWeight || pergroupSize % 2 == 0, ACLNN_ERR_PARAM_INVALID, // 2: a factor | ||
| 1030 | + "In op [%s], when A16W4 per-group antiquant and weight is transposed, [%s] is not supported, got " | ||
| 1031 | + "[%ld]. Constraint:[pergroup size should be even].", | ||
| 1032 | + opName, "pergroupSize", pergroupSize); | ||
| 1033 | + for (size_t i = 0; i < gmmParams.antiquantScaleOptional->Size(); ++i) { | ||
| 1034 | + auto antiquantScaleShape = (*gmmParams.antiquantScaleOptional)[i]->GetViewShape(); | ||
| 1035 | + size_t antiquantScaleDimNum = antiquantScaleShape.GetDimNum(); | ||
| 1036 | + CHECK_COND( | ||
| 1037 | + antiquantScaleDimNum == antiquantScale0DimNum, ACLNN_ERR_PARAM_INVALID, | ||
| 1038 | + "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantScale[%zu] dim " | ||
| 1039 | + "num %zu should equal antiquantScale[0] dim num %zu when %s].", | ||
| 1040 | + opName, "antiquantScale", i, antiquantScaleDimNum, antiquantScale0DimNum, scenario); | ||
| 1041 | + auto wShape = (*gmmParams.weight)[i]->GetViewShape(); | ||
| 1042 | + int64_t pergroupSizeOfScale = GetPergroupSize(gmmParams, w0DimNum, wShape, antiquantScaleShape); | ||
| 1043 | + CHECK_COND(pergroupSizeOfScale == pergroupSize, ACLNN_ERR_PARAM_INVALID, | ||
| 1044 | + "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantScale[%zu] " | ||
| 1045 | + "pergroup size %ld should be %ld when %s].", | ||
| 1046 | + opName, "antiquantScale, weight", i, pergroupSizeOfScale, pergroupSize, scenario); | ||
| 1047 | + if (gmmParams.antiquantOffsetOptional != nullptr) { | ||
| 1048 | + auto antiquantOffsetShape = (*gmmParams.antiquantOffsetOptional)[i]->GetViewShape(); | ||
| 1049 | + size_t antiquantOffsetDimNum = antiquantOffsetShape.GetDimNum(); | ||
| 1050 | + CHECK_COND( | ||
| 1051 | + antiquantScale0DimNum == antiquantOffsetDimNum, ACLNN_ERR_PARAM_INVALID, | ||
| 1052 | + "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantOffset[%zu] dim " | ||
| 1053 | + "num %zu should equal antiquantScale[0] dim num %zu when %s].", | ||
| 1054 | + opName, "antiquantOffset, antiquantScale", i, antiquantOffsetDimNum, antiquantScale0DimNum, | ||
| 1055 | + scenario); | ||
| 1056 | + int64_t pergroupSizeOfOffset = GetPergroupSize(gmmParams, w0DimNum, wShape, antiquantOffsetShape); | ||
| 1057 | + CHECK_COND( | ||
| 1058 | + pergroupSizeOfOffset == pergroupSize, ACLNN_ERR_PARAM_INVALID, | ||
| 1059 | + "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantOffset[%zu] " | ||
| 1060 | + "pergroup size %ld should be %ld when %s].", | ||
| 1061 | + opName, "antiquantOffset, weight", i, pergroupSizeOfOffset, pergroupSize, scenario); | ||
| 1062 | + } | ||
| 1063 | + } | ||
| 1064 | + return ACLNN_SUCCESS; | ||
| 1065 | +} | ||
| 1066 | + | ||
| 1067 | +static aclnnStatus CheckAntiQuantDtypeAndEmpty(const gmm::GroupedMatmulParams &gmmParams, const char *opName, | ||
| 1068 | + const char *scenario) | ||
| 1069 | +{ | ||
| 1070 | + CHECK_COND(CheckTensorListDataType(gmmParams.antiquantScaleOptional, gmmParams.xDtype) == ACLNN_SUCCESS, | ||
| 1071 | + ACLNN_ERR_PARAM_INVALID, | ||
| 1072 | + "In op [%s], the data type of [%s] is not supported. Constraint:[antiquantScale dtype should be %s " | ||
| 1073 | + "when %s].", | ||
| 1074 | + opName, "antiquantScale", gmm::dTypeToString(gmmParams.xDtype).c_str(), scenario); | ||
| 1075 | + if (gmmParams.antiquantOffsetOptional != nullptr) { | ||
| 1076 | + CHECK_COND(CheckTensorListDataType(gmmParams.antiquantOffsetOptional, gmmParams.xDtype) == ACLNN_SUCCESS, | ||
| 1077 | + ACLNN_ERR_PARAM_INVALID, | ||
| 1078 | + "In op [%s], the data type of [%s] is not supported. Constraint:[antiquantOffset dtype should be %s " | ||
| 1079 | + "when %s].", | ||
| 1080 | + opName, "antiquantOffset", gmm::dTypeToString(gmmParams.xDtype).c_str(), scenario); | ||
| 1081 | + } | ||
| 1082 | + CHECK_COND(IsGmmQuantEmpty(gmmParams) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, | ||
| 1083 | + "In op [%s], when %s, [%s] must be empty.", opName, scenario, "quant inputs"); | ||
| 1084 | + return ACLNN_SUCCESS; | ||
| 1085 | +} | ||
| 1086 | + | ||
| 1020 | static aclnnStatus CheckGroupedMatmulAntiQuant(const gmm::GroupedMatmulParams &gmmParams, const char *opName) | 1087 | static aclnnStatus CheckGroupedMatmulAntiQuant(const gmm::GroupedMatmulParams &gmmParams, const char *opName) |
| 1021 | { | 1088 | { |
| 1022 | DataType weightDtype = (*gmmParams.weight)[0]->GetDataType(); | 1089 | DataType weightDtype = (*gmmParams.weight)[0]->GetDataType(); |
| @@ -1044,64 +1111,10 @@ static aclnnStatus CheckGroupedMatmulAntiQuant(const gmm::GroupedMatmulParams &g | |||
| 1044 | ACLNN_ERR_PARAM_INVALID, "In op [%s], when %s, [%s] tensor list is invalid.", opName, scenario, | 1111 | ACLNN_ERR_PARAM_INVALID, "In op [%s], when %s, [%s] tensor list is invalid.", opName, scenario, |
| 1045 | "antiquantOffset"); | 1112 | "antiquantOffset"); |
| 1046 | } | 1113 | } |
| 1047 | - // check perGroupNum | ||
| 1048 | if (isAntiquantInt4) { | 1114 | if (isAntiquantInt4) { |
| 1049 | - auto antiquantScale0Shape = (*gmmParams.antiquantScaleOptional)[0]->GetViewShape(); | 1115 | + CHECK_RET(CheckAntiQuantPergroupSize(gmmParams, opName, scenario) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); |
| 1050 | - size_t antiquantScale0DimNum = antiquantScale0Shape.GetDimNum(); | ||
| 1051 | - auto w0Shape = (*gmmParams.weight)[0]->GetViewShape(); | ||
| 1052 | - size_t w0DimNum = w0Shape.GetDimNum(); | ||
| 1053 | - int64_t pergroupSize = GetPergroupSize(gmmParams, w0DimNum, w0Shape, antiquantScale0Shape); | ||
| 1054 | - CHECK_COND(!gmmParams.transposeWeight || pergroupSize % 2 == 0, ACLNN_ERR_PARAM_INVALID, // 2: a factor | ||
| 1055 | - "In op [%s], when A16W4 per-group antiquant and weight is transposed, [%s] is not supported, got " | ||
| 1056 | - "[%ld]. Constraint:[pergroup size should be even].", | ||
| 1057 | - opName, "pergroupSize", pergroupSize); | ||
| 1058 | - for (size_t i = 0; i < gmmParams.antiquantScaleOptional->Size(); ++i) { | ||
| 1059 | - auto antiquantScaleShape = (*gmmParams.antiquantScaleOptional)[i]->GetViewShape(); | ||
| 1060 | - size_t antiquantScaleDimNum = antiquantScaleShape.GetDimNum(); | ||
| 1061 | - CHECK_COND( | ||
| 1062 | - antiquantScaleDimNum == antiquantScale0DimNum, ACLNN_ERR_PARAM_INVALID, | ||
| 1063 | - "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantScale[%zu] dim " | ||
| 1064 | - "num %zu should equal antiquantScale[0] dim num %zu when %s].", | ||
| 1065 | - opName, "antiquantScale", i, antiquantScaleDimNum, antiquantScale0DimNum, scenario); | ||
| 1066 | - auto wShape = (*gmmParams.weight)[i]->GetViewShape(); | ||
| 1067 | - int64_t pergroupSizeOfScale = GetPergroupSize(gmmParams, w0DimNum, wShape, antiquantScaleShape); | ||
| 1068 | - CHECK_COND(pergroupSizeOfScale == pergroupSize, ACLNN_ERR_PARAM_INVALID, | ||
| 1069 | - "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantScale[%zu] " | ||
| 1070 | - "pergroup size %ld should be %ld when %s].", | ||
| 1071 | - opName, "antiquantScale, weight", i, pergroupSizeOfScale, pergroupSize, scenario); | ||
| 1072 | - if (gmmParams.antiquantOffsetOptional != nullptr) { | ||
| 1073 | - auto antiquantOffsetShape = (*gmmParams.antiquantOffsetOptional)[i]->GetViewShape(); | ||
| 1074 | - size_t antiquantOffsetDimNum = antiquantOffsetShape.GetDimNum(); | ||
| 1075 | - CHECK_COND( | ||
| 1076 | - antiquantScale0DimNum == antiquantOffsetDimNum, ACLNN_ERR_PARAM_INVALID, | ||
| 1077 | - "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantOffset[%zu] dim " | ||
| 1078 | - "num %zu should equal antiquantScale[0] dim num %zu when %s].", | ||
| 1079 | - opName, "antiquantOffset, antiquantScale", i, antiquantOffsetDimNum, antiquantScale0DimNum, | ||
| 1080 | - scenario); | ||
| 1081 | - int64_t pergroupSizeOfOffset = GetPergroupSize(gmmParams, w0DimNum, wShape, antiquantOffsetShape); | ||
| 1082 | - CHECK_COND( | ||
| 1083 | - pergroupSizeOfOffset == pergroupSize, ACLNN_ERR_PARAM_INVALID, | ||
| 1084 | - "In op [%s], the tensor shapes of [%s...] are mismatched, the reason is: [antiquantOffset[%zu] " | ||
| 1085 | - "pergroup size %ld should be %ld when %s].", | ||
| 1086 | - opName, "antiquantOffset, weight", i, pergroupSizeOfOffset, pergroupSize, scenario); | ||
| 1087 | - } | ||
| 1088 | - } | ||
| 1089 | } | 1116 | } |
| 1090 | - CHECK_COND(CheckTensorListDataType(gmmParams.antiquantScaleOptional, gmmParams.xDtype) == ACLNN_SUCCESS, | 1117 | + return CheckAntiQuantDtypeAndEmpty(gmmParams, opName, scenario); |
| 1091 | - ACLNN_ERR_PARAM_INVALID, | ||
| 1092 | - "In op [%s], the data type of [%s] is not supported. Constraint:[antiquantScale dtype should be %s " | ||
| 1093 | - "when %s].", | ||
| 1094 | - opName, "antiquantScale", gmm::dTypeToString(gmmParams.xDtype).c_str(), scenario); | ||
| 1095 | - if (gmmParams.antiquantOffsetOptional != nullptr) { | ||
| 1096 | - CHECK_COND(CheckTensorListDataType(gmmParams.antiquantOffsetOptional, gmmParams.xDtype) == ACLNN_SUCCESS, | ||
| 1097 | - ACLNN_ERR_PARAM_INVALID, | ||
| 1098 | - "In op [%s], the data type of [%s] is not supported. Constraint:[antiquantOffset dtype should be %s " | ||
| 1099 | - "when %s].", | ||
| 1100 | - opName, "antiquantOffset", gmm::dTypeToString(gmmParams.xDtype).c_str(), scenario); | ||
| 1101 | - } | ||
| 1102 | - CHECK_COND(IsGmmQuantEmpty(gmmParams) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, | ||
| 1103 | - "In op [%s], when %s, [%s] must be empty.", opName, scenario, "quant inputs"); | ||
| 1104 | - return ACLNN_SUCCESS; | ||
| 1105 | } | 1118 | } |
| 1106 | static aclnnStatus Check310PlatformForFunction(const gmm::GroupedMatmulParams &gmmParams, const DataType &weightDtype, | 1119 | static aclnnStatus Check310PlatformForFunction(const gmm::GroupedMatmulParams &gmmParams, const DataType &weightDtype, |
| 1107 | bool isNoActivation, const char *opName) | 1120 | bool isNoActivation, const char *opName) |
| @@ -1754,31 +1767,31 @@ static aclnnStatus SplitMSingleXSingleWeightSingleY(const gmm::GroupedMatmulPara | |||
| 1754 | return ACLNN_SUCCESS; | 1767 | return ACLNN_SUCCESS; |
| 1755 | } | 1768 | } |
| 1756 | 1769 | ||
| 1757 | -static aclnnStatus SplitMSingleXSeparatedWeightSingleY(const gmm::GroupedMatmulParams &gmmParams, const char *opName) | 1770 | +static aclnnStatus CheckSplitMDimNumAndFormat(const gmm::GroupedMatmulParams &gmmParams, const char *opName, |
| 1771 | + const std::string &errorMessage, const std::string &scenario) | ||
| 1758 | { | 1772 | { |
| 1759 | - size_t weightSize = gmmParams.weight->Size(); | ||
| 1760 | - static const std::vector<std::string> TENSOR_WEIGHT_X{"Weight", "x", "true"}; | ||
| 1761 | - static const std::vector<std::string> TENSOR_X_Y{"x", "y", "false"}; | ||
| 1762 | - static const std::vector<std::string> TENSOR_WEIGHT_Y{"Weight", "y", "true"}; | ||
| 1763 | - std::string errorMessage = | ||
| 1764 | - gmmParams.apiVersion != gmm::GMMApiVersion::V2 ? "split axis is M" : "groupType == 0(split-M)"; | ||
| 1765 | - CHECK_COND(gmmParams.splitItem == X_SEPARATED || gmmParams.splitItem == NO_SEPARATED, ACLNN_ERR_PARAM_INVALID, | ||
| 1766 | - "In op [%s], when %s and y is not separated, [%s] is invalid, got [%ld]. Constraint:[splitItem should " | ||
| 1767 | - "be 2 or 3].", | ||
| 1768 | - opName, errorMessage.c_str(), "splitItem", gmmParams.splitItem); | ||
| 1769 | // check dim | 1773 | // check dim |
| 1770 | CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.x, gmm::MIN_FM_DIM, "x") == ACLNN_SUCCESS, | 1774 | CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.x, gmm::MIN_FM_DIM, "x") == ACLNN_SUCCESS, |
| 1771 | ACLNN_ERR_PARAM_INVALID, | 1775 | ACLNN_ERR_PARAM_INVALID, |
| 1772 | - "In op [%s], when %s with single x, separated weight and single y, [%s] dim num or format is invalid.", | 1776 | + "In op [%s], when %s %s, [%s] dim num or format is invalid.", |
| 1773 | - opName, errorMessage.c_str(), "x"); | 1777 | + opName, errorMessage.c_str(), scenario.c_str(), "x"); |
| 1774 | CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.weight, SEPARATED_WEIGHT_DIM, "weight") == ACLNN_SUCCESS, | 1778 | CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.weight, SEPARATED_WEIGHT_DIM, "weight") == ACLNN_SUCCESS, |
| 1775 | ACLNN_ERR_PARAM_INVALID, | 1779 | ACLNN_ERR_PARAM_INVALID, |
| 1776 | - "In op [%s], when %s with single x, separated weight and single y, [%s] dim num or format is invalid.", | 1780 | + "In op [%s], when %s %s, [%s] dim num or format is invalid.", |
| 1777 | - opName, errorMessage.c_str(), "weight"); | 1781 | + opName, errorMessage.c_str(), scenario.c_str(), "weight"); |
| 1778 | CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.y, gmm::MIN_FM_DIM, "y") == ACLNN_SUCCESS, | 1782 | CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.y, gmm::MIN_FM_DIM, "y") == ACLNN_SUCCESS, |
| 1779 | ACLNN_ERR_PARAM_INVALID, | 1783 | ACLNN_ERR_PARAM_INVALID, |
| 1780 | - "In op [%s], when %s with single x, separated weight and single y, [%s] dim num or format is invalid.", | 1784 | + "In op [%s], when %s %s, [%s] dim num or format is invalid.", |
| 1781 | - opName, errorMessage.c_str(), "y"); | 1785 | + opName, errorMessage.c_str(), scenario.c_str(), "y"); |
| 1786 | + return ACLNN_SUCCESS; | ||
| 1787 | +} | ||
| 1788 | + | ||
| 1789 | +static aclnnStatus CheckSplitMShape(const gmm::GroupedMatmulParams &gmmParams, const char *opName, | ||
| 1790 | + const std::string &errorMessage, size_t weightSize) | ||
| 1791 | +{ | ||
| 1792 | + static const std::vector<std::string> TENSOR_WEIGHT_X{"Weight", "x", "true"}; | ||
| 1793 | + static const std::vector<std::string> TENSOR_X_Y{"x", "y", "false"}; | ||
| 1794 | + static const std::vector<std::string> TENSOR_WEIGHT_Y{"Weight", "y", "true"}; | ||
| 1782 | // check shape, x(m,k), weight(k,n), y(m,n) | 1795 | // check shape, x(m,k), weight(k,n), y(m,n) |
| 1783 | int64_t innerAxisDimId = 1; // x always is not transposed, check K axis | 1796 | int64_t innerAxisDimId = 1; // x always is not transposed, check K axis |
| 1784 | CHECK_COND(CheckShapeDiffLengthTensorList(gmmParams.weight, gmmParams.x, {0, 1}, innerAxisDimId, TENSOR_WEIGHT_X) == | 1797 | CHECK_COND(CheckShapeDiffLengthTensorList(gmmParams.weight, gmmParams.x, {0, 1}, innerAxisDimId, TENSOR_WEIGHT_X) == |
| @@ -1806,6 +1819,22 @@ static aclnnStatus SplitMSingleXSeparatedWeightSingleY(const gmm::GroupedMatmulP | |||
| 1806 | ACLNN_ERR_PARAM_INVALID, | 1819 | ACLNN_ERR_PARAM_INVALID, |
| 1807 | "In op [%s], when %s with single x, separated weight and single y, weight inner axis check failed.", | 1820 | "In op [%s], when %s with single x, separated weight and single y, weight inner axis check failed.", |
| 1808 | opName, errorMessage.c_str()); | 1821 | opName, errorMessage.c_str()); |
| 1822 | + return ACLNN_SUCCESS; | ||
| 1823 | +} | ||
| 1824 | + | ||
| 1825 | +static aclnnStatus SplitMSingleXSeparatedWeightSingleY(const gmm::GroupedMatmulParams &gmmParams, const char *opName) | ||
| 1826 | +{ | ||
| 1827 | + size_t weightSize = gmmParams.weight->Size(); | ||
| 1828 | + std::string errorMessage = | ||
| 1829 | + gmmParams.apiVersion != gmm::GMMApiVersion::V2 ? "split axis is M" : "groupType == 0(split-M)"; | ||
| 1830 | + CHECK_COND(gmmParams.splitItem == X_SEPARATED || gmmParams.splitItem == NO_SEPARATED, ACLNN_ERR_PARAM_INVALID, | ||
| 1831 | + "In op [%s], when %s and y is not separated, [%s] is invalid, got [%ld]. Constraint:[splitItem should " | ||
| 1832 | + "be 2 or 3].", | ||
| 1833 | + opName, errorMessage.c_str(), "splitItem", gmmParams.splitItem); | ||
| 1834 | + CHECK_RET(CheckSplitMDimNumAndFormat(gmmParams, opName, errorMessage, "with single x, separated weight and single y") == | ||
| 1835 | + ACLNN_SUCCESS, | ||
| 1836 | + ACLNN_ERR_PARAM_INVALID); | ||
| 1837 | + CHECK_RET(CheckSplitMShape(gmmParams, opName, errorMessage, weightSize) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 1809 | // check groupList | 1838 | // check groupList |
| 1810 | CHECK_COND(CheckGroupListSplitM(gmmParams, true, false, false, weightSize, opName) == ACLNN_SUCCESS, | 1839 | CHECK_COND(CheckGroupListSplitM(gmmParams, true, false, false, weightSize, opName) == ACLNN_SUCCESS, |
| 1811 | ACLNN_ERR_PARAM_INVALID, | 1840 | ACLNN_ERR_PARAM_INVALID, |
| @@ -1882,39 +1911,12 @@ static aclnnStatus SplitMSingleXSeparatedWeightSeparatedY(const gmm::GroupedMatm | |||
| 1882 | return ACLNN_SUCCESS; | 1911 | return ACLNN_SUCCESS; |
| 1883 | } | 1912 | } |
| 1884 | 1913 | ||
| 1885 | -static aclnnStatus SplitMSeparatedXSeparatedWeightSingleY(const gmm::GroupedMatmulParams &gmmParams, const char *opName) | 1914 | +static aclnnStatus CheckSeparatedXShape(const gmm::GroupedMatmulParams &gmmParams, const char *opName, |
| 1915 | + const std::string &errorMessage, size_t weightSize) | ||
| 1886 | { | 1916 | { |
| 1887 | - size_t xSize = gmmParams.x->Size(); | ||
| 1888 | - size_t weightSize = gmmParams.weight->Size(); | ||
| 1889 | static const std::vector<std::string> TENSOR_WEIGHT_X{"Weight", "x", "true"}; | 1917 | static const std::vector<std::string> TENSOR_WEIGHT_X{"Weight", "x", "true"}; |
| 1890 | static const std::vector<std::string> TENSOR_X_Y{"x", "y", "false"}; | 1918 | static const std::vector<std::string> TENSOR_X_Y{"x", "y", "false"}; |
| 1891 | static const std::vector<std::string> TENSOR_WEIGHT_Y{"Weight", "y", "true"}; | 1919 | static const std::vector<std::string> TENSOR_WEIGHT_Y{"Weight", "y", "true"}; |
| 1892 | - std::string errorMessage = | ||
| 1893 | - gmmParams.apiVersion != gmm::GMMApiVersion::V2 ? "split axis is M" : "groupType == 0(split-M)"; | ||
| 1894 | - CHECK_COND(gmmParams.splitItem == X_SEPARATED || gmmParams.splitItem == NO_SEPARATED, ACLNN_ERR_PARAM_INVALID, | ||
| 1895 | - "In op [%s], when %s and y is not separated, [%s] is invalid, got [%ld]. Constraint:[splitItem should " | ||
| 1896 | - "be 2 or 3].", | ||
| 1897 | - opName, errorMessage.c_str(), "splitItem", gmmParams.splitItem); | ||
| 1898 | - CHECK_COND(xSize == weightSize, ACLNN_ERR_PARAM_INVALID, | ||
| 1899 | - "In op [%s], when %s with separated x, separated weight and single y, tensor list lengths are " | ||
| 1900 | - "mismatched, got [x size %zu, weight size %zu].", | ||
| 1901 | - opName, errorMessage.c_str(), xSize, weightSize); | ||
| 1902 | - // check dim | ||
| 1903 | - CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.x, gmm::MIN_FM_DIM, "x") == ACLNN_SUCCESS, | ||
| 1904 | - ACLNN_ERR_PARAM_INVALID, | ||
| 1905 | - "In op [%s], when %s with separated x, separated weight and single y, [%s] dim num or format is " | ||
| 1906 | - "invalid.", | ||
| 1907 | - opName, errorMessage.c_str(), "x"); | ||
| 1908 | - CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.weight, SEPARATED_WEIGHT_DIM, "weight") == ACLNN_SUCCESS, | ||
| 1909 | - ACLNN_ERR_PARAM_INVALID, | ||
| 1910 | - "In op [%s], when %s with separated x, separated weight and single y, [%s] dim num or format is " | ||
| 1911 | - "invalid.", | ||
| 1912 | - opName, errorMessage.c_str(), "weight"); | ||
| 1913 | - CHECK_COND(CheckDimNumAndFormat(gmmParams, gmmParams.y, gmm::MIN_FM_DIM, "y") == ACLNN_SUCCESS, | ||
| 1914 | - ACLNN_ERR_PARAM_INVALID, | ||
| 1915 | - "In op [%s], when %s with separated x, separated weight and single y, [%s] dim num or format is " | ||
| 1916 | - "invalid.", | ||
| 1917 | - opName, errorMessage.c_str(), "y"); | ||
| 1918 | // check shape, x(m,k), weight(k,n), y(m,n) | 1920 | // check shape, x(m,k), weight(k,n), y(m,n) |
| 1919 | int64_t innerAxisDimId = 0; // 0: the index of weight's K axis. x always is not transposed, check K axis | 1921 | int64_t innerAxisDimId = 0; // 0: the index of weight's K axis. x always is not transposed, check K axis |
| 1920 | CHECK_COND(CheckShapeSameLengthTensorList(gmmParams.weight, gmmParams.x, {0, 1}, innerAxisDimId, TENSOR_WEIGHT_X) == | 1922 | CHECK_COND(CheckShapeSameLengthTensorList(gmmParams.weight, gmmParams.x, {0, 1}, innerAxisDimId, TENSOR_WEIGHT_X) == |
| @@ -1942,6 +1944,28 @@ static aclnnStatus SplitMSeparatedXSeparatedWeightSingleY(const gmm::GroupedMatm | |||
| 1942 | ACLNN_ERR_PARAM_INVALID, | 1944 | ACLNN_ERR_PARAM_INVALID, |
| 1943 | "In op [%s], when %s with separated x, separated weight and single y, weight inner axis check failed.", | 1945 | "In op [%s], when %s with separated x, separated weight and single y, weight inner axis check failed.", |
| 1944 | opName, errorMessage.c_str()); | 1946 | opName, errorMessage.c_str()); |
| 1947 | + return ACLNN_SUCCESS; | ||
| 1948 | +} | ||
| 1949 | + | ||
| 1950 | +static aclnnStatus SplitMSeparatedXSeparatedWeightSingleY(const gmm::GroupedMatmulParams &gmmParams, const char *opName) | ||
| 1951 | +{ | ||
| 1952 | + size_t xSize = gmmParams.x->Size(); | ||
| 1953 | + size_t weightSize = gmmParams.weight->Size(); | ||
| 1954 | + std::string errorMessage = | ||
| 1955 | + gmmParams.apiVersion != gmm::GMMApiVersion::V2 ? "split axis is M" : "groupType == 0(split-M)"; | ||
| 1956 | + CHECK_COND(gmmParams.splitItem == X_SEPARATED || gmmParams.splitItem == NO_SEPARATED, ACLNN_ERR_PARAM_INVALID, | ||
| 1957 | + "In op [%s], when %s and y is not separated, [%s] is invalid, got [%ld]. Constraint:[splitItem should " | ||
| 1958 | + "be 2 or 3].", | ||
| 1959 | + opName, errorMessage.c_str(), "splitItem", gmmParams.splitItem); | ||
| 1960 | + CHECK_COND(xSize == weightSize, ACLNN_ERR_PARAM_INVALID, | ||
| 1961 | + "In op [%s], when %s with separated x, separated weight and single y, tensor list lengths are " | ||
| 1962 | + "mismatched, got [x size %zu, weight size %zu].", | ||
| 1963 | + opName, errorMessage.c_str(), xSize, weightSize); | ||
| 1964 | + CHECK_RET(CheckSplitMDimNumAndFormat(gmmParams, opName, errorMessage, | ||
| 1965 | + "with separated x, separated weight and single y") == ACLNN_SUCCESS, | ||
| 1966 | + ACLNN_ERR_PARAM_INVALID); | ||
| 1967 | + CHECK_RET(CheckSeparatedXShape(gmmParams, opName, errorMessage, weightSize) == ACLNN_SUCCESS, | ||
| 1968 | + ACLNN_ERR_PARAM_INVALID); | ||
| 1945 | // check groupList | 1969 | // check groupList |
| 1946 | CHECK_COND(CheckGroupListSplitM(gmmParams, false, true, false, xSize, opName) == ACLNN_SUCCESS, | 1970 | CHECK_COND(CheckGroupListSplitM(gmmParams, false, true, false, xSize, opName) == ACLNN_SUCCESS, |
| 1947 | ACLNN_ERR_PARAM_INVALID, | 1971 | ACLNN_ERR_PARAM_INVALID, |
| @@ -2084,13 +2108,8 @@ static aclnnStatus CheckCaseSplitK(const gmm::GroupedMatmulParams &gmmParams, co | |||
| 2084 | return ACLNN_ERR_PARAM_INVALID; | 2108 | return ACLNN_ERR_PARAM_INVALID; |
| 2085 | } | 2109 | } |
| 2086 | 2110 | ||
| 2087 | -static aclnnStatus CheckCaseNoSplit(const gmm::GroupedMatmulParams &gmmParams, const char *opName) | 2111 | +static aclnnStatus CheckNoSplitGroupNum(const gmm::GroupedMatmulParams &gmmParams, const char *opName) |
| 2088 | { | 2112 | { |
| 2089 | - // When groupType is -1, splitItem mast be 0/1. | ||
| 2090 | - CHECK_COND(gmmParams.splitItem == X_Y_SEPARATED || gmmParams.splitItem == Y_SEPARATED, ACLNN_ERR_PARAM_INVALID, | ||
| 2091 | - "In op [%s], when groupType == -1(no split) and y is separated, [%s] is invalid, got [%ld]. " | ||
| 2092 | - "Constraint:[splitItem should be 0 or 1].", | ||
| 2093 | - opName, "splitItem", gmmParams.splitItem); | ||
| 2094 | // 校验group num | 2113 | // 校验group num |
| 2095 | size_t xSize = gmmParams.x->Size(); | 2114 | size_t xSize = gmmParams.x->Size(); |
| 2096 | size_t ySize = gmmParams.y->Size(); | 2115 | size_t ySize = gmmParams.y->Size(); |
| @@ -2103,11 +2122,13 @@ static aclnnStatus CheckCaseNoSplit(const gmm::GroupedMatmulParams &gmmParams, c | |||
| 2103 | "In op [%s], when groupType == -1(no split) and x/weight are separated, tensor list lengths are " | 2122 | "In op [%s], when groupType == -1(no split) and x/weight are separated, tensor list lengths are " |
| 2104 | "mismatched, got [x size %zu, weight size %zu].", | 2123 | "mismatched, got [x size %zu, weight size %zu].", |
| 2105 | opName, xSize, weightSize); | 2124 | opName, xSize, weightSize); |
| 2106 | - // check dim | 2125 | + return ACLNN_SUCCESS; |
| 2107 | - CHECK_COND(CheckDimNumAndGroupListNoSplitAndFormat(gmmParams, opName) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, | 2126 | +} |
| 2108 | - "In op [%s], when groupType == -1(no split), tensor list dim num, format or [%s] check failed.", opName, | 2127 | + |
| 2109 | - "groupList"); | 2128 | +static aclnnStatus CheckNoSplitShape(const gmm::GroupedMatmulParams &gmmParams, const char *opName) |
| 2129 | +{ | ||
| 2110 | // check shape | 2130 | // check shape |
| 2131 | + size_t xSize = gmmParams.x->Size(); | ||
| 2111 | for (size_t i = 0; i < xSize; i++) { | 2132 | for (size_t i = 0; i < xSize; i++) { |
| 2112 | size_t xDimNum = (*gmmParams.x)[i]->GetViewShape().GetDimNum(); | 2133 | size_t xDimNum = (*gmmParams.x)[i]->GetViewShape().GetDimNum(); |
| 2113 | // 2: Indicates validation up to the second last dimension, x and y must be equal in every dimension except the | 2134 | // 2: Indicates validation up to the second last dimension, x and y must be equal in every dimension except the |
| @@ -2161,6 +2182,21 @@ static aclnnStatus CheckCaseNoSplit(const gmm::GroupedMatmulParams &gmmParams, c | |||
| 2161 | return ACLNN_SUCCESS; | 2182 | return ACLNN_SUCCESS; |
| 2162 | } | 2183 | } |
| 2163 | 2184 | ||
| 2185 | +static aclnnStatus CheckCaseNoSplit(const gmm::GroupedMatmulParams &gmmParams, const char *opName) | ||
| 2186 | +{ | ||
| 2187 | + // When groupType is -1, splitItem mast be 0/1. | ||
| 2188 | + CHECK_COND(gmmParams.splitItem == X_Y_SEPARATED || gmmParams.splitItem == Y_SEPARATED, ACLNN_ERR_PARAM_INVALID, | ||
| 2189 | + "In op [%s], when groupType == -1(no split) and y is separated, [%s] is invalid, got [%ld]. " | ||
| 2190 | + "Constraint:[splitItem should be 0 or 1].", | ||
| 2191 | + opName, "splitItem", gmmParams.splitItem); | ||
| 2192 | + CHECK_RET(CheckNoSplitGroupNum(gmmParams, opName) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 2193 | + // check dim | ||
| 2194 | + CHECK_COND(CheckDimNumAndGroupListNoSplitAndFormat(gmmParams, opName) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, | ||
| 2195 | + "In op [%s], when groupType == -1(no split), tensor list dim num, format or [%s] check failed.", opName, | ||
| 2196 | + "groupList"); | ||
| 2197 | + return CheckNoSplitShape(gmmParams, opName); | ||
| 2198 | +} | ||
| 2199 | + | ||
| 2164 | static bool IsMultiTensorWeight(const gmm::GroupedMatmulParams &gmmParams) | 2200 | static bool IsMultiTensorWeight(const gmm::GroupedMatmulParams &gmmParams) |
| 2165 | { | 2201 | { |
| 2166 | return gmmParams.weight != nullptr && gmmParams.weight->Size() > 0UL && (*gmmParams.weight)[0] != nullptr && | 2202 | return gmmParams.weight != nullptr && gmmParams.weight->Size() > 0UL && (*gmmParams.weight)[0] != nullptr && |
| @@ -2923,12 +2959,8 @@ static aclnnStatus SetStorageShape(gmm::GroupedMatmulParams ¶ms, const std:: | |||
| 2923 | return ACLNN_SUCCESS; | 2959 | return ACLNN_SUCCESS; |
| 2924 | } | 2960 | } |
| 2925 | 2961 | ||
| 2926 | -static aclnnStatus GetGMMResultByL0Api(gmm::GroupedMatmulParams ¶ms, uint64_t *workspaceSize, | 2962 | +static aclnnStatus PrepareParamsForL0(gmm::GroupedMatmulParams ¶ms, aclOpExecutor *executorPtr) |
| 2927 | - aclOpExecutor **executor, const char *opName) | ||
| 2928 | { | 2963 | { |
| 2929 | - auto uniqueExecutor = CREATE_EXECUTOR(); // fixed writen style, create OpExecutor | ||
| 2930 | - aclOpExecutor *executorPtr = uniqueExecutor.get(); | ||
| 2931 | - CHECK_RET(executorPtr != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | ||
| 2932 | if (params.xDtype != DataType::DT_INT4) { // A4W4 has no bias | 2964 | if (params.xDtype != DataType::DT_INT4) { // A4W4 has no bias |
| 2933 | CHECK_COND(gmm::BIAS_DTYPE.find(params.xDtype) != gmm::BIAS_DTYPE.cend(), ACLNN_ERR_PARAM_INVALID, | 2965 | CHECK_COND(gmm::BIAS_DTYPE.find(params.xDtype) != gmm::BIAS_DTYPE.cend(), ACLNN_ERR_PARAM_INVALID, |
| 2934 | "GMM: Cannot find bias dtype match with xDtype[%s]", gmm::dTypeToString(params.xDtype).c_str()); | 2966 | "GMM: Cannot find bias dtype match with xDtype[%s]", gmm::dTypeToString(params.xDtype).c_str()); |
| @@ -2938,18 +2970,11 @@ static aclnnStatus GetGMMResultByL0Api(gmm::GroupedMatmulParams ¶ms, uint64_ | |||
| 2938 | CHECK_RET(SetTransposedTensorListContiguous(params, executorPtr) == ACLNN_SUCCESS, ACLNN_ERR_INNER_NULLPTR); | 2970 | CHECK_RET(SetTransposedTensorListContiguous(params, executorPtr) == ACLNN_SUCCESS, ACLNN_ERR_INNER_NULLPTR); |
| 2939 | CHECK_COND(ParamsDataContiguous(params, executorPtr) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, | 2971 | CHECK_COND(ParamsDataContiguous(params, executorPtr) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, |
| 2940 | "ParamsDataContiguous failed."); | 2972 | "ParamsDataContiguous failed."); |
| 2941 | - if (params.groupType == gmm::SPLIT_K) { | 2973 | + return ACLNN_SUCCESS; |
| 2942 | - if (CheckZeroShapeSplitK(params, workspaceSize, opName) != ACLNN_SUCCESS) { | 2974 | +} |
| 2943 | - uniqueExecutor.ReleaseTo(executor); | ||
| 2944 | - return ACLNN_SUCCESS; | ||
| 2945 | - } | ||
| 2946 | - } else { | ||
| 2947 | - if (CheckZeroShape(params, workspaceSize) != ACLNN_SUCCESS) { | ||
| 2948 | - uniqueExecutor.ReleaseTo(executor); | ||
| 2949 | - return ACLNN_SUCCESS; | ||
| 2950 | - } | ||
| 2951 | - } | ||
| 2952 | 2975 | ||
| 2976 | +static aclnnStatus PrepareWeightNz(gmm::GroupedMatmulParams ¶ms, const char *opName, aclOpExecutor *executorPtr) | ||
| 2977 | +{ | ||
| 2953 | std::vector<op::Shape> nzShapes; | 2978 | std::vector<op::Shape> nzShapes; |
| 2954 | for (uint64_t idx = 0; idx < (*params.weight).Size(); idx++) { | 2979 | for (uint64_t idx = 0; idx < (*params.weight).Size(); idx++) { |
| 2955 | nzShapes.push_back((*params.weight)[idx]->GetStorageShape()); | 2980 | nzShapes.push_back((*params.weight)[idx]->GetStorageShape()); |
| @@ -2972,11 +2997,12 @@ static aclnnStatus GetGMMResultByL0Api(gmm::GroupedMatmulParams ¶ms, uint64_ | |||
| 2972 | } | 2997 | } |
| 2973 | CHECK_COND(TransWeightToNz(params, executorPtr) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, | 2998 | CHECK_COND(TransWeightToNz(params, executorPtr) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID, |
| 2974 | "TransWeightToNz failed."); | 2999 | "TransWeightToNz failed."); |
| 2975 | - if (params.groupListOptional != nullptr) { | 3000 | + return ACLNN_SUCCESS; |
| 2976 | - params.groupTensorOptional = | 3001 | +} |
| 2977 | - uniqueExecutor->ConvertToTensor(params.groupListOptional, op::ToOpDataType(ACL_INT64)); | 3002 | + |
| 2978 | - CHECK_RET(params.groupTensorOptional != nullptr, ACLNN_ERR_INNER_NULLPTR); | 3003 | +static aclnnStatus ExecuteL0GroupedMatmul(gmm::GroupedMatmulParams ¶ms, aclOpExecutor *executorPtr, |
| 2979 | - } | 3004 | + const char *opName) |
| 3005 | +{ | ||
| 2980 | auto perTokenScaleOptional = | 3006 | auto perTokenScaleOptional = |
| 2981 | (*params.perTokenScaleOptional)[0]->IsEmpty() ? nullptr : (*params.perTokenScaleOptional)[0]; | 3007 | (*params.perTokenScaleOptional)[0]->IsEmpty() ? nullptr : (*params.perTokenScaleOptional)[0]; |
| 2982 | // Invoke l0 operator GroupedMatmul for calculation. | 3008 | // Invoke l0 operator GroupedMatmul for calculation. |
| @@ -2994,6 +3020,38 @@ static aclnnStatus GetGMMResultByL0Api(gmm::GroupedMatmulParams ¶ms, uint64_ | |||
| 2994 | auto viewCopyResult = l0op::ViewCopy((*result)[i], (*params.y)[i], executorPtr); | 3020 | auto viewCopyResult = l0op::ViewCopy((*result)[i], (*params.y)[i], executorPtr); |
| 2995 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | 3021 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); |
| 2996 | } | 3022 | } |
| 3023 | + return ACLNN_SUCCESS; | ||
| 3024 | +} | ||
| 3025 | + | ||
| 3026 | +static aclnnStatus GetGMMResultByL0Api(gmm::GroupedMatmulParams ¶ms, uint64_t *workspaceSize, | ||
| 3027 | + aclOpExecutor **executor, const char *opName) | ||
| 3028 | +{ | ||
| 3029 | + auto uniqueExecutor = CREATE_EXECUTOR(); // fixed writen style, create OpExecutor | ||
| 3030 | + aclOpExecutor *executorPtr = uniqueExecutor.get(); | ||
| 3031 | + CHECK_RET(executorPtr != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | ||
| 3032 | + aclnnStatus ret = PrepareParamsForL0(params, executorPtr); | ||
| 3033 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); | ||
| 3034 | + if (params.groupType == gmm::SPLIT_K) { | ||
| 3035 | + if (CheckZeroShapeSplitK(params, workspaceSize, opName) != ACLNN_SUCCESS) { | ||
| 3036 | + uniqueExecutor.ReleaseTo(executor); | ||
| 3037 | + return ACLNN_SUCCESS; | ||
| 3038 | + } | ||
| 3039 | + } else { | ||
| 3040 | + if (CheckZeroShape(params, workspaceSize) != ACLNN_SUCCESS) { | ||
| 3041 | + uniqueExecutor.ReleaseTo(executor); | ||
| 3042 | + return ACLNN_SUCCESS; | ||
| 3043 | + } | ||
| 3044 | + } | ||
| 3045 | + | ||
| 3046 | + ret = PrepareWeightNz(params, opName, executorPtr); | ||
| 3047 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); | ||
| 3048 | + if (params.groupListOptional != nullptr) { | ||
| 3049 | + params.groupTensorOptional = | ||
| 3050 | + uniqueExecutor->ConvertToTensor(params.groupListOptional, op::ToOpDataType(ACL_INT64)); | ||
| 3051 | + CHECK_RET(params.groupTensorOptional != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 3052 | + } | ||
| 3053 | + ret = ExecuteL0GroupedMatmul(params, executorPtr, opName); | ||
| 3054 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); | ||
| 2997 | // Standard syntax, get the size of workspace needed during computation. | 3055 | // Standard syntax, get the size of workspace needed during computation. |
| 2998 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | 3056 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); |
| 2999 | uniqueExecutor.ReleaseTo(executor); | 3057 | uniqueExecutor.ReleaseTo(executor); |
| @@ -3063,6 +3121,22 @@ static aclnnStatus CheckEmptyTensor(const aclTensorList *x, const aclTensorList | |||
| 3063 | return ACLNN_SUCCESS; | 3121 | return ACLNN_SUCCESS; |
| 3064 | } | 3122 | } |
| 3065 | 3123 | ||
| 3124 | +static aclnnStatus PrepareGmmParams(gmm::GroupedMatmulParams &gmmParams, const aclTensorList *x, | ||
| 3125 | + const aclTensorList *y, int64_t splitItem, const char *opName) | ||
| 3126 | +{ | ||
| 3127 | + if (gmmParams.scaleOptional != nullptr) { | ||
| 3128 | + for (size_t i = 0; i < gmmParams.scaleOptional->Size(); i++) { | ||
| 3129 | + if ((*gmmParams.scaleOptional)[i]->GetDataType() == DataType::DT_INT64) { | ||
| 3130 | + (void)const_cast<aclTensor *>((*gmmParams.scaleOptional)[i])->SetDataType(op::DataType::DT_UINT64); | ||
| 3131 | + } | ||
| 3132 | + } | ||
| 3133 | + } | ||
| 3134 | + ResetEmptyTensor(gmmParams); // make empty tensor/tensorList nullptr | ||
| 3135 | + CHECK_RET(CheckParam(gmmParams, opName) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 3136 | + gmmParams.splitItem = CorrectSplitItem(x, y, splitItem); | ||
| 3137 | + return ACLNN_SUCCESS; | ||
| 3138 | +} | ||
| 3139 | + | ||
| 3066 | static aclnnStatus aclnnGroupedMatmulGetWorkspaceSizeCommon( | 3140 | static aclnnStatus aclnnGroupedMatmulGetWorkspaceSizeCommon( |
| 3067 | const aclTensorList *x, const aclTensorList *weight, const aclTensorList *biasOptional, | 3141 | const aclTensorList *x, const aclTensorList *weight, const aclTensorList *biasOptional, |
| 3068 | const aclTensorList *scaleOptional, const aclTensorList *offsetOptional, | 3142 | const aclTensorList *scaleOptional, const aclTensorList *offsetOptional, |
| @@ -3117,16 +3191,7 @@ static aclnnStatus aclnnGroupedMatmulGetWorkspaceSizeCommon( | |||
| 3117 | activationFeatureOutOptional, | 3191 | activationFeatureOutOptional, |
| 3118 | dynQuantScaleOutOptional, | 3192 | dynQuantScaleOutOptional, |
| 3119 | xDtype}; | 3193 | xDtype}; |
| 3120 | - if (gmmParams.scaleOptional != nullptr) { | 3194 | + CHECK_RET(PrepareGmmParams(gmmParams, x, y, splitItem, opName) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); |
| 3121 | - for (size_t i = 0; i < gmmParams.scaleOptional->Size(); i++) { | ||
| 3122 | - if ((*gmmParams.scaleOptional)[i]->GetDataType() == DataType::DT_INT64) { | ||
| 3123 | - (void)const_cast<aclTensor *>((*gmmParams.scaleOptional)[i])->SetDataType(op::DataType::DT_UINT64); | ||
| 3124 | - } | ||
| 3125 | - } | ||
| 3126 | - } | ||
| 3127 | - ResetEmptyTensor(gmmParams); // make empty tensor/tensorList nullptr | ||
| 3128 | - CHECK_RET(CheckParam(gmmParams, opName) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 3129 | - gmmParams.splitItem = CorrectSplitItem(x, y, splitItem); | ||
| 3130 | 3195 | ||
| 3131 | aclnnStatus ret = GetGMMResultByL0Api(gmmParams, workspaceSize, executor, opName); | 3196 | aclnnStatus ret = GetGMMResultByL0Api(gmmParams, workspaceSize, executor, opName); |
| 3132 | 3197 | ||
| @@ -3177,27 +3242,8 @@ aclnnStatus CheckCommonParam(const aclTensorList *x, const aclTensorList *weight | |||
| 3177 | return ACLNN_SUCCESS; | 3242 | return ACLNN_SUCCESS; |
| 3178 | } | 3243 | } |
| 3179 | 3244 | ||
| 3180 | -aclnnStatus aclnnGroupedMatmulWeightNzGetWorkspaceSize( | 3245 | +static void UnpackWeightQuantInputs(const aclTensorList *x, const aclTensorList *weight) |
| 3181 | - const aclTensorList *x, const aclTensorList *weight, const aclTensorList *biasOptional, | ||
| 3182 | - const aclTensorList *scaleOptional, const aclTensorList *offsetOptional, | ||
| 3183 | - const aclTensorList *antiquantScaleOptional, const aclTensorList *antiquantOffsetOptional, | ||
| 3184 | - const aclTensorList *perTokenScaleOptional, const aclTensor *groupListOptional, | ||
| 3185 | - const aclTensorList *activationInputOptional, const aclTensorList *activationQuantScaleOptional, | ||
| 3186 | - const aclTensorList *activationQuantOffsetOptional, int64_t splitItem, int64_t groupType, int64_t groupListType, | ||
| 3187 | - int64_t actType, aclIntArray *tuningConfigOptional, int64_t quantGroupSize, aclTensorList *out, | ||
| 3188 | - aclTensorList *activationFeatureOutOptional, aclTensorList *dynQuantScaleOutOptional, uint64_t *workspaceSize, | ||
| 3189 | - aclOpExecutor **executor) | ||
| 3190 | { | 3246 | { |
| 3191 | - const char *opName = "grouped_matmul"; | ||
| 3192 | - CHECK_COND(CheckNotNull(x, weight, out) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_NULLPTR, | ||
| 3193 | - "In op [%s], required inputs must not be nullptr.", opName); | ||
| 3194 | - // Standard syntax, Check parameters. | ||
| 3195 | - L2_DFX_PHASE_1(aclnnGroupedMatmulWeightNz, | ||
| 3196 | - DFX_IN(x, weight, biasOptional, scaleOptional, offsetOptional, antiquantScaleOptional, | ||
| 3197 | - antiquantOffsetOptional, perTokenScaleOptional, activationInputOptional, | ||
| 3198 | - activationQuantScaleOptional, activationQuantOffsetOptional, groupListOptional, splitItem, | ||
| 3199 | - groupType, groupListType, actType, tuningConfigOptional), | ||
| 3200 | - DFX_OUT(out, activationFeatureOutOptional, dynQuantScaleOutOptional)); | ||
| 3201 | if ((*weight)[0]->GetDataType() == DataType::DT_INT32) { | 3247 | if ((*weight)[0]->GetDataType() == DataType::DT_INT32) { |
| 3202 | // convert weight from int32 to int4 | 3248 | // convert weight from int32 to int4 |
| 3203 | UnpackB32ToB4(weight, "weight"); | 3249 | UnpackB32ToB4(weight, "weight"); |
| @@ -3223,6 +3269,30 @@ aclnnStatus aclnnGroupedMatmulWeightNzGetWorkspaceSize( | |||
| 3223 | UnpackB32ToB4(x, "x", true); | 3269 | UnpackB32ToB4(x, "x", true); |
| 3224 | } | 3270 | } |
| 3225 | } | 3271 | } |
| 3272 | +} | ||
| 3273 | + | ||
| 3274 | +aclnnStatus aclnnGroupedMatmulWeightNzGetWorkspaceSize( | ||
| 3275 | + const aclTensorList *x, const aclTensorList *weight, const aclTensorList *biasOptional, | ||
| 3276 | + const aclTensorList *scaleOptional, const aclTensorList *offsetOptional, | ||
| 3277 | + const aclTensorList *antiquantScaleOptional, const aclTensorList *antiquantOffsetOptional, | ||
| 3278 | + const aclTensorList *perTokenScaleOptional, const aclTensor *groupListOptional, | ||
| 3279 | + const aclTensorList *activationInputOptional, const aclTensorList *activationQuantScaleOptional, | ||
| 3280 | + const aclTensorList *activationQuantOffsetOptional, int64_t splitItem, int64_t groupType, int64_t groupListType, | ||
| 3281 | + int64_t actType, aclIntArray *tuningConfigOptional, int64_t quantGroupSize, aclTensorList *out, | ||
| 3282 | + aclTensorList *activationFeatureOutOptional, aclTensorList *dynQuantScaleOutOptional, uint64_t *workspaceSize, | ||
| 3283 | + aclOpExecutor **executor) | ||
| 3284 | +{ | ||
| 3285 | + const char *opName = "grouped_matmul"; | ||
| 3286 | + CHECK_COND(CheckNotNull(x, weight, out) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_NULLPTR, | ||
| 3287 | + "In op [%s], required inputs must not be nullptr.", opName); | ||
| 3288 | + // Standard syntax, Check parameters. | ||
| 3289 | + L2_DFX_PHASE_1(aclnnGroupedMatmulWeightNz, | ||
| 3290 | + DFX_IN(x, weight, biasOptional, scaleOptional, offsetOptional, antiquantScaleOptional, | ||
| 3291 | + antiquantOffsetOptional, perTokenScaleOptional, activationInputOptional, | ||
| 3292 | + activationQuantScaleOptional, activationQuantOffsetOptional, groupListOptional, splitItem, | ||
| 3293 | + groupType, groupListType, actType, tuningConfigOptional), | ||
| 3294 | + DFX_OUT(out, activationFeatureOutOptional, dynQuantScaleOutOptional)); | ||
| 3295 | + UnpackWeightQuantInputs(x, weight); | ||
| 3226 | if (IsS8S4PseudoQuantWeightNz(x, weight, scaleOptional)) { | 3296 | if (IsS8S4PseudoQuantWeightNz(x, weight, scaleOptional)) { |
| 3227 | bool hasOffset = offsetOptional != nullptr && offsetOptional->Size() == 1 && (*offsetOptional)[0] != nullptr; | 3297 | bool hasOffset = offsetOptional != nullptr && offsetOptional->Size() == 1 && (*offsetOptional)[0] != nullptr; |
| 3228 | if (hasOffset) { | 3298 | if (hasOffset) { |
| @@ -259,8 +259,7 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckQuantCasesFormat() const | |||
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | template <typename T> | 261 | template <typename T> |
| 262 | -aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightStorageShape(const aclTensor *weightTensor, | 262 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightNzStorageDim(const aclTensor *weightTensor) const |
| 263 | - int64_t kDimValue, int64_t nDimValue) const | ||
| 264 | { | 263 | { |
| 265 | auto weightStorage = weightTensor->GetStorageShape(); | 264 | auto weightStorage = weightTensor->GetStorageShape(); |
| 266 | auto weightStorageShapeDim = weightStorage.GetDimNum(); | 265 | auto weightStorageShapeDim = weightStorage.GetDimNum(); |
| @@ -273,12 +272,14 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightStorageShape(const a | |||
| 273 | IsWeightNzMultiTensorLayout() ? std::to_string(WEIGHTNZ_MULTI_TENSOR_STORAGE_DIM) + " or " + | 272 | IsWeightNzMultiTensorLayout() ? std::to_string(WEIGHTNZ_MULTI_TENSOR_STORAGE_DIM) + " or " + |
| 274 | std::to_string(QUANT_WEIGHTNZ_STORAGE_DIM) : | 273 | std::to_string(QUANT_WEIGHTNZ_STORAGE_DIM) : |
| 275 | std::to_string(QUANT_WEIGHTNZ_STORAGE_DIM))); | 274 | std::to_string(QUANT_WEIGHTNZ_STORAGE_DIM))); |
| 275 | + return ACLNN_SUCCESS; | ||
| 276 | +} | ||
| 276 | 277 | ||
| 277 | - auto weightStorageLastFourthDim = weightStorage.GetDim(weightStorageShapeDim - LAST_FOURTH_DIM_INDEX); | 278 | +template <typename T> |
| 278 | - auto weightStorageLastThirdDim = weightStorage.GetDim(weightStorageShapeDim - LAST_THIRD_DIM_INDEX); | 279 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightNzC0(const aclTensor *weightTensor, |
| 279 | - auto weightStorageLastSecondDim = weightStorage.GetDim(weightStorageShapeDim - LAST_SECOND_DIM_INDEX); | 280 | + int64_t weightStorageLastDim, |
| 280 | - auto weightStorageLastDim = weightStorage.GetDim(weightStorageShapeDim - LAST_FIRST_DIM_INDEX); | 281 | + int64_t &cubeBlockSizeK) const |
| 281 | - | 282 | +{ |
| 282 | const bool isInt4 = (gmmParams_.xDtype == DataType::DT_INT4); | 283 | const bool isInt4 = (gmmParams_.xDtype == DataType::DT_INT4); |
| 283 | const bool isMxfp4 = | 284 | const bool isMxfp4 = |
| 284 | (gmmParams_.xDtype == DataType::DT_FLOAT4_E2M1 || gmmParams_.xDtype == DataType::DT_FLOAT4_E1M2); | 285 | (gmmParams_.xDtype == DataType::DT_FLOAT4_E2M1 || gmmParams_.xDtype == DataType::DT_FLOAT4_E1M2); |
| @@ -286,17 +287,20 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightStorageShape(const a | |||
| 286 | // INT4 C0 is 32. Keep accepting the historical C0=64 layout as well; the selected | 287 | // INT4 C0 is 32. Keep accepting the historical C0=64 layout as well; the selected |
| 287 | // C0 is used below to validate the two outer NZ dimensions consistently. | 288 | // C0 is used below to validate the two outer NZ dimensions consistently. |
| 288 | const bool validInt4C0 = weightStorageLastDim == CUBE_BLOCK_SIZE_32 || weightStorageLastDim == CUBE_BLOCK_SIZE_64; | 289 | const bool validInt4C0 = weightStorageLastDim == CUBE_BLOCK_SIZE_32 || weightStorageLastDim == CUBE_BLOCK_SIZE_64; |
| 289 | - const int64_t cubeBlockSizeK = isInt4 ? weightStorageLastDim : (isMxfp4 ? CUBE_BLOCK_SIZE_64 : CUBE_BLOCK_SIZE_32); | 290 | + cubeBlockSizeK = isInt4 ? weightStorageLastDim : (isMxfp4 ? CUBE_BLOCK_SIZE_64 : CUBE_BLOCK_SIZE_32); |
| 290 | GMM_CHECK_REPORT(isInt4 ? validInt4C0 : weightStorageLastDim == cubeBlockSizeK, | 291 | GMM_CHECK_REPORT(isInt4 ? validInt4C0 : weightStorageLastDim == cubeBlockSizeK, |
| 291 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 292 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 292 | GetAclnnOpName(), weightName_.c_str(), StorageShapeToString(weightTensor), | 293 | GetAclnnOpName(), weightName_.c_str(), StorageShapeToString(weightTensor), |
| 293 | "when the format of weight is FRACTAL_NZ, storage shape last dim of weight must be equal to " | 294 | "when the format of weight is FRACTAL_NZ, storage shape last dim of weight must be equal to " |
| 294 | "32 for fp8 dtype, 32 or 64 for int4 dtype, or 64 for mxfp4 dtype")); | 295 | "32 for fp8 dtype, 32 or 64 for int4 dtype, or 64 for mxfp4 dtype")); |
| 295 | - GMM_CHECK_REPORT( | 296 | + return ACLNN_SUCCESS; |
| 296 | - weightStorageLastSecondDim == CUBE_BLOCK_SIZE_16, | 297 | +} |
| 297 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 298 | + |
| 298 | - GetAclnnOpName(), weightName_.c_str(), StorageShapeToString(weightTensor), | 299 | +template <typename T> |
| 299 | - "when the format of weight is FRACTAL_NZ, storage shape last second dim of weight must be equal to 16")); | 300 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightNzOuterDims( |
| 301 | + const aclTensor *weightTensor, int64_t kDimValue, int64_t nDimValue, int64_t cubeBlockSizeK, | ||
| 302 | + int64_t weightStorageLastFourthDim, int64_t weightStorageLastThirdDim) const | ||
| 303 | +{ | ||
| 300 | if (gmmParams_.transposeWeight) { | 304 | if (gmmParams_.transposeWeight) { |
| 301 | GMM_CHECK_REPORT( | 305 | GMM_CHECK_REPORT( |
| 302 | weightStorageLastFourthDim == (kDimValue + cubeBlockSizeK - 1) / cubeBlockSizeK, | 306 | weightStorageLastFourthDim == (kDimValue + cubeBlockSizeK - 1) / cubeBlockSizeK, |
| @@ -331,6 +335,31 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightStorageShape(const a | |||
| 331 | return ACLNN_SUCCESS; | 335 | return ACLNN_SUCCESS; |
| 332 | } | 336 | } |
| 333 | 337 | ||
| 338 | +template <typename T> | ||
| 339 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightStorageShape(const aclTensor *weightTensor, | ||
| 340 | + int64_t kDimValue, int64_t nDimValue) const | ||
| 341 | +{ | ||
| 342 | + auto weightStorage = weightTensor->GetStorageShape(); | ||
| 343 | + auto weightStorageShapeDim = weightStorage.GetDimNum(); | ||
| 344 | + CHECK_RET(CheckWeightNzStorageDim(weightTensor) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 345 | + | ||
| 346 | + auto weightStorageLastFourthDim = weightStorage.GetDim(weightStorageShapeDim - LAST_FOURTH_DIM_INDEX); | ||
| 347 | + auto weightStorageLastThirdDim = weightStorage.GetDim(weightStorageShapeDim - LAST_THIRD_DIM_INDEX); | ||
| 348 | + auto weightStorageLastSecondDim = weightStorage.GetDim(weightStorageShapeDim - LAST_SECOND_DIM_INDEX); | ||
| 349 | + auto weightStorageLastDim = weightStorage.GetDim(weightStorageShapeDim - LAST_FIRST_DIM_INDEX); | ||
| 350 | + | ||
| 351 | + int64_t cubeBlockSizeK = CUBE_BLOCK_SIZE_32; | ||
| 352 | + CHECK_RET(CheckWeightNzC0(weightTensor, weightStorageLastDim, cubeBlockSizeK) == ACLNN_SUCCESS, | ||
| 353 | + ACLNN_ERR_PARAM_INVALID); | ||
| 354 | + GMM_CHECK_REPORT( | ||
| 355 | + weightStorageLastSecondDim == CUBE_BLOCK_SIZE_16, | ||
| 356 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 357 | + GetAclnnOpName(), weightName_.c_str(), StorageShapeToString(weightTensor), | ||
| 358 | + "when the format of weight is FRACTAL_NZ, storage shape last second dim of weight must be equal to 16")); | ||
| 359 | + return CheckWeightNzOuterDims(weightTensor, kDimValue, nDimValue, cubeBlockSizeK, weightStorageLastFourthDim, | ||
| 360 | + weightStorageLastThirdDim); | ||
| 361 | +} | ||
| 362 | + | ||
| 334 | template <typename T> | 363 | template <typename T> |
| 335 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightNzSpecialParams() const | 364 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckWeightNzSpecialParams() const |
| 336 | { | 365 | { |
| @@ -496,6 +525,62 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulMxDtype() con | |||
| 496 | return ACLNN_SUCCESS; | 525 | return ACLNN_SUCCESS; |
| 497 | } | 526 | } |
| 498 | 527 | ||
| 528 | +template <typename T> | ||
| 529 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckPerGroupWeightDim(size_t weightDimNumber) const | ||
| 530 | +{ | ||
| 531 | + if (gmmParams_.groupType == SPLIT_M) { | ||
| 532 | + const size_t expectedWeightDim = IsWeightNzMultiTensorLayout() ? MIN_FM_DIM : SPLIT_M_SINGLE_WEIGHT_DIM; | ||
| 533 | + GMM_CHECK_REPORT( | ||
| 534 | + weightDimNumber == expectedWeightDim, | ||
| 535 | + OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), weightName_.c_str(), std::to_string(weightDimNumber), | ||
| 536 | + std::to_string(expectedWeightDim))); | ||
| 537 | + } else if (gmmParams_.groupType == SPLIT_K) { | ||
| 538 | + GMM_CHECK_REPORT( | ||
| 539 | + weightDimNumber == SPLIT_K_SINGLE_WEIGHT_DIM, | ||
| 540 | + OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), weightName_.c_str(), std::to_string(weightDimNumber), | ||
| 541 | + std::to_string(SPLIT_K_SINGLE_WEIGHT_DIM))); | ||
| 542 | + } | ||
| 543 | + return ACLNN_SUCCESS; | ||
| 544 | +} | ||
| 545 | + | ||
| 546 | +template <typename T> | ||
| 547 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckPerGroupScaleDim(const TensorIndexInfo &tensorIndex, | ||
| 548 | + size_t scaleDimNumber, | ||
| 549 | + size_t perTokenDimNumber, size_t xDimNumber, | ||
| 550 | + size_t weightDimNumber) const | ||
| 551 | +{ | ||
| 552 | + if (gmmParams_.groupType == SPLIT_M) { | ||
| 553 | + DataType scaleDtype = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetDataType(); | ||
| 554 | + if (scaleDtype == DataType::DT_FLOAT8_E8M0) { | ||
| 555 | + const size_t expectedScaleDim = | ||
| 556 | + IsWeightNzMultiTensorLayout() ? MX_SPLIT_K_SCALE_DIM : MX_SPLIT_M_SCALE_DIM; | ||
| 557 | + GMM_CHECK_REPORT( | ||
| 558 | + scaleDimNumber == expectedScaleDim, | ||
| 559 | + OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), scaleName_.c_str(), std::to_string(scaleDimNumber), | ||
| 560 | + std::to_string(expectedScaleDim))); | ||
| 561 | + GMM_CHECK_REPORT(perTokenDimNumber == MX_SPLIT_M_PER_TOKEN_SCALE_DIM, | ||
| 562 | + OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 563 | + std::to_string(perTokenDimNumber), | ||
| 564 | + std::to_string(MX_SPLIT_M_PER_TOKEN_SCALE_DIM))); | ||
| 565 | + } else { | ||
| 566 | + GMM_CHECK_REPORT(scaleDimNumber == weightDimNumber, | ||
| 567 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | ||
| 568 | + GetAclnnOpName(), scaleName_.c_str(), std::to_string(scaleDimNumber), | ||
| 569 | + "when split m and in G-B quant mode, the shape dim of scale must be equal to the " | ||
| 570 | + "shape dim of weight [" + | ||
| 571 | + std::to_string(weightDimNumber) + "]")); | ||
| 572 | + GMM_CHECK_REPORT( | ||
| 573 | + perTokenDimNumber == xDimNumber, | ||
| 574 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | ||
| 575 | + GetAclnnOpName(), perTokenScaleName_.c_str(), std::to_string(perTokenDimNumber), | ||
| 576 | + "when split m and in G-B quant mode, the shape dim of perTokenScale must be equal to " | ||
| 577 | + "the shape dim of x [" + | ||
| 578 | + std::to_string(xDimNumber) + "]")); | ||
| 579 | + } | ||
| 580 | + } | ||
| 581 | + return ACLNN_SUCCESS; | ||
| 582 | +} | ||
| 583 | + | ||
| 499 | template <typename T> | 584 | template <typename T> |
| 500 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulPerGroupDim() const | 585 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulPerGroupDim() const |
| 501 | { | 586 | { |
| @@ -510,47 +595,10 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulPerGroupDim() | |||
| 510 | GMM_CHECK_REPORT(xDimNumber == MIN_FM_DIM, | 595 | GMM_CHECK_REPORT(xDimNumber == MIN_FM_DIM, |
| 511 | OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), xName_.c_str(), std::to_string(xDimNumber), | 596 | OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), xName_.c_str(), std::to_string(xDimNumber), |
| 512 | std::to_string(MIN_FM_DIM))); | 597 | std::to_string(MIN_FM_DIM))); |
| 513 | - if (gmmParams_.groupType == SPLIT_M) { | 598 | + CHECK_RET(CheckPerGroupWeightDim(weightDimNumber) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); |
| 514 | - const size_t expectedWeightDim = IsWeightNzMultiTensorLayout() ? MIN_FM_DIM : SPLIT_M_SINGLE_WEIGHT_DIM; | 599 | + CHECK_RET(CheckPerGroupScaleDim(tensorIndex, scaleDimNumber, perTokenDimNumber, xDimNumber, weightDimNumber) == |
| 515 | - GMM_CHECK_REPORT( | 600 | + ACLNN_SUCCESS, |
| 516 | - weightDimNumber == expectedWeightDim, | 601 | + ACLNN_ERR_PARAM_INVALID); |
| 517 | - OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), weightName_.c_str(), std::to_string(weightDimNumber), | ||
| 518 | - std::to_string(expectedWeightDim))); | ||
| 519 | - } else if (gmmParams_.groupType == SPLIT_K) { | ||
| 520 | - GMM_CHECK_REPORT( | ||
| 521 | - weightDimNumber == SPLIT_K_SINGLE_WEIGHT_DIM, | ||
| 522 | - OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), weightName_.c_str(), std::to_string(weightDimNumber), | ||
| 523 | - std::to_string(SPLIT_K_SINGLE_WEIGHT_DIM))); | ||
| 524 | - } | ||
| 525 | - if (gmmParams_.groupType == SPLIT_M) { | ||
| 526 | - DataType scaleDtype = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetDataType(); | ||
| 527 | - if (scaleDtype == DataType::DT_FLOAT8_E8M0) { | ||
| 528 | - const size_t expectedScaleDim = | ||
| 529 | - IsWeightNzMultiTensorLayout() ? MX_SPLIT_K_SCALE_DIM : MX_SPLIT_M_SCALE_DIM; | ||
| 530 | - GMM_CHECK_REPORT( | ||
| 531 | - scaleDimNumber == expectedScaleDim, | ||
| 532 | - OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), scaleName_.c_str(), std::to_string(scaleDimNumber), | ||
| 533 | - std::to_string(expectedScaleDim))); | ||
| 534 | - GMM_CHECK_REPORT(perTokenDimNumber == MX_SPLIT_M_PER_TOKEN_SCALE_DIM, | ||
| 535 | - OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 536 | - std::to_string(perTokenDimNumber), | ||
| 537 | - std::to_string(MX_SPLIT_M_PER_TOKEN_SCALE_DIM))); | ||
| 538 | - } else { | ||
| 539 | - GMM_CHECK_REPORT(scaleDimNumber == weightDimNumber, | ||
| 540 | - OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | ||
| 541 | - GetAclnnOpName(), scaleName_.c_str(), std::to_string(scaleDimNumber), | ||
| 542 | - "when split m and in G-B quant mode, the shape dim of scale must be equal to the " | ||
| 543 | - "shape dim of weight [" + | ||
| 544 | - std::to_string(weightDimNumber) + "]")); | ||
| 545 | - GMM_CHECK_REPORT( | ||
| 546 | - perTokenDimNumber == xDimNumber, | ||
| 547 | - OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | ||
| 548 | - GetAclnnOpName(), perTokenScaleName_.c_str(), std::to_string(perTokenDimNumber), | ||
| 549 | - "when split m and in G-B quant mode, the shape dim of perTokenScale must be equal to " | ||
| 550 | - "the shape dim of x [" + | ||
| 551 | - std::to_string(xDimNumber) + "]")); | ||
| 552 | - } | ||
| 553 | - } | ||
| 554 | } | 602 | } |
| 555 | return ACLNN_SUCCESS; | 603 | return ACLNN_SUCCESS; |
| 556 | } | 604 | } |
| @@ -587,102 +635,127 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxBiasInputShape(const Ten | |||
| 587 | } | 635 | } |
| 588 | 636 | ||
| 589 | template <typename T> | 637 | template <typename T> |
| 590 | -aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxTypeMCaseInputShape(const TensorDimInfo &dimInfo, | 638 | +typename AclnnGroupedMatmulDAV3510Checker<T>::MxTypeMDims |
| 591 | - size_t index) const | 639 | +AclnnGroupedMatmulDAV3510Checker<T>::ExtractMxTypeMDims(const TensorDimInfo &dimInfo, size_t index) const |
| 592 | { | 640 | { |
| 593 | const auto tensorIndex = GetTensorIndexInfo(index); | 641 | const auto tensorIndex = GetTensorIndexInfo(index); |
| 594 | auto weightNIndex = GetInputTensor(gmmParams_.weight, tensorIndex.weight)->GetViewShape().GetDimNum() - 1; | 642 | auto weightNIndex = GetInputTensor(gmmParams_.weight, tensorIndex.weight)->GetViewShape().GetDimNum() - 1; |
| 595 | - size_t scaleDimNum = dimInfo.scaleDimNum; | 643 | + MxTypeMDims dims{}; |
| 596 | - size_t pertokenScaleDimNum = dimInfo.pertokenScaleDimNum; | 644 | + dims.xMDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(0); |
| 597 | - int64_t groupNum = dimInfo.groupNum; | 645 | + dims.xKDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(1); |
| 598 | - auto xMDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(0); | 646 | + dims.pertokenMDimValue = |
| 599 | - auto xKDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(1); | ||
| 600 | - auto pertokenMDimValue = | ||
| 601 | GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)->GetViewShape().GetDim(0); | 647 | GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)->GetViewShape().GetDim(0); |
| 602 | - auto pertokenScaleKDimValue = | 648 | + dims.pertokenScaleKDimValue = |
| 603 | GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)->GetViewShape().GetDim(1); | 649 | GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)->GetViewShape().GetDim(1); |
| 604 | - auto pertokenScaleLastDimValue = GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale) | 650 | + dims.pertokenScaleLastDimValue = GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale) |
| 605 | ->GetViewShape() | 651 | ->GetViewShape() |
| 606 | - .GetDim(pertokenScaleDimNum - 1); | 652 | + .GetDim(dimInfo.pertokenScaleDimNum - 1); |
| 607 | - auto weightNDimValue = GetInputTensor(gmmParams_.weight, tensorIndex.weight)->GetViewShape().GetDim(weightNIndex); | 653 | + dims.weightNDimValue = GetInputTensor(gmmParams_.weight, tensorIndex.weight)->GetViewShape().GetDim(weightNIndex); |
| 608 | - auto inferedScaleKDimValue = (xKDimValue + MXFP_DIVISOR_SIZE - 1) / MXFP_DIVISOR_SIZE; | 654 | + dims.inferedScaleKDimValue = (dims.xKDimValue + MXFP_DIVISOR_SIZE - 1) / MXFP_DIVISOR_SIZE; |
| 609 | - auto scaleLastDimValue = | 655 | + dims.scaleLastDimValue = |
| 610 | - GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(scaleDimNum - 1); | 656 | + GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(dimInfo.scaleDimNum - 1); |
| 611 | - CHECK_RET(CheckMxBiasInputShape(dimInfo, index) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | 657 | + return dims; |
| 612 | - GMM_CHECK_REPORT( | 658 | +} |
| 613 | - xMDimValue == pertokenMDimValue, | 659 | + |
| 614 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 660 | +template <typename T> |
| 615 | - GetAclnnOpName(), xName_.c_str(), ViewShapeToString(GetInputTensor(gmmParams_.x, tensorIndex.x)), | 661 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxTypeMScaleShape(const MxTypeMDims &dims, |
| 616 | - "axis M of x must be equal to axis M of perTokenScale [" + std::to_string(pertokenMDimValue) + "]")); | 662 | + const TensorDimInfo &tensorIndex) const |
| 663 | +{ | ||
| 664 | + auto weightNIndex = GetInputTensor(gmmParams_.weight, tensorIndex.weight)->GetViewShape().GetDimNum() - 1; | ||
| 617 | if (IsWeightNzMultiTensorLayout()) { | 665 | if (IsWeightNzMultiTensorLayout()) { |
| 618 | auto scaleFirstDimValue = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(0); | 666 | auto scaleFirstDimValue = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(0); |
| 619 | auto scaleSecondDimValue = | 667 | auto scaleSecondDimValue = |
| 620 | GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(1); | 668 | GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(1); |
| 621 | - const bool isNkLayout = scaleFirstDimValue == weightNDimValue && scaleSecondDimValue == inferedScaleKDimValue; | 669 | + const bool isNkLayout = scaleFirstDimValue == dims.weightNDimValue && |
| 622 | - const bool isKnLayout = scaleFirstDimValue == inferedScaleKDimValue && scaleSecondDimValue == weightNDimValue; | 670 | + scaleSecondDimValue == dims.inferedScaleKDimValue; |
| 671 | + const bool isKnLayout = scaleFirstDimValue == dims.inferedScaleKDimValue && | ||
| 672 | + scaleSecondDimValue == dims.weightNDimValue; | ||
| 623 | const bool isBroadcastLayout = scaleFirstDimValue == 1L || scaleSecondDimValue == 1L; | 673 | const bool isBroadcastLayout = scaleFirstDimValue == 1L || scaleSecondDimValue == 1L; |
| 624 | GMM_CHECK_REPORT(isNkLayout || isKnLayout || isBroadcastLayout, | 674 | GMM_CHECK_REPORT(isNkLayout || isKnLayout || isBroadcastLayout, |
| 625 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 675 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 626 | GetAclnnOpName(), scaleName_.c_str(), | 676 | GetAclnnOpName(), scaleName_.c_str(), |
| 627 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), | 677 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), |
| 628 | "the first two axes of scale must match axis N of weight and ceil(k/" + | 678 | "the first two axes of scale must match axis N of weight and ceil(k/" + |
| 629 | - std::to_string(MXFP_DIVISOR_SIZE) + ") [" + std::to_string(weightNDimValue) + ", " + | 679 | + std::to_string(MXFP_DIVISOR_SIZE) + ") [" + std::to_string(dims.weightNDimValue) + |
| 630 | - std::to_string(inferedScaleKDimValue) + "]")); | 680 | + ", " + std::to_string(dims.inferedScaleKDimValue) + "]")); |
| 631 | } else { | 681 | } else { |
| 632 | auto scaleNDimValue = | 682 | auto scaleNDimValue = |
| 633 | GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(weightNIndex); | 683 | GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(weightNIndex); |
| 634 | auto scaleKDimValue = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(1); | 684 | auto scaleKDimValue = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(1); |
| 635 | GMM_CHECK_REPORT( | 685 | GMM_CHECK_REPORT( |
| 636 | - weightNDimValue == scaleNDimValue, | 686 | + dims.weightNDimValue == scaleNDimValue, |
| 637 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 687 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 638 | GetAclnnOpName(), weightName_.c_str(), | 688 | GetAclnnOpName(), weightName_.c_str(), |
| 639 | ViewShapeToString(GetInputTensor(gmmParams_.weight, tensorIndex.weight)), | 689 | ViewShapeToString(GetInputTensor(gmmParams_.weight, tensorIndex.weight)), |
| 640 | "axis N of weight must be equal to axis N of scale [" + std::to_string(scaleNDimValue) + "]")); | 690 | "axis N of weight must be equal to axis N of scale [" + std::to_string(scaleNDimValue) + "]")); |
| 641 | auto scaleGDimValue = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(0); | 691 | auto scaleGDimValue = GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)->GetViewShape().GetDim(0); |
| 642 | GMM_CHECK_REPORT( | 692 | GMM_CHECK_REPORT( |
| 643 | - scaleGDimValue == groupNum, | 693 | + scaleGDimValue == dims.groupNum, |
| 644 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 694 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 645 | GetAclnnOpName(), scaleName_.c_str(), | 695 | GetAclnnOpName(), scaleName_.c_str(), |
| 646 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), | 696 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), |
| 647 | - "axis group of scale must be equal to axis 0 of groupTensor [" + std::to_string(groupNum) + "]")); | 697 | + "axis group of scale must be equal to axis 0 of groupTensor [" + |
| 648 | - GMM_CHECK_REPORT(scaleKDimValue == inferedScaleKDimValue, | 698 | + std::to_string(dims.groupNum) + "]")); |
| 699 | + GMM_CHECK_REPORT(scaleKDimValue == dims.inferedScaleKDimValue, | ||
| 649 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 700 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 650 | GetAclnnOpName(), scaleName_.c_str(), | 701 | GetAclnnOpName(), scaleName_.c_str(), |
| 651 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), | 702 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), |
| 652 | "axis K of scale must be equal to ceil(k/" + std::to_string(MXFP_DIVISOR_SIZE) + ") [" + | 703 | "axis K of scale must be equal to ceil(k/" + std::to_string(MXFP_DIVISOR_SIZE) + ") [" + |
| 653 | - std::to_string(inferedScaleKDimValue) + "]")); | 704 | + std::to_string(dims.inferedScaleKDimValue) + "]")); |
| 654 | } | 705 | } |
| 655 | - GMM_CHECK_REPORT(pertokenScaleKDimValue == inferedScaleKDimValue, | 706 | + return ACLNN_SUCCESS; |
| 707 | +} | ||
| 708 | + | ||
| 709 | +template <typename T> | ||
| 710 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxTypeMPerTokenAndScaleLastDim( | ||
| 711 | + const MxTypeMDims &dims, const TensorDimInfo &tensorIndex) const | ||
| 712 | +{ | ||
| 713 | + GMM_CHECK_REPORT(dims.pertokenScaleKDimValue == dims.inferedScaleKDimValue, | ||
| 656 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 714 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 657 | GetAclnnOpName(), perTokenScaleName_.c_str(), | 715 | GetAclnnOpName(), perTokenScaleName_.c_str(), |
| 658 | ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)), | 716 | ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)), |
| 659 | "axis K of perTokenScale must be equal to ceil(k/" + std::to_string(MXFP_DIVISOR_SIZE) + | 717 | "axis K of perTokenScale must be equal to ceil(k/" + std::to_string(MXFP_DIVISOR_SIZE) + |
| 660 | - ") [" + std::to_string(inferedScaleKDimValue) + "]")); | 718 | + ") [" + std::to_string(dims.inferedScaleKDimValue) + "]")); |
| 661 | - GMM_CHECK_REPORT(pertokenScaleLastDimValue == MXFP_MULTI_BASE_SIZE, | 719 | + GMM_CHECK_REPORT(dims.pertokenScaleLastDimValue == MXFP_MULTI_BASE_SIZE, |
| 662 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 720 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 663 | GetAclnnOpName(), perTokenScaleName_.c_str(), | 721 | GetAclnnOpName(), perTokenScaleName_.c_str(), |
| 664 | ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)), | 722 | ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, tensorIndex.perTokenScale)), |
| 665 | - "current perTokenScale last axis is " + std::to_string(pertokenScaleLastDimValue) + | 723 | + "current perTokenScale last axis is " + std::to_string(dims.pertokenScaleLastDimValue) + |
| 666 | ", expected " + std::to_string(MXFP_MULTI_BASE_SIZE))); | 724 | ", expected " + std::to_string(MXFP_MULTI_BASE_SIZE))); |
| 667 | - GMM_CHECK_REPORT(scaleLastDimValue == MXFP_MULTI_BASE_SIZE, | 725 | + GMM_CHECK_REPORT(dims.scaleLastDimValue == MXFP_MULTI_BASE_SIZE, |
| 668 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | 726 | OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( |
| 669 | GetAclnnOpName(), scaleName_.c_str(), | 727 | GetAclnnOpName(), scaleName_.c_str(), |
| 670 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), | 728 | ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, tensorIndex.scale)), |
| 671 | - "current scale last axis is " + std::to_string(scaleLastDimValue) + ", expected " + | 729 | + "current scale last axis is " + std::to_string(dims.scaleLastDimValue) + ", expected " + |
| 672 | std::to_string(MXFP_MULTI_BASE_SIZE))); | 730 | std::to_string(MXFP_MULTI_BASE_SIZE))); |
| 673 | return ACLNN_SUCCESS; | 731 | return ACLNN_SUCCESS; |
| 674 | } | 732 | } |
| 675 | 733 | ||
| 676 | template <typename T> | 734 | template <typename T> |
| 677 | -aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxFp8TypeKCaseInputShape(const TensorDimInfo &dimInfo, | 735 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxTypeMCaseInputShape(const TensorDimInfo &dimInfo, |
| 678 | - size_t index) const | 736 | + size_t index) const |
| 679 | { | 737 | { |
| 680 | const auto tensorIndex = GetTensorIndexInfo(index); | 738 | const auto tensorIndex = GetTensorIndexInfo(index); |
| 739 | + auto dims = ExtractMxTypeMDims(dimInfo, index); | ||
| 740 | + dims.groupNum = dimInfo.groupNum; | ||
| 741 | + CHECK_RET(CheckMxBiasInputShape(dimInfo, index) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 742 | + GMM_CHECK_REPORT( | ||
| 743 | + dims.xMDimValue == dims.pertokenMDimValue, | ||
| 744 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 745 | + GetAclnnOpName(), xName_.c_str(), ViewShapeToString(GetInputTensor(gmmParams_.x, tensorIndex.x)), | ||
| 746 | + "axis M of x must be equal to axis M of perTokenScale [" + std::to_string(dims.pertokenMDimValue) + "]")); | ||
| 747 | + CHECK_RET(CheckMxTypeMScaleShape(dims, tensorIndex) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 748 | + CHECK_RET(CheckMxTypeMPerTokenAndScaleLastDim(dims, tensorIndex) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 749 | + return ACLNN_SUCCESS; | ||
| 750 | +} | ||
| 751 | + | ||
| 752 | +template <typename T> | ||
| 753 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxSplitKDimNum(const TensorDimInfo &dimInfo) const | ||
| 754 | +{ | ||
| 681 | size_t xDimNum = dimInfo.xDimNum; | 755 | size_t xDimNum = dimInfo.xDimNum; |
| 682 | size_t weightDimNum = dimInfo.weightDimNum; | 756 | size_t weightDimNum = dimInfo.weightDimNum; |
| 683 | size_t scaleDimNum = dimInfo.scaleDimNum; | 757 | size_t scaleDimNum = dimInfo.scaleDimNum; |
| 684 | size_t pertokenScaleDimNum = dimInfo.pertokenScaleDimNum; | 758 | size_t pertokenScaleDimNum = dimInfo.pertokenScaleDimNum; |
| 685 | - int64_t groupNum = dimInfo.groupNum; | ||
| 686 | // split k, x is (m,k), weight is (k,n), scale is (k//64+g, n, 2), pertoken is (m, k//64+g, 2) | 759 | // split k, x is (m,k), weight is (k,n), scale is (k//64+g, n, 2), pertoken is (m, k//64+g, 2) |
| 687 | GMM_CHECK_REPORT(xDimNum == MX_SPLIT_K_SINGLE_X_DIM, | 760 | GMM_CHECK_REPORT(xDimNum == MX_SPLIT_K_SINGLE_X_DIM, |
| 688 | OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), xName_.c_str(), std::to_string(xDimNum), | 761 | OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), xName_.c_str(), std::to_string(xDimNum), |
| @@ -697,6 +770,13 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxFp8TypeKCaseInputShape(c | |||
| 697 | pertokenScaleDimNum == MX_SPLIT_K_PER_TOKEN_SCALE_DIM, | 770 | pertokenScaleDimNum == MX_SPLIT_K_PER_TOKEN_SCALE_DIM, |
| 698 | OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), perTokenScaleName_.c_str(), std::to_string(pertokenScaleDimNum), | 771 | OP_LOGE_FOR_INVALID_SHAPEDIM(GetAclnnOpName(), perTokenScaleName_.c_str(), std::to_string(pertokenScaleDimNum), |
| 699 | std::to_string(MX_SPLIT_K_PER_TOKEN_SCALE_DIM))); | 772 | std::to_string(MX_SPLIT_K_PER_TOKEN_SCALE_DIM))); |
| 773 | + return ACLNN_SUCCESS; | ||
| 774 | +} | ||
| 775 | + | ||
| 776 | +template <typename T> | ||
| 777 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxSplitKDimValue(const TensorIndexInfo &tensorIndex, | ||
| 778 | + int64_t groupNum) const | ||
| 779 | +{ | ||
| 700 | auto xMDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(0); | 780 | auto xMDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(0); |
| 701 | auto xKDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(1); | 781 | auto xKDimValue = GetInputTensor(gmmParams_.x, tensorIndex.x)->GetViewShape().GetDim(1); |
| 702 | auto weightNDimValue = GetInputTensor(gmmParams_.weight, tensorIndex.weight)->GetViewShape().GetDim(1); | 782 | auto weightNDimValue = GetInputTensor(gmmParams_.weight, tensorIndex.weight)->GetViewShape().GetDim(1); |
| @@ -749,6 +829,15 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxFp8TypeKCaseInputShape(c | |||
| 749 | return ACLNN_SUCCESS; | 829 | return ACLNN_SUCCESS; |
| 750 | } | 830 | } |
| 751 | 831 | ||
| 832 | +template <typename T> | ||
| 833 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckMxFp8TypeKCaseInputShape(const TensorDimInfo &dimInfo, | ||
| 834 | + size_t index) const | ||
| 835 | +{ | ||
| 836 | + const auto tensorIndex = GetTensorIndexInfo(index); | ||
| 837 | + CHECK_RET(CheckMxSplitKDimNum(dimInfo) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 838 | + return CheckMxSplitKDimValue(tensorIndex, dimInfo.groupNum); | ||
| 839 | +} | ||
| 840 | + | ||
| 752 | template <typename T> | 841 | template <typename T> |
| 753 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulMxShape() const | 842 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulMxShape() const |
| 754 | { | 843 | { |
| @@ -970,6 +1059,65 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckNonPerGroupQuantDim() cons | |||
| 970 | return ACLNN_SUCCESS; | 1059 | return ACLNN_SUCCESS; |
| 971 | } | 1060 | } |
| 972 | 1061 | ||
| 1062 | +template <typename T> | ||
| 1063 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckSplitMPerTokenShape(size_t perTokenDimNumber, | ||
| 1064 | + int64_t perTokenFirstDim, int64_t xMDim, | ||
| 1065 | + int64_t groupNum) const | ||
| 1066 | +{ | ||
| 1067 | + if (perTokenDimNumber == 1) { | ||
| 1068 | + GMM_CHECK_REPORT( | ||
| 1069 | + perTokenFirstDim == xMDim || perTokenFirstDim == groupNum, | ||
| 1070 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1071 | + GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1072 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1073 | + "in non-pergroup quantification mode and when groupType is 0 (split M) and " | ||
| 1074 | + "perTokenScale has 1 dim, axis 0 of perTokenScale must be equal to axis M of x [" + | ||
| 1075 | + std::to_string(xMDim) + "] or axis 0 of groupTensor [" + std::to_string(groupNum) + "]")); | ||
| 1076 | + } else { | ||
| 1077 | + GMM_CHECK_REPORT(perTokenFirstDim == groupNum, | ||
| 1078 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1079 | + GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1080 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1081 | + "in non-pergroup quantification mode and when groupType is 0 (split M) and " | ||
| 1082 | + "perTokenScale has 2 dims, axis 0 of perTokenScale must be equal to axis 0 of " | ||
| 1083 | + "groupTensor [" + | ||
| 1084 | + std::to_string(groupNum) + "]")); | ||
| 1085 | + auto perTokenSecondDim = GetInputTensor(gmmParams_.perTokenScaleOptional)->GetViewShape().GetDim(1); | ||
| 1086 | + GMM_CHECK_REPORT(perTokenSecondDim == 1, | ||
| 1087 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1088 | + GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1089 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1090 | + "in non-pergroup quantification mode and when groupType is 0 (split M) and " | ||
| 1091 | + "perTokenScale has 2 dims, axis 1 of perTokenScale must be equal to 1")); | ||
| 1092 | + } | ||
| 1093 | + return ACLNN_SUCCESS; | ||
| 1094 | +} | ||
| 1095 | + | ||
| 1096 | +template <typename T> | ||
| 1097 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckSplitKPerTokenShape(size_t perTokenDimNumber, | ||
| 1098 | + int64_t perTokenFirstDim, int64_t xMDim, | ||
| 1099 | + int64_t groupNum) const | ||
| 1100 | +{ | ||
| 1101 | + GMM_CHECK_REPORT(perTokenFirstDim == groupNum, | ||
| 1102 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1103 | + GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1104 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1105 | + "in non-pergroup quantification mode and when groupType is 2 (split K), axis 0 of " | ||
| 1106 | + "perTokenScale must be equal to axis 0 of groupTensor [" + | ||
| 1107 | + std::to_string(groupNum) + "]")); | ||
| 1108 | + if (perTokenDimNumber > 1) { | ||
| 1109 | + auto perTokenSecondDim = GetInputTensor(gmmParams_.perTokenScaleOptional)->GetViewShape().GetDim(1); | ||
| 1110 | + GMM_CHECK_REPORT(perTokenSecondDim == xMDim || perTokenSecondDim == 1, | ||
| 1111 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1112 | + GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1113 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1114 | + "in non-pergroup quantification mode and when groupType is 2 (split K) and " | ||
| 1115 | + "perTokenScale has 2 dims, axis 1 of perTokenScale must be equal to axis M of x [" + | ||
| 1116 | + std::to_string(xMDim) + "] or 1")); | ||
| 1117 | + } | ||
| 1118 | + return ACLNN_SUCCESS; | ||
| 1119 | +} | ||
| 1120 | + | ||
| 973 | template <typename T> | 1121 | template <typename T> |
| 974 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckNonPerGroupQuantPertokenShape() const | 1122 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckNonPerGroupQuantPertokenShape() const |
| 975 | { | 1123 | { |
| @@ -978,50 +1126,9 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckNonPerGroupQuantPertokenSh | |||
| 978 | auto xMDim = GetInputTensor(gmmParams_.x)->GetViewShape().GetDim(0); | 1126 | auto xMDim = GetInputTensor(gmmParams_.x)->GetViewShape().GetDim(0); |
| 979 | auto groupNum = gmmParams_.groupTensorOptional->GetViewShape().GetDim(0); | 1127 | auto groupNum = gmmParams_.groupTensorOptional->GetViewShape().GetDim(0); |
| 980 | if (gmmParams_.groupType == SPLIT_M) { | 1128 | if (gmmParams_.groupType == SPLIT_M) { |
| 981 | - if (perTokenDimNumber == 1) { | 1129 | + return CheckSplitMPerTokenShape(perTokenDimNumber, perTokenFirstDim, xMDim, groupNum); |
| 982 | - GMM_CHECK_REPORT( | ||
| 983 | - perTokenFirstDim == xMDim || perTokenFirstDim == groupNum, | ||
| 984 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 985 | - GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 986 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 987 | - "in non-pergroup quantification mode and when groupType is 0 (split M) and " | ||
| 988 | - "perTokenScale has 1 dim, axis 0 of perTokenScale must be equal to axis M of x [" + | ||
| 989 | - std::to_string(xMDim) + "] or axis 0 of groupTensor [" + std::to_string(groupNum) + "]")); | ||
| 990 | - } else { | ||
| 991 | - GMM_CHECK_REPORT(perTokenFirstDim == groupNum, | ||
| 992 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 993 | - GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 994 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 995 | - "in non-pergroup quantification mode and when groupType is 0 (split M) and " | ||
| 996 | - "perTokenScale has 2 dims, axis 0 of perTokenScale must be equal to axis 0 of " | ||
| 997 | - "groupTensor [" + | ||
| 998 | - std::to_string(groupNum) + "]")); | ||
| 999 | - auto perTokenSecondDim = GetInputTensor(gmmParams_.perTokenScaleOptional)->GetViewShape().GetDim(1); | ||
| 1000 | - GMM_CHECK_REPORT(perTokenSecondDim == 1, | ||
| 1001 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1002 | - GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1003 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1004 | - "in non-pergroup quantification mode and when groupType is 0 (split M) and " | ||
| 1005 | - "perTokenScale has 2 dims, axis 1 of perTokenScale must be equal to 1")); | ||
| 1006 | - } | ||
| 1007 | } else if (gmmParams_.groupType == SPLIT_K) { | 1130 | } else if (gmmParams_.groupType == SPLIT_K) { |
| 1008 | - GMM_CHECK_REPORT(perTokenFirstDim == groupNum, | 1131 | + return CheckSplitKPerTokenShape(perTokenDimNumber, perTokenFirstDim, xMDim, groupNum); |
| 1009 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1010 | - GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1011 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1012 | - "in non-pergroup quantification mode and when groupType is 2 (split K), axis 0 of " | ||
| 1013 | - "perTokenScale must be equal to axis 0 of groupTensor [" + | ||
| 1014 | - std::to_string(groupNum) + "]")); | ||
| 1015 | - if (perTokenDimNumber > 1) { | ||
| 1016 | - auto perTokenSecondDim = GetInputTensor(gmmParams_.perTokenScaleOptional)->GetViewShape().GetDim(1); | ||
| 1017 | - GMM_CHECK_REPORT(perTokenSecondDim == xMDim || perTokenSecondDim == 1, | ||
| 1018 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1019 | - GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1020 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional)), | ||
| 1021 | - "in non-pergroup quantification mode and when groupType is 2 (split K) and " | ||
| 1022 | - "perTokenScale has 2 dims, axis 1 of perTokenScale must be equal to axis M of x [" + | ||
| 1023 | - std::to_string(xMDim) + "] or 1")); | ||
| 1024 | - } | ||
| 1025 | } | 1132 | } |
| 1026 | return ACLNN_SUCCESS; | 1133 | return ACLNN_SUCCESS; |
| 1027 | } | 1134 | } |
| @@ -1229,6 +1336,62 @@ bool AclnnGroupedMatmulDAV3510Checker<T>::IsPerTileQuantMode() const | |||
| 1229 | return isPerTileQuantMode; | 1336 | return isPerTileQuantMode; |
| 1230 | } | 1337 | } |
| 1231 | 1338 | ||
| 1339 | +template <typename T> | ||
| 1340 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckPerTileMNShape(size_t i, int64_t xMDim, int64_t perTokenMDim, | ||
| 1341 | + int64_t weightNDim, int64_t scaleNDim) const | ||
| 1342 | +{ | ||
| 1343 | + GMM_CHECK_REPORT( | ||
| 1344 | + xMDim == perTokenMDim, | ||
| 1345 | + OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( | ||
| 1346 | + GetAclnnOpName(), "x and perTokenScale", | ||
| 1347 | + xName_ + "=" + ViewShapeToString(GetInputTensor(gmmParams_.x, i)) + ", " + perTokenScaleName_ + "=" + | ||
| 1348 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, i)), | ||
| 1349 | + "when quantification mode is G-B quantification, the M value in x and perTokenScale should " | ||
| 1350 | + "be consistent")); | ||
| 1351 | + GMM_CHECK_REPORT( | ||
| 1352 | + scaleNDim == (weightNDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE, | ||
| 1353 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1354 | + GetAclnnOpName(), scaleName_.c_str(), ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, i)), | ||
| 1355 | + "when quantification mode is G-B quantification, axis N of scale must be equal to axis N of " | ||
| 1356 | + "weight divided by 128 [" + | ||
| 1357 | + std::to_string((weightNDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE) + "]")); | ||
| 1358 | + return ACLNN_SUCCESS; | ||
| 1359 | +} | ||
| 1360 | + | ||
| 1361 | +template <typename T> | ||
| 1362 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckPerTileKShape(size_t i, int64_t weightKDim, int64_t scaleKDim, | ||
| 1363 | + int64_t perTokenKDim) const | ||
| 1364 | +{ | ||
| 1365 | + if (gmmParams_.groupType == SPLIT_M) { | ||
| 1366 | + int64_t expectScaleKValue = (weightKDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE; | ||
| 1367 | + GMM_CHECK_REPORT( | ||
| 1368 | + perTokenKDim == scaleKDim && scaleKDim == expectScaleKValue, | ||
| 1369 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1370 | + GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1371 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, i)), | ||
| 1372 | + "when quantification mode is G-B quantification and groupType is 0 (split M), axis K of " | ||
| 1373 | + "perTokenScale must be equal to axis K of scale [" + | ||
| 1374 | + std::to_string(scaleKDim) + | ||
| 1375 | + "], and its value must be equal to axis K of weight divided by 128, rounded up to the " | ||
| 1376 | + "next integer [" + | ||
| 1377 | + std::to_string(expectScaleKValue) + "]")); | ||
| 1378 | + } else { | ||
| 1379 | + int64_t expectScaleKValue = | ||
| 1380 | + (weightKDim / PERTILE_GROUP_SIZE) + gmmParams_.groupTensorOptional->GetViewShape().GetDim(0); | ||
| 1381 | + GMM_CHECK_REPORT( | ||
| 1382 | + perTokenKDim == scaleKDim && scaleKDim == expectScaleKValue, | ||
| 1383 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1384 | + GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1385 | + ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, i)), | ||
| 1386 | + "when quantification mode is G-B quantification and groupType is 2 (split K), axis K of " | ||
| 1387 | + "perTokenScale must be equal to axis K of scale [" + | ||
| 1388 | + std::to_string(scaleKDim) + | ||
| 1389 | + "], and its value must be equal to axis K of weight divided by 128, plus groupSize [" + | ||
| 1390 | + std::to_string(expectScaleKValue) + "]")); | ||
| 1391 | + } | ||
| 1392 | + return ACLNN_SUCCESS; | ||
| 1393 | +} | ||
| 1394 | + | ||
| 1232 | template <typename T> | 1395 | template <typename T> |
| 1233 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulPerTileShape() const | 1396 | aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulPerTileShape() const |
| 1234 | { | 1397 | { |
| @@ -1244,48 +1407,10 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulPerTileShape( | |||
| 1244 | auto perTokenKDim = GetInputTensor(gmmParams_.perTokenScaleOptional, i)->GetViewShape().GetDim(xKIndex); | 1407 | auto perTokenKDim = GetInputTensor(gmmParams_.perTokenScaleOptional, i)->GetViewShape().GetDim(xKIndex); |
| 1245 | auto scaleNDim = GetInputTensor(gmmParams_.scaleOptional, i)->GetViewShape().GetDim(weightNIndex); | 1408 | auto scaleNDim = GetInputTensor(gmmParams_.scaleOptional, i)->GetViewShape().GetDim(weightNIndex); |
| 1246 | auto perTokenMDim = GetInputTensor(gmmParams_.perTokenScaleOptional, i)->GetViewShape().GetDim(xMIndex); | 1409 | auto perTokenMDim = GetInputTensor(gmmParams_.perTokenScaleOptional, i)->GetViewShape().GetDim(xMIndex); |
| 1247 | - GMM_CHECK_REPORT( | 1410 | + CHECK_RET(CheckPerTileMNShape(i, xMDim, perTokenMDim, weightNDim, scaleNDim) == ACLNN_SUCCESS, |
| 1248 | - xMDim == perTokenMDim, | 1411 | + ACLNN_ERR_PARAM_INVALID); |
| 1249 | - OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( | 1412 | + CHECK_RET(CheckPerTileKShape(i, weightKDim, scaleKDim, perTokenKDim) == ACLNN_SUCCESS, |
| 1250 | - GetAclnnOpName(), "x and perTokenScale", | 1413 | + ACLNN_ERR_PARAM_INVALID); |
| 1251 | - xName_ + "=" + ViewShapeToString(GetInputTensor(gmmParams_.x, i)) + ", " + perTokenScaleName_ + "=" + | ||
| 1252 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, i)), | ||
| 1253 | - "when quantification mode is G-B quantification, the M value in x and perTokenScale should " | ||
| 1254 | - "be consistent")); | ||
| 1255 | - GMM_CHECK_REPORT( | ||
| 1256 | - scaleNDim == (weightNDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE, | ||
| 1257 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1258 | - GetAclnnOpName(), scaleName_.c_str(), ViewShapeToString(GetInputTensor(gmmParams_.scaleOptional, i)), | ||
| 1259 | - "when quantification mode is G-B quantification, axis N of scale must be equal to axis N of " | ||
| 1260 | - "weight divided by 128 [" + | ||
| 1261 | - std::to_string((weightNDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE) + "]")); | ||
| 1262 | - if (gmmParams_.groupType == SPLIT_M) { | ||
| 1263 | - int64_t expectScaleKValue = (weightKDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE; | ||
| 1264 | - GMM_CHECK_REPORT( | ||
| 1265 | - perTokenKDim == scaleKDim && scaleKDim == expectScaleKValue, | ||
| 1266 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1267 | - GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1268 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, i)), | ||
| 1269 | - "when quantification mode is G-B quantification and groupType is 0 (split M), axis K of " | ||
| 1270 | - "perTokenScale must be equal to axis K of scale [" + | ||
| 1271 | - std::to_string(scaleKDim) + | ||
| 1272 | - "], and its value must be equal to axis K of weight divided by 128, rounded up to the " | ||
| 1273 | - "next integer [" + | ||
| 1274 | - std::to_string(expectScaleKValue) + "]")); | ||
| 1275 | - } else { | ||
| 1276 | - int64_t expectScaleKValue = | ||
| 1277 | - (weightKDim / PERTILE_GROUP_SIZE) + gmmParams_.groupTensorOptional->GetViewShape().GetDim(0); | ||
| 1278 | - GMM_CHECK_REPORT( | ||
| 1279 | - perTokenKDim == scaleKDim && scaleKDim == expectScaleKValue, | ||
| 1280 | - OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON( | ||
| 1281 | - GetAclnnOpName(), perTokenScaleName_.c_str(), | ||
| 1282 | - ViewShapeToString(GetInputTensor(gmmParams_.perTokenScaleOptional, i)), | ||
| 1283 | - "when quantification mode is G-B quantification and groupType is 2 (split K), axis K of " | ||
| 1284 | - "perTokenScale must be equal to axis K of scale [" + | ||
| 1285 | - std::to_string(scaleKDim) + | ||
| 1286 | - "], and its value must be equal to axis K of weight divided by 128, plus groupSize [" + | ||
| 1287 | - std::to_string(expectScaleKValue) + "]")); | ||
| 1288 | - } | ||
| 1289 | } | 1414 | } |
| 1290 | return ACLNN_SUCCESS; | 1415 | return ACLNN_SUCCESS; |
| 1291 | } | 1416 | } |
| @@ -1479,11 +1604,8 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckInputParamsForV3Version() | |||
| 1479 | } | 1604 | } |
| 1480 | 1605 | ||
| 1481 | template <typename T> | 1606 | template <typename T> |
| 1482 | -aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulDAV3510() const | 1607 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckBasicQuantParams(DataType yDtype) const |
| 1483 | { | 1608 | { |
| 1484 | - DataType xDtype = gmmParams_.xDtype; | ||
| 1485 | - DataType weightDtype = GetInputTensor(gmmParams_.weight)->GetDataType(); | ||
| 1486 | - DataType yDtype = GetInputTensor(gmmParams_.y)->GetDataType(); | ||
| 1487 | if (yDtype != DataType::DT_INT32) { | 1609 | if (yDtype != DataType::DT_INT32) { |
| 1488 | GMM_CHECK_REPORT( | 1610 | GMM_CHECK_REPORT( |
| 1489 | gmmParams_.scaleOptional != nullptr, | 1611 | gmmParams_.scaleOptional != nullptr, |
| @@ -1500,6 +1622,12 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulDAV3510() con | |||
| 1500 | gmmParams_.groupType != SPLIT_N, | 1622 | gmmParams_.groupType != SPLIT_N, |
| 1501 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(GetAclnnOpName(), "groupType", std::to_string(gmmParams_.groupType), | 1623 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(GetAclnnOpName(), "groupType", std::to_string(gmmParams_.groupType), |
| 1502 | "the value of groupType must be in 0 or 2")); | 1624 | "the value of groupType must be in 0 or 2")); |
| 1625 | + return ACLNN_SUCCESS; | ||
| 1626 | +} | ||
| 1627 | + | ||
| 1628 | +template <typename T> | ||
| 1629 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckQuantShapeAndFormat() const | ||
| 1630 | +{ | ||
| 1503 | const size_t xTensorNum = GetInputTensorSize(gmmParams_.x); | 1631 | const size_t xTensorNum = GetInputTensorSize(gmmParams_.x); |
| 1504 | const size_t weightTensorNum = GetInputTensorSize(gmmParams_.weight); | 1632 | const size_t weightTensorNum = GetInputTensorSize(gmmParams_.weight); |
| 1505 | const size_t yTensorNum = GetInputTensorSize(gmmParams_.y); | 1633 | const size_t yTensorNum = GetInputTensorSize(gmmParams_.y); |
| @@ -1515,14 +1643,13 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulDAV3510() con | |||
| 1515 | CHECK_RET(CheckWeightNzSpecialParams() == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | 1643 | CHECK_RET(CheckWeightNzSpecialParams() == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); |
| 1516 | } | 1644 | } |
| 1517 | CHECK_RET(CheckGeneralQuantShape() == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | 1645 | CHECK_RET(CheckGeneralQuantShape() == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); |
| 1646 | + return ACLNN_SUCCESS; | ||
| 1647 | +} | ||
| 1518 | 1648 | ||
| 1519 | - if (gmmParams_.apiVersion == gmm::GMMApiVersion::V3) { | 1649 | +template <typename T> |
| 1520 | - CHECK_RET(CheckInputParamsForV3Version() == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | 1650 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckQuantParamsByDtype(DataType xDtype, DataType weightDtype, |
| 1521 | - } | 1651 | + DataType yDtype, DataType scaleDtype) const |
| 1522 | - DataType scaleDtype = DataType::DT_UINT64; | 1652 | +{ |
| 1523 | - if (gmmParams_.scaleOptional != nullptr) { | ||
| 1524 | - scaleDtype = GetInputTensor(gmmParams_.scaleOptional)->GetDataType(); | ||
| 1525 | - } | ||
| 1526 | if (xDtype == DataType::DT_INT8 && weightDtype == DataType::DT_INT8) { | 1653 | if (xDtype == DataType::DT_INT8 && weightDtype == DataType::DT_INT8) { |
| 1527 | return CheckInt8QuantParams(); | 1654 | return CheckInt8QuantParams(); |
| 1528 | } else if (xDtype == DataType::DT_HIFLOAT8 && weightDtype == DataType::DT_HIFLOAT8) { | 1655 | } else if (xDtype == DataType::DT_HIFLOAT8 && weightDtype == DataType::DT_HIFLOAT8) { |
| @@ -1572,3 +1699,22 @@ aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulDAV3510() con | |||
| 1572 | } | 1699 | } |
| 1573 | return ACLNN_SUCCESS; | 1700 | return ACLNN_SUCCESS; |
| 1574 | } | 1701 | } |
| 1702 | + | ||
| 1703 | +template <typename T> | ||
| 1704 | +aclnnStatus AclnnGroupedMatmulDAV3510Checker<T>::CheckGroupedMatmulDAV3510() const | ||
| 1705 | +{ | ||
| 1706 | + DataType xDtype = gmmParams_.xDtype; | ||
| 1707 | + DataType weightDtype = GetInputTensor(gmmParams_.weight)->GetDataType(); | ||
| 1708 | + DataType yDtype = GetInputTensor(gmmParams_.y)->GetDataType(); | ||
| 1709 | + CHECK_RET(CheckBasicQuantParams(yDtype) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 1710 | + CHECK_RET(CheckQuantShapeAndFormat() == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 1711 | + | ||
| 1712 | + if (gmmParams_.apiVersion == gmm::GMMApiVersion::V3) { | ||
| 1713 | + CHECK_RET(CheckInputParamsForV3Version() == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 1714 | + } | ||
| 1715 | + DataType scaleDtype = DataType::DT_UINT64; | ||
| 1716 | + if (gmmParams_.scaleOptional != nullptr) { | ||
| 1717 | + scaleDtype = GetInputTensor(gmmParams_.scaleOptional)->GetDataType(); | ||
| 1718 | + } | ||
| 1719 | + return CheckQuantParamsByDtype(xDtype, weightDtype, yDtype, scaleDtype); | ||
| 1720 | +} | ||
| @@ -52,19 +52,39 @@ private: | |||
| 52 | aclnnStatus CheckWeightNzTensorShape(const aclTensor *weightTensor, const aclTensor *firstWeightTensor, | 52 | aclnnStatus CheckWeightNzTensorShape(const aclTensor *weightTensor, const aclTensor *firstWeightTensor, |
| 53 | size_t index, int64_t &firstKDimValue, int64_t &firstNDimValue) const; | 53 | size_t index, int64_t &firstKDimValue, int64_t &firstNDimValue) const; |
| 54 | aclnnStatus CheckWeightStorageShape(const aclTensor *weightTensor, int64_t kDimValue, int64_t nDimValue) const; | 54 | aclnnStatus CheckWeightStorageShape(const aclTensor *weightTensor, int64_t kDimValue, int64_t nDimValue) const; |
| 55 | + aclnnStatus CheckWeightNzStorageDim(const aclTensor *weightTensor) const; | ||
| 56 | + aclnnStatus CheckWeightNzC0(const aclTensor *weightTensor, int64_t weightStorageLastDim, | ||
| 57 | + int64_t &cubeBlockSizeK) const; | ||
| 58 | + aclnnStatus CheckWeightNzOuterDims(const aclTensor *weightTensor, int64_t kDimValue, int64_t nDimValue, | ||
| 59 | + int64_t cubeBlockSizeK, int64_t weightStorageLastFourthDim, | ||
| 60 | + int64_t weightStorageLastThirdDim) const; | ||
| 61 | + aclnnStatus CheckBasicQuantParams(DataType yDtype) const; | ||
| 62 | + aclnnStatus CheckQuantShapeAndFormat() const; | ||
| 63 | + aclnnStatus CheckQuantParamsByDtype(DataType xDtype, DataType weightDtype, DataType yDtype, | ||
| 64 | + DataType scaleDtype) const; | ||
| 55 | 65 | ||
| 56 | aclnnStatus CheckGroupedMatmulMxDtype() const; | 66 | aclnnStatus CheckGroupedMatmulMxDtype() const; |
| 57 | aclnnStatus CheckGroupedMatmulPerGroupDim() const; | 67 | aclnnStatus CheckGroupedMatmulPerGroupDim() const; |
| 68 | + aclnnStatus CheckPerGroupWeightDim(size_t weightDimNumber) const; | ||
| 69 | + aclnnStatus CheckPerGroupScaleDim(const TensorIndexInfo &tensorIndex, size_t scaleDimNumber, | ||
| 70 | + size_t perTokenDimNumber, size_t xDimNumber, size_t weightDimNumber) const; | ||
| 58 | aclnnStatus CheckGroupedMatmulMxShape() const; | 71 | aclnnStatus CheckGroupedMatmulMxShape() const; |
| 59 | aclnnStatus CheckGroupedMatmulMxScaleTranspose() const; | 72 | aclnnStatus CheckGroupedMatmulMxScaleTranspose() const; |
| 60 | aclnnStatus CheckGroupedMatmulPerTile() const; | 73 | aclnnStatus CheckGroupedMatmulPerTile() const; |
| 61 | aclnnStatus CheckGroupedMatmulPerTileShape() const; | 74 | aclnnStatus CheckGroupedMatmulPerTileShape() const; |
| 75 | + aclnnStatus CheckPerTileMNShape(size_t i, int64_t xMDim, int64_t perTokenMDim, int64_t weightNDim, | ||
| 76 | + int64_t scaleNDim) const; | ||
| 77 | + aclnnStatus CheckPerTileKShape(size_t i, int64_t weightKDim, int64_t scaleKDim, int64_t perTokenKDim) const; | ||
| 62 | aclnnStatus CheckGroupedMatmulMxfp8() const; | 78 | aclnnStatus CheckGroupedMatmulMxfp8() const; |
| 63 | aclnnStatus CheckGroupedMatmulMxfp4() const; | 79 | aclnnStatus CheckGroupedMatmulMxfp4() const; |
| 64 | aclnnStatus CheckGroupedMatmulFp4MxDimValue() const; | 80 | aclnnStatus CheckGroupedMatmulFp4MxDimValue() const; |
| 65 | 81 | ||
| 66 | aclnnStatus CheckNonPerGroupQuantDim() const; | 82 | aclnnStatus CheckNonPerGroupQuantDim() const; |
| 67 | aclnnStatus CheckNonPerGroupQuantPertokenShape() const; | 83 | aclnnStatus CheckNonPerGroupQuantPertokenShape() const; |
| 84 | + aclnnStatus CheckSplitMPerTokenShape(size_t perTokenDimNumber, int64_t perTokenFirstDim, int64_t xMDim, | ||
| 85 | + int64_t groupNum) const; | ||
| 86 | + aclnnStatus CheckSplitKPerTokenShape(size_t perTokenDimNumber, int64_t perTokenFirstDim, int64_t xMDim, | ||
| 87 | + int64_t groupNum) const; | ||
| 68 | aclnnStatus CheckNonPerGroupQuantShape() const; | 88 | aclnnStatus CheckNonPerGroupQuantShape() const; |
| 69 | aclnnStatus CheckInt8QuantDtype() const; | 89 | aclnnStatus CheckInt8QuantDtype() const; |
| 70 | aclnnStatus CheckInt8QuantParams() const; | 90 | aclnnStatus CheckInt8QuantParams() const; |
| @@ -82,7 +102,23 @@ private: | |||
| 82 | bool IsWeightNzMultiTensorLayout() const; | 102 | bool IsWeightNzMultiTensorLayout() const; |
| 83 | TensorIndexInfo GetTensorIndexInfo(size_t index = 0) const; | 103 | TensorIndexInfo GetTensorIndexInfo(size_t index = 0) const; |
| 84 | aclnnStatus CheckMxFp8TypeKCaseInputShape(const TensorDimInfo &dimInfo, size_t index) const; | 104 | aclnnStatus CheckMxFp8TypeKCaseInputShape(const TensorDimInfo &dimInfo, size_t index) const; |
| 105 | + aclnnStatus CheckMxSplitKDimNum(const TensorDimInfo &dimInfo) const; | ||
| 106 | + aclnnStatus CheckMxSplitKDimValue(const TensorIndexInfo &tensorIndex, int64_t groupNum) const; | ||
| 107 | + struct MxTypeMDims { | ||
| 108 | + int64_t xMDimValue; | ||
| 109 | + int64_t xKDimValue; | ||
| 110 | + int64_t pertokenMDimValue; | ||
| 111 | + int64_t pertokenScaleKDimValue; | ||
| 112 | + int64_t pertokenScaleLastDimValue; | ||
| 113 | + int64_t weightNDimValue; | ||
| 114 | + int64_t inferedScaleKDimValue; | ||
| 115 | + int64_t scaleLastDimValue; | ||
| 116 | + }; | ||
| 85 | aclnnStatus CheckMxTypeMCaseInputShape(const TensorDimInfo &dimInfo, size_t index) const; | 117 | aclnnStatus CheckMxTypeMCaseInputShape(const TensorDimInfo &dimInfo, size_t index) const; |
| 118 | + MxTypeMDims ExtractMxTypeMDims(const TensorDimInfo &dimInfo, size_t index) const; | ||
| 119 | + aclnnStatus CheckMxTypeMScaleShape(const MxTypeMDims &dims, const TensorDimInfo &tensorIndex) const; | ||
| 120 | + aclnnStatus CheckMxTypeMPerTokenAndScaleLastDim(const MxTypeMDims &dims, | ||
| 121 | + const TensorDimInfo &tensorIndex) const; | ||
| 86 | aclnnStatus CheckMxBiasInputShape(const TensorDimInfo &dimInfo, size_t index) const; | 122 | aclnnStatus CheckMxBiasInputShape(const TensorDimInfo &dimInfo, size_t index) const; |
| 87 | bool LastTwoDimValueIsOne(const aclTensor *tensor) const; | 123 | bool LastTwoDimValueIsOne(const aclTensor *tensor) const; |
| 88 | bool IsSpecialperTileScene(int64_t groupNum, int64_t weightNDim, int64_t weightKDim, int64_t xMDim, | 124 | bool IsSpecialperTileScene(int64_t groupNum, int64_t weightNDim, int64_t weightKDim, int64_t xMDim, |
| @@ -282,6 +282,81 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckTensorDtype(const | |||
| 282 | return ACLNN_SUCCESS; | 282 | return ACLNN_SUCCESS; |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | +aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::GetExpectedDimNum( | ||
| 286 | + const AclnnGroupedMatmulWeightQuantDAV3510Checker &checker, const std::string &tensorType, size_t tensorDimNum, | ||
| 287 | + size_t &expectedDimNum) | ||
| 288 | +{ | ||
| 289 | + if ((checker.IsA16MxFp4NZ() || checker.IsS8S4NZ()) && tensorType.find("antiquant") != std::string::npos) { | ||
| 290 | + expectedDimNum = 3; // Mx / PerGroup量化,仅支持antiquantSacle/antiquantOffset维度为3 | ||
| 291 | + } else if (checker.IsMxA8W4NZ()) { | ||
| 292 | + if (tensorType.find("antiquant") != std::string::npos) { | ||
| 293 | + expectedDimNum = | ||
| 294 | + checker.IsMultiTensorWeight() ? MX_MULTI_ANTIQUANT_SCALE_DIM : MX_SINGLE_ANTIQUANT_SCALE_DIM; | ||
| 295 | + } else if (tensorType.find("token") != std::string::npos) { | ||
| 296 | + expectedDimNum = 3; // MxA8W4场景,perTokenScale维度为3 | ||
| 297 | + } else if (tensorType.find("bias") != std::string::npos) { | ||
| 298 | + expectedDimNum = checker.IsMultiTensorWeight() ? MX_MULTI_BIAS_DIM : MX_SINGLE_BIAS_DIM; | ||
| 299 | + } | ||
| 300 | + } else if (checker.IsA16W4() && tensorType.find("antiquant") != std::string::npos) { | ||
| 301 | + size_t perchannelDim = | ||
| 302 | + checker.gmmParams_.groupType == SPLIT_M ? 2 : 1; // 单单单场景默认维度为2,多多多场景默认维度为1 | ||
| 303 | + size_t pergroupDim = perchannelDim + 1; | ||
| 304 | + if (tensorDimNum != perchannelDim && tensorDimNum != pergroupDim) { | ||
| 305 | + std::string reason = "When x_dtype-weight_dtype is fp16/bf16-int4, Dim must be [" + | ||
| 306 | + std::to_string(perchannelDim) + "] (perchannel) or [" + std::to_string(pergroupDim) + | ||
| 307 | + "] (pergroup), but now is [" + std::to_string(tensorDimNum) + "]"; | ||
| 308 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(checker.GetAclnnName(), tensorType, | ||
| 309 | + std::to_string(tensorDimNum), reason); | ||
| 310 | + return ACLNN_ERR_PARAM_INVALID; | ||
| 311 | + } | ||
| 312 | + expectedDimNum = tensorDimNum; | ||
| 313 | + } | ||
| 314 | + return ACLNN_SUCCESS; | ||
| 315 | +} | ||
| 316 | + | ||
| 317 | +aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckBatchSizeConsistency( | ||
| 318 | + const AclnnGroupedMatmulWeightQuantDAV3510Checker &checker, const op::Shape &tensorShape, | ||
| 319 | + const op::Shape &weightShape, const std::string &tensorType) | ||
| 320 | +{ | ||
| 321 | + if (checker.gmmParams_.groupType == SPLIT_M && !checker.IsMultiTensorWeight()) { | ||
| 322 | + uint64_t groupNum = weightShape.GetDim(0); | ||
| 323 | + uint64_t batchSize = tensorShape.GetDim(0); | ||
| 324 | + if (unlikely(batchSize != groupNum)) { | ||
| 325 | + std::string incorrectValue = std::to_string(batchSize); | ||
| 326 | + std::string reason = "batch size[" + incorrectValue + "] should be equal with groupList length[" + | ||
| 327 | + std::to_string(groupNum) + "]"; | ||
| 328 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(checker.GetAclnnName(), tensorType, incorrectValue, reason); | ||
| 329 | + return ACLNN_ERR_PARAM_INVALID; | ||
| 330 | + } | ||
| 331 | + } | ||
| 332 | + return ACLNN_SUCCESS; | ||
| 333 | +} | ||
| 334 | + | ||
| 335 | +// Check tensor’s Ndim must match weight’s Ndim. | ||
| 336 | +aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckNDimConsistency( | ||
| 337 | + const AclnnGroupedMatmulWeightQuantDAV3510Checker &checker, const op::Shape &tensorShape, | ||
| 338 | + const op::Shape &weightShape, size_t tensorDimNum, const std::string &tensorType) | ||
| 339 | +{ | ||
| 340 | + uint64_t weightNDimIdx = | ||
| 341 | + checker.IsS8S4SpecialWeightFormat() ? S8S4_WEIGHT_K_DIM : weightShape.GetDimNum() - 1; | ||
| 342 | + int64_t weightNDimValue = weightShape.GetDim(weightNDimIdx); | ||
| 343 | + int64_t tensorNDimValue; | ||
| 344 | + if (checker.IsMxA8W4NZ() && tensorType.find("antiquant") != std::string::npos) { // viewShape,所以是-2 | ||
| 345 | + tensorNDimValue = tensorShape.GetDim(tensorDimNum - 2); | ||
| 346 | + } else { | ||
| 347 | + tensorNDimValue = tensorShape.GetDim(tensorDimNum - 1); | ||
| 348 | + } | ||
| 349 | + if (unlikely(tensorNDimValue != weightNDimValue)) { | ||
| 350 | + std::string incorrectValues = std::to_string(tensorNDimValue) + ", " + std::to_string(weightNDimValue); | ||
| 351 | + std::string reason = "NDim[" + std::to_string(tensorNDimValue) + "] of " + tensorType + | ||
| 352 | + " must be equal to NDim[" + std::to_string(weightNDimValue) + "] of weight"; | ||
| 353 | + OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(checker.GetAclnnName(), tensorType + ", weight", incorrectValues, | ||
| 354 | + reason); | ||
| 355 | + return ACLNN_ERR_PARAM_INVALID; | ||
| 356 | + } | ||
| 357 | + return ACLNN_SUCCESS; | ||
| 358 | +} | ||
| 359 | + | ||
| 285 | aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckTensorShape(const aclTensorList *tensorList, size_t idx, | 360 | aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckTensorShape(const aclTensorList *tensorList, size_t idx, |
| 286 | const std::string &tensorType) const | 361 | const std::string &tensorType) const |
| 287 | { | 362 | { |
| @@ -292,28 +367,8 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckTensorShape(const | |||
| 292 | size_t tensorDimNum = tensorShape.GetDimNum(); | 367 | size_t tensorDimNum = tensorShape.GetDimNum(); |
| 293 | size_t expectedDimNum = gmmParams_.groupType == SPLIT_M ? 2 : 1; // 单单单场景默认维度为2,多多多场景默认维度为1 | 368 | size_t expectedDimNum = gmmParams_.groupType == SPLIT_M ? 2 : 1; // 单单单场景默认维度为2,多多多场景默认维度为1 |
| 294 | 369 | ||
| 295 | - if ((IsA16MxFp4NZ() || IsS8S4NZ()) && tensorType.find("antiquant") != std::string::npos) { | 370 | + CHECK_RET(GetExpectedDimNum(*this, tensorType, tensorDimNum, expectedDimNum) == ACLNN_SUCCESS, |
| 296 | - expectedDimNum = 3; // Mx / PerGroup量化,仅支持antiquantSacle/antiquantOffset维度为3 | 371 | + ACLNN_ERR_PARAM_INVALID); |
| 297 | - } else if (IsMxA8W4NZ()) { | ||
| 298 | - if (tensorType.find("antiquant") != std::string::npos) { | ||
| 299 | - expectedDimNum = IsMultiTensorWeight() ? MX_MULTI_ANTIQUANT_SCALE_DIM : MX_SINGLE_ANTIQUANT_SCALE_DIM; | ||
| 300 | - } else if (tensorType.find("token") != std::string::npos) { | ||
| 301 | - expectedDimNum = 3; // MxA8W4场景,perTokenScale维度为3 | ||
| 302 | - } else if (tensorType.find("bias") != std::string::npos) { | ||
| 303 | - expectedDimNum = IsMultiTensorWeight() ? MX_MULTI_BIAS_DIM : MX_SINGLE_BIAS_DIM; | ||
| 304 | - } | ||
| 305 | - } else if (IsA16W4() && tensorType.find("antiquant") != std::string::npos) { | ||
| 306 | - size_t perchannelDim = gmmParams_.groupType == SPLIT_M ? 2 : 1; // 单单单场景默认维度为2,多多多场景默认维度为1 | ||
| 307 | - size_t pergroupDim = perchannelDim + 1; | ||
| 308 | - if (tensorDimNum != perchannelDim && tensorDimNum != pergroupDim) { | ||
| 309 | - std::string reason = "When x_dtype-weight_dtype is fp16/bf16-int4, Dim must be [" + | ||
| 310 | - std::to_string(perchannelDim) + "] (perchannel) or [" + std::to_string(pergroupDim) + | ||
| 311 | - "] (pergroup), but now is [" + std::to_string(tensorDimNum) + "]"; | ||
| 312 | - OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(GetAclnnName(), tensorType, std::to_string(tensorDimNum), reason); | ||
| 313 | - return ACLNN_ERR_PARAM_INVALID; | ||
| 314 | - } | ||
| 315 | - expectedDimNum = tensorDimNum; | ||
| 316 | - } | ||
| 317 | 372 | ||
| 318 | if (unlikely(tensorDimNum != expectedDimNum)) { | 373 | if (unlikely(tensorDimNum != expectedDimNum)) { |
| 319 | std::string incorrectDim = std::to_string(tensorDimNum); | 374 | std::string incorrectDim = std::to_string(tensorDimNum); |
| @@ -322,35 +377,11 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckTensorShape(const | |||
| 322 | return ACLNN_ERR_PARAM_INVALID; | 377 | return ACLNN_ERR_PARAM_INVALID; |
| 323 | } | 378 | } |
| 324 | 379 | ||
| 325 | - if (gmmParams_.groupType == SPLIT_M && !IsMultiTensorWeight()) { | 380 | + CHECK_RET(CheckBatchSizeConsistency(*this, tensorShape, wShape, tensorType) == ACLNN_SUCCESS, |
| 326 | - uint64_t groupNum = wShape.GetDim(0); | 381 | + ACLNN_ERR_PARAM_INVALID); |
| 327 | - uint64_t batchSize = tensorShape.GetDim(0); | ||
| 328 | - if (unlikely(batchSize != groupNum)) { | ||
| 329 | - std::string incorrectValue = std::to_string(batchSize); | ||
| 330 | - std::string reason = "batch size[" + incorrectValue + "] should be equal with groupList length[" + | ||
| 331 | - std::to_string(groupNum) + "]"; | ||
| 332 | - OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(GetAclnnName(), tensorType, incorrectValue, reason); | ||
| 333 | - return ACLNN_ERR_PARAM_INVALID; | ||
| 334 | - } | ||
| 335 | - } | ||
| 336 | 382 | ||
| 337 | - // Check tensor’s Ndim must match weight’s Ndim. | 383 | + CHECK_RET(CheckNDimConsistency(*this, tensorShape, wShape, tensorDimNum, tensorType) == ACLNN_SUCCESS, |
| 338 | - uint64_t weightNDimIdx = | 384 | + ACLNN_ERR_PARAM_INVALID); |
| 339 | - IsS8S4SpecialWeightFormat() ? S8S4_WEIGHT_K_DIM : wShape.GetDimNum() - 1; | ||
| 340 | - int64_t weightNDimValue = wShape.GetDim(weightNDimIdx); | ||
| 341 | - int64_t tensorNDimValue; | ||
| 342 | - if (IsMxA8W4NZ() && tensorType.find("antiquant") != std::string::npos) { // viewShape,所以是-2 | ||
| 343 | - tensorNDimValue = tensorShape.GetDim(tensorDimNum - 2); | ||
| 344 | - } else { | ||
| 345 | - tensorNDimValue = tensorShape.GetDim(tensorDimNum - 1); | ||
| 346 | - } | ||
| 347 | - if (unlikely(tensorNDimValue != weightNDimValue)) { | ||
| 348 | - std::string incorrectValues = std::to_string(tensorNDimValue) + ", " + std::to_string(weightNDimValue); | ||
| 349 | - std::string reason = "NDim[" + std::to_string(tensorNDimValue) + "] of " + tensorType + | ||
| 350 | - " must be equal to NDim[" + std::to_string(weightNDimValue) + "] of weight"; | ||
| 351 | - OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(GetAclnnName(), tensorType + ", weight", incorrectValues, reason); | ||
| 352 | - return ACLNN_ERR_PARAM_INVALID; | ||
| 353 | - } | ||
| 354 | 385 | ||
| 355 | return ACLNN_SUCCESS; | 386 | return ACLNN_SUCCESS; |
| 356 | } | 387 | } |
| @@ -430,8 +461,7 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckQuantParams() cons | |||
| 430 | return ACLNN_SUCCESS; | 461 | return ACLNN_SUCCESS; |
| 431 | } | 462 | } |
| 432 | 463 | ||
| 433 | -aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckDimNumAndFormat(size_t xIdx, size_t yIdx, | 464 | +aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckInputFormat(size_t xIdx, size_t yIdx) const |
| 434 | - size_t wIdx) const | ||
| 435 | { | 465 | { |
| 436 | if (IsS8S4PseudoQuant()) { | 466 | if (IsS8S4PseudoQuant()) { |
| 437 | CHECK_COND(ge::GetPrimaryFormat((*gmmParams_.x)[xIdx]->GetStorageFormat()) == op::Format::FORMAT_ND && | 467 | CHECK_COND(ge::GetPrimaryFormat((*gmmParams_.x)[xIdx]->GetStorageFormat()) == op::Format::FORMAT_ND && |
| @@ -448,7 +478,11 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckDimNumAndFormat(si | |||
| 448 | op::ToString((*gmmParams_.y)[yIdx]->GetStorageFormat()).GetString(), "ND"); | 478 | op::ToString((*gmmParams_.y)[yIdx]->GetStorageFormat()).GetString(), "ND"); |
| 449 | return ACLNN_ERR_PARAM_INVALID; | 479 | return ACLNN_ERR_PARAM_INVALID; |
| 450 | } | 480 | } |
| 481 | + return ACLNN_SUCCESS; | ||
| 482 | +} | ||
| 451 | 483 | ||
| 484 | +aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckWeightFormat(size_t wIdx) const | ||
| 485 | +{ | ||
| 452 | if (IsS8S4PseudoQuant()) { | 486 | if (IsS8S4PseudoQuant()) { |
| 453 | const auto weightFormat = static_cast<op::Format>( | 487 | const auto weightFormat = static_cast<op::Format>( |
| 454 | ge::GetPrimaryFormat((*gmmParams_.weight)[wIdx]->GetStorageFormat())); | 488 | ge::GetPrimaryFormat((*gmmParams_.weight)[wIdx]->GetStorageFormat())); |
| @@ -478,12 +512,13 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckDimNumAndFormat(si | |||
| 478 | return ACLNN_ERR_PARAM_INVALID; | 512 | return ACLNN_ERR_PARAM_INVALID; |
| 479 | } | 513 | } |
| 480 | } | 514 | } |
| 515 | + return ACLNN_SUCCESS; | ||
| 516 | +} | ||
| 481 | 517 | ||
| 482 | - // check dimNum | 518 | +aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckDimNumByGroupType(size_t xIdx, size_t wIdx, |
| 483 | - size_t xDimNum = (*gmmParams_.x)[xIdx]->GetViewShape().GetDimNum(); | 519 | + size_t xDimNum, |
| 484 | - size_t weightDimNum = (*gmmParams_.weight)[wIdx]->GetViewShape().GetDimNum(); | 520 | + size_t weightDimNum) const |
| 485 | - size_t yDimNum = (*gmmParams_.y)[yIdx]->GetViewShape().GetDimNum(); | 521 | +{ |
| 486 | - | ||
| 487 | if (gmmParams_.groupType == NO_SPLIT) { | 522 | if (gmmParams_.groupType == NO_SPLIT) { |
| 488 | if (IsA16W4Pergroup(wIdx)) { | 523 | if (IsA16W4Pergroup(wIdx)) { |
| 489 | if (unlikely(xDimNum != MIN_FM_DIM)) { | 524 | if (unlikely(xDimNum != MIN_FM_DIM)) { |
| @@ -529,6 +564,21 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckDimNumAndFormat(si | |||
| 529 | } | 564 | } |
| 530 | } | 565 | } |
| 531 | } | 566 | } |
| 567 | + return ACLNN_SUCCESS; | ||
| 568 | +} | ||
| 569 | + | ||
| 570 | +aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckDimNumAndFormat(size_t xIdx, size_t yIdx, | ||
| 571 | + size_t wIdx) const | ||
| 572 | +{ | ||
| 573 | + CHECK_RET(CheckInputFormat(xIdx, yIdx) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 574 | + CHECK_RET(CheckWeightFormat(wIdx) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 575 | + | ||
| 576 | + // check dimNum | ||
| 577 | + size_t xDimNum = (*gmmParams_.x)[xIdx]->GetViewShape().GetDimNum(); | ||
| 578 | + size_t weightDimNum = (*gmmParams_.weight)[wIdx]->GetViewShape().GetDimNum(); | ||
| 579 | + size_t yDimNum = (*gmmParams_.y)[yIdx]->GetViewShape().GetDimNum(); | ||
| 580 | + | ||
| 581 | + CHECK_RET(CheckDimNumByGroupType(xIdx, wIdx, xDimNum, weightDimNum) == ACLNN_SUCCESS, ACLNN_ERR_PARAM_INVALID); | ||
| 532 | 582 | ||
| 533 | if (unlikely(xDimNum != yDimNum)) { | 583 | if (unlikely(xDimNum != yDimNum)) { |
| 534 | std::string incorrectValues = std::to_string(xDimNum) + ", " + std::to_string(yDimNum); | 584 | std::string incorrectValues = std::to_string(xDimNum) + ", " + std::to_string(yDimNum); |
| @@ -967,7 +1017,7 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckS8S4NZScaleShape() | |||
| 967 | return ACLNN_ERR_PARAM_INVALID; | 1017 | return ACLNN_ERR_PARAM_INVALID; |
| 968 | } | 1018 | } |
| 969 | auto scaleShape = (*gmmParams_.scaleOptional)[0]->GetViewShape(); | 1019 | auto scaleShape = (*gmmParams_.scaleOptional)[0]->GetViewShape(); |
| 970 | - if (unlikely(scaleShape.GetDimNum() != 2)) { | 1020 | + if (unlikely(scaleShape.GetDimNum() != 2)) { //S8S4 NZ 模式下 scale tensor 必须是 2 维 |
| 971 | OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(GetAclnnName(), "scale", std::to_string(scaleShape.GetDimNum()), | 1021 | OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(GetAclnnName(), "scale", std::to_string(scaleShape.GetDimNum()), |
| 972 | "The shape dim of scale must be 2"); | 1022 | "The shape dim of scale must be 2"); |
| 973 | return ACLNN_ERR_PARAM_INVALID; | 1023 | return ACLNN_ERR_PARAM_INVALID; |
| @@ -977,7 +1027,7 @@ aclnnStatus AclnnGroupedMatmulWeightQuantDAV3510Checker::CheckS8S4NZScaleShape() | |||
| 977 | "The dim0 of scale must be equal to g"); | 1027 | "The dim0 of scale must be equal to g"); |
| 978 | return ACLNN_ERR_PARAM_INVALID; | 1028 | return ACLNN_ERR_PARAM_INVALID; |
| 979 | } | 1029 | } |
| 980 | - if (unlikely(scaleShape.GetDim(1) != weightShape.GetDim(2))) { | 1030 | + if (unlikely(scaleShape.GetDim(1) != weightShape.GetDim(2))) { //校验 S8S4 NZ 格式下 scale tensor 的 N 维度是否和 weight tensor 的 N 维度一致 |
| 981 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(GetAclnnName(), "scale", std::to_string(scaleShape.GetDim(1)), | 1031 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(GetAclnnName(), "scale", std::to_string(scaleShape.GetDim(1)), |
| 982 | "The dim1 of scale must be equal to n"); | 1032 | "The dim1 of scale must be equal to n"); |
| 983 | return ACLNN_ERR_PARAM_INVALID; | 1033 | return ACLNN_ERR_PARAM_INVALID; |
| @@ -38,9 +38,21 @@ private: | |||
| 38 | aclnnStatus CheckTensorDtype(const aclTensorList *tensorList, const DataType &tensorDtype, size_t idx, | 38 | aclnnStatus CheckTensorDtype(const aclTensorList *tensorList, const DataType &tensorDtype, size_t idx, |
| 39 | const std::string &tensorType) const; | 39 | const std::string &tensorType) const; |
| 40 | aclnnStatus CheckTensorShape(const aclTensorList *tensorList, size_t idx, const std::string &tensorType) const; | 40 | aclnnStatus CheckTensorShape(const aclTensorList *tensorList, size_t idx, const std::string &tensorType) const; |
| 41 | + static aclnnStatus GetExpectedDimNum(const AclnnGroupedMatmulWeightQuantDAV3510Checker &checker, | ||
| 42 | + const std::string &tensorType, size_t tensorDimNum, | ||
| 43 | + size_t &expectedDimNum); | ||
| 44 | + static aclnnStatus CheckBatchSizeConsistency(const AclnnGroupedMatmulWeightQuantDAV3510Checker &checker, | ||
| 45 | + const op::Shape &tensorShape, const op::Shape &weightShape, | ||
| 46 | + const std::string &tensorType); | ||
| 47 | + static aclnnStatus CheckNDimConsistency(const AclnnGroupedMatmulWeightQuantDAV3510Checker &checker, | ||
| 48 | + const op::Shape &tensorShape, const op::Shape &weightShape, | ||
| 49 | + size_t tensorDimNum, const std::string &tensorType); | ||
| 41 | 50 | ||
| 42 | aclnnStatus CheckWeightInnerAxisEven(size_t idx) const; | 51 | aclnnStatus CheckWeightInnerAxisEven(size_t idx) const; |
| 43 | aclnnStatus CheckDimNumAndFormat(size_t xIdx, size_t yIdx, size_t wIdx) const; | 52 | aclnnStatus CheckDimNumAndFormat(size_t xIdx, size_t yIdx, size_t wIdx) const; |
| 53 | + aclnnStatus CheckInputFormat(size_t xIdx, size_t yIdx) const; | ||
| 54 | + aclnnStatus CheckWeightFormat(size_t wIdx) const; | ||
| 55 | + aclnnStatus CheckDimNumByGroupType(size_t xIdx, size_t wIdx, size_t xDimNum, size_t weightDimNum) const; | ||
| 44 | aclnnStatus CheckTransposeStatus() const; | 56 | aclnnStatus CheckTransposeStatus() const; |
| 45 | aclnnStatus CheckDimValue(size_t xIdx, size_t yIdx, size_t wIdx) const; | 57 | aclnnStatus CheckDimValue(size_t xIdx, size_t yIdx, size_t wIdx) const; |
| 46 | aclnnStatus CheckDimMatching(size_t xIdx, size_t yIdx, size_t wIdx) const; | 58 | aclnnStatus CheckDimMatching(size_t xIdx, size_t yIdx, size_t wIdx) const; |
| @@ -73,7 +85,7 @@ private: | |||
| 73 | bool IsS8S4AsymmetricQuant() const; | 85 | bool IsS8S4AsymmetricQuant() const; |
| 74 | bool IsA16W4() const; | 86 | bool IsA16W4() const; |
| 75 | bool IsMultiTensorWeight() const; | 87 | bool IsMultiTensorWeight() const; |
| 76 | - bool IsA16W4Pergroup(const size_t xIdx) const; | 88 | + bool IsA16W4Pergroup(const size_t idx) const; |
| 77 | 89 | ||
| 78 | std::string GetDataFlowString() const; | 90 | std::string GetDataFlowString() const; |
| 79 | const char *GetAclnnName() const; | 91 | const char *GetAclnnName() const; |
| @@ -283,49 +283,117 @@ static bool IsPerTileQuantMode(const OpExecuteContext* host_api_ctx, bool transp | |||
| 283 | return (scaleNDim == (weightNDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE && isKdimValid); | 283 | return (scaleNDim == (weightNDim + PERTILE_GROUP_SIZE - 1) / PERTILE_GROUP_SIZE && isKdimValid); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | +struct GmmExecuteAttrs { | ||
| 287 | + const int64_t* splitItemGe; | ||
| 288 | + const bool* isWeightTransposedPtr; | ||
| 289 | + const bool* isXTransposed; | ||
| 290 | + const int64_t* groupTypeGe; | ||
| 291 | + const int64_t* groupListTypeGe; | ||
| 292 | + const int64_t* actTypeGe; | ||
| 293 | + const gert::TypedContinuousVector<int64_t>* tuningConfigGe; | ||
| 294 | +}; | ||
| 295 | + | ||
| 296 | +static graphStatus GetGmmAttrs(const OpExecuteContext* host_api_ctx, GmmExecuteAttrs& out) | ||
| 297 | +{ | ||
| 298 | + auto attrs = host_api_ctx->GetAttrs(); | ||
| 299 | + OP_CHECK_IF(attrs == nullptr, OP_LOGE("aclnnfallback", "attrs is null"), return GRAPH_FAILED); | ||
| 300 | + out.splitItemGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_SPLIT_ITEM); | ||
| 301 | + OP_CHECK_IF(out.splitItemGe == nullptr, OP_LOGE("aclnnfallback", "splitItemGe is null"), return GRAPH_FAILED); | ||
| 302 | + out.isWeightTransposedPtr = attrs->GetAttrPointer<bool>(INDEX_GMM_ATTR_TRANSPOSE_WEIGHT); | ||
| 303 | + OP_CHECK_IF(out.isWeightTransposedPtr == nullptr, OP_LOGE("aclnnfallback", "isWeightTransposedPtr is null"), | ||
| 304 | + return GRAPH_FAILED); | ||
| 305 | + out.isXTransposed = attrs->GetAttrPointer<bool>(INDEX_GMM_ATTR_TRANSPOSE_X); | ||
| 306 | + OP_CHECK_IF(out.isXTransposed == nullptr, OP_LOGE("aclnnfallback", "isXTransposed is null"), return GRAPH_FAILED); | ||
| 307 | + out.groupTypeGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_GROUP_TYPE); | ||
| 308 | + OP_CHECK_IF(out.groupTypeGe == nullptr, OP_LOGE("aclnnfallback", "groupTypeGe is null"), return GRAPH_FAILED); | ||
| 309 | + out.groupListTypeGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_GROUP_LIST_TYPE); | ||
| 310 | + OP_CHECK_IF(out.groupListTypeGe == nullptr, OP_LOGE("aclnnfallback", "groupListTypeGe is null"), return GRAPH_FAILED); | ||
| 311 | + out.actTypeGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_ACT_TYPE); | ||
| 312 | + OP_CHECK_IF(out.actTypeGe == nullptr, OP_LOGE("aclnnfallback", "actTypeGe is null"), return GRAPH_FAILED); | ||
| 313 | + out.tuningConfigGe = attrs->GetListInt(INDEX_GMM_ATTR_TUNING_CONFIG); | ||
| 314 | + OP_CHECK_IF(out.tuningConfigGe == nullptr, OP_LOGE("aclnnfallback", "tuningConfigGe is null"), return GRAPH_FAILED); | ||
| 315 | + return GRAPH_SUCCESS; | ||
| 316 | +} | ||
| 317 | + | ||
| 318 | +static graphStatus PreparePerTokenScaleList(const OpExecuteContext* host_api_ctx, | ||
| 319 | + std::vector<const aclTensor*>& perTokenScaleVec, | ||
| 320 | + bool isXTransposed, bool isPerTile) | ||
| 321 | +{ | ||
| 322 | + auto perTokenScaleTensor = host_api_ctx->GetOptionalInputTensor(INDEX_GMM_INPUT_PER_TOKEN_SCALE); | ||
| 323 | + auto perTokenScale = ConvertType(perTokenScaleTensor); | ||
| 324 | + if (perTokenScale == nullptr) { | ||
| 325 | + std::vector<int64_t> shape{0}; | ||
| 326 | + static const auto aclCreateTensor = GET_OP_API_FUNC(aclCreateTensor); | ||
| 327 | + OP_CHECK_IF(aclCreateTensor == nullptr, OP_LOGE("aclnnfallback", "aclCreateTensor nullptr"), return GRAPH_FAILED); | ||
| 328 | + perTokenScale = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT, shape.data(), | ||
| 329 | + 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), nullptr); | ||
| 330 | + OP_CHECK_IF(perTokenScale == nullptr, OP_LOGE("aclnnfallback", "perTokenScale nullptr"), return GRAPH_FAILED); | ||
| 331 | + } | ||
| 332 | + if (perTokenScaleTensor != nullptr && (perTokenScaleTensor->GetDataType() == ge::DataType::DT_FLOAT8_E8M0 || | ||
| 333 | + isPerTile)) { | ||
| 334 | + PrepareAclTensorVector(host_api_ctx, perTokenScaleVec, INDEX_GMM_INPUT_PER_TOKEN_SCALE, isXTransposed, false); | ||
| 335 | + } else { | ||
| 336 | + perTokenScaleVec.push_back(perTokenScale); | ||
| 337 | + } | ||
| 338 | + return GRAPH_SUCCESS; | ||
| 339 | +} | ||
| 340 | + | ||
| 341 | +static graphStatus ExecuteGmmApi( | ||
| 342 | + aclTensorList* aclTensorListX, aclTensorList* aclTensorListWeight, | ||
| 343 | + std::vector<const gert::Tensor*>& geTensorVectorBias, aclTensorList* aclTensorListScale, | ||
| 344 | + std::vector<const gert::Tensor*>& geTensorVectorOffset, | ||
| 345 | + std::vector<const gert::Tensor*>& geTensorVectorAntiquantScale, | ||
| 346 | + std::vector<const gert::Tensor*>& geTensorVectorAntiquantOffset, | ||
| 347 | + aclTensorList* aclTensorListPerTokenScale, const gert::Tensor* groupListTensor, | ||
| 348 | + int64_t splitItem, int64_t groupType, int64_t groupListType, int64_t actType, | ||
| 349 | + std::vector<int64_t>& tuningConfig, std::vector<const gert::Tensor*>& geTensorVectorY) | ||
| 350 | +{ | ||
| 351 | + aclTensorList* activationInputOptional = nullptr; | ||
| 352 | + aclTensorList* activationQuantScaleOptional = nullptr; | ||
| 353 | + aclTensorList* activationQuantOffsetOptional = nullptr; | ||
| 354 | + aclTensorList* actFeatureOutOptional = nullptr; | ||
| 355 | + aclTensorList* dynQuantScaleOutOptional = nullptr; | ||
| 356 | + auto api_ret_gmm = EXEC_OPAPI_CMD(aclnnGroupedMatmulV5, aclTensorListX, aclTensorListWeight, geTensorVectorBias, | ||
| 357 | + aclTensorListScale, geTensorVectorOffset, geTensorVectorAntiquantScale, | ||
| 358 | + geTensorVectorAntiquantOffset, aclTensorListPerTokenScale, groupListTensor, | ||
| 359 | + activationInputOptional, activationQuantScaleOptional, activationQuantOffsetOptional, | ||
| 360 | + splitItem, groupType, groupListType, actType, tuningConfig, | ||
| 361 | + geTensorVectorY, actFeatureOutOptional, dynQuantScaleOutOptional); | ||
| 362 | + OP_CHECK_IF(api_ret_gmm != GRAPH_SUCCESS, OP_LOGE("aclnnfallback", "api_ret failed:%u", api_ret_gmm), | ||
| 363 | + return GRAPH_FAILED); | ||
| 364 | + return GRAPH_SUCCESS; | ||
| 365 | +} | ||
| 366 | + | ||
| 286 | static graphStatus GroupedMatmulExecuteFunc(OpExecuteContext* host_api_ctx) | 367 | static graphStatus GroupedMatmulExecuteFunc(OpExecuteContext* host_api_ctx) |
| 287 | { | 368 | { |
| 288 | OP_CHECK_IF(host_api_ctx == nullptr, OP_LOGE("aclnnfallback", "host_api_ctx is null"), return GRAPH_FAILED); | 369 | OP_CHECK_IF(host_api_ctx == nullptr, OP_LOGE("aclnnfallback", "host_api_ctx is null"), return GRAPH_FAILED); |
| 289 | 370 | ||
| 290 | - auto attrs = host_api_ctx->GetAttrs(); | 371 | + GmmExecuteAttrs attrs{}; |
| 291 | - OP_CHECK_IF(attrs == nullptr, OP_LOGE("aclnnfallback", "attrs is null"), return GRAPH_FAILED); | 372 | + auto attrRet = GetGmmAttrs(host_api_ctx, attrs); |
| 292 | - const int64_t* splitItemGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_SPLIT_ITEM); | 373 | + OP_CHECK_IF(attrRet != GRAPH_SUCCESS, return attrRet); |
| 293 | - OP_CHECK_IF(splitItemGe == nullptr, OP_LOGE("aclnnfallback", "splitItemGe is null"), return GRAPH_FAILED); | ||
| 294 | - const bool* isWeightTransposedPtr = attrs->GetAttrPointer<bool>(INDEX_GMM_ATTR_TRANSPOSE_WEIGHT); | ||
| 295 | - OP_CHECK_IF(isWeightTransposedPtr == nullptr, OP_LOGE("aclnnfallback", "isWeightTransposedPtr is null"), | ||
| 296 | - return GRAPH_FAILED); | ||
| 297 | - const bool* isXTransposed = attrs->GetAttrPointer<bool>(INDEX_GMM_ATTR_TRANSPOSE_X); | ||
| 298 | - OP_CHECK_IF(isXTransposed == nullptr, OP_LOGE("aclnnfallback", "isXTransposed is null"), return GRAPH_FAILED); | ||
| 299 | - const int64_t* groupTypeGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_GROUP_TYPE); | ||
| 300 | - OP_CHECK_IF(groupTypeGe == nullptr, OP_LOGE("aclnnfallback", "groupTypeGe is null"), return GRAPH_FAILED); | ||
| 301 | - const int64_t* groupListTypeGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_GROUP_LIST_TYPE); | ||
| 302 | - OP_CHECK_IF(groupListTypeGe == nullptr, OP_LOGE("aclnnfallback", "groupListTypeGe is null"), return GRAPH_FAILED); | ||
| 303 | - const int64_t* actTypeGe = attrs->GetAttrPointer<int64_t>(INDEX_GMM_ATTR_ACT_TYPE); | ||
| 304 | - OP_CHECK_IF(actTypeGe == nullptr, OP_LOGE("aclnnfallback", "actTypeGe is null"), return GRAPH_FAILED); | ||
| 305 | - const auto tuningConfigGe = attrs->GetListInt(INDEX_GMM_ATTR_TUNING_CONFIG); | ||
| 306 | - OP_CHECK_IF(tuningConfigGe == nullptr, OP_LOGE("aclnnfallback", "tuningConfigGe is null"), return GRAPH_FAILED); | ||
| 307 | 374 | ||
| 308 | static const auto aclCreateTensorList = GET_OP_API_FUNC(aclCreateTensorList); | 375 | static const auto aclCreateTensorList = GET_OP_API_FUNC(aclCreateTensorList); |
| 309 | OP_CHECK_IF(aclCreateTensorList == nullptr, | 376 | OP_CHECK_IF(aclCreateTensorList == nullptr, |
| 310 | OP_LOGE("aclnnfallback", "Get opapi func aclCreateTensorList failed"), return GRAPH_FAILED); | 377 | OP_LOGE("aclnnfallback", "Get opapi func aclCreateTensorList failed"), return GRAPH_FAILED); |
| 311 | 378 | ||
| 312 | std::vector<const aclTensor*> aclTensorVectorX; | 379 | std::vector<const aclTensor*> aclTensorVectorX; |
| 313 | - PrepareAclTensorVector(host_api_ctx, aclTensorVectorX, INDEX_GMM_INPUT_X, *isXTransposed, false); | 380 | + PrepareAclTensorVector(host_api_ctx, aclTensorVectorX, INDEX_GMM_INPUT_X, *attrs.isXTransposed, false); |
| 314 | auto aclTensorListX = aclCreateTensorList(aclTensorVectorX.data(), aclTensorVectorX.size()); | 381 | auto aclTensorListX = aclCreateTensorList(aclTensorVectorX.data(), aclTensorVectorX.size()); |
| 315 | 382 | ||
| 316 | std::vector<const aclTensor*> aclTensorVectorWeight; | 383 | std::vector<const aclTensor*> aclTensorVectorWeight; |
| 317 | - PrepareAclTensorVector(host_api_ctx, aclTensorVectorWeight, INDEX_GMM_INPUT_WEIGHT, *isWeightTransposedPtr, true); | 384 | + PrepareAclTensorVector(host_api_ctx, aclTensorVectorWeight, INDEX_GMM_INPUT_WEIGHT, *attrs.isWeightTransposedPtr, true); |
| 318 | size_t numGeWeight = aclTensorVectorWeight.size(); | 385 | size_t numGeWeight = aclTensorVectorWeight.size(); |
| 319 | auto aclTensorListWeight = aclCreateTensorList(aclTensorVectorWeight.data(), aclTensorVectorWeight.size()); | 386 | auto aclTensorListWeight = aclCreateTensorList(aclTensorVectorWeight.data(), aclTensorVectorWeight.size()); |
| 320 | 387 | ||
| 321 | std::vector<const gert::Tensor*> geTensorVectorBias; | 388 | std::vector<const gert::Tensor*> geTensorVectorBias; |
| 322 | PrepareGeTensorVector(host_api_ctx, geTensorVectorBias, INDEX_GMM_INPUT_BIAS); | 389 | PrepareGeTensorVector(host_api_ctx, geTensorVectorBias, INDEX_GMM_INPUT_BIAS); |
| 390 | + | ||
| 323 | bool isScaleTransposed = false; | 391 | bool isScaleTransposed = false; |
| 324 | const bool* isScaleTransposedPtr = &isScaleTransposed; | 392 | const bool* isScaleTransposedPtr = &isScaleTransposed; |
| 325 | auto scaleTensor = host_api_ctx->GetDynamicInputTensor(INDEX_GMM_INPUT_SCALE, 0); | 393 | auto scaleTensor = host_api_ctx->GetDynamicInputTensor(INDEX_GMM_INPUT_SCALE, 0); |
| 326 | - bool isPerTile = IsPerTileQuantMode(host_api_ctx, *isXTransposed, *isWeightTransposedPtr, *groupTypeGe); | 394 | + bool isPerTile = IsPerTileQuantMode(host_api_ctx, *attrs.isXTransposed, *attrs.isWeightTransposedPtr, *attrs.groupTypeGe); |
| 327 | if (scaleTensor != nullptr && (scaleTensor->GetDataType() == ge::DataType::DT_FLOAT8_E8M0 || isPerTile)) { | 395 | if (scaleTensor != nullptr && (scaleTensor->GetDataType() == ge::DataType::DT_FLOAT8_E8M0 || isPerTile)) { |
| 328 | - isScaleTransposedPtr = isWeightTransposedPtr; | 396 | + isScaleTransposedPtr = attrs.isWeightTransposedPtr; |
| 329 | } | 397 | } |
| 330 | std::vector<const aclTensor*> aclTensorVectorScale; | 398 | std::vector<const aclTensor*> aclTensorVectorScale; |
| 331 | PrepareAclTensorVector(host_api_ctx, aclTensorVectorScale, INDEX_GMM_INPUT_SCALE, *isScaleTransposedPtr, false); | 399 | PrepareAclTensorVector(host_api_ctx, aclTensorVectorScale, INDEX_GMM_INPUT_SCALE, *isScaleTransposedPtr, false); |
| @@ -342,49 +410,24 @@ static graphStatus GroupedMatmulExecuteFunc(OpExecuteContext* host_api_ctx) | |||
| 342 | 410 | ||
| 343 | auto groupListTensor = host_api_ctx->GetOptionalInputTensor(INDEX_GMM_INPUT_GROUP_LIST); | 411 | auto groupListTensor = host_api_ctx->GetOptionalInputTensor(INDEX_GMM_INPUT_GROUP_LIST); |
| 344 | 412 | ||
| 345 | - auto perTokenScaleTensor = host_api_ctx->GetOptionalInputTensor(INDEX_GMM_INPUT_PER_TOKEN_SCALE); | ||
| 346 | std::vector<const aclTensor*> geTensorVectorPerTokenScale; | 413 | std::vector<const aclTensor*> geTensorVectorPerTokenScale; |
| 347 | - auto perTokenScale = ConvertType(perTokenScaleTensor); | 414 | + auto ptsRet = PreparePerTokenScaleList(host_api_ctx, geTensorVectorPerTokenScale, *attrs.isXTransposed, isPerTile); |
| 348 | - if (perTokenScale == nullptr) { | 415 | + OP_CHECK_IF(ptsRet != GRAPH_SUCCESS, return ptsRet); |
| 349 | - std::vector<int64_t> shape{0}; | ||
| 350 | - static const auto aclCreateTensor = GET_OP_API_FUNC(aclCreateTensor); | ||
| 351 | - OP_CHECK_IF(aclCreateTensor == nullptr, OP_LOGE("aclnnfallback", "aclCreateTensor nullptr"), return GRAPH_FAILED); | ||
| 352 | - perTokenScale = aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_FLOAT, shape.data(), | ||
| 353 | - 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), nullptr); | ||
| 354 | - OP_CHECK_IF(perTokenScale == nullptr, OP_LOGE("aclnnfallback", "perTokenScale nullptr"), return GRAPH_FAILED); | ||
| 355 | - } | ||
| 356 | - if (perTokenScaleTensor != nullptr && (perTokenScaleTensor->GetDataType() == ge::DataType::DT_FLOAT8_E8M0 || | ||
| 357 | - isPerTile)) { | ||
| 358 | - PrepareAclTensorVector(host_api_ctx, geTensorVectorPerTokenScale, INDEX_GMM_INPUT_PER_TOKEN_SCALE, | ||
| 359 | - *isXTransposed, false); | ||
| 360 | - } else { | ||
| 361 | - geTensorVectorPerTokenScale.push_back(perTokenScale); | ||
| 362 | - } | ||
| 363 | auto aclTensorListPerTokenScale = aclCreateTensorList(geTensorVectorPerTokenScale.data(), | 416 | auto aclTensorListPerTokenScale = aclCreateTensorList(geTensorVectorPerTokenScale.data(), |
| 364 | geTensorVectorPerTokenScale.size()); | 417 | geTensorVectorPerTokenScale.size()); |
| 365 | 418 | ||
| 366 | std::vector<const gert::Tensor*> geTensorVectorY; | 419 | std::vector<const gert::Tensor*> geTensorVectorY; |
| 367 | - PrepareOutputTensorVector(host_api_ctx, geTensorVectorY, INDEX_GMM_OUTPUT_Y, numGeWeight, *splitItemGe); | 420 | + PrepareOutputTensorVector(host_api_ctx, geTensorVectorY, INDEX_GMM_OUTPUT_Y, numGeWeight, *attrs.splitItemGe); |
| 368 | 421 | ||
| 369 | - aclTensorList* activationInputOptional = nullptr; | ||
| 370 | - aclTensorList* activationQuantScaleOptional = nullptr; | ||
| 371 | - aclTensorList* activationQuantOffsetOptional = nullptr; | ||
| 372 | - aclTensorList* actFeatureOutOptional = nullptr; | ||
| 373 | - aclTensorList* dynQuantScaleOutOptional = nullptr; | ||
| 374 | std::vector<int64_t> tuningConfig; | 422 | std::vector<int64_t> tuningConfig; |
| 375 | tuningConfig.reserve(1); | 423 | tuningConfig.reserve(1); |
| 376 | - tuningConfig.push_back(tuningConfigGe->GetData()[0]); | 424 | + tuningConfig.push_back(attrs.tuningConfigGe->GetData()[0]); |
| 377 | 425 | ||
| 378 | - // execute opapi | 426 | + return ExecuteGmmApi(aclTensorListX, aclTensorListWeight, geTensorVectorBias, aclTensorListScale, |
| 379 | - auto api_ret_gmm = EXEC_OPAPI_CMD(aclnnGroupedMatmulV5, aclTensorListX, aclTensorListWeight, geTensorVectorBias, | 427 | + geTensorVectorOffset, geTensorVectorAntiquantScale, geTensorVectorAntiquantOffset, |
| 380 | - aclTensorListScale, geTensorVectorOffset, geTensorVectorAntiquantScale, | 428 | + aclTensorListPerTokenScale, groupListTensor, |
| 381 | - geTensorVectorAntiquantOffset, aclTensorListPerTokenScale, groupListTensor, | 429 | + *attrs.splitItemGe, *attrs.groupTypeGe, *attrs.groupListTypeGe, *attrs.actTypeGe, |
| 382 | - activationInputOptional, activationQuantScaleOptional, activationQuantOffsetOptional, | 430 | + tuningConfig, geTensorVectorY); |
| 383 | - *splitItemGe, *groupTypeGe, *groupListTypeGe, *actTypeGe, tuningConfig, | ||
| 384 | - geTensorVectorY, actFeatureOutOptional, dynQuantScaleOutOptional); | ||
| 385 | - OP_CHECK_IF(api_ret_gmm != GRAPH_SUCCESS, OP_LOGE("aclnnfallback", "api_ret failed:%u", api_ret_gmm), | ||
| 386 | - return GRAPH_FAILED); | ||
| 387 | - return GRAPH_SUCCESS; | ||
| 388 | } | 431 | } |
| 389 | 432 | ||
| 390 | IMPL_OP(GroupedMatmul).OpExecuteFunc(GroupedMatmulExecuteFunc); | 433 | IMPL_OP(GroupedMatmul).OpExecuteFunc(GroupedMatmulExecuteFunc); |
| @@ -27,6 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | + | ||
| 30 | 31 | ||
| 31 | using namespace ge; | 32 | using namespace ge; |
| 32 | using namespace ge::fusion; | 33 | using namespace ge::fusion; |
| @@ -165,11 +166,17 @@ bool GetConstScalar(const GNode& node, int32_t inputIndex, int64_t& value) | |||
| 165 | return false; | 166 | return false; |
| 166 | } | 167 | } |
| 167 | if (desc.GetDataType() == DT_INT32 && tensor.GetSize() >= sizeof(int32_t)) { | 168 | if (desc.GetDataType() == DT_INT32 && tensor.GetSize() >= sizeof(int32_t)) { |
| 168 | - value = static_cast<int64_t>(*reinterpret_cast<const int32_t*>(tensor.GetData())); | 169 | + int32_t int32Value = 0; |
| 170 | + if (memcpy_s(&int32Value, sizeof(int32Value), tensor.GetData(), sizeof(int32_t)) != EOK) { | ||
| 171 | + return false; | ||
| 172 | + } | ||
| 173 | + value = static_cast<int64_t>(int32Value); | ||
| 169 | return true; | 174 | return true; |
| 170 | } | 175 | } |
| 171 | if (desc.GetDataType() == DT_INT64 && tensor.GetSize() >= sizeof(int64_t)) { | 176 | if (desc.GetDataType() == DT_INT64 && tensor.GetSize() >= sizeof(int64_t)) { |
| 172 | - value = *reinterpret_cast<const int64_t*>(tensor.GetData()); | 177 | + if (memcpy_s(&value, sizeof(value), tensor.GetData(), sizeof(int64_t)) != EOK) { |
| 178 | + return false; | ||
| 179 | + } | ||
| 173 | return true; | 180 | return true; |
| 174 | } | 181 | } |
| 175 | return false; | 182 | return false; |
| @@ -298,6 +305,24 @@ bool IsMxWeightQuantMode(const GNode& groupedMatmulNode) | |||
| 298 | antiquantScaleDesc.GetDataType() == DT_FLOAT8_E8M0; | 305 | antiquantScaleDesc.GetDataType() == DT_FLOAT8_E8M0; |
| 299 | } | 306 | } |
| 300 | 307 | ||
| 308 | +bool GetTransposeAxesForScale(bool isMxScale, bool isMxPertokenScale, std::size_t dimNum, | ||
| 309 | + std::size_t &firstTransposeAxis, std::size_t &secondTransposeAxis) | ||
| 310 | +{ | ||
| 311 | + firstTransposeAxis = dimNum - kMiniShapeLen; | ||
| 312 | + secondTransposeAxis = dimNum - 1; | ||
| 313 | + if (isMxScale) { | ||
| 314 | + if (dimNum < kPermScale.size()) { | ||
| 315 | + return false; | ||
| 316 | + } | ||
| 317 | + firstTransposeAxis = dimNum - 3; //倒数索引,定位N轴 | ||
| 318 | + secondTransposeAxis = dimNum - 2; //倒数索引,定位K/gs | ||
| 319 | + } else if (isMxPertokenScale) { | ||
| 320 | + firstTransposeAxis = 0; | ||
| 321 | + secondTransposeAxis = 1; | ||
| 322 | + } | ||
| 323 | + return true; | ||
| 324 | +} | ||
| 325 | + | ||
| 301 | bool IsReshapeTransForScale( | 326 | bool IsReshapeTransForScale( |
| 302 | int32_t index, const GNodePtr& nodePerInput, bool isMxQuantMode, bool allowFullyDynamicMxFp4Scale) | 327 | int32_t index, const GNodePtr& nodePerInput, bool isMxQuantMode, bool allowFullyDynamicMxFp4Scale) |
| 303 | { | 328 | { |
| @@ -318,20 +343,14 @@ bool IsReshapeTransForScale( | |||
| 318 | return false; | 343 | return false; |
| 319 | } | 344 | } |
| 320 | 345 | ||
| 321 | - std::size_t firstTransposeAxis = expectedOutputDims.size() - kMiniShapeLen; | ||
| 322 | - std::size_t secondTransposeAxis = expectedOutputDims.size() - 1; | ||
| 323 | const bool isMxScale = | 346 | const bool isMxScale = |
| 324 | index == kScaleIndex && (isMxQuantMode || inputDesc.GetDataType() == DT_FLOAT8_E8M0); | 347 | index == kScaleIndex && (isMxQuantMode || inputDesc.GetDataType() == DT_FLOAT8_E8M0); |
| 325 | const bool isMxPertokenScale = index == kPertokenScaleIndex && inputDesc.GetDataType() == DT_FLOAT8_E8M0; | 348 | const bool isMxPertokenScale = index == kPertokenScaleIndex && inputDesc.GetDataType() == DT_FLOAT8_E8M0; |
| 326 | - if (isMxScale) { | 349 | + std::size_t firstTransposeAxis = 0; |
| 327 | - if (expectedOutputDims.size() < kPermScale.size()) { | 350 | + std::size_t secondTransposeAxis = 0; |
| 328 | - return false; | 351 | + if (!GetTransposeAxesForScale(isMxScale, isMxPertokenScale, expectedOutputDims.size(), firstTransposeAxis, |
| 329 | - } | 352 | + secondTransposeAxis)) { |
| 330 | - firstTransposeAxis = expectedOutputDims.size() - 3; | 353 | + return false; |
| 331 | - secondTransposeAxis = expectedOutputDims.size() - 2; | ||
| 332 | - } else if (isMxPertokenScale) { | ||
| 333 | - firstTransposeAxis = 0; | ||
| 334 | - secondTransposeAxis = 1; | ||
| 335 | } | 354 | } |
| 336 | 355 | ||
| 337 | if (expectedOutputDims[firstTransposeAxis] != 1 && expectedOutputDims[secondTransposeAxis] != 1) { | 356 | if (expectedOutputDims[firstTransposeAxis] != 1 && expectedOutputDims[secondTransposeAxis] != 1) { |
| @@ -385,12 +404,20 @@ bool GetTransposePerm(const GNodePtr& transposeNode, std::vector<int64_t>& perm) | |||
| 385 | if (permDtype == DT_INT32) { | 404 | if (permDtype == DT_INT32) { |
| 386 | size = permTensor.GetSize() / sizeof(int32_t); | 405 | size = permTensor.GetSize() / sizeof(int32_t); |
| 387 | for (std::size_t i = 0; i < size; ++i) { | 406 | for (std::size_t i = 0; i < size; ++i) { |
| 388 | - perm.emplace_back(static_cast<int64_t>(*(reinterpret_cast<const int32_t*>(constDataPtr) + i))); | 407 | + int32_t val32 = 0; |
| 408 | + if (memcpy_s(&val32, sizeof(val32), constDataPtr + i * sizeof(int32_t), sizeof(int32_t)) != EOK) { | ||
| 409 | + return false; | ||
| 410 | + } | ||
| 411 | + perm.emplace_back(val32); | ||
| 389 | } | 412 | } |
| 390 | } else if (permDtype == DT_INT64) { | 413 | } else if (permDtype == DT_INT64) { |
| 391 | size = permTensor.GetSize() / sizeof(int64_t); | 414 | size = permTensor.GetSize() / sizeof(int64_t); |
| 392 | for (std::size_t i = 0; i < size; ++i) { | 415 | for (std::size_t i = 0; i < size; ++i) { |
| 393 | - perm.emplace_back(*(reinterpret_cast<const int64_t*>(constDataPtr) + i)); | 416 | + int64_t val64 = 0; |
| 417 | + if (memcpy_s(&val64, sizeof(val64), constDataPtr + i * sizeof(int64_t), sizeof(int64_t)) != EOK) { | ||
| 418 | + return false; | ||
| 419 | + } | ||
| 420 | + perm.emplace_back(val64); | ||
| 394 | } | 421 | } |
| 395 | } else { | 422 | } else { |
| 396 | OP_LOGW(kPassName, "Transpose perm dtype must be int32 or int64."); | 423 | OP_LOGW(kPassName, "Transpose perm dtype must be int32 or int64."); |
| @@ -254,9 +254,9 @@ static ge::graphStatus GetAttrsValue(T context, GMMAttrs &gmmAttrs) | |||
| 254 | gmmAttrs.outputDtype = *dtypePtr; | 254 | gmmAttrs.outputDtype = *dtypePtr; |
| 255 | OP_LOGI(context->GetNodeName(), "Attr dtype = %ld", gmmAttrs.outputDtype); | 255 | OP_LOGI(context->GetNodeName(), "Attr dtype = %ld", gmmAttrs.outputDtype); |
| 256 | 256 | ||
| 257 | - const auto tuningConfigPtr = attrs->GetAttrPointer<gert::ContinuousVector>(GMM_INDEX_ATTR_TUNING_CONFIG); | 257 | + const auto tuningConfigPtr = attrs->GetAttrPointer<gert::TypedContinuousVector<int64_t>>(GMM_INDEX_ATTR_TUNING_CONFIG); |
| 258 | gmmAttrs.tuningConfig = (tuningConfigPtr != nullptr && tuningConfigPtr->GetSize() > 0) ? | 258 | gmmAttrs.tuningConfig = (tuningConfigPtr != nullptr && tuningConfigPtr->GetSize() > 0) ? |
| 259 | - (reinterpret_cast<const int64_t *>(tuningConfigPtr->GetData()))[0] : 0; | 259 | + tuningConfigPtr->GetData()[0] : 0; |
| 260 | OP_LOGI(context->GetNodeName(), "Attr tuningConfig = %ld", gmmAttrs.tuningConfig); | 260 | OP_LOGI(context->GetNodeName(), "Attr tuningConfig = %ld", gmmAttrs.tuningConfig); |
| 261 | 261 | ||
| 262 | const int64_t *groupTypePtr = attrs->GetAttrPointer<int64_t>(GMM_INDEX_ATTR_GROUP_TYPE); | 262 | const int64_t *groupTypePtr = attrs->GetAttrPointer<int64_t>(GMM_INDEX_ATTR_GROUP_TYPE); |
| @@ -394,11 +394,11 @@ static bool IsS8S4SpecialWeightFormat(const gert::InferShapeContext* context) | |||
| 394 | if (attrs == nullptr) { | 394 | if (attrs == nullptr) { |
| 395 | return false; | 395 | return false; |
| 396 | } | 396 | } |
| 397 | - const auto tuningConfigPtr = attrs->GetAttrPointer<gert::ContinuousVector>(GMM_INDEX_ATTR_TUNING_CONFIG); | 397 | + const auto tuningConfigPtr = attrs->GetAttrPointer<gert::TypedContinuousVector<int64_t>>(GMM_INDEX_ATTR_TUNING_CONFIG); |
| 398 | if (tuningConfigPtr == nullptr || tuningConfigPtr->GetSize() <= 1) { | 398 | if (tuningConfigPtr == nullptr || tuningConfigPtr->GetSize() <= 1) { |
| 399 | return false; | 399 | return false; |
| 400 | } | 400 | } |
| 401 | - const auto tuningConfig = reinterpret_cast<const int64_t *>(tuningConfigPtr->GetData()); | 401 | + const auto tuningConfig = tuningConfigPtr->GetData(); |
| 402 | return tuningConfig[1] == 1; | 402 | return tuningConfig[1] == 1; |
| 403 | } | 403 | } |
| 404 | 404 | ||
| @@ -1176,7 +1176,7 @@ static ge::graphStatus SplitMSingleXSingleWeightSingleY(gert::InferShapeContext* | |||
| 1176 | OP_CHECK_IF(CheckShapeSameLengthTensorList(context, {1, kAxisOfWeight}, innerAxisDimId, tenorXAndWeight, paramsInfo.numX) != GRAPH_SUCCESS, | 1176 | OP_CHECK_IF(CheckShapeSameLengthTensorList(context, {1, kAxisOfWeight}, innerAxisDimId, tenorXAndWeight, paramsInfo.numX) != GRAPH_SUCCESS, |
| 1177 | OP_LOGE(context->GetNodeName(), "k dim value of x and weight is not matched."), | 1177 | OP_LOGE(context->GetNodeName(), "k dim value of x and weight is not matched."), |
| 1178 | return GRAPH_FAILED); | 1178 | return GRAPH_FAILED); |
| 1179 | - innerAxisDimId = specialWeightFormat ? static_cast<int64_t>(weightAxis.n) : (!transposeWeight ? 2 : -1); | 1179 | + innerAxisDimId = specialWeightFormat ? static_cast<int64_t>(weightAxis.n) : (!transposeWeight ? 2 : -1); //转置 weight 的内轴 K 位于第 3 维(索引 2) |
| 1180 | OP_CHECK_IF(CheckInnerAxisOfTensorList(context, GMM_INDEX_IN_WEIGHT, innerAxisDimId, paramsInfo.numWeight) != GRAPH_SUCCESS, | 1180 | OP_CHECK_IF(CheckInnerAxisOfTensorList(context, GMM_INDEX_IN_WEIGHT, innerAxisDimId, paramsInfo.numWeight) != GRAPH_SUCCESS, |
| 1181 | OP_LOGE(context->GetNodeName(), "inner axis size of weight is larger than %ld!", GMM_MAX_INNER_AXIS), | 1181 | OP_LOGE(context->GetNodeName(), "inner axis size of weight is larger than %ld!", GMM_MAX_INNER_AXIS), |
| 1182 | return GRAPH_FAILED); | 1182 | return GRAPH_FAILED); |
| @@ -1528,51 +1528,60 @@ static graphStatus IsDavidQuantGMMByShape(T context) { | |||
| 1528 | return (GetSizeByDataType(xDtype) == 1 && GetSizeByDataType(weightDtype) == 1) ? GRAPH_SUCCESS : GRAPH_FAILED; | 1528 | return (GetSizeByDataType(xDtype) == 1 && GetSizeByDataType(weightDtype) == 1) ? GRAPH_SUCCESS : GRAPH_FAILED; |
| 1529 | } | 1529 | } |
| 1530 | 1530 | ||
| 1531 | -static ge::graphStatus InferShape4GroupedMatmul(gert::InferShapeContext* context) { | 1531 | +static ge::graphStatus TryDavidInferShape(gert::InferShapeContext* context) |
| 1532 | - OP_CHECK_NULL_WITH_CONTEXT(context, context); | 1532 | +{ |
| 1533 | fe::PlatformInfo platformInfo; | 1533 | fe::PlatformInfo platformInfo; |
| 1534 | fe::OptionalInfo optionalInfo; | 1534 | fe::OptionalInfo optionalInfo; |
| 1535 | auto ret = fe::PlatformInfoManager::Instance().GetPlatformInfoWithOutSocVersion(platformInfo, optionalInfo); | 1535 | auto ret = fe::PlatformInfoManager::Instance().GetPlatformInfoWithOutSocVersion(platformInfo, optionalInfo); |
| 1536 | - if (ret == GRAPH_SUCCESS && GmmDavidSupportSoc.count(platformInfo.str_info.short_soc_version) > 0 && | 1536 | + if (ret != GRAPH_SUCCESS || GmmDavidSupportSoc.count(platformInfo.str_info.short_soc_version) == 0 || |
| 1537 | - !IsS8S4PseudoQuant(context)) { | 1537 | + IsS8S4PseudoQuant(context)) { |
| 1538 | - if (IsDavidQuantGMMByShape(context) == GRAPH_SUCCESS) { | 1538 | + return GRAPH_FAILED; // not handled by David path |
| 1539 | - OP_CHECK_IF(InferShape4DavidQuantGMM(context) != GRAPH_SUCCESS, | ||
| 1540 | - OP_LOGE(context->GetNodeName(), "Check params failed"), return GRAPH_FAILED); | ||
| 1541 | - return GRAPH_SUCCESS; | ||
| 1542 | - } else if (IsDavidWeightQuantGMMByShape(context) == GRAPH_SUCCESS) { | ||
| 1543 | - OP_CHECK_IF(InferShape4DavidWeightQuantGMM(context) != GRAPH_SUCCESS, | ||
| 1544 | - OP_LOGE(context->GetNodeName(), "Check params failed"), return GRAPH_FAILED); | ||
| 1545 | - return GRAPH_SUCCESS; | ||
| 1546 | - } | ||
| 1547 | } | 1539 | } |
| 1548 | - GMMAttrs gmmAttrs{GMM_X_Y_SEPARATED, 0, GMM_NO_SPLIT, false, false, 0, 0}; | 1540 | + if (IsDavidQuantGMMByShape(context) == GRAPH_SUCCESS) { |
| 1549 | - OP_CHECK_IF(GetAttrsValue(context, gmmAttrs) != GRAPH_SUCCESS || CheckAttrs(context, gmmAttrs) != GRAPH_SUCCESS, | 1541 | + OP_CHECK_IF(InferShape4DavidQuantGMM(context) != GRAPH_SUCCESS, |
| 1550 | - OP_LOGE(context->GetNodeName(), "Failed to get attrs."), return GRAPH_FAILED); | 1542 | + OP_LOGE(context->GetNodeName(), "Check params failed"), return GRAPH_FAILED); |
| 1543 | + return GRAPH_SUCCESS; | ||
| 1544 | + } else if (IsDavidWeightQuantGMMByShape(context) == GRAPH_SUCCESS) { | ||
| 1545 | + OP_CHECK_IF(InferShape4DavidWeightQuantGMM(context) != GRAPH_SUCCESS, | ||
| 1546 | + OP_LOGE(context->GetNodeName(), "Check params failed"), return GRAPH_FAILED); | ||
| 1547 | + return GRAPH_SUCCESS; | ||
| 1548 | + } | ||
| 1549 | + return GRAPH_FAILED; // not a David quant case | ||
| 1550 | +} | ||
| 1551 | 1551 | ||
| 1552 | - size_t numX = 0; // init numX | 1552 | +static ge::graphStatus ParseAttrsAndCountInputs(gert::InferShapeContext* context, GMMAttrs& gmmAttrs, |
| 1553 | - size_t numWeight = 0; // init numWeight | 1553 | + size_t& numX, size_t& numWeight, int64_t& lenGroupList) |
| 1554 | - int64_t lenGroupList = 0; // init lenGroupList | 1554 | +{ |
| 1555 | - size_t numY = context->GetComputeNodeOutputNum(); | 1555 | + numX = 0; |
| 1556 | - if (GetNumOfInputs(context, numX, numWeight, lenGroupList) == GRAPH_SUCCESS) { // check input shape value inside | 1556 | + numWeight = 0; |
| 1557 | - GMMParamsInfo paramsInfo{numX, numWeight, numY, lenGroupList, 0, 0, 0, 0, 0, PlatformID::UNKNOWN}; | 1557 | + lenGroupList = 0; |
| 1558 | - OP_CHECK_IF(GetGroupSize(context, paramsInfo) != GRAPH_SUCCESS, | 1558 | + if (GetNumOfInputs(context, numX, numWeight, lenGroupList) != GRAPH_SUCCESS) { |
| 1559 | - OP_LOGE(context->GetNodeName(), "check groupNum failed"), return GRAPH_FAILED); | 1559 | + OP_CHECK_IF(CheckDimNum(context, numX, GMM_MIN_FM_DIM, "x") != GRAPH_SUCCESS, |
| 1560 | - OP_CHECK_IF(CheckFunctionParamsForShape(context, gmmAttrs, paramsInfo) != GRAPH_SUCCESS, | ||
| 1561 | - OP_LOGE(context->GetNodeName(), "CheckFunctionParamsForShape failed."), return GRAPH_FAILED); | ||
| 1562 | - OP_CHECK_IF(CheckParamDifferentGroupType(context, gmmAttrs, paramsInfo) != GRAPH_SUCCESS, | ||
| 1563 | - OP_LOGE(context->GetNodeName(), "CheckParamDifferentGroupType failed."), return GRAPH_FAILED); | ||
| 1564 | - } else { | ||
| 1565 | - OP_CHECK_IF(CheckDimNum(context, numX, GMM_MIN_FM_DIM, "x") != GRAPH_SUCCESS, // check dim number of tensors | ||
| 1566 | OP_LOGE(context->GetNodeName(), "Dim num of tensor in tensorList x is invalid."), | 1560 | OP_LOGE(context->GetNodeName(), "Dim num of tensor in tensorList x is invalid."), |
| 1567 | return GRAPH_FAILED); | 1561 | return GRAPH_FAILED); |
| 1562 | + return GRAPH_SUCCESS; | ||
| 1568 | } | 1563 | } |
| 1564 | + size_t numY = context->GetComputeNodeOutputNum(); | ||
| 1565 | + GMMParamsInfo paramsInfo{numX, numWeight, numY, lenGroupList, 0, 0, 0, 0, 0, PlatformID::UNKNOWN}; | ||
| 1566 | + OP_CHECK_IF(GetGroupSize(context, paramsInfo) != GRAPH_SUCCESS, | ||
| 1567 | + OP_LOGE(context->GetNodeName(), "check groupNum failed"), return GRAPH_FAILED); | ||
| 1568 | + OP_CHECK_IF(CheckFunctionParamsForShape(context, gmmAttrs, paramsInfo) != GRAPH_SUCCESS, | ||
| 1569 | + OP_LOGE(context->GetNodeName(), "CheckFunctionParamsForShape failed."), return GRAPH_FAILED); | ||
| 1570 | + OP_CHECK_IF(CheckParamDifferentGroupType(context, gmmAttrs, paramsInfo) != GRAPH_SUCCESS, | ||
| 1571 | + OP_LOGE(context->GetNodeName(), "CheckParamDifferentGroupType failed."), return GRAPH_FAILED); | ||
| 1572 | + return GRAPH_SUCCESS; | ||
| 1573 | +} | ||
| 1569 | 1574 | ||
| 1575 | +static ge::graphStatus ComputeAndSetOutputShape(gert::InferShapeContext* context, GMMAttrs& gmmAttrs, | ||
| 1576 | + size_t numX, size_t numWeight, int64_t lenGroupList) | ||
| 1577 | +{ | ||
| 1570 | const gert::Shape* x0Shape = context->GetDynamicInputShape(GMM_INDEX_IN_X, 0); | 1578 | const gert::Shape* x0Shape = context->GetDynamicInputShape(GMM_INDEX_IN_X, 0); |
| 1571 | OP_CHECK_NULL_WITH_CONTEXT(context, x0Shape); | 1579 | OP_CHECK_NULL_WITH_CONTEXT(context, x0Shape); |
| 1572 | size_t xDimNum = x0Shape->GetDimNum(); | 1580 | size_t xDimNum = x0Shape->GetDimNum(); |
| 1573 | const gert::Shape* w0Shape = context->GetDynamicInputShape(GMM_INDEX_IN_WEIGHT, 0); | 1581 | const gert::Shape* w0Shape = context->GetDynamicInputShape(GMM_INDEX_IN_WEIGHT, 0); |
| 1574 | OP_CHECK_NULL_WITH_CONTEXT(context, w0Shape); | 1582 | OP_CHECK_NULL_WITH_CONTEXT(context, w0Shape); |
| 1575 | size_t weightDimNum = w0Shape->GetDimNum(); | 1583 | size_t weightDimNum = w0Shape->GetDimNum(); |
| 1584 | + size_t numY = context->GetComputeNodeOutputNum(); | ||
| 1576 | bool isSingleX = (numX == 1UL) && (gmmAttrs.groupType != GMM_NO_SPLIT); | 1585 | bool isSingleX = (numX == 1UL) && (gmmAttrs.groupType != GMM_NO_SPLIT); |
| 1577 | bool isSingleY = (numY == 1UL) && (gmmAttrs.groupType != GMM_NO_SPLIT); | 1586 | bool isSingleY = (numY == 1UL) && (gmmAttrs.groupType != GMM_NO_SPLIT); |
| 1578 | size_t xDimM = gmmAttrs.transposeX ? xDimNum - 1UL : xDimNum - 2UL; | 1587 | size_t xDimM = gmmAttrs.transposeX ? xDimNum - 1UL : xDimNum - 2UL; |
| @@ -1588,10 +1597,25 @@ static ge::graphStatus InferShape4GroupedMatmul(gert::InferShapeContext* context | |||
| 1588 | outputParams.numWeight = numWeight; | 1597 | outputParams.numWeight = numWeight; |
| 1589 | OP_CHECK_IF(GMMSetOutputShape(context, gmmAttrs, outputParams, x0Shape, w0Shape) != GRAPH_SUCCESS, | 1598 | OP_CHECK_IF(GMMSetOutputShape(context, gmmAttrs, outputParams, x0Shape, w0Shape) != GRAPH_SUCCESS, |
| 1590 | OP_LOGE(context->GetNodeName(), "GMMSetOutputShape failed"), return GRAPH_FAILED); | 1599 | OP_LOGE(context->GetNodeName(), "GMMSetOutputShape failed"), return GRAPH_FAILED); |
| 1591 | - | ||
| 1592 | return GRAPH_SUCCESS; | 1600 | return GRAPH_SUCCESS; |
| 1593 | } | 1601 | } |
| 1594 | 1602 | ||
| 1603 | +static ge::graphStatus InferShape4GroupedMatmul(gert::InferShapeContext* context) { | ||
| 1604 | + OP_CHECK_NULL_WITH_CONTEXT(context, context); | ||
| 1605 | + if (TryDavidInferShape(context) == GRAPH_SUCCESS) { | ||
| 1606 | + return GRAPH_SUCCESS; | ||
| 1607 | + } | ||
| 1608 | + GMMAttrs gmmAttrs{GMM_X_Y_SEPARATED, 0, GMM_NO_SPLIT, false, false, 0, 0}; | ||
| 1609 | + OP_CHECK_IF(GetAttrsValue(context, gmmAttrs) != GRAPH_SUCCESS || CheckAttrs(context, gmmAttrs) != GRAPH_SUCCESS, | ||
| 1610 | + OP_LOGE(context->GetNodeName(), "Failed to get attrs."), return GRAPH_FAILED); | ||
| 1611 | + size_t numX = 0; | ||
| 1612 | + size_t numWeight = 0; | ||
| 1613 | + int64_t lenGroupList = 0; | ||
| 1614 | + OP_CHECK_IF(ParseAttrsAndCountInputs(context, gmmAttrs, numX, numWeight, lenGroupList) != GRAPH_SUCCESS, | ||
| 1615 | + return GRAPH_FAILED); | ||
| 1616 | + return ComputeAndSetOutputShape(context, gmmAttrs, numX, numWeight, lenGroupList); | ||
| 1617 | +} | ||
| 1618 | + | ||
| 1595 | // ========================================================================================= | 1619 | // ========================================================================================= |
| 1596 | // ========================================================================================= | 1620 | // ========================================================================================= |
| 1597 | static graphStatus CheckTensorListDataType(const gert::InferDataTypeContext* context, uint32_t index, | 1621 | static graphStatus CheckTensorListDataType(const gert::InferDataTypeContext* context, uint32_t index, |
| @@ -329,6 +329,7 @@ ge::graphStatus GroupedMatmulWeightQuantChecker::CheckTensorNDimMultiScenario(co | |||
| 329 | auto antiquantScaleShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_SCALE, index); | 329 | auto antiquantScaleShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_SCALE, index); |
| 330 | OP_CHECK_NULL_WITH_CONTEXT(context, antiquantScaleShape); | 330 | OP_CHECK_NULL_WITH_CONTEXT(context, antiquantScaleShape); |
| 331 | int64_t antiquantScaleNDim; | 331 | int64_t antiquantScaleNDim; |
| 332 | + //返回维度数量 | ||
| 332 | if (IsA16W4(xDtype_, weightDtype_) && antiquantScaleShape->GetDimNum() == 2) { | 333 | if (IsA16W4(xDtype_, weightDtype_) && antiquantScaleShape->GetDimNum() == 2) { |
| 333 | antiquantScaleNDim = antiquantScaleShape->GetDim(antiquantScaleShape->GetDimNum() - 1); | 334 | antiquantScaleNDim = antiquantScaleShape->GetDim(antiquantScaleShape->GetDimNum() - 1); |
| 334 | } else { | 335 | } else { |
| @@ -356,6 +357,7 @@ ge::graphStatus GroupedMatmulWeightQuantChecker::CheckTensorNDimMultiScenario(co | |||
| 356 | auto antiquantOffsetShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_OFFSET, index); | 357 | auto antiquantOffsetShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_OFFSET, index); |
| 357 | OP_CHECK_NULL_WITH_CONTEXT(context, antiquantOffsetShape); | 358 | OP_CHECK_NULL_WITH_CONTEXT(context, antiquantOffsetShape); |
| 358 | int64_t antiquantOffsetNDim; | 359 | int64_t antiquantOffsetNDim; |
| 360 | + //返回维度数量 | ||
| 359 | if (IsA16W4(xDtype_, weightDtype_) && antiquantOffsetShape->GetDimNum() == 2) { | 361 | if (IsA16W4(xDtype_, weightDtype_) && antiquantOffsetShape->GetDimNum() == 2) { |
| 360 | antiquantOffsetNDim = antiquantOffsetShape->GetDim(antiquantOffsetShape->GetDimNum() - 1); | 362 | antiquantOffsetNDim = antiquantOffsetShape->GetDim(antiquantOffsetShape->GetDimNum() - 1); |
| 361 | } else { | 363 | } else { |
| @@ -370,26 +372,12 @@ ge::graphStatus GroupedMatmulWeightQuantChecker::CheckTensorNDimMultiScenario(co | |||
| 370 | return ge::GRAPH_SUCCESS; | 372 | return ge::GRAPH_SUCCESS; |
| 371 | } | 373 | } |
| 372 | 374 | ||
| 373 | -ge::graphStatus GroupedMatmulWeightQuantChecker::CheckCaseMultiScenario(const gert::InferShapeContext *context, | 375 | +ge::graphStatus GroupedMatmulWeightQuantChecker::CheckPerTensorShapeMultiScenario(const gert::InferShapeContext *context, |
| 374 | - const GMMAttrs &gmmAttrs, | 376 | + size_t wKDimIdx, size_t wNDimIdx, |
| 375 | - const GMMInputParamsInfo ¶msInputInfo) const | 377 | + size_t xSize) const |
| 376 | { | 378 | { |
| 377 | - const size_t &xSize = paramsInputInfo.numX; | ||
| 378 | - // check group size | ||
| 379 | - OP_CHECK_IF(CheckXWeightYGroupSizeMultiScenario(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 380 | - OP_LOGE(context->GetNodeName(), "The size of X, Y and weight are not equal."), return ge::GRAPH_FAILED); | ||
| 381 | - OP_CHECK_IF(CheckTensorListSizeMultiScenario(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 382 | - OP_LOGE(context->GetNodeName(), "CheckTensorListSizeMultiScenario failed."), return ge::GRAPH_FAILED); | ||
| 383 | - // check dimension | ||
| 384 | - OP_CHECK_IF(CheckDimNumNoSplit(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 385 | - OP_LOGE(context->GetNodeName(), "Dim num of tensor in tensor lists or grouplist is invalid."), | ||
| 386 | - return ge::GRAPH_FAILED); | ||
| 387 | - | ||
| 388 | auto xShape = context->GetDynamicInputShape(GMM_INDEX_IN_X, 0); | 379 | auto xShape = context->GetDynamicInputShape(GMM_INDEX_IN_X, 0); |
| 389 | auto wShape = context->GetDynamicInputShape(GMM_INDEX_IN_WEIGHT, 0); | 380 | auto wShape = context->GetDynamicInputShape(GMM_INDEX_IN_WEIGHT, 0); |
| 390 | - size_t wKDimIdx = gmmAttrs.transposeWeight ? 1UL : 0UL; | ||
| 391 | - size_t wNDimIdx = gmmAttrs.transposeWeight ? 0UL : 1UL; | ||
| 392 | - | ||
| 393 | int64_t weightKDimValue = wShape->GetDim(wKDimIdx); | 381 | int64_t weightKDimValue = wShape->GetDim(wKDimIdx); |
| 394 | int64_t weightNDimValue = wShape->GetDim(wNDimIdx); | 382 | int64_t weightNDimValue = wShape->GetDim(wNDimIdx); |
| 395 | 383 | ||
| @@ -429,28 +417,60 @@ ge::graphStatus GroupedMatmulWeightQuantChecker::CheckCaseMultiScenario(const ge | |||
| 429 | OP_LOGE(context->GetNodeName(), "CheckTensorNDimMultiScenario is failed."), | 417 | OP_LOGE(context->GetNodeName(), "CheckTensorNDimMultiScenario is failed."), |
| 430 | return ge::GRAPH_FAILED); | 418 | return ge::GRAPH_FAILED); |
| 431 | } | 419 | } |
| 420 | + return ge::GRAPH_SUCCESS; | ||
| 421 | +} | ||
| 422 | + | ||
| 423 | +ge::graphStatus GroupedMatmulWeightQuantChecker::CheckA16W4PergroupMultiScenario(const gert::InferShapeContext *context, | ||
| 424 | + size_t wKDimIdx, size_t xSize) const | ||
| 425 | +{ | ||
| 426 | + for (size_t i = 0; i < xSize; i++) { | ||
| 427 | + auto antiquantScaleShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_SCALE, i); | ||
| 428 | + if (antiquantScaleShape == nullptr || antiquantScaleShape->GetDimNum() <= 1) { | ||
| 429 | + continue; | ||
| 430 | + } | ||
| 431 | + auto wShape_i = context->GetDynamicInputShape(GMM_INDEX_IN_WEIGHT, i); | ||
| 432 | + OP_CHECK_NULL_WITH_CONTEXT(context, wShape_i); | ||
| 433 | + int64_t kSize = wShape_i->GetDim(wKDimIdx); | ||
| 434 | + int64_t groupNum = antiquantScaleShape->GetDim(0); | ||
| 435 | + OP_CHECK_IF(groupNum <= 0, OP_LOGE(context->GetNodeName(), "GroupNum must be greater than 0."), | ||
| 436 | + return ge::GRAPH_FAILED); | ||
| 437 | + OP_CHECK_IF(kSize % groupNum != 0, | ||
| 438 | + OP_LOGE(context->GetNodeName(), "GroupNum must be multiple of the k axis of weight."), | ||
| 439 | + return ge::GRAPH_FAILED); | ||
| 440 | + int64_t groupSize = kSize / groupNum; | ||
| 441 | + OP_CHECK_IF( | ||
| 442 | + groupSize != 32 && groupSize != 64 && groupSize != 128 && groupSize != 256, | ||
| 443 | + OP_LOGE(context->GetNodeName(), | ||
| 444 | + "groupSize must be 32/64/128/256 on Ascend 950PR, but current groupSize is (%ld).", groupSize), | ||
| 445 | + return ge::GRAPH_FAILED); | ||
| 446 | + } | ||
| 447 | + return ge::GRAPH_SUCCESS; | ||
| 448 | +} | ||
| 449 | + | ||
| 450 | +ge::graphStatus GroupedMatmulWeightQuantChecker::CheckCaseMultiScenario(const gert::InferShapeContext *context, | ||
| 451 | + const GMMAttrs &gmmAttrs, | ||
| 452 | + const GMMInputParamsInfo ¶msInputInfo) const | ||
| 453 | +{ | ||
| 454 | + const size_t &xSize = paramsInputInfo.numX; | ||
| 455 | + // check group size | ||
| 456 | + OP_CHECK_IF(CheckXWeightYGroupSizeMultiScenario(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 457 | + OP_LOGE(context->GetNodeName(), "The size of X, Y and weight are not equal."), return ge::GRAPH_FAILED); | ||
| 458 | + OP_CHECK_IF(CheckTensorListSizeMultiScenario(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 459 | + OP_LOGE(context->GetNodeName(), "CheckTensorListSizeMultiScenario failed."), return ge::GRAPH_FAILED); | ||
| 460 | + // check dimension | ||
| 461 | + OP_CHECK_IF(CheckDimNumNoSplit(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 462 | + OP_LOGE(context->GetNodeName(), "Dim num of tensor in tensor lists or grouplist is invalid."), | ||
| 463 | + return ge::GRAPH_FAILED); | ||
| 464 | + | ||
| 465 | + size_t wKDimIdx = gmmAttrs.transposeWeight ? 1UL : 0UL; | ||
| 466 | + size_t wNDimIdx = gmmAttrs.transposeWeight ? 0UL : 1UL; | ||
| 467 | + if (CheckPerTensorShapeMultiScenario(context, wKDimIdx, wNDimIdx, xSize) != ge::GRAPH_SUCCESS) { | ||
| 468 | + return ge::GRAPH_FAILED; | ||
| 469 | + } | ||
| 432 | 470 | ||
| 433 | if (IsA16W4(xDtype_, weightDtype_)) { | 471 | if (IsA16W4(xDtype_, weightDtype_)) { |
| 434 | - for (size_t i = 0; i < xSize; i++) { | 472 | + if (CheckA16W4PergroupMultiScenario(context, wKDimIdx, xSize) != ge::GRAPH_SUCCESS) { |
| 435 | - auto antiquantScaleShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_SCALE, i); | 473 | + return ge::GRAPH_FAILED; |
| 436 | - if (antiquantScaleShape == nullptr || antiquantScaleShape->GetDimNum() <= 1) { | ||
| 437 | - continue; | ||
| 438 | - } | ||
| 439 | - auto wShape_i = context->GetDynamicInputShape(GMM_INDEX_IN_WEIGHT, i); | ||
| 440 | - OP_CHECK_NULL_WITH_CONTEXT(context, wShape_i); | ||
| 441 | - int64_t kSize = wShape_i->GetDim(wKDimIdx); | ||
| 442 | - int64_t groupNum = antiquantScaleShape->GetDim(0); | ||
| 443 | - OP_CHECK_IF(groupNum <= 0, OP_LOGE(context->GetNodeName(), "GroupNum must be greater than 0."), | ||
| 444 | - return ge::GRAPH_FAILED); | ||
| 445 | - OP_CHECK_IF(kSize % groupNum != 0, | ||
| 446 | - OP_LOGE(context->GetNodeName(), "GroupNum must be multiple of the k axis of weight."), | ||
| 447 | - return ge::GRAPH_FAILED); | ||
| 448 | - int64_t groupSize = kSize / groupNum; | ||
| 449 | - OP_CHECK_IF( | ||
| 450 | - groupSize != 32 && groupSize != 64 && groupSize != 128 && groupSize != 256, | ||
| 451 | - OP_LOGE(context->GetNodeName(), | ||
| 452 | - "groupSize must be 32/64/128/256 on Ascend 950PR, but current groupSize is (%ld).", groupSize), | ||
| 453 | - return ge::GRAPH_FAILED); | ||
| 454 | } | 474 | } |
| 455 | } | 475 | } |
| 456 | 476 | ||
| @@ -630,6 +650,7 @@ ge::graphStatus GroupedMatmulWeightQuantChecker::CheckShapeForTensorListAtIndex( | |||
| 630 | const GMMAttrs &gmmAttrs, | 650 | const GMMAttrs &gmmAttrs, |
| 631 | size_t tensorIdx) const | 651 | size_t tensorIdx) const |
| 632 | { | 652 | { |
| 653 | + (void)gmmAttrs; // 保留传参以保持接口一致性,当前逻辑暂未使用 | ||
| 633 | auto tensorShape = context->GetDynamicInputShape(gmm_index, tensorIdx); | 654 | auto tensorShape = context->GetDynamicInputShape(gmm_index, tensorIdx); |
| 634 | if (IsNonEmpty(tensorShape)) { | 655 | if (IsNonEmpty(tensorShape)) { |
| 635 | size_t tensorDimNum = tensorShape->GetDimNum(); | 656 | size_t tensorDimNum = tensorShape->GetDimNum(); |
| @@ -832,60 +853,74 @@ ge::graphStatus GroupedMatmulWeightQuantChecker::CheckTensorListSizeMultiScenari | |||
| 832 | return ge::GRAPH_SUCCESS; | 853 | return ge::GRAPH_SUCCESS; |
| 833 | } | 854 | } |
| 834 | 855 | ||
| 856 | +ge::graphStatus GroupedMatmulWeightQuantChecker::CheckShapeValidNoSplit(const gert::InferShapeContext *context, | ||
| 857 | + const GMMAttrs &gmmAttrs) | ||
| 858 | +{ | ||
| 859 | + // 多多多场景校验 | ||
| 860 | + GMMInputParamsInfo paramsInputInfo{0, 0, 0, 0, 0, 0, 0}; | ||
| 861 | + OP_CHECK_IF(GetNumOfInputs(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 862 | + OP_LOGE(context->GetNodeName(), "GetNumOfInputs failed."), return ge::GRAPH_FAILED); | ||
| 863 | + hasBias_ = paramsInputInfo.numBias > 0; | ||
| 864 | + if (paramsInputInfo.numBias == 1) { | ||
| 865 | + auto biasShape = context->GetDynamicInputShape(GMM_INDEX_IN_BIAS, 0); | ||
| 866 | + hasBias_ = biasShape->GetShapeSize() != 0; | ||
| 867 | + } | ||
| 868 | + hasAntiquantOffset_ = paramsInputInfo.numAntiquantOffset > 0; | ||
| 869 | + if (paramsInputInfo.numAntiquantOffset == 1) { | ||
| 870 | + auto antiQuantOffsetShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_OFFSET, 0); | ||
| 871 | + hasAntiquantOffset_ = antiQuantOffsetShape->GetShapeSize() != 0; | ||
| 872 | + } | ||
| 873 | + OP_CHECK_IF(CheckCaseMultiScenario(context, gmmAttrs, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 874 | + OP_LOGE(context->GetNodeName(), "CheckCaseMultiScenario failed."), return ge::GRAPH_FAILED); | ||
| 875 | + return ge::GRAPH_SUCCESS; | ||
| 876 | +} | ||
| 877 | + | ||
| 878 | +ge::graphStatus GroupedMatmulWeightQuantChecker::CheckShapeValidSplitM(const gert::InferShapeContext *context, | ||
| 879 | + const GMMAttrs &gmmAttrs) | ||
| 880 | +{ | ||
| 881 | + auto groupListShape = context->GetOptionalInputShape(GMM_INDEX_IN_GROUP_LIST); | ||
| 882 | + OP_CHECK_NULL_WITH_CONTEXT(context, groupListShape); | ||
| 883 | + OP_CHECK_IF(CheckShapeForGrouplist(context, groupListShape) != ge::GRAPH_SUCCESS, | ||
| 884 | + OP_LOGE(context->GetNodeName(), "CheckShapeForGrouplist failed."), return ge::GRAPH_FAILED); | ||
| 885 | + groupNum_ = groupListShape->GetDim(0); | ||
| 886 | + OP_CHECK_IF(CheckShapeForXAndWeight(context) != ge::GRAPH_SUCCESS, | ||
| 887 | + OP_LOGE(context->GetNodeName(), "CheckShapeForXAndWeight failed."), return ge::GRAPH_FAILED); | ||
| 888 | + if (isMultiTensorWeight_) { | ||
| 889 | + for (size_t i = 0; i < numWeight_; i++) { | ||
| 890 | + OP_CHECK_IF(CheckShapeForTensorListAtIndex(context, GMM_INDEX_IN_BIAS, "bias", gmmAttrs, i) != | ||
| 891 | + ge::GRAPH_SUCCESS, | ||
| 892 | + OP_LOGE(context->GetNodeName(), "CheckShapeForBias at index [%zu] failed.", i), | ||
| 893 | + return ge::GRAPH_FAILED); | ||
| 894 | + OP_CHECK_IF(CheckShapeForTensorListAtIndex(context, GMM_INDEX_IN_ANTIQUANT_SCALE, "antiquantScale", | ||
| 895 | + gmmAttrs, i) != ge::GRAPH_SUCCESS, | ||
| 896 | + OP_LOGE(context->GetNodeName(), "CheckShapeForAntiquantScale at index [%zu] failed.", i), | ||
| 897 | + return ge::GRAPH_FAILED); | ||
| 898 | + OP_CHECK_IF(CheckShapeForTensorListAtIndex(context, GMM_INDEX_IN_ANTIQUANT_OFFSET, "antiquantOffset", | ||
| 899 | + gmmAttrs, i) != ge::GRAPH_SUCCESS, | ||
| 900 | + OP_LOGE(context->GetNodeName(), "CheckShapeForAntiquantOffset failed."), | ||
| 901 | + return ge::GRAPH_FAILED); | ||
| 902 | + OP_CHECK_IF(CheckGroupSize(context, gmmAttrs, i) != ge::GRAPH_SUCCESS, | ||
| 903 | + OP_LOGE(context->GetNodeName(), "CheckGroupSize failed."), return ge::GRAPH_FAILED); | ||
| 904 | + } | ||
| 905 | + } else { | ||
| 906 | + OP_CHECK_IF(CheckShapeForTensorList(context, GMM_INDEX_IN_BIAS, "bias", gmmAttrs) != ge::GRAPH_SUCCESS, | ||
| 907 | + OP_LOGE(context->GetNodeName(), "CheckShapeForBias failed."), return ge::GRAPH_FAILED); | ||
| 908 | + OP_CHECK_IF(CheckShapeForWeightQuantParam(context, gmmAttrs) != ge::GRAPH_SUCCESS, | ||
| 909 | + OP_LOGE(context->GetNodeName(), "CheckShapeForWeightQuantParam failed."), | ||
| 910 | + return ge::GRAPH_FAILED); | ||
| 911 | + OP_CHECK_IF(CheckGroupSize(context, gmmAttrs, 0) != ge::GRAPH_SUCCESS, | ||
| 912 | + OP_LOGE(context->GetNodeName(), "CheckGroupSize failed."), return ge::GRAPH_FAILED); | ||
| 913 | + } | ||
| 914 | + return ge::GRAPH_SUCCESS; | ||
| 915 | +} | ||
| 916 | + | ||
| 835 | ge::graphStatus GroupedMatmulWeightQuantChecker::CheckShapeValid(const gert::InferShapeContext *context, | 917 | ge::graphStatus GroupedMatmulWeightQuantChecker::CheckShapeValid(const gert::InferShapeContext *context, |
| 836 | const GMMAttrs &gmmAttrs) | 918 | const GMMAttrs &gmmAttrs) |
| 837 | { | 919 | { |
| 838 | if (gmmAttrs.groupType == GMM_NO_SPLIT) { | 920 | if (gmmAttrs.groupType == GMM_NO_SPLIT) { |
| 839 | - // 多多多场景校验 | 921 | + return CheckShapeValidNoSplit(context, gmmAttrs); |
| 840 | - GMMInputParamsInfo paramsInputInfo{0, 0, 0, 0, 0, 0, 0}; | ||
| 841 | - OP_CHECK_IF(GetNumOfInputs(context, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 842 | - OP_LOGE(context->GetNodeName(), "GetNumOfInputs failed."), return ge::GRAPH_FAILED); | ||
| 843 | - hasBias_ = paramsInputInfo.numBias > 0; | ||
| 844 | - if (paramsInputInfo.numBias == 1) { | ||
| 845 | - auto biasShape = context->GetDynamicInputShape(GMM_INDEX_IN_BIAS, 0); | ||
| 846 | - hasBias_ = biasShape->GetShapeSize() != 0; | ||
| 847 | - } | ||
| 848 | - hasAntiquantOffset_ = paramsInputInfo.numAntiquantOffset > 0; | ||
| 849 | - if (paramsInputInfo.numAntiquantOffset == 1) { | ||
| 850 | - auto antiQuantOffsetShape = context->GetDynamicInputShape(GMM_INDEX_IN_ANTIQUANT_OFFSET, 0); | ||
| 851 | - hasAntiquantOffset_ = antiQuantOffsetShape->GetShapeSize() != 0; | ||
| 852 | - } | ||
| 853 | - OP_CHECK_IF(CheckCaseMultiScenario(context, gmmAttrs, paramsInputInfo) != ge::GRAPH_SUCCESS, | ||
| 854 | - OP_LOGE(context->GetNodeName(), "CheckCaseMultiScenario failed."), return ge::GRAPH_FAILED); | ||
| 855 | } else { | 922 | } else { |
| 856 | - auto groupListShape = context->GetOptionalInputShape(GMM_INDEX_IN_GROUP_LIST); | 923 | + return CheckShapeValidSplitM(context, gmmAttrs); |
| 857 | - OP_CHECK_NULL_WITH_CONTEXT(context, groupListShape); | ||
| 858 | - OP_CHECK_IF(CheckShapeForGrouplist(context, groupListShape) != ge::GRAPH_SUCCESS, | ||
| 859 | - OP_LOGE(context->GetNodeName(), "CheckShapeForGrouplist failed."), return ge::GRAPH_FAILED); | ||
| 860 | - groupNum_ = groupListShape->GetDim(0); | ||
| 861 | - OP_CHECK_IF(CheckShapeForXAndWeight(context) != ge::GRAPH_SUCCESS, | ||
| 862 | - OP_LOGE(context->GetNodeName(), "CheckShapeForXAndWeight failed."), return ge::GRAPH_FAILED); | ||
| 863 | - if (isMultiTensorWeight_) { | ||
| 864 | - for (size_t i = 0; i < numWeight_; i++) { | ||
| 865 | - OP_CHECK_IF(CheckShapeForTensorListAtIndex(context, GMM_INDEX_IN_BIAS, "bias", gmmAttrs, i) != | ||
| 866 | - ge::GRAPH_SUCCESS, | ||
| 867 | - OP_LOGE(context->GetNodeName(), "CheckShapeForBias at index [%zu] failed.", i), | ||
| 868 | - return ge::GRAPH_FAILED); | ||
| 869 | - OP_CHECK_IF(CheckShapeForTensorListAtIndex(context, GMM_INDEX_IN_ANTIQUANT_SCALE, "antiquantScale", | ||
| 870 | - gmmAttrs, i) != ge::GRAPH_SUCCESS, | ||
| 871 | - OP_LOGE(context->GetNodeName(), "CheckShapeForAntiquantScale at index [%zu] failed.", i), | ||
| 872 | - return ge::GRAPH_FAILED); | ||
| 873 | - OP_CHECK_IF(CheckShapeForTensorListAtIndex(context, GMM_INDEX_IN_ANTIQUANT_OFFSET, "antiquantOffset", | ||
| 874 | - gmmAttrs, i) != ge::GRAPH_SUCCESS, | ||
| 875 | - OP_LOGE(context->GetNodeName(), "CheckShapeForAntiquantOffset failed."), | ||
| 876 | - return ge::GRAPH_FAILED); | ||
| 877 | - OP_CHECK_IF(CheckGroupSize(context, gmmAttrs, i) != ge::GRAPH_SUCCESS, | ||
| 878 | - OP_LOGE(context->GetNodeName(), "CheckGroupSize failed."), return ge::GRAPH_FAILED); | ||
| 879 | - } | ||
| 880 | - } else { | ||
| 881 | - OP_CHECK_IF(CheckShapeForTensorList(context, GMM_INDEX_IN_BIAS, "bias", gmmAttrs) != ge::GRAPH_SUCCESS, | ||
| 882 | - OP_LOGE(context->GetNodeName(), "CheckShapeForBias failed."), return ge::GRAPH_FAILED); | ||
| 883 | - OP_CHECK_IF(CheckShapeForWeightQuantParam(context, gmmAttrs) != ge::GRAPH_SUCCESS, | ||
| 884 | - OP_LOGE(context->GetNodeName(), "CheckShapeForWeightQuantParam failed."), | ||
| 885 | - return ge::GRAPH_FAILED); | ||
| 886 | - OP_CHECK_IF(CheckGroupSize(context, gmmAttrs, 0) != ge::GRAPH_SUCCESS, | ||
| 887 | - OP_LOGE(context->GetNodeName(), "CheckGroupSize failed."), return ge::GRAPH_FAILED); | ||
| 888 | - } | ||
| 889 | } | 924 | } |
| 890 | return ge::GRAPH_SUCCESS; | 925 | return ge::GRAPH_SUCCESS; |
| 891 | } | 926 | } |
| @@ -52,6 +52,10 @@ private: | |||
| 52 | const int64_t weightNDimValue, const size_t index) const; | 52 | const int64_t weightNDimValue, const size_t index) const; |
| 53 | ge::graphStatus CheckCaseMultiScenario(const gert::InferShapeContext *context, const GMMAttrs &gmmAttrs, | 53 | ge::graphStatus CheckCaseMultiScenario(const gert::InferShapeContext *context, const GMMAttrs &gmmAttrs, |
| 54 | const GMMInputParamsInfo ¶msInputInfo) const; | 54 | const GMMInputParamsInfo ¶msInputInfo) const; |
| 55 | + ge::graphStatus CheckPerTensorShapeMultiScenario(const gert::InferShapeContext *context, size_t wKDimIdx, | ||
| 56 | + size_t wNDimIdx, size_t xSize) const; | ||
| 57 | + ge::graphStatus CheckA16W4PergroupMultiScenario(const gert::InferShapeContext *context, size_t wKDimIdx, | ||
| 58 | + size_t xSize) const; | ||
| 55 | ge::graphStatus CheckShapeForTensorList(const gert::InferShapeContext *context, size_t gmm_index, | 59 | ge::graphStatus CheckShapeForTensorList(const gert::InferShapeContext *context, size_t gmm_index, |
| 56 | const std::string &tensorType, const GMMAttrs &gmmAttrs) const; | 60 | const std::string &tensorType, const GMMAttrs &gmmAttrs) const; |
| 57 | ge::graphStatus CheckShapeForTensorListAtIndex(const gert::InferShapeContext *context, size_t gmm_index, | 61 | ge::graphStatus CheckShapeForTensorListAtIndex(const gert::InferShapeContext *context, size_t gmm_index, |
| @@ -62,6 +66,8 @@ private: | |||
| 62 | ge::graphStatus CheckTensorListSizeMultiScenario(const gert::InferShapeContext *context, | 66 | ge::graphStatus CheckTensorListSizeMultiScenario(const gert::InferShapeContext *context, |
| 63 | const GMMInputParamsInfo ¶msInputInfo) const; | 67 | const GMMInputParamsInfo ¶msInputInfo) const; |
| 64 | ge::graphStatus CheckShapeValid(const gert::InferShapeContext *context, const GMMAttrs &gmmAttrs); | 68 | ge::graphStatus CheckShapeValid(const gert::InferShapeContext *context, const GMMAttrs &gmmAttrs); |
| 69 | + ge::graphStatus CheckShapeValidNoSplit(const gert::InferShapeContext *context, const GMMAttrs &gmmAttrs); | ||
| 70 | + ge::graphStatus CheckShapeValidSplitM(const gert::InferShapeContext *context, const GMMAttrs &gmmAttrs); | ||
| 65 | 71 | ||
| 66 | ge::graphStatus CheckShapeForWeightQuantParam(const gert::InferShapeContext *context, | 72 | ge::graphStatus CheckShapeForWeightQuantParam(const gert::InferShapeContext *context, |
| 67 | const GMMAttrs &gmmAttrs) const; | 73 | const GMMAttrs &gmmAttrs) const; |
| @@ -558,11 +558,13 @@ ge::graphStatus GroupedS4S4IntQuantTiling::GetShapeAttrsInfo() | |||
| 558 | OP_CHECK_NULL_WITH_CONTEXT(context_, xShapePtr); | 558 | OP_CHECK_NULL_WITH_CONTEXT(context_, xShapePtr); |
| 559 | OP_CHECK_NULL_WITH_CONTEXT(context_, wShapePtr); | 559 | OP_CHECK_NULL_WITH_CONTEXT(context_, wShapePtr); |
| 560 | const auto &weightStorageShape = wShapePtr->GetStorageShape(); | 560 | const auto &weightStorageShape = wShapePtr->GetStorageShape(); |
| 561 | - weightNzC032_ = inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ && weightStorageShape.GetDimNum() > 0U && | 561 | + weightNzC032_ = inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ && |
| 562 | - weightStorageShape.GetDim(weightStorageShape.GetDimNum() - 1U) == 32; | 562 | + weightStorageShape.GetDimNum() > 0U && |
| 563 | - OP_CHECK_IF(!SetMKN(xShapePtr->GetOriginShape(), wShapePtr->GetOriginShape()), | 563 | + weightStorageShape.GetDim(weightStorageShape.GetDimNum() - 1U) == INT8_NZ_C0; |
| 564 | - OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 SetMKN failed."), return ge::GRAPH_FAILED); | 564 | + OP_CHECK_IF(!SetMKNForS4S4(xShapePtr->GetOriginShape(), wShapePtr->GetOriginShape()), |
| 565 | - OP_CHECK_IF(!SetGroupNum(GROUPLIST_INDEX), | 565 | + OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 SetMKN failed."), |
| 566 | + return ge::GRAPH_FAILED); | ||
| 567 | + OP_CHECK_IF(!SetGroupNumForS4S4(GROUPLIST_INDEX), | ||
| 566 | OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 SetGroupNum failed."), | 568 | OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 SetGroupNum failed."), |
| 567 | return ge::GRAPH_FAILED); | 569 | return ge::GRAPH_FAILED); |
| 568 | OP_CHECK_IF(!AnalyzeS4S4(), OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 AnalyzeS4S4 failed."), | 570 | OP_CHECK_IF(!AnalyzeS4S4(), OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 AnalyzeS4S4 failed."), |
| @@ -573,7 +575,7 @@ ge::graphStatus GroupedS4S4IntQuantTiling::GetShapeAttrsInfo() | |||
| 573 | return ge::GRAPH_SUCCESS; | 575 | return ge::GRAPH_SUCCESS; |
| 574 | } | 576 | } |
| 575 | 577 | ||
| 576 | -bool GroupedS4S4IntQuantTiling::SetMKN(const gert::Shape &xShape, const gert::Shape &wShape) | 578 | +bool GroupedS4S4IntQuantTiling::SetMKNForS4S4(const gert::Shape &xShape, const gert::Shape &wShape) |
| 577 | { | 579 | { |
| 578 | uint32_t xDimNum = static_cast<uint32_t>(xShape.GetDimNum()); | 580 | uint32_t xDimNum = static_cast<uint32_t>(xShape.GetDimNum()); |
| 579 | uint32_t wDimNum = static_cast<uint32_t>(wShape.GetDimNum()); | 581 | uint32_t wDimNum = static_cast<uint32_t>(wShape.GetDimNum()); |
| @@ -589,7 +591,7 @@ bool GroupedS4S4IntQuantTiling::SetMKN(const gert::Shape &xShape, const gert::Sh | |||
| 589 | return true; | 591 | return true; |
| 590 | } | 592 | } |
| 591 | 593 | ||
| 592 | -bool GroupedS4S4IntQuantTiling::SetGroupNum(uint32_t groupListIndex) | 594 | +bool GroupedS4S4IntQuantTiling::SetGroupNumForS4S4(uint32_t groupListIndex) |
| 593 | { | 595 | { |
| 594 | OP_CHECK_IF(!GroupedQmmBasicApiTiling::SetGroupNum(groupListIndex), | 596 | OP_CHECK_IF(!GroupedQmmBasicApiTiling::SetGroupNum(groupListIndex), |
| 595 | OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 base SetGroupNum failed."), return false); | 597 | OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "S4S4 base SetGroupNum failed."), return false); |
| @@ -597,7 +599,7 @@ bool GroupedS4S4IntQuantTiling::SetGroupNum(uint32_t groupListIndex) | |||
| 597 | return true; | 599 | return true; |
| 598 | } | 600 | } |
| 599 | 601 | ||
| 600 | -bool GroupedS4S4IntQuantTiling::SetMKNList() | 602 | +bool GroupedS4S4IntQuantTiling::SetMKNListForS4S4() |
| 601 | { | 603 | { |
| 602 | // Base's mList_/kList_/nList_ is private (inaccessible to derived). | 604 | // Base's mList_/kList_/nList_ is private (inaccessible to derived). |
| 603 | // Write to our own shadow arrays (mimic base GroupedQmmTiling::SetMKNList). | 605 | // Write to our own shadow arrays (mimic base GroupedQmmTiling::SetMKNList). |
| @@ -641,7 +643,7 @@ bool GroupedS4S4IntQuantTiling::AnalyzeS4S4() | |||
| 641 | return true; | 643 | return true; |
| 642 | } | 644 | } |
| 643 | 645 | ||
| 644 | -bool GroupedS4S4IntQuantTiling::CheckS4S4Params() | 646 | +bool GroupedS4S4IntQuantTiling::CheckS4S4Params() const |
| 645 | { | 647 | { |
| 646 | OP_CHECK_IF(inputParams_.aDtype != ge::DT_INT4 || inputParams_.bDtype != ge::DT_INT4, | 648 | OP_CHECK_IF(inputParams_.aDtype != ge::DT_INT4 || inputParams_.bDtype != ge::DT_INT4, |
| 647 | OP_LOGE(context_->GetNodeName(), "S4S4: x/weight must be INT4."), return false); | 649 | OP_LOGE(context_->GetNodeName(), "S4S4: x/weight must be INT4."), return false); |
| @@ -706,7 +708,8 @@ ge::graphStatus GroupedS4S4IntQuantTiling::DoOpTiling() | |||
| 706 | OP_CHECK_IF(CalUbDivideS4S4() != ge::GRAPH_SUCCESS, | 708 | OP_CHECK_IF(CalUbDivideS4S4() != ge::GRAPH_SUCCESS, |
| 707 | OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "CalUbDivideS4S4 failed."), | 709 | OPS_REPORT_VECTOR_INNER_ERR(context_->GetNodeName(), "CalUbDivideS4S4 failed."), |
| 708 | return ge::GRAPH_FAILED); | 710 | return ge::GRAPH_FAILED); |
| 709 | - OP_CHECK_IF(!SetMKNList(), OP_LOGE(context_->GetNodeName(), "SetMKNList failed."), return ge::GRAPH_FAILED); | 711 | + OP_CHECK_IF(!SetMKNListForS4S4(), OP_LOGE(context_->GetNodeName(), "SetMKNList failed."), |
| 712 | + return ge::GRAPH_FAILED); | ||
| 710 | s4s4Tiling_.singleN = FindBestSingleN(); | 713 | s4s4Tiling_.singleN = FindBestSingleN(); |
| 711 | return ge::GRAPH_SUCCESS; | 714 | return ge::GRAPH_SUCCESS; |
| 712 | } | 715 | } |
| @@ -750,7 +753,7 @@ ge::graphStatus GroupedS4S4IntQuantTiling::CalUbDivideS4S4() | |||
| 750 | return ge::GRAPH_SUCCESS; | 753 | return ge::GRAPH_SUCCESS; |
| 751 | } | 754 | } |
| 752 | 755 | ||
| 753 | -void GroupedS4S4IntQuantTiling::InitCommonL1TilingFields() | 756 | +void GroupedS4S4IntQuantTiling::InitS4S4CommonL1TilingFields() |
| 754 | { | 757 | { |
| 755 | s4s4Tiling_.stepM = 1UL; | 758 | s4s4Tiling_.stepM = 1UL; |
| 756 | s4s4Tiling_.stepN = 1UL; | 759 | s4s4Tiling_.stepN = 1UL; |
| @@ -764,7 +767,7 @@ void GroupedS4S4IntQuantTiling::InitCommonL1TilingFields() | |||
| 764 | 1U; | 767 | 1U; |
| 765 | } | 768 | } |
| 766 | 769 | ||
| 767 | -ge::graphStatus GroupedS4S4IntQuantTiling::CalcLeftL1Size(uint64_t &leftL1Size) const | 770 | +ge::graphStatus GroupedS4S4IntQuantTiling::CalcS4S4LeftL1Size(uint64_t &leftL1Size) const |
| 768 | { | 771 | { |
| 769 | leftL1Size = aicoreParams_.l1Size; | 772 | leftL1Size = aicoreParams_.l1Size; |
| 770 | return ge::GRAPH_SUCCESS; | 773 | return ge::GRAPH_SUCCESS; |
| @@ -772,13 +775,11 @@ ge::graphStatus GroupedS4S4IntQuantTiling::CalcLeftL1Size(uint64_t &leftL1Size) | |||
| 772 | 775 | ||
| 773 | ge::graphStatus GroupedS4S4IntQuantTiling::CalL1Tiling() | 776 | ge::graphStatus GroupedS4S4IntQuantTiling::CalL1Tiling() |
| 774 | { | 777 | { |
| 775 | - InitCommonL1TilingFields(); | 778 | + InitS4S4CommonL1TilingFields(); |
| 776 | - if (inputParams_.kSize == 0UL) { | 779 | + if (inputParams_.kSize == 0UL) { return ge::GRAPH_SUCCESS; } |
| 777 | - return ge::GRAPH_SUCCESS; | ||
| 778 | - } | ||
| 779 | uint64_t leftL1Size = 0UL; | 780 | uint64_t leftL1Size = 0UL; |
| 780 | - OP_CHECK_IF(CalcLeftL1Size(leftL1Size) != ge::GRAPH_SUCCESS, | 781 | + OP_CHECK_IF(CalcS4S4LeftL1Size(leftL1Size) != ge::GRAPH_SUCCESS, |
| 781 | - OP_LOGE(context_->GetNodeName(), "CalcLeftL1Size failed."), return ge::GRAPH_FAILED); | 782 | + OP_LOGE(context_->GetNodeName(), "CalcS4S4LeftL1Size failed."), return ge::GRAPH_FAILED); |
| 782 | return CalL1Depth(leftL1Size); | 783 | return CalL1Depth(leftL1Size); |
| 783 | } | 784 | } |
| 784 | 785 | ||
| @@ -801,16 +802,18 @@ ge::graphStatus GroupedS4S4IntQuantTiling::CalL1Depth(uint64_t leftL1Size) | |||
| 801 | constexpr uint64_t elemBytes = 1UL; | 802 | constexpr uint64_t elemBytes = 1UL; |
| 802 | constexpr uint64_t scaleElemBytes = sizeof(uint64_t); | 803 | constexpr uint64_t scaleElemBytes = sizeof(uint64_t); |
| 803 | auto AlignUpL = [](uint64_t v, uint64_t a) -> uint64_t { return (v + a - 1UL) / a * a; }; | 804 | auto AlignUpL = [](uint64_t v, uint64_t a) -> uint64_t { return (v + a - 1UL) / a * a; }; |
| 804 | - auto GetAL1Bytes = [&](uint64_t kAL1) -> uint64_t { | 805 | + auto GetAL1Bytes = [this](uint64_t kAL1) -> uint64_t { |
| 805 | return AlignUpL(s4s4Tiling_.baseM, CUBE_BLOCK) * AlignUpL(kAL1, INT8_C0) * elemBytes; | 806 | return AlignUpL(s4s4Tiling_.baseM, CUBE_BLOCK) * AlignUpL(kAL1, INT8_C0) * elemBytes; |
| 806 | }; | 807 | }; |
| 807 | - auto GetBL1Bytes = [&](uint64_t kBL1) -> uint64_t { | 808 | + auto GetBL1Bytes = [this](uint64_t kBL1) -> uint64_t { |
| 808 | return AlignUpL(kBL1, INT8_C0) * AlignUpL(s4s4Tiling_.baseN, CUBE_BLOCK) * elemBytes; | 809 | return AlignUpL(kBL1, INT8_C0) * AlignUpL(s4s4Tiling_.baseN, CUBE_BLOCK) * elemBytes; |
| 809 | }; | 810 | }; |
| 810 | - auto GetScaleL1Bytes = [&]() -> uint64_t { return AlignUpL(s4s4Tiling_.baseN * scaleElemBytes, DATA_BLOCK_BYTES); }; | 811 | + auto GetScaleL1Bytes = [this]() -> uint64_t { |
| 811 | - auto GetL1StageBytes = [&](uint64_t kAL1, uint64_t kBL1) -> uint64_t { | 812 | + return AlignUpL(s4s4Tiling_.baseN * scaleElemBytes, DATA_BLOCK_BYTES); |
| 812 | - return AlignUpL(GetAL1Bytes(kAL1), DATA_BLOCK_BYTES) + AlignUpL(GetBL1Bytes(kBL1), DATA_BLOCK_BYTES) + | 813 | + }; |
| 813 | - GetScaleL1Bytes(); | 814 | + auto GetL1StageBytes = [this](uint64_t kAL1, uint64_t kBL1) -> uint64_t { |
| 815 | + return AlignUpL(GetAL1Bytes(kAL1), DATA_BLOCK_BYTES) + | ||
| 816 | + AlignUpL(GetBL1Bytes(kBL1), DATA_BLOCK_BYTES) + GetScaleL1Bytes(); | ||
| 814 | }; | 817 | }; |
| 815 | 818 | ||
| 816 | const uint64_t halfL1 = leftL1Size / L1_BUFFER_NUM; | 819 | const uint64_t halfL1 = leftL1Size / L1_BUFFER_NUM; |
| @@ -891,7 +894,7 @@ uint64_t GroupedS4S4IntQuantTiling::GetTilingKey() const | |||
| 891 | return GET_TPL_TILING_KEY(static_cast<uint64_t>(inputParams_.transB ? 1 : 0), 0UL, S4S4_KERNEL_TYPE_MIX); | 894 | return GET_TPL_TILING_KEY(static_cast<uint64_t>(inputParams_.transB ? 1 : 0), 0UL, S4S4_KERNEL_TYPE_MIX); |
| 892 | } | 895 | } |
| 893 | 896 | ||
| 894 | -ge::graphStatus GroupedS4S4IntQuantTiling::PostTiling() | 897 | +void GroupedS4S4IntQuantTiling::SetS4S4Params() |
| 895 | { | 898 | { |
| 896 | using namespace GroupedMatmulTilingData; | 899 | using namespace GroupedMatmulTilingData; |
| 897 | auto &p = tilingData_.gmmS4S4Params; | 900 | auto &p = tilingData_.gmmS4S4Params; |
| @@ -913,7 +916,11 @@ ge::graphStatus GroupedS4S4IntQuantTiling::PostTiling() | |||
| 913 | p.groupListType = s4s4Tiling_.groupListType; | 916 | p.groupListType = s4s4Tiling_.groupListType; |
| 914 | p.reserved = ((inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ) ? S4S4_WEIGHT_NZ_FLAG : 0ULL) | | 917 | p.reserved = ((inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ) ? S4S4_WEIGHT_NZ_FLAG : 0ULL) | |
| 915 | (inputParams_.transB ? S4S4_TRANSPOSE_WEIGHT_FLAG : 0ULL) | | 918 | (inputParams_.transB ? S4S4_TRANSPOSE_WEIGHT_FLAG : 0ULL) | |
| 916 | - (weightNzC032_ ? S4S4_WEIGHT_NZ_C0_32_FLAG : 0ULL); | 919 | + (weightNzC032_ ? S4S4_WEIGHT_NZ_C0_32_FLAG : 0ULL); |
| 920 | +} | ||
| 921 | + | ||
| 922 | +ge::graphStatus GroupedS4S4IntQuantTiling::SetArrayParams() | ||
| 923 | +{ | ||
| 917 | errno_t retM = memcpy_s(tilingData_.gmmArray.mList, sizeof(tilingData_.gmmArray.mList), mList_, sizeof(mList_)); | 924 | errno_t retM = memcpy_s(tilingData_.gmmArray.mList, sizeof(tilingData_.gmmArray.mList), mList_, sizeof(mList_)); |
| 918 | OP_CHECK_IF(retM != EOK, OP_LOGE(context_->GetNodeName(), "memcpy_s mList failed, ret=%d", retM), | 925 | OP_CHECK_IF(retM != EOK, OP_LOGE(context_->GetNodeName(), "memcpy_s mList failed, ret=%d", retM), |
| 919 | return ge::GRAPH_FAILED); | 926 | return ge::GRAPH_FAILED); |
| @@ -923,6 +930,11 @@ ge::graphStatus GroupedS4S4IntQuantTiling::PostTiling() | |||
| 923 | errno_t retN = memcpy_s(tilingData_.gmmArray.nList, sizeof(tilingData_.gmmArray.nList), nList_, sizeof(nList_)); | 930 | errno_t retN = memcpy_s(tilingData_.gmmArray.nList, sizeof(tilingData_.gmmArray.nList), nList_, sizeof(nList_)); |
| 924 | OP_CHECK_IF(retN != EOK, OP_LOGE(context_->GetNodeName(), "memcpy_s nList failed, ret=%d", retN), | 931 | OP_CHECK_IF(retN != EOK, OP_LOGE(context_->GetNodeName(), "memcpy_s nList failed, ret=%d", retN), |
| 925 | return ge::GRAPH_FAILED); | 932 | return ge::GRAPH_FAILED); |
| 933 | + return ge::GRAPH_SUCCESS; | ||
| 934 | +} | ||
| 935 | + | ||
| 936 | +void GroupedS4S4IntQuantTiling::SetMmTilingData() | ||
| 937 | +{ | ||
| 926 | // mmTilingData(TCubeTiling) | 938 | // mmTilingData(TCubeTiling) |
| 927 | auto &mm = tilingData_.mmTilingData; | 939 | auto &mm = tilingData_.mmTilingData; |
| 928 | mm.M = inputParams_.mSize; | 940 | mm.M = inputParams_.mSize; |
| @@ -947,6 +959,16 @@ ge::graphStatus GroupedS4S4IntQuantTiling::PostTiling() | |||
| 947 | mm.dbL0A = DB_SIZE; | 959 | mm.dbL0A = DB_SIZE; |
| 948 | mm.dbL0B = DB_SIZE; | 960 | mm.dbL0B = DB_SIZE; |
| 949 | mm.dbL0C = s4s4Tiling_.dbL0c; | 961 | mm.dbL0C = s4s4Tiling_.dbL0c; |
| 962 | +} | ||
| 963 | + | ||
| 964 | +ge::graphStatus GroupedS4S4IntQuantTiling::PostTiling() | ||
| 965 | +{ | ||
| 966 | + SetS4S4Params(); | ||
| 967 | + if (SetArrayParams() != ge::GRAPH_SUCCESS) { | ||
| 968 | + return ge::GRAPH_FAILED; | ||
| 969 | + } | ||
| 970 | + SetMmTilingData(); | ||
| 971 | + auto &p = tilingData_.gmmS4S4Params; | ||
| 950 | OP_LOGI(context_->GetNodeName(), | 972 | OP_LOGI(context_->GetNodeName(), |
| 951 | "S4S4 tiling: baseM=%u baseN=%u baseK=%u ubCalSize=%u ubRestBytes=%u quantGroupNum=%u isPerToken=%u " | 973 | "S4S4 tiling: baseM=%u baseN=%u baseK=%u ubCalSize=%u ubRestBytes=%u quantGroupNum=%u isPerToken=%u " |
| 952 | "depthA1=%lu depthB1=%lu", | 974 | "depthA1=%lu depthB1=%lu", |
| @@ -118,20 +118,23 @@ protected: | |||
| 118 | ge::graphStatus PostTiling() override; | 118 | ge::graphStatus PostTiling() override; |
| 119 | virtual void Reset(); | 119 | virtual void Reset(); |
| 120 | 120 | ||
| 121 | - // S4S4-specific (hide base's same-named; call base then sync s4s4Tiling_) | 121 | + // S4S4-specific (call base then sync s4s4Tiling_) |
| 122 | - bool SetMKN(const gert::Shape &xShape, const gert::Shape &wShape); | 122 | + bool SetMKNForS4S4(const gert::Shape &xShape, const gert::Shape &wShape); |
| 123 | - bool SetGroupNum(uint32_t groupListIndex); | 123 | + bool SetGroupNumForS4S4(uint32_t groupListIndex); |
| 124 | - bool SetMKNList(); | 124 | + bool SetMKNListForS4S4(); |
| 125 | bool AnalyzeS4S4(); | 125 | bool AnalyzeS4S4(); |
| 126 | - bool CheckS4S4Params(); | 126 | + bool CheckS4S4Params() const; |
| 127 | void CalBasicBlockS4S4(); | 127 | void CalBasicBlockS4S4(); |
| 128 | ge::graphStatus CalUbDivideS4S4(); | 128 | ge::graphStatus CalUbDivideS4S4(); |
| 129 | ge::graphStatus CalWorkspaceS4S4(); | 129 | ge::graphStatus CalWorkspaceS4S4(); |
| 130 | uint32_t FindBestSingleN() const; | 130 | uint32_t FindBestSingleN() const; |
| 131 | - void InitCommonL1TilingFields(); | 131 | + void InitS4S4CommonL1TilingFields(); |
| 132 | - ge::graphStatus CalcLeftL1Size(uint64_t &leftL1Size) const; | 132 | + ge::graphStatus CalcS4S4LeftL1Size(uint64_t &leftL1Size) const; |
| 133 | ge::graphStatus CalL1Tiling(); | 133 | ge::graphStatus CalL1Tiling(); |
| 134 | ge::graphStatus CalL1Depth(uint64_t leftL1Size); | 134 | ge::graphStatus CalL1Depth(uint64_t leftL1Size); |
| 135 | + void SetS4S4Params(); | ||
| 136 | + ge::graphStatus SetArrayParams(); | ||
| 137 | + void SetMmTilingData(); | ||
| 135 | 138 | ||
| 136 | private: | 139 | private: |
| 137 | struct S4S4BasicTiling { | 140 | struct S4S4BasicTiling { |
| @@ -717,7 +717,7 @@ bool GroupedWeightQuantBatchMatmulTiling::CheckGroupList(const gert::TilingConte | |||
| 717 | return true; | 717 | return true; |
| 718 | } | 718 | } |
| 719 | 719 | ||
| 720 | -bool GroupedWeightQuantBatchMatmulTiling::AnalyzeAttr(const gert::TilingContext *context) | 720 | +bool GroupedWeightQuantBatchMatmulTiling::AnalyzeCompileInfoAndAttrs(const gert::TilingContext *context) |
| 721 | { | 721 | { |
| 722 | auto compileInfoPtr = context->GetCompileInfo<GMMCompileInfo>(); | 722 | auto compileInfoPtr = context->GetCompileInfo<GMMCompileInfo>(); |
| 723 | OP_CHECK_IF(compileInfoPtr == nullptr, OP_LOGE(context->GetNodeName(), "compileInfoPtr is nullptr."), return false); | 723 | OP_CHECK_IF(compileInfoPtr == nullptr, OP_LOGE(context->GetNodeName(), "compileInfoPtr is nullptr."), return false); |
| @@ -738,7 +738,11 @@ bool GroupedWeightQuantBatchMatmulTiling::AnalyzeAttr(const gert::TilingContext | |||
| 738 | groupListType_ = groupListTypePtr != nullptr ? *groupListTypePtr : 0; | 738 | groupListType_ = groupListTypePtr != nullptr ? *groupListTypePtr : 0; |
| 739 | isSingleX_ = (groupType_ != static_cast<int64_t>(GroupType::NO_SPLIT) && | 739 | isSingleX_ = (groupType_ != static_cast<int64_t>(GroupType::NO_SPLIT) && |
| 740 | context->GetDynamicInputTensor(X_IDX, 1) == nullptr); | 740 | context->GetDynamicInputTensor(X_IDX, 1) == nullptr); |
| 741 | + return true; | ||
| 742 | +} | ||
| 741 | 743 | ||
| 744 | +bool GroupedWeightQuantBatchMatmulTiling::AnalyzeTensorLayout(const gert::TilingContext *context) | ||
| 745 | +{ | ||
| 742 | // 2: when x is multi-tensor, y is single-tensor; 3: when x is single-tensor, y is single-tensor | 746 | // 2: when x is multi-tensor, y is single-tensor; 3: when x is single-tensor, y is single-tensor |
| 743 | isSingleY_ = (splitItem_ == 2 || splitItem_ == 3); | 747 | isSingleY_ = (splitItem_ == 2 || splitItem_ == 3); |
| 744 | GetNumOfInputs(context); | 748 | GetNumOfInputs(context); |
| @@ -751,7 +755,11 @@ bool GroupedWeightQuantBatchMatmulTiling::AnalyzeAttr(const gert::TilingContext | |||
| 751 | context->GetDynamicInputTensor(WEIGHT_IDX, 0) != nullptr && | 755 | context->GetDynamicInputTensor(WEIGHT_IDX, 0) != nullptr && |
| 752 | context->GetDynamicInputTensor(WEIGHT_IDX, 0)->GetStorageShape().GetDimNum() == singleWeightDim); | 756 | context->GetDynamicInputTensor(WEIGHT_IDX, 0)->GetStorageShape().GetDimNum() == singleWeightDim); |
| 753 | isSingleMultiSingle_ = IsMxA8W4() && isSingleX_ && !isSingleWeight_ && isSingleY_; | 757 | isSingleMultiSingle_ = IsMxA8W4() && isSingleX_ && !isSingleWeight_ && isSingleY_; |
| 758 | + return true; | ||
| 759 | +} | ||
| 754 | 760 | ||
| 761 | +bool GroupedWeightQuantBatchMatmulTiling::CheckAllParams(const gert::TilingContext *context) | ||
| 762 | +{ | ||
| 755 | // 参数校验 | 763 | // 参数校验 |
| 756 | OP_CHECK_IF(!CheckCoreNum(context), OP_LOGE(context->GetNodeName(), "Invalid core number ratio"), return false); | 764 | OP_CHECK_IF(!CheckCoreNum(context), OP_LOGE(context->GetNodeName(), "Invalid core number ratio"), return false); |
| 757 | OP_CHECK_IF(!CheckUnsupportDataFlow(), | 765 | OP_CHECK_IF(!CheckUnsupportDataFlow(), |
| @@ -770,6 +778,22 @@ bool GroupedWeightQuantBatchMatmulTiling::AnalyzeAttr(const gert::TilingContext | |||
| 770 | OP_CHECK_IF(!CheckEveryTensor(context), OP_LOGE(context->GetNodeName(), "CheckEveryTensor failed."), | 778 | OP_CHECK_IF(!CheckEveryTensor(context), OP_LOGE(context->GetNodeName(), "CheckEveryTensor failed."), |
| 771 | return false); | 779 | return false); |
| 772 | } | 780 | } |
| 781 | + return true; | ||
| 782 | +} | ||
| 783 | + | ||
| 784 | +bool GroupedWeightQuantBatchMatmulTiling::AnalyzeAttr(const gert::TilingContext *context) | ||
| 785 | +{ | ||
| 786 | + if (!AnalyzeCompileInfoAndAttrs(context)) { | ||
| 787 | + return false; | ||
| 788 | + } | ||
| 789 | + | ||
| 790 | + if (!AnalyzeTensorLayout(context)) { | ||
| 791 | + return false; | ||
| 792 | + } | ||
| 793 | + | ||
| 794 | + if (!CheckAllParams(context)) { | ||
| 795 | + return false; | ||
| 796 | + } | ||
| 773 | 797 | ||
| 774 | // 参数设置 | 798 | // 参数设置 |
| 775 | OP_CHECK_IF(!SetShapeList(context), OP_LOGE(context->GetNodeName(), "SetShapeList failed."), return false); | 799 | OP_CHECK_IF(!SetShapeList(context), OP_LOGE(context->GetNodeName(), "SetShapeList failed."), return false); |
| @@ -1265,8 +1289,8 @@ bool GroupedWeightQuantBatchMatmulTiling::CheckEmptyTensorSingleXMultiWeightSing | |||
| 1265 | int64_t n = transB_ ? wShape.GetDim(wDimNum - 2) : wShape.GetDim(wDimNum - 1); | 1289 | int64_t n = transB_ ? wShape.GetDim(wDimNum - 2) : wShape.GetDim(wDimNum - 1); |
| 1266 | if (weightNzFlag_) { | 1290 | if (weightNzFlag_) { |
| 1267 | // 非转置NZ排布(N1, K1, K0, N0), 转置NZ排布(K1, N1, N0, K0) | 1291 | // 非转置NZ排布(N1, K1, K0, N0), 转置NZ排布(K1, N1, N0, K0) |
| 1268 | - n = transB_ ? wShape.GetDim(wDimNum - 3) * wShape.GetDim(wDimNum - 2) : | 1292 | + n = transB_ ? wShape.GetDim(wDimNum - 3) * wShape.GetDim(wDimNum - 2) : //wDimNum = 4,代表4维NZ,数字各自代表倒数第几维 |
| 1269 | - wShape.GetDim(wDimNum - 4) * wShape.GetDim(wDimNum - 1); | 1293 | + wShape.GetDim(wDimNum - 4) * wShape.GetDim(wDimNum - 1); //wDimNum = 4,代表4维NZ,数字各自代表倒数第几维 |
| 1270 | } | 1294 | } |
| 1271 | // k不能单独为0 | 1295 | // k不能单独为0 |
| 1272 | OP_CHECK_IF( | 1296 | OP_CHECK_IF( |
| @@ -1344,8 +1368,7 @@ bool GroupedWeightQuantBatchMatmulTiling::SetShapeListSplitMSingleXSingleWeightS | |||
| 1344 | // -3含义:转置N1索引;-2含义:转置N0索引 | 1368 | // -3含义:转置N1索引;-2含义:转置N0索引 |
| 1345 | nSize_ = transB_ ? wShape.GetDim(wDimNum - 3) * wShape.GetDim(wDimNum - 2) | 1369 | nSize_ = transB_ ? wShape.GetDim(wDimNum - 3) * wShape.GetDim(wDimNum - 2) |
| 1346 | // -4含义:非转置N1索引;-1含义:非转置N0索引 | 1370 | // -4含义:非转置N1索引;-1含义:非转置N0索引 |
| 1347 | - : | 1371 | + :wShape.GetDim(wDimNum - 4) * wShape.GetDim(wDimNum - 1); |
| 1348 | - wShape.GetDim(wDimNum - 4) * wShape.GetDim(wDimNum - 1); | ||
| 1349 | const gert::StorageShape *yShapePtr = context->GetOutputShape(0); | 1372 | const gert::StorageShape *yShapePtr = context->GetOutputShape(0); |
| 1350 | OP_CHECK_IF(yShapePtr == nullptr, OP_LOGE(context->GetNodeName(), "yShapePtr is nullptr."), return false); | 1373 | OP_CHECK_IF(yShapePtr == nullptr, OP_LOGE(context->GetNodeName(), "yShapePtr is nullptr."), return false); |
| 1351 | const gert::Shape &yShape = yShapePtr->GetOriginShape(); | 1374 | const gert::Shape &yShape = yShapePtr->GetOriginShape(); |
| @@ -1415,8 +1438,7 @@ bool GroupedWeightQuantBatchMatmulTiling::SetShapeListSplitMSingleXMultiWeightSi | |||
| 1415 | // -3含义:转置N1索引;-2含义:转置N0索引 | 1438 | // -3含义:转置N1索引;-2含义:转置N0索引 |
| 1416 | nSize = transB_ ? wShape.GetDim(wDimNum - 3) * wShape.GetDim(wDimNum - 2) | 1439 | nSize = transB_ ? wShape.GetDim(wDimNum - 3) * wShape.GetDim(wDimNum - 2) |
| 1417 | // -4含义:非转置N1索引;-1含义:非转置N0索引 | 1440 | // -4含义:非转置N1索引;-1含义:非转置N0索引 |
| 1418 | - : | 1441 | + :wShape.GetDim(wDimNum - 4) * wShape.GetDim(wDimNum - 1); |
| 1419 | - wShape.GetDim(wDimNum - 4) * wShape.GetDim(wDimNum - 1); | ||
| 1420 | } | 1442 | } |
| 1421 | if (isFp4PackType && !transB_) { | 1443 | if (isFp4PackType && !transB_) { |
| 1422 | // 一个float32/int32表示8个fp4/int4,设置为正确shape;kSize来自x,不需要考虑转置场景k轴扩大 | 1444 | // 一个float32/int32表示8个fp4/int4,设置为正确shape;kSize来自x,不需要考虑转置场景k轴扩大 |
| @@ -1550,7 +1572,7 @@ bool GroupedWeightQuantBatchMatmulTiling::DeriveGroupSizeSingle(const gert::Tili | |||
| 1550 | } else { | 1572 | } else { |
| 1551 | // (g, K, N) format: K axis index depends on transB | 1573 | // (g, K, N) format: K axis index depends on transB |
| 1552 | groupNum = transB_ ? antiquantScaleShape.GetDim(antiquantScaleDimNum - 1) : | 1574 | groupNum = transB_ ? antiquantScaleShape.GetDim(antiquantScaleDimNum - 1) : |
| 1553 | - antiquantScaleShape.GetDim(antiquantScaleDimNum - 2); | 1575 | + antiquantScaleShape.GetDim(antiquantScaleDimNum - 2); //- 2代表倒数第二个维度,目的是在是否转置时取得N维度 |
| 1554 | } | 1576 | } |
| 1555 | } else if (antiquantScaleDimNum == ANTIQUANT_SCALE_DIM_NUM) { | 1577 | } else if (antiquantScaleDimNum == ANTIQUANT_SCALE_DIM_NUM) { |
| 1556 | // antiquantScaleShape: (g,n,k/64,2) or (g,k/64,n,2) | 1578 | // antiquantScaleShape: (g,n,k/64,2) or (g,k/64,n,2) |
| @@ -1927,7 +1949,7 @@ ge::graphStatus GroupedS8S4BasicApiTiling::GetShapeAttrsInfo() | |||
| 1927 | return GroupedQmmTiling::GetShapeAttrsInfo(); | 1949 | return GroupedQmmTiling::GetShapeAttrsInfo(); |
| 1928 | } | 1950 | } |
| 1929 | 1951 | ||
| 1930 | -bool GroupedS8S4BasicApiTiling::AnalyzeDtype() | 1952 | +bool GroupedS8S4BasicApiTiling::AnalyzeInputDtypes() |
| 1931 | { | 1953 | { |
| 1932 | auto xDesc = context_->GetDynamicInputDesc(X_INDEX, 0); | 1954 | auto xDesc = context_->GetDynamicInputDesc(X_INDEX, 0); |
| 1933 | auto weightDesc = context_->GetDynamicInputDesc(WEIGHT_INDEX, 0); | 1955 | auto weightDesc = context_->GetDynamicInputDesc(WEIGHT_INDEX, 0); |
| @@ -1953,7 +1975,11 @@ bool GroupedS8S4BasicApiTiling::AnalyzeDtype() | |||
| 1953 | "S8S4 BasicApi expects weight format ND, NCL, NCHW or FRACTAL_NZ."), | 1975 | "S8S4 BasicApi expects weight format ND, NCL, NCHW or FRACTAL_NZ."), |
| 1954 | return false); | 1976 | return false); |
| 1955 | inputParams_.bFormat = weightFormat == ge::FORMAT_FRACTAL_NZ ? ge::FORMAT_FRACTAL_NZ : ge::FORMAT_ND; | 1977 | inputParams_.bFormat = weightFormat == ge::FORMAT_FRACTAL_NZ ? ge::FORMAT_FRACTAL_NZ : ge::FORMAT_ND; |
| 1978 | + return true; | ||
| 1979 | +} | ||
| 1956 | 1980 | ||
| 1981 | +bool GroupedS8S4BasicApiTiling::CheckDtypeAndFormat() | ||
| 1982 | +{ | ||
| 1957 | OP_CHECK_IF(inputParams_.aDtype != ge::DT_INT8 || | 1983 | OP_CHECK_IF(inputParams_.aDtype != ge::DT_INT8 || |
| 1958 | (inputParams_.bDtype != ge::DT_INT4 && inputParams_.bDtype != ge::DT_INT32), | 1984 | (inputParams_.bDtype != ge::DT_INT4 && inputParams_.bDtype != ge::DT_INT32), |
| 1959 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects x INT8 and weight INT4/packed INT32."), | 1985 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects x INT8 and weight INT4/packed INT32."), |
| @@ -1967,6 +1993,11 @@ bool GroupedS8S4BasicApiTiling::AnalyzeDtype() | |||
| 1967 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects out BF16 or FLOAT16."), return false); | 1993 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects out BF16 or FLOAT16."), return false); |
| 1968 | OP_CHECK_IF(inputParams_.aFormat != ge::FORMAT_ND, | 1994 | OP_CHECK_IF(inputParams_.aFormat != ge::FORMAT_ND, |
| 1969 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects x in ND format."), return false); | 1995 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects x in ND format."), return false); |
| 1996 | + return true; | ||
| 1997 | +} | ||
| 1998 | + | ||
| 1999 | +bool GroupedS8S4BasicApiTiling::AnalyzeBiasAndOffset() | ||
| 2000 | +{ | ||
| 1970 | auto biasShape = context_->GetDynamicInputShape(BIAS_INDEX, 0); | 2001 | auto biasShape = context_->GetDynamicInputShape(BIAS_INDEX, 0); |
| 1971 | inputParams_.hasBias = biasShape != nullptr && biasShape->GetStorageShape().GetShapeSize() != 0; | 2002 | inputParams_.hasBias = biasShape != nullptr && biasShape->GetStorageShape().GetShapeSize() != 0; |
| 1972 | auto biasDesc = context_->GetDynamicInputDesc(BIAS_INDEX, 0); | 2003 | auto biasDesc = context_->GetDynamicInputDesc(BIAS_INDEX, 0); |
| @@ -1990,6 +2021,21 @@ bool GroupedS8S4BasicApiTiling::AnalyzeDtype() | |||
| 1990 | return true; | 2021 | return true; |
| 1991 | } | 2022 | } |
| 1992 | 2023 | ||
| 2024 | +bool GroupedS8S4BasicApiTiling::AnalyzeDtype() | ||
| 2025 | +{ | ||
| 2026 | + if (!AnalyzeInputDtypes()) { | ||
| 2027 | + return false; | ||
| 2028 | + } | ||
| 2029 | + | ||
| 2030 | + if (!CheckDtypeAndFormat()) { | ||
| 2031 | + return false; | ||
| 2032 | + } | ||
| 2033 | + if (!AnalyzeBiasAndOffset()) { | ||
| 2034 | + return false; | ||
| 2035 | + } | ||
| 2036 | + return true; | ||
| 2037 | +} | ||
| 2038 | + | ||
| 1993 | bool GroupedS8S4BasicApiTiling::AnalyzeAttrs() | 2039 | bool GroupedS8S4BasicApiTiling::AnalyzeAttrs() |
| 1994 | { | 2040 | { |
| 1995 | auto attrs = context_->GetAttrs(); | 2041 | auto attrs = context_->GetAttrs(); |
| @@ -2000,7 +2046,7 @@ bool GroupedS8S4BasicApiTiling::AnalyzeAttrs() | |||
| 2000 | const int64_t *groupTypePtr = attrs->GetAttrPointer<int64_t>(ATTR_INDEX_GROUPTYPE); | 2046 | const int64_t *groupTypePtr = attrs->GetAttrPointer<int64_t>(ATTR_INDEX_GROUPTYPE); |
| 2001 | const int64_t *groupListTypePtr = attrs->GetAttrPointer<int64_t>(ATTR_INDEX_GROUP_LIST_TYPE); | 2047 | const int64_t *groupListTypePtr = attrs->GetAttrPointer<int64_t>(ATTR_INDEX_GROUP_LIST_TYPE); |
| 2002 | const int64_t *actTypePtr = attrs->GetAttrPointer<int64_t>(ATTR_INDEX_ACT_TYPE); | 2048 | const int64_t *actTypePtr = attrs->GetAttrPointer<int64_t>(ATTR_INDEX_ACT_TYPE); |
| 2003 | - const auto tuningConfigPtr = attrs->GetAttrPointer<gert::ContinuousVector>(ATTR_INDEX_TUNING_CONFIG); | 2049 | + const auto tuningConfigPtr = attrs->GetAttrPointer<gert::TypedContinuousVector<int64_t>>(ATTR_INDEX_TUNING_CONFIG); |
| 2004 | 2050 | ||
| 2005 | inputParams_.splitItem = splitItemPtr != nullptr ? static_cast<int8_t>(*splitItemPtr) : inputParams_.splitItem; | 2051 | inputParams_.splitItem = splitItemPtr != nullptr ? static_cast<int8_t>(*splitItemPtr) : inputParams_.splitItem; |
| 2006 | inputParams_.transB = transposeWeightPtr != nullptr ? *transposeWeightPtr : false; | 2052 | inputParams_.transB = transposeWeightPtr != nullptr ? *transposeWeightPtr : false; |
| @@ -2015,7 +2061,7 @@ bool GroupedS8S4BasicApiTiling::AnalyzeAttrs() | |||
| 2015 | OP_CHECK_IF(inputParams_.splitItem != X_SEPARATED && inputParams_.splitItem != NO_SEPARATED, | 2061 | OP_CHECK_IF(inputParams_.splitItem != X_SEPARATED && inputParams_.splitItem != NO_SEPARATED, |
| 2016 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects splitItem to be 2 or 3."), return false); | 2062 | OP_LOGE(context_->GetNodeName(), "S8S4 BasicApi expects splitItem to be 2 or 3."), return false); |
| 2017 | if (tuningConfigPtr != nullptr && tuningConfigPtr->GetSize() > 0) { | 2063 | if (tuningConfigPtr != nullptr && tuningConfigPtr->GetSize() > 0) { |
| 2018 | - const auto tuningConfig = reinterpret_cast<const int64_t *>(tuningConfigPtr->GetData()); | 2064 | + const auto tuningConfig = tuningConfigPtr->GetData(); |
| 2019 | OP_CHECK_IF(tuningConfig[TUNING_CONFIG_EXPECTED_TOKEN_INDEX] < 0 || | 2065 | OP_CHECK_IF(tuningConfig[TUNING_CONFIG_EXPECTED_TOKEN_INDEX] < 0 || |
| 2020 | static_cast<uint64_t>(tuningConfig[TUNING_CONFIG_EXPECTED_TOKEN_INDEX]) > UINT32_MAX, | 2066 | static_cast<uint64_t>(tuningConfig[TUNING_CONFIG_EXPECTED_TOKEN_INDEX]) > UINT32_MAX, |
| 2021 | OP_LOGE(context_->GetNodeName(), "tuningConfig[0] must be in [0, UINT32_MAX]."), return false); | 2067 | OP_LOGE(context_->GetNodeName(), "tuningConfig[0] must be in [0, UINT32_MAX]."), return false); |
| @@ -2150,41 +2196,46 @@ bool GroupedS8S4BasicApiTiling::CheckAntiquantInputsEmpty() const | |||
| 2150 | return true; | 2196 | return true; |
| 2151 | } | 2197 | } |
| 2152 | 2198 | ||
| 2199 | +bool GroupedS8S4BasicApiTiling::CheckWeightNzStorageShape(const gert::Shape &storageShape) | ||
| 2200 | +{ | ||
| 2201 | + // torch_npu constructs the normal A5 KN-NZ path as follows: | ||
| 2202 | + // INT8 NZ: [E, ceil(N/32), ceil(K/16), 16, 32] | ||
| 2203 | + // packed INT32: [E, ceil(N/32), ceil(K/16), 16, 4] | ||
| 2204 | + // The special ENK-NZ path uses the same C0 and swaps the logical K/N | ||
| 2205 | + // block axes: [E, ceil(K/32), ceil(N/16), 16, 32/4]. | ||
| 2206 | + // ACLNN reinterprets the INT32 carrier as INT4 and restores the last | ||
| 2207 | + // storage dimension from 4 to 32 before Host tiling. Keep support for | ||
| 2208 | + // a direct INT32 Host invocation as well, but reject all other physical | ||
| 2209 | + // layouts instead of accepting a same-sized, differently blocked NZ. | ||
| 2210 | + const uint64_t expectedC0 = weightPackedInt32_ ? 4UL : 32UL; | ||
| 2211 | + const uint64_t expectedOuter0 = specialWeightFormat_ ? | ||
| 2212 | + CeilDiv(inputParams_.kSize, NZ_SPECIAL_K_ALIGN) : | ||
| 2213 | + CeilDiv(inputParams_.nSize, NZ_BASE_N_ALIGN); | ||
| 2214 | + const uint64_t expectedOuter1 = specialWeightFormat_ ? | ||
| 2215 | + CeilDiv(inputParams_.nSize, NZ_SPECIAL_N_ALIGN) : | ||
| 2216 | + CeilDiv(inputParams_.kSize, NZ_BASE_K_ALIGN); | ||
| 2217 | + const bool shapeMatches = storageShape.GetDimNum() == 5 && | ||
| 2218 | + static_cast<uint64_t>(storageShape.GetDim(0)) == inputParams_.groupNum && | ||
| 2219 | + static_cast<uint64_t>(storageShape.GetDim(1)) == expectedOuter0 && | ||
| 2220 | + static_cast<uint64_t>(storageShape.GetDim(2)) == expectedOuter1 && | ||
| 2221 | + static_cast<uint64_t>(storageShape.GetDim(3)) == NZ_BASE_K_ALIGN && | ||
| 2222 | + static_cast<uint64_t>(storageShape.GetDim(4)) == expectedC0; | ||
| 2223 | + OP_CHECK_IF(!shapeMatches, | ||
| 2224 | + OP_LOGE(context_->GetNodeName(), | ||
| 2225 | + "A5 INT4 %s weight storage shape must be " | ||
| 2226 | + "[E,%s,%s,16,%lu].", | ||
| 2227 | + specialWeightFormat_ ? "special ENK-NZ" : "normal KN-NZ", | ||
| 2228 | + specialWeightFormat_ ? "ceil(K/32)" : "ceil(N/32)", | ||
| 2229 | + specialWeightFormat_ ? "ceil(N/16)" : "ceil(K/16)", expectedC0), | ||
| 2230 | + return false); | ||
| 2231 | + return true; | ||
| 2232 | +} | ||
| 2233 | + | ||
| 2153 | bool GroupedS8S4BasicApiTiling::CheckWeightStorageShape(const gert::StorageShape &weightShape) | 2234 | bool GroupedS8S4BasicApiTiling::CheckWeightStorageShape(const gert::StorageShape &weightShape) |
| 2154 | { | 2235 | { |
| 2155 | const gert::Shape &storageShape = weightShape.GetStorageShape(); | 2236 | const gert::Shape &storageShape = weightShape.GetStorageShape(); |
| 2156 | if (inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ) { | 2237 | if (inputParams_.bFormat == ge::FORMAT_FRACTAL_NZ) { |
| 2157 | - // torch_npu constructs the normal A5 KN-NZ path as follows: | 2238 | + return CheckWeightNzStorageShape(storageShape); |
| 2158 | - // INT8 NZ: [E, ceil(N/32), ceil(K/16), 16, 32] | ||
| 2159 | - // packed INT32: [E, ceil(N/32), ceil(K/16), 16, 4] | ||
| 2160 | - // The special ENK-NZ path uses the same C0 and swaps the logical K/N | ||
| 2161 | - // block axes: [E, ceil(K/32), ceil(N/16), 16, 32/4]. | ||
| 2162 | - // ACLNN reinterprets the INT32 carrier as INT4 and restores the last | ||
| 2163 | - // storage dimension from 4 to 32 before Host tiling. Keep support for | ||
| 2164 | - // a direct INT32 Host invocation as well, but reject all other physical | ||
| 2165 | - // layouts instead of accepting a same-sized, differently blocked NZ. | ||
| 2166 | - const uint64_t expectedC0 = weightPackedInt32_ ? 4UL : 32UL; | ||
| 2167 | - const uint64_t expectedOuter0 = specialWeightFormat_ ? | ||
| 2168 | - CeilDiv(inputParams_.kSize, NZ_SPECIAL_K_ALIGN) : | ||
| 2169 | - CeilDiv(inputParams_.nSize, NZ_BASE_N_ALIGN); | ||
| 2170 | - const uint64_t expectedOuter1 = specialWeightFormat_ ? | ||
| 2171 | - CeilDiv(inputParams_.nSize, NZ_SPECIAL_N_ALIGN) : | ||
| 2172 | - CeilDiv(inputParams_.kSize, NZ_BASE_K_ALIGN); | ||
| 2173 | - const bool shapeMatches = storageShape.GetDimNum() == 5 && | ||
| 2174 | - static_cast<uint64_t>(storageShape.GetDim(0)) == inputParams_.groupNum && | ||
| 2175 | - static_cast<uint64_t>(storageShape.GetDim(1)) == expectedOuter0 && | ||
| 2176 | - static_cast<uint64_t>(storageShape.GetDim(2)) == expectedOuter1 && | ||
| 2177 | - static_cast<uint64_t>(storageShape.GetDim(3)) == NZ_BASE_K_ALIGN && | ||
| 2178 | - static_cast<uint64_t>(storageShape.GetDim(4)) == expectedC0; | ||
| 2179 | - OP_CHECK_IF(!shapeMatches, | ||
| 2180 | - OP_LOGE(context_->GetNodeName(), | ||
| 2181 | - "A5 INT4 %s weight storage shape must be " | ||
| 2182 | - "[E,%s,%s,16,%lu].", | ||
| 2183 | - specialWeightFormat_ ? "special ENK-NZ" : "normal KN-NZ", | ||
| 2184 | - specialWeightFormat_ ? "ceil(K/32)" : "ceil(N/32)", | ||
| 2185 | - specialWeightFormat_ ? "ceil(N/16)" : "ceil(K/16)", expectedC0), | ||
| 2186 | - return false); | ||
| 2187 | - return true; | ||
| 2188 | } | 2239 | } |
| 2189 | 2240 | ||
| 2190 | uint64_t scalarSlotNum = inputParams_.groupNum * inputParams_.kSize * inputParams_.nSize; | 2241 | uint64_t scalarSlotNum = inputParams_.groupNum * inputParams_.kSize * inputParams_.nSize; |
| @@ -2384,18 +2435,8 @@ void GroupedS8S4BasicApiTiling::SetBasicBlock() | |||
| 2384 | basicTiling_.baseK = S8S4_BASE_K; | 2435 | basicTiling_.baseK = S8S4_BASE_K; |
| 2385 | } | 2436 | } |
| 2386 | 2437 | ||
| 2387 | -ge::graphStatus GroupedS8S4BasicApiTiling::DoLibApiTiling() | 2438 | +void GroupedS8S4BasicApiTiling::SetMmTilingData(uint64_t kL1) |
| 2388 | { | 2439 | { |
| 2389 | - SetBasicBlock(); | ||
| 2390 | - uint64_t kL1 = dequantMode_ == DequantMode::SYMMETRIC_PER_GROUP ? | ||
| 2391 | - S8S4_PER_GROUP_K_L1 : | ||
| 2392 | - S8S4_PER_CHANNEL_K_L1; | ||
| 2393 | - const uint64_t alignedK = CeilAlign(inputParams_.kSize, static_cast<uint64_t>(QUANT_GROUP_SIZE)); | ||
| 2394 | - kL1 = std::min(kL1, alignedK); | ||
| 2395 | - OP_CHECK_IF(ValidateFixedTileResources(kL1) != ge::GRAPH_SUCCESS, | ||
| 2396 | - OP_LOGE(context_->GetNodeName(), "S8S4 fixed tile resource validation failed."), | ||
| 2397 | - return ge::GRAPH_FAILED); | ||
| 2398 | - | ||
| 2399 | tilingData_.mmTilingData.m = static_cast<uint32_t>(inputParams_.mSize); | 2440 | tilingData_.mmTilingData.m = static_cast<uint32_t>(inputParams_.mSize); |
| 2400 | tilingData_.mmTilingData.n = static_cast<uint32_t>(inputParams_.nSize); | 2441 | tilingData_.mmTilingData.n = static_cast<uint32_t>(inputParams_.nSize); |
| 2401 | tilingData_.mmTilingData.k = static_cast<uint32_t>(inputParams_.kSize); | 2442 | tilingData_.mmTilingData.k = static_cast<uint32_t>(inputParams_.kSize); |
| @@ -2412,7 +2453,10 @@ ge::graphStatus GroupedS8S4BasicApiTiling::DoLibApiTiling() | |||
| 2412 | const uint64_t l0cTileBytes = basicTiling_.baseM * basicTiling_.baseN * sizeof(int32_t); | 2453 | const uint64_t l0cTileBytes = basicTiling_.baseM * basicTiling_.baseN * sizeof(int32_t); |
| 2413 | tilingData_.mmTilingData.dbL0C = | 2454 | tilingData_.mmTilingData.dbL0C = |
| 2414 | l0cTileBytes * 2UL <= aicoreParams_.l0cSize ? 2U : 1U; | 2455 | l0cTileBytes * 2UL <= aicoreParams_.l0cSize ? 2U : 1U; |
| 2456 | +} | ||
| 2415 | 2457 | ||
| 2458 | +ge::graphStatus GroupedS8S4BasicApiTiling::ComputeWorkspaceLayout() | ||
| 2459 | +{ | ||
| 2416 | { | 2460 | { |
| 2417 | constexpr uint64_t WORKSPACE_ALIGN = 512UL; | 2461 | constexpr uint64_t WORKSPACE_ALIGN = 512UL; |
| 2418 | constexpr uint64_t NZ_K_ALIGN = 16UL; | 2462 | constexpr uint64_t NZ_K_ALIGN = 16UL; |
| @@ -2432,7 +2476,7 @@ ge::graphStatus GroupedS8S4BasicApiTiling::DoLibApiTiling() | |||
| 2432 | result = lhs + rhs; | 2476 | result = lhs + rhs; |
| 2433 | return true; | 2477 | return true; |
| 2434 | }; | 2478 | }; |
| 2435 | - auto checkedAlign = [&](uint64_t value, uint64_t &result) { | 2479 | + auto checkedAlign = [](uint64_t value, uint64_t &result) { |
| 2436 | if (value > UINT64_MAX_VALUE - (WORKSPACE_ALIGN - 1UL)) { | 2480 | if (value > UINT64_MAX_VALUE - (WORKSPACE_ALIGN - 1UL)) { |
| 2437 | return false; | 2481 | return false; |
| 2438 | } | 2482 | } |
| @@ -2495,6 +2539,22 @@ ge::graphStatus GroupedS8S4BasicApiTiling::DoLibApiTiling() | |||
| 2495 | return ge::GRAPH_SUCCESS; | 2539 | return ge::GRAPH_SUCCESS; |
| 2496 | } | 2540 | } |
| 2497 | 2541 | ||
| 2542 | +ge::graphStatus GroupedS8S4BasicApiTiling::DoLibApiTiling() | ||
| 2543 | +{ | ||
| 2544 | + SetBasicBlock(); | ||
| 2545 | + uint64_t kL1 = dequantMode_ == DequantMode::SYMMETRIC_PER_GROUP ? | ||
| 2546 | + S8S4_PER_GROUP_K_L1 : | ||
| 2547 | + S8S4_PER_CHANNEL_K_L1; | ||
| 2548 | + const uint64_t alignedK = CeilAlign(inputParams_.kSize, static_cast<uint64_t>(QUANT_GROUP_SIZE)); | ||
| 2549 | + kL1 = std::min(kL1, alignedK); | ||
| 2550 | + OP_CHECK_IF(ValidateFixedTileResources(kL1) != ge::GRAPH_SUCCESS, | ||
| 2551 | + OP_LOGE(context_->GetNodeName(), "S8S4 fixed tile resource validation failed."), | ||
| 2552 | + return ge::GRAPH_FAILED); | ||
| 2553 | + | ||
| 2554 | + SetMmTilingData(kL1); | ||
| 2555 | + return ComputeWorkspaceLayout(); | ||
| 2556 | +} | ||
| 2557 | + | ||
| 2498 | ge::graphStatus GroupedS8S4BasicApiTiling::PostTiling() | 2558 | ge::graphStatus GroupedS8S4BasicApiTiling::PostTiling() |
| 2499 | { | 2559 | { |
| 2500 | // Weight preprocessing synchronizes all vector cores, so all participating cores must be resident. | 2560 | // Weight preprocessing synchronizes all vector cores, so all participating cores must be resident. |
| @@ -270,10 +270,16 @@ private: | |||
| 270 | bool CheckPerTokenScaleShape() const; | 270 | bool CheckPerTokenScaleShape() const; |
| 271 | bool CheckAntiquantInputsEmpty() const; | 271 | bool CheckAntiquantInputsEmpty() const; |
| 272 | bool CheckWeightStorageShape(const gert::StorageShape &weightShape); | 272 | bool CheckWeightStorageShape(const gert::StorageShape &weightShape); |
| 273 | + bool CheckWeightNzStorageShape(const gert::Shape &storageShape); | ||
| 273 | bool CheckScaleAndOffsetShapes(); | 274 | bool CheckScaleAndOffsetShapes(); |
| 274 | bool SetLogicalMKN(const gert::Shape &xShape, const gert::Shape &wShape); | 275 | bool SetLogicalMKN(const gert::Shape &xShape, const gert::Shape &wShape); |
| 275 | void SetBasicBlock(); | 276 | void SetBasicBlock(); |
| 276 | ge::graphStatus ValidateFixedTileResources(uint64_t kL1) const; | 277 | ge::graphStatus ValidateFixedTileResources(uint64_t kL1) const; |
| 278 | + void SetMmTilingData(uint64_t kL1); | ||
| 279 | + ge::graphStatus ComputeWorkspaceLayout(); | ||
| 280 | + bool AnalyzeInputDtypes(); | ||
| 281 | + bool CheckDtypeAndFormat(); | ||
| 282 | + bool AnalyzeBiasAndOffset(); | ||
| 277 | 283 | ||
| 278 | static constexpr uint32_t QUANT_GROUP_SIZE = 256U; | 284 | static constexpr uint32_t QUANT_GROUP_SIZE = 256U; |
| 279 | static constexpr uint32_t S8S4_BASE_M = 256U; | 285 | static constexpr uint32_t S8S4_BASE_M = 256U; |
| @@ -343,6 +349,9 @@ protected: | |||
| 343 | bool CheckEveryTensorSingleXMultiWeightSingleY(const gert::TilingContext *context) const; | 349 | bool CheckEveryTensorSingleXMultiWeightSingleY(const gert::TilingContext *context) const; |
| 344 | bool CheckGroupList(const gert::TilingContext *context) const; | 350 | bool CheckGroupList(const gert::TilingContext *context) const; |
| 345 | bool AnalyzeAttr(const gert::TilingContext *context); | 351 | bool AnalyzeAttr(const gert::TilingContext *context); |
| 352 | + bool AnalyzeCompileInfoAndAttrs(const gert::TilingContext *context); | ||
| 353 | + bool AnalyzeTensorLayout(const gert::TilingContext *context); | ||
| 354 | + bool CheckAllParams(const gert::TilingContext *context); | ||
| 346 | bool AnalyzeInput(const gert::TilingContext *context); | 355 | bool AnalyzeInput(const gert::TilingContext *context); |
| 347 | bool CalcResplitTiling(const gert::TilingContext *context); | 356 | bool CalcResplitTiling(const gert::TilingContext *context); |
| 348 | bool SetBaseTiling(); | 357 | bool SetBaseTiling(); |
| @@ -1358,6 +1358,53 @@ aclnnStatus aclnnGroupedMatmulFinalizeRouting(void *workspace, uint64_t workspac | |||
| 1358 | return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | 1358 | return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); |
| 1359 | } | 1359 | } |
| 1360 | 1360 | ||
| 1361 | +static aclnnStatus ValidateV2Inputs(const aclTensor *x1, const aclTensor *x2, | ||
| 1362 | + const aclTensor *scaleOptional, const aclTensor *biasOptional, | ||
| 1363 | + const aclTensor *pertokenScaleOptional, const aclTensor *groupListOptional, | ||
| 1364 | + const aclTensor *logitOptional, const aclTensor *rowIndexOptional, | ||
| 1365 | + const aclTensor *antiquantScaleOptional, const aclTensor *antiquantOffsetOptional, | ||
| 1366 | + int64_t dtype, bool transposeX1, bool transposeX2) | ||
| 1367 | +{ | ||
| 1368 | + auto scene = x1 != nullptr && x2 != nullptr && scaleOptional != nullptr && pertokenScaleOptional != nullptr && | ||
| 1369 | + groupListOptional != nullptr && logitOptional != nullptr && rowIndexOptional != nullptr && | ||
| 1370 | + biasOptional != nullptr && antiquantScaleOptional == nullptr && antiquantOffsetOptional == nullptr; | ||
| 1371 | + if (!scene) { | ||
| 1372 | + OP_LOGE(ACLNN_ERR_PARAM_NULLPTR, "GroupedMatmulFinalizeRoutingV2 weightNd do not support input nullptr."); | ||
| 1373 | + return ACLNN_ERR_PARAM_NULLPTR; | ||
| 1374 | + } | ||
| 1375 | + int64_t viewDimNum = x2->GetViewShape().GetDimNum(); | ||
| 1376 | + if (dtype != 0) { | ||
| 1377 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "GroupedMatmulFinalizeRoutingV2 weightNd dtype must be 0, but is %lld.", | ||
| 1378 | + dtype); | ||
| 1379 | + return ACLNN_ERR_PARAM_INVALID; | ||
| 1380 | + } else if (viewDimNum < MIN_DIM_NUM_ND) { | ||
| 1381 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 1382 | + "GroupedMatmulFinalizeRoutingV2 weightNd x2's view dimNum should greater than 1, but is %lld.", | ||
| 1383 | + viewDimNum); | ||
| 1384 | + return ACLNN_ERR_PARAM_INVALID; | ||
| 1385 | + } else if (!(transposeX1 == false && transposeX2 == false)) { | ||
| 1386 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "GroupedMatmulFinalizeRoutingV2 weightNd transpose should be false"); | ||
| 1387 | + return ACLNN_ERR_PARAM_INVALID; | ||
| 1388 | + } | ||
| 1389 | + return ACLNN_SUCCESS; | ||
| 1390 | +} | ||
| 1391 | + | ||
| 1392 | +static aclnnStatus UnpackWeightInt32ToInt4(aclTensor *&weight, const char *opName) | ||
| 1393 | +{ | ||
| 1394 | + if (weight->GetDataType() != DataType::DT_INT32) { | ||
| 1395 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 1396 | + "%s weightNd weight type should be DT_INT32, but now is %s", | ||
| 1397 | + opName, op::ToString(weight->GetDataType()).GetString()); | ||
| 1398 | + return ACLNN_ERR_PARAM_INVALID; | ||
| 1399 | + } | ||
| 1400 | + op::Shape weightShape = weight->GetViewShape(); | ||
| 1401 | + auto viewShapeDim = weightShape.GetDimNum(); | ||
| 1402 | + weightShape[viewShapeDim - 1] = weightShape[viewShapeDim - 1] * PER_INT4_IN_U32; | ||
| 1403 | + weight->SetViewShape(weightShape); | ||
| 1404 | + weight->SetDataType(DataType::DT_INT4); | ||
| 1405 | + return ACLNN_SUCCESS; | ||
| 1406 | +} | ||
| 1407 | + | ||
| 1361 | aclnnStatus aclnnGroupedMatmulFinalizeRoutingV2GetWorkspaceSize( | 1408 | aclnnStatus aclnnGroupedMatmulFinalizeRoutingV2GetWorkspaceSize( |
| 1362 | const aclTensor *x1, aclTensor *x2, const aclTensor *scaleOptional, const aclTensor *biasOptional, | 1409 | const aclTensor *x1, aclTensor *x2, const aclTensor *scaleOptional, const aclTensor *biasOptional, |
| 1363 | const aclTensor *offsetOptional, const aclTensor *antiquantScaleOptional, const aclTensor *antiquantOffsetOptional, | 1410 | const aclTensor *offsetOptional, const aclTensor *antiquantScaleOptional, const aclTensor *antiquantOffsetOptional, |
| @@ -1373,44 +1420,12 @@ aclnnStatus aclnnGroupedMatmulFinalizeRoutingV2GetWorkspaceSize( | |||
| 1373 | sharedInputOptional, logitOptional, rowIndexOptional, dtype, sharedInputWeight, | 1420 | sharedInputOptional, logitOptional, rowIndexOptional, dtype, sharedInputWeight, |
| 1374 | sharedInputOffset, transposeX1, transposeX2, groupListType), | 1421 | sharedInputOffset, transposeX1, transposeX2, groupListType), |
| 1375 | DFX_OUT(out)); | 1422 | DFX_OUT(out)); |
| 1376 | - auto scene = x1 != nullptr && x2 != nullptr && scaleOptional != nullptr && pertokenScaleOptional != nullptr && | 1423 | + auto ret0 = ValidateV2Inputs(x1, x2, scaleOptional, biasOptional, pertokenScaleOptional, groupListOptional, |
| 1377 | - groupListOptional != nullptr && logitOptional != nullptr && rowIndexOptional != nullptr && | 1424 | + logitOptional, rowIndexOptional, antiquantScaleOptional, antiquantOffsetOptional, |
| 1378 | - biasOptional != nullptr && antiquantScaleOptional == nullptr && antiquantOffsetOptional == nullptr; | 1425 | + dtype, transposeX1, transposeX2); |
| 1379 | - if (!scene) { | 1426 | + CHECK_RET(ret0 == ACLNN_SUCCESS, ret0); |
| 1380 | - OP_LOGE(ACLNN_ERR_PARAM_NULLPTR, "GroupedMatmulFinalizeRoutingV2 weightNd do not support input nullptr."); | 1427 | + auto ret1 = UnpackWeightInt32ToInt4(x2, "GroupedMatmulFinalizeRoutingV2"); |
| 1381 | - return ACLNN_ERR_PARAM_NULLPTR; | 1428 | + CHECK_RET(ret1 == ACLNN_SUCCESS, ret1); |
| 1382 | - } | ||
| 1383 | - | ||
| 1384 | - int64_t viewDimNum = x2->GetViewShape().GetDimNum(); | ||
| 1385 | - if (dtype != 0) { | ||
| 1386 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "GroupedMatmulFinalizeRoutingV2 weightNd dtype must be 0, but is %lld.", | ||
| 1387 | - dtype); | ||
| 1388 | - return ACLNN_ERR_PARAM_INVALID; | ||
| 1389 | - } else if (viewDimNum < MIN_DIM_NUM_ND) { | ||
| 1390 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 1391 | - "GroupedMatmulFinalizeRoutingV2 weightNd x2's view dimNum should greater than 1, but is %lld.", | ||
| 1392 | - viewDimNum); | ||
| 1393 | - return ACLNN_ERR_PARAM_INVALID; | ||
| 1394 | - } else if (!(transposeX1 == false && transposeX2 == false)) { | ||
| 1395 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "GroupedMatmulFinalizeRoutingV2 weightNd transpose should be false"); | ||
| 1396 | - return ACLNN_ERR_PARAM_INVALID; | ||
| 1397 | - } | ||
| 1398 | - | ||
| 1399 | - // unpack int32 to int4 | ||
| 1400 | - auto tmpWeightV2 = x2; | ||
| 1401 | - if (tmpWeightV2->GetDataType() == DataType::DT_INT32) { | ||
| 1402 | - op::Shape weightShapeV2 = tmpWeightV2->GetViewShape(); | ||
| 1403 | - auto viewShapeDimV2 = weightShapeV2.GetDimNum(); | ||
| 1404 | - weightShapeV2[viewShapeDimV2 - 1] = weightShapeV2[viewShapeDimV2 - 1] * PER_INT4_IN_U32; | ||
| 1405 | - tmpWeightV2->SetViewShape(weightShapeV2); | ||
| 1406 | - tmpWeightV2->SetDataType(DataType::DT_INT4); | ||
| 1407 | - } else { | ||
| 1408 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, | ||
| 1409 | - "GroupedMatmulFinalizeRoutingV2 weightNd weight type should be DT_INT32, but now is %s", | ||
| 1410 | - op::ToString(tmpWeightV2->GetDataType()).GetString()); | ||
| 1411 | - return ACLNN_ERR_PARAM_INVALID; | ||
| 1412 | - } | ||
| 1413 | - | ||
| 1414 | auto uniqueExecutor = CREATE_EXECUTOR(); | 1429 | auto uniqueExecutor = CREATE_EXECUTOR(); |
| 1415 | CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | 1430 | CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); |
| 1416 | const aclIntArray *unusedTuningConfig = nullptr; | 1431 | const aclIntArray *unusedTuningConfig = nullptr; |
| @@ -1427,8 +1442,8 @@ aclnnStatus aclnnGroupedMatmulFinalizeRoutingV2GetWorkspaceSize( | |||
| 1427 | .SetNumbers(sharedInputWeight, sharedInputOffset, groupListType) | 1442 | .SetNumbers(sharedInputWeight, sharedInputOffset, groupListType) |
| 1428 | .SetTranspose(transposeX1, transposeX2) | 1443 | .SetTranspose(transposeX1, transposeX2) |
| 1429 | .Build(); | 1444 | .Build(); |
| 1430 | - auto ret1 = aclnnGroupedMatmulFinalizeRoutingGetWorkspaceSizeCommonProcess(params, uniqueExecutor.get()); | 1445 | + auto ret = aclnnGroupedMatmulFinalizeRoutingGetWorkspaceSizeCommonProcess(params, uniqueExecutor.get()); |
| 1431 | - CHECK_RET(ret1 == ACLNN_SUCCESS, ret1); | 1446 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); |
| 1432 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | 1447 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); |
| 1433 | uniqueExecutor.ReleaseTo(executor); | 1448 | uniqueExecutor.ReleaseTo(executor); |
| 1434 | return ACLNN_SUCCESS; | 1449 | return ACLNN_SUCCESS; |
| @@ -200,7 +200,7 @@ static aclnnStatus ProcessSingleWeightNz(const aclTensorList *weight) | |||
| 200 | auto w = (*weight)[0]; | 200 | auto w = (*weight)[0]; |
| 201 | auto storgeShape = w->GetStorageShape(); | 201 | auto storgeShape = w->GetStorageShape(); |
| 202 | auto viewShape = w->GetViewShape(); | 202 | auto viewShape = w->GetViewShape(); |
| 203 | - aclTensor *weightNZ = const_cast<aclTensor *>(w); | 203 | + aclTensor *weightNZ = const_cast<aclTensor *>(w); // NOLINT: SetStorageFormat/SetViewFormat are non-const but do not alter tensor data |
| 204 | std::ostringstream gotShape; | 204 | std::ostringstream gotShape; |
| 205 | gotShape << op::ToString(storgeShape).GetString() << " with dim num " << storgeShape.GetDimNum(); | 205 | gotShape << op::ToString(storgeShape).GetString() << " with dim num " << storgeShape.GetDimNum(); |
| 206 | std::string gotShapeStr = gotShape.str(); | 206 | std::string gotShapeStr = gotShape.str(); |
| @@ -227,7 +227,7 @@ static aclnnStatus ProcessMultiWeightNz(const aclTensorList *weight) | |||
| 227 | CHECK_RET(w != nullptr, ACLNN_ERR_PARAM_NULLPTR); | 227 | CHECK_RET(w != nullptr, ACLNN_ERR_PARAM_NULLPTR); |
| 228 | auto storgeShape = w->GetStorageShape(); | 228 | auto storgeShape = w->GetStorageShape(); |
| 229 | auto viewShape = w->GetViewShape(); | 229 | auto viewShape = w->GetViewShape(); |
| 230 | - aclTensor *weightNZ = const_cast<aclTensor *>(w); | 230 | + aclTensor *weightNZ = const_cast<aclTensor *>(w); // NOLINT: SetStorageFormat/SetViewFormat are non-const but do not alter tensor data |
| 231 | std::ostringstream gotShape; | 231 | std::ostringstream gotShape; |
| 232 | gotShape << op::ToString(storgeShape).GetString() << " with dim num " << storgeShape.GetDimNum(); | 232 | gotShape << op::ToString(storgeShape).GetString() << " with dim num " << storgeShape.GetDimNum(); |
| 233 | std::string gotShapeStr = gotShape.str(); | 233 | std::string gotShapeStr = gotShape.str(); |
| @@ -555,7 +555,7 @@ protected: | |||
| 555 | shape.SetScalar(); | 555 | shape.SetScalar(); |
| 556 | shape.AppendDim(viewShape.GetDim(1)); | 556 | shape.AppendDim(viewShape.GetDim(1)); |
| 557 | shape.AppendDim(viewShape.GetDim(0)); | 557 | shape.AppendDim(viewShape.GetDim(0)); |
| 558 | - shape.AppendDim(viewShape.GetDim(2)); | 558 | + shape.AppendDim(viewShape.GetDim(2)); //第三维不交换 |
| 559 | aclTensor *tensor = executor->CreateView(inputTensor, shape, inputTensor->GetViewOffset()); | 559 | aclTensor *tensor = executor->CreateView(inputTensor, shape, inputTensor->GetViewOffset()); |
| 560 | tensor->SetStorageFormat(inputTensor->GetStorageFormat()); | 560 | tensor->SetStorageFormat(inputTensor->GetStorageFormat()); |
| 561 | tensor->SetStorageShape(storageShape); | 561 | tensor->SetStorageShape(storageShape); |
| @@ -966,7 +966,7 @@ protected: | |||
| 966 | // 1:检查K是否为偶数 | 966 | // 1:检查K是否为偶数 |
| 967 | int64_t kModValue = kValue % MXFP4_K_CONSTRAINT; | 967 | int64_t kModValue = kValue % MXFP4_K_CONSTRAINT; |
| 968 | // 2:检查N是否为偶数 | 968 | // 2:检查N是否为偶数 |
| 969 | - int64_t nModValue = nValue % MXFP4_N_CONSTRAINT; | 969 | + //int64_t nModValue = nValue % MXFP4_N_CONSTRAINT; |
| 970 | if (kModValue != 0) { | 970 | if (kModValue != 0) { |
| 971 | std::string gotStr = BuildLogValue("K", kValue); | 971 | std::string gotStr = BuildLogValue("K", kValue); |
| 972 | OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( | 972 | OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( |
| @@ -1039,7 +1039,7 @@ protected: | |||
| 1039 | 1039 | ||
| 1040 | bool CheckMxA8W4InputShape() | 1040 | bool CheckMxA8W4InputShape() |
| 1041 | { | 1041 | { |
| 1042 | - int64_t m = gmmDsqParams_.x->GetViewShape().GetDim(0); | 1042 | + //int64_t m = gmmDsqParams_.x->GetViewShape().GetDim(0); |
| 1043 | int64_t k = gmmDsqParams_.x->GetViewShape().GetDim(1); | 1043 | int64_t k = gmmDsqParams_.x->GetViewShape().GetDim(1); |
| 1044 | // 多tensor下shape:(n,k), 单tensor下shape:(e, n, k) | 1044 | // 多tensor下shape:(n,k), 单tensor下shape:(e, n, k) |
| 1045 | int64_t n = IsMultiTensorWeight() ? ((*gmmDsqParams_.weight)[0])->GetViewShape().GetDim(0) : | 1045 | int64_t n = IsMultiTensorWeight() ? ((*gmmDsqParams_.weight)[0])->GetViewShape().GetDim(0) : |
| @@ -1291,19 +1291,9 @@ protected: | |||
| 1291 | return true; | 1291 | return true; |
| 1292 | } | 1292 | } |
| 1293 | 1293 | ||
| 1294 | - bool CheckDtypeValid() override | 1294 | + bool CheckNdE1M2Restriction(DataType xDtype, DataType weightDtype, const aclTensor *weight, |
| 1295 | + const aclTensor *output) | ||
| 1295 | { | 1296 | { |
| 1296 | - DataType xDtype = gmmDsqParams_.x->GetDataType(); | ||
| 1297 | - DataType weightDtype = ((*gmmDsqParams_.weight)[0])->GetDataType(); | ||
| 1298 | - const aclTensor *x = gmmDsqParams_.x; | ||
| 1299 | - const aclTensor *weight = (*gmmDsqParams_.weight)[0]; | ||
| 1300 | - const aclTensor *xScale = gmmDsqParams_.xScale; | ||
| 1301 | - const aclTensor *groupList = gmmDsqParams_.groupList; | ||
| 1302 | - const aclTensor *output = gmmDsqParams_.output; | ||
| 1303 | - const aclTensor *outputScale = gmmDsqParams_.outputScale; | ||
| 1304 | - if (!CheckWeightFormatConsistency()) { | ||
| 1305 | - return false; | ||
| 1306 | - } | ||
| 1307 | if (weight->GetStorageFormat() == ge::FORMAT_ND && | 1297 | if (weight->GetStorageFormat() == ge::FORMAT_ND && |
| 1308 | (weightDtype == DataType::DT_FLOAT4_E1M2 || xDtype == DataType::DT_FLOAT4_E1M2 || | 1298 | (weightDtype == DataType::DT_FLOAT4_E1M2 || xDtype == DataType::DT_FLOAT4_E1M2 || |
| 1309 | output->GetDataType() == DataType::DT_FLOAT4_E1M2)) { | 1299 | output->GetDataType() == DataType::DT_FLOAT4_E1M2)) { |
| @@ -1314,6 +1304,11 @@ protected: | |||
| 1314 | "when the format of weight is ND, the dtypes of weight, x and output can not be DT_FLOAT4_E1M2"); | 1304 | "when the format of weight is ND, the dtypes of weight, x and output can not be DT_FLOAT4_E1M2"); |
| 1315 | return false; | 1305 | return false; |
| 1316 | } | 1306 | } |
| 1307 | + return true; | ||
| 1308 | + } | ||
| 1309 | + | ||
| 1310 | + bool CheckXAndWeightDtypeSupport(DataType xDtype, DataType weightDtype, const aclTensor *weight) | ||
| 1311 | + { | ||
| 1317 | const auto &xDtypeSupportListMxfp4 = GetXSupportListMxfp4(weight); | 1312 | const auto &xDtypeSupportListMxfp4 = GetXSupportListMxfp4(weight); |
| 1318 | const auto &weightDtypeSupportListMxfp4 = GetWeightSupportListMxfp4(weight); | 1313 | const auto &weightDtypeSupportListMxfp4 = GetWeightSupportListMxfp4(weight); |
| 1319 | const char *dtypeSupportList = IsMxfp4WeightNzFormat(weight) ? | 1314 | const char *dtypeSupportList = IsMxfp4WeightNzFormat(weight) ? |
| @@ -1343,6 +1338,12 @@ protected: | |||
| 1343 | dtypeSupportList); | 1338 | dtypeSupportList); |
| 1344 | return false; | 1339 | return false; |
| 1345 | } | 1340 | } |
| 1341 | + return true; | ||
| 1342 | + } | ||
| 1343 | + | ||
| 1344 | + bool CheckQuantModeDtype(DataType xDtype, DataType weightDtype, const aclTensor *x, const aclTensor *xScale, | ||
| 1345 | + const aclTensor *groupList, const aclTensor *output, const aclTensor *outputScale) | ||
| 1346 | + { | ||
| 1346 | if (gmmDsqParams_.quantMode == QUNAT_MODE_MX && | 1347 | if (gmmDsqParams_.quantMode == QUNAT_MODE_MX && |
| 1347 | (xDtype == DataType::DT_FLOAT8_E4M3FN || xDtype == DataType::DT_FLOAT8_E5M2) && | 1348 | (xDtype == DataType::DT_FLOAT8_E4M3FN || xDtype == DataType::DT_FLOAT8_E5M2) && |
| 1348 | (weightDtype == DataType::DT_FLOAT8_E4M3FN || weightDtype == DataType::DT_FLOAT8_E5M2)) { | 1349 | (weightDtype == DataType::DT_FLOAT8_E4M3FN || weightDtype == DataType::DT_FLOAT8_E5M2)) { |
| @@ -1372,6 +1373,28 @@ protected: | |||
| 1372 | return true; | 1373 | return true; |
| 1373 | } | 1374 | } |
| 1374 | 1375 | ||
| 1376 | + bool CheckDtypeValid() override | ||
| 1377 | + { | ||
| 1378 | + DataType xDtype = gmmDsqParams_.x->GetDataType(); | ||
| 1379 | + DataType weightDtype = ((*gmmDsqParams_.weight)[0])->GetDataType(); | ||
| 1380 | + const aclTensor *x = gmmDsqParams_.x; | ||
| 1381 | + const aclTensor *weight = (*gmmDsqParams_.weight)[0]; | ||
| 1382 | + const aclTensor *xScale = gmmDsqParams_.xScale; | ||
| 1383 | + const aclTensor *groupList = gmmDsqParams_.groupList; | ||
| 1384 | + const aclTensor *output = gmmDsqParams_.output; | ||
| 1385 | + const aclTensor *outputScale = gmmDsqParams_.outputScale; | ||
| 1386 | + if (!CheckWeightFormatConsistency()) { | ||
| 1387 | + return false; | ||
| 1388 | + } | ||
| 1389 | + if (!CheckNdE1M2Restriction(xDtype, weightDtype, weight, output)) { | ||
| 1390 | + return false; | ||
| 1391 | + } | ||
| 1392 | + if (!CheckXAndWeightDtypeSupport(xDtype, weightDtype, weight)) { | ||
| 1393 | + return false; | ||
| 1394 | + } | ||
| 1395 | + return CheckQuantModeDtype(xDtype, weightDtype, x, xScale, groupList, output, outputScale); | ||
| 1396 | + } | ||
| 1397 | + | ||
| 1375 | bool CheckFormat() override | 1398 | bool CheckFormat() override |
| 1376 | { | 1399 | { |
| 1377 | size_t wLength = gmmDsqParams_.weight->Size(); | 1400 | size_t wLength = gmmDsqParams_.weight->Size(); |
| @@ -258,14 +258,14 @@ bool GroupedMatmulSwigluQuantV2BasicApiTiling950::CheckTensorApiScaleShapes() co | |||
| 258 | 258 | ||
| 259 | const int64_t kBlocks = static_cast<int64_t>(GroupedMatmul::CeilDiv(inputParams_.kSize, MX_SCALE_K_ALIGN)); | 259 | const int64_t kBlocks = static_cast<int64_t>(GroupedMatmul::CeilDiv(inputParams_.kSize, MX_SCALE_K_ALIGN)); |
| 260 | if (xScaleShape.GetDim(0) != static_cast<int64_t>(inputParams_.mSize) || xScaleShape.GetDim(1) != kBlocks || | 260 | if (xScaleShape.GetDim(0) != static_cast<int64_t>(inputParams_.mSize) || xScaleShape.GetDim(1) != kBlocks || |
| 261 | - xScaleShape.GetDim(2) != SHAPE_DIM_TWO) { | 261 | + xScaleShape.GetDim(2) != SHAPE_DIM_TWO) { //xScale 的最后一维(索引 2,即第 3 维)也必须等于 2 |
| 262 | return false; | 262 | return false; |
| 263 | } | 263 | } |
| 264 | const int64_t weightScaleN = inputParams_.transB ? weightScaleShape.GetDim(1) : weightScaleShape.GetDim(2); | 264 | const int64_t weightScaleN = inputParams_.transB ? weightScaleShape.GetDim(1) : weightScaleShape.GetDim(2); |
| 265 | const int64_t weightScaleK = inputParams_.transB ? weightScaleShape.GetDim(2) : weightScaleShape.GetDim(1); | 265 | const int64_t weightScaleK = inputParams_.transB ? weightScaleShape.GetDim(2) : weightScaleShape.GetDim(1); |
| 266 | return weightScaleShape.GetDim(0) == static_cast<int64_t>(inputParams_.groupNum) && | 266 | return weightScaleShape.GetDim(0) == static_cast<int64_t>(inputParams_.groupNum) && |
| 267 | weightScaleN == static_cast<int64_t>(inputParams_.nSize) && weightScaleK == kBlocks && | 267 | weightScaleN == static_cast<int64_t>(inputParams_.nSize) && weightScaleK == kBlocks && |
| 268 | - weightScaleShape.GetDim(3) == SHAPE_DIM_TWO; | 268 | + weightScaleShape.GetDim(3) == SHAPE_DIM_TWO; //4 维 weightScale 的最后一维索引,该维固定为 2 |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | bool GroupedMatmulSwigluQuantV2BasicApiTiling950::IsCapable() | 271 | bool GroupedMatmulSwigluQuantV2BasicApiTiling950::IsCapable() |
| @@ -509,50 +509,119 @@ bool GroupedMatmulSwigluQuantV2Tiling950::CheckDims(const gert::Shape &xShape, c | |||
| 509 | 509 | ||
| 510 | return true; | 510 | return true; |
| 511 | } | 511 | } |
| 512 | +bool GroupedMatmulSwigluQuantV2Tiling950::GetInputShapes(const gert::Shape *&xShape, const gert::Shape *&wShape, | ||
| 513 | + const gert::Shape *&wScaleShape) | ||
| 514 | +{ | ||
| 515 | + auto xStorageShape = context_->GetInputShape(X_INDEX); | ||
| 516 | + OP_CHECK_IF( | ||
| 517 | + xStorageShape == nullptr, | ||
| 518 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "x", "nullptr", "xStorageShape cannot be nullptr"), | ||
| 519 | + return false); | ||
| 520 | + xShape = &xStorageShape->GetOriginShape(); | ||
| 521 | + auto wStorageShape = context_->GetDynamicInputShape(WEIGHT_INDEX, 0); | ||
| 522 | + OP_CHECK_IF(wStorageShape == nullptr, | ||
| 523 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "weight", "nullptr", | ||
| 524 | + "wStorageShape cannot be nullptr"), | ||
| 525 | + return false); | ||
| 526 | + wShape = &wStorageShape->GetOriginShape(); | ||
| 527 | + auto scaleStorageShape = context_->GetDynamicInputShape(SCALE_INDEX, 0); | ||
| 528 | + OP_CHECK_IF(scaleStorageShape == nullptr, | ||
| 529 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "scale", "nullptr", | ||
| 530 | + "scaleStorageShape cannot be nullptr"), | ||
| 531 | + return false); | ||
| 532 | + wScaleShape = &scaleStorageShape->GetOriginShape(); | ||
| 533 | + return true; | ||
| 534 | +} | ||
| 535 | + | ||
| 536 | +bool GroupedMatmulSwigluQuantV2Tiling950::GetAndCheckXScaleShape(const gert::Shape *&xScaleShape) | ||
| 537 | +{ | ||
| 538 | + auto x1ScaleStorageShape = context_->GetInputShape(PER_TOKEN_SCALE_INDEX); | ||
| 539 | + OP_CHECK_IF(x1ScaleStorageShape == nullptr, | ||
| 540 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "x_scale", "nullptr", | ||
| 541 | + "xScaleStorageShape cannot be nullptr"), | ||
| 542 | + return false); | ||
| 543 | + xScaleShape = &x1ScaleStorageShape->GetOriginShape(); | ||
| 544 | + auto xScaleDimNum = xScaleShape->GetDimNum(); | ||
| 545 | + OP_CHECK_IF(xScaleDimNum != MX_X_SCALE_DIM, | ||
| 546 | + OP_LOGE_FOR_INVALID_SHAPEDIM(inputParams_.opType, "x_scale", std::to_string(xScaleDimNum), "3"), | ||
| 547 | + return false); | ||
| 548 | + return true; | ||
| 549 | +} | ||
| 550 | + | ||
| 551 | +bool GroupedMatmulSwigluQuantV2Tiling950::CheckMxPerGroupShape(const gert::Shape &xScaleShape, | ||
| 552 | + const gert::Shape &wScaleShape, size_t weightCount, | ||
| 553 | + bool isMultiWeightNz) | ||
| 554 | +{ | ||
| 555 | + if (isMultiWeightNz) { | ||
| 556 | + auto expectedKDimValue = GroupedMatmul::CeilDiv(inputParams_.kSize, MXFP_BASEK_FACTOR); | ||
| 557 | + uint64_t expectedWeightDim0 = inputParams_.transB ? inputParams_.nSize : inputParams_.kSize; | ||
| 558 | + uint64_t expectedWeightDim1 = inputParams_.transB ? inputParams_.kSize : inputParams_.nSize; | ||
| 559 | + uint64_t expectedScaleDim0 = inputParams_.transB ? inputParams_.nSize : expectedKDimValue; | ||
| 560 | + uint64_t expectedScaleDim1 = inputParams_.transB ? expectedKDimValue : inputParams_.nSize; | ||
| 561 | + for (size_t i = 0; i < weightCount; ++i) { | ||
| 562 | + auto curWStorageShape = context_->GetDynamicInputShape(WEIGHT_INDEX, i); | ||
| 563 | + auto curScaleStorageShape = context_->GetDynamicInputShape(SCALE_INDEX, i); | ||
| 564 | + OP_CHECK_IF(curWStorageShape == nullptr || curScaleStorageShape == nullptr, | ||
| 565 | + OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "weight/weight_scale", "nullptr", | ||
| 566 | + "dynamic weight and weightScale cannot be nullptr"), | ||
| 567 | + return false); | ||
| 568 | + const gert::Shape &curWShape = curWStorageShape->GetOriginShape(); | ||
| 569 | + const gert::Shape &curScaleShape = curScaleStorageShape->GetOriginShape(); | ||
| 570 | + OP_CHECK_IF(curWShape.GetDimNum() != MIN_WEIGHT_ORIGIN_SHAPE_DIM || | ||
| 571 | + static_cast<uint64_t>(curWShape.GetDim(0)) != expectedWeightDim0 || | ||
| 572 | + static_cast<uint64_t>(curWShape.GetDim(1)) != expectedWeightDim1, | ||
| 573 | + OP_LOGE_FOR_INVALID_SHAPE(inputParams_.opType, "weight", ShapeToString(curWShape), | ||
| 574 | + ShapeDimsToString(expectedWeightDim0, expectedWeightDim1)), | ||
| 575 | + return false); | ||
| 576 | + OP_CHECK_IF(curScaleShape.GetDimNum() != MX_MULTI_WEIGHT_SCALE_DIM || | ||
| 577 | + static_cast<uint64_t>(curScaleShape.GetDim(0)) != expectedScaleDim0 || | ||
| 578 | + static_cast<uint64_t>(curScaleShape.GetDim(1)) != expectedScaleDim1 || | ||
| 579 | + static_cast<uint64_t>(curScaleShape.GetDim(2)) != MXFP_MULTI_BASE_SIZE, | ||
| 580 | + OP_LOGE_FOR_INVALID_SHAPE( | ||
| 581 | + inputParams_.opType, "weight_scale", ShapeToString(curScaleShape), | ||
| 582 | + ShapeDimsToString(expectedScaleDim0, expectedScaleDim1, MXFP_MULTI_BASE_SIZE)), | ||
| 583 | + return false); | ||
| 584 | + } | ||
| 585 | + OP_CHECK_IF(static_cast<uint64_t>(xScaleShape.GetDim(0)) != inputParams_.mSize || | ||
| 586 | + static_cast<uint64_t>(xScaleShape.GetDim(1)) != expectedKDimValue || | ||
| 587 | + static_cast<uint64_t>(xScaleShape.GetDim(2)) != MXFP_MULTI_BASE_SIZE, | ||
| 588 | + OP_LOGE_FOR_INVALID_SHAPE( | ||
| 589 | + inputParams_.opType, "x_scale", ShapeToString(xScaleShape), | ||
| 590 | + ShapeDimsToString(inputParams_.mSize, expectedKDimValue, MXFP_MULTI_BASE_SIZE)), | ||
| 591 | + return false); | ||
| 592 | + } else { | ||
| 593 | + OP_CHECK_IF(!CheckQuantParamsForMXTypeM(xScaleShape, wScaleShape), | ||
| 594 | + OP_LOGE(inputParams_.opName, "CheckShapeForMxQuant failed."), return false); | ||
| 595 | + } | ||
| 596 | + return true; | ||
| 597 | +} | ||
| 598 | + | ||
| 512 | bool GroupedMatmulSwigluQuantV2Tiling950::AnalyzeInputs() | 599 | bool GroupedMatmulSwigluQuantV2Tiling950::AnalyzeInputs() |
| 513 | { | 600 | { |
| 514 | OP_CHECK_IF(!CheckCoreNum(), OP_LOGE(inputParams_.opName, "CheckCoreNum failed."), return false); | 601 | OP_CHECK_IF(!CheckCoreNum(), OP_LOGE(inputParams_.opName, "CheckCoreNum failed."), return false); |
| 515 | if (inputParams_.aQuantMode == optiling::QuantMode::PERTOKEN_MODE) { | 602 | if (inputParams_.aQuantMode == optiling::QuantMode::PERTOKEN_MODE) { |
| 516 | return AnalyzeInputsPertoken(); | 603 | return AnalyzeInputsPertoken(); |
| 517 | } | 604 | } |
| 518 | - auto xStorageShape = context_->GetInputShape(X_INDEX); | 605 | + const gert::Shape *xShape = nullptr; |
| 519 | - OP_CHECK_IF( | 606 | + const gert::Shape *wShape = nullptr; |
| 520 | - xStorageShape == nullptr, | 607 | + const gert::Shape *wScaleShape = nullptr; |
| 521 | - OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "x", "nullptr", "xStorageShape cannot be nullptr"), | 608 | + if (!GetInputShapes(xShape, wShape, wScaleShape)) { |
| 522 | - return false); | 609 | + return false; |
| 523 | - const gert::Shape &xShape = xStorageShape->GetOriginShape(); | 610 | + } |
| 524 | - auto wStorageShape = context_->GetDynamicInputShape(WEIGHT_INDEX, 0); | 611 | + auto scaleDimNum = wScaleShape->GetDimNum(); |
| 525 | - OP_CHECK_IF(wStorageShape == nullptr, | ||
| 526 | - OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "weight", "nullptr", | ||
| 527 | - "wStorageShape cannot be nullptr"), | ||
| 528 | - return false); | ||
| 529 | - const gert::Shape &wShape = wStorageShape->GetOriginShape(); | ||
| 530 | - auto scaleStorageShape = context_->GetDynamicInputShape(SCALE_INDEX, 0); | ||
| 531 | - OP_CHECK_IF(scaleStorageShape == nullptr, | ||
| 532 | - OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "scale", "nullptr", | ||
| 533 | - "scaleStorageShape cannot be nullptr"), | ||
| 534 | - return false); | ||
| 535 | - const gert::Shape &wScaleShape = scaleStorageShape->GetOriginShape(); | ||
| 536 | - auto scaleDimNum = wScaleShape.GetDimNum(); | ||
| 537 | size_t weightCount = GetDynamicInputCount(context_, WEIGHT_INDEX); | 612 | size_t weightCount = GetDynamicInputCount(context_, WEIGHT_INDEX); |
| 538 | size_t scaleCount = GetDynamicInputCount(context_, SCALE_INDEX); | 613 | size_t scaleCount = GetDynamicInputCount(context_, SCALE_INDEX); |
| 539 | - bool isMultiWeightNz = IsMxWeightNzMultiTensor(wShape); | 614 | + bool isMultiWeightNz = IsMxWeightNzMultiTensor(*wShape); |
| 540 | isMxWeightNzMultiTensor_ = isMultiWeightNz; | 615 | isMxWeightNzMultiTensor_ = isMultiWeightNz; |
| 541 | size_t expectedScaleDim = isMultiWeightNz ? MX_MULTI_WEIGHT_SCALE_DIM : MX_WEIGHT_SCALE_DIM; | 616 | size_t expectedScaleDim = isMultiWeightNz ? MX_MULTI_WEIGHT_SCALE_DIM : MX_WEIGHT_SCALE_DIM; |
| 542 | OP_CHECK_IF(scaleDimNum != expectedScaleDim, | 617 | OP_CHECK_IF(scaleDimNum != expectedScaleDim, |
| 543 | OP_LOGE_FOR_INVALID_SHAPEDIM(inputParams_.opType, "weight_scale", std::to_string(scaleDimNum), | 618 | OP_LOGE_FOR_INVALID_SHAPEDIM(inputParams_.opType, "weight_scale", std::to_string(scaleDimNum), |
| 544 | std::to_string(expectedScaleDim)), | 619 | std::to_string(expectedScaleDim)), |
| 545 | return false); | 620 | return false); |
| 546 | - auto x1ScaleStorageShape = context_->GetInputShape(PER_TOKEN_SCALE_INDEX); | 621 | + const gert::Shape *xScaleShape = nullptr; |
| 547 | - OP_CHECK_IF(x1ScaleStorageShape == nullptr, | 622 | + if (!GetAndCheckXScaleShape(xScaleShape)) { |
| 548 | - OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "x_scale", "nullptr", | 623 | + return false; |
| 549 | - "xScaleStorageShape cannot be nullptr"), | 624 | + } |
| 550 | - return false); | ||
| 551 | - const gert::Shape &xScaleShape = x1ScaleStorageShape->GetOriginShape(); | ||
| 552 | - auto xScaleDimNum = xScaleShape.GetDimNum(); | ||
| 553 | - OP_CHECK_IF(xScaleDimNum != MX_X_SCALE_DIM, | ||
| 554 | - OP_LOGE_FOR_INVALID_SHAPEDIM(inputParams_.opType, "x_scale", std::to_string(xScaleDimNum), "3"), | ||
| 555 | - return false); | ||
| 556 | OP_CHECK_IF(!SetGroupNum(GROUPLIST_INDEX), OP_LOGE(inputParams_.opName, "SetGroupNum failed."), return false); | 625 | OP_CHECK_IF(!SetGroupNum(GROUPLIST_INDEX), OP_LOGE(inputParams_.opName, "SetGroupNum failed."), return false); |
| 557 | OP_CHECK_IF(isMultiWeightNz && weightCount != static_cast<size_t>(inputParams_.groupNum), | 626 | OP_CHECK_IF(isMultiWeightNz && weightCount != static_cast<size_t>(inputParams_.groupNum), |
| 558 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "weight", std::to_string(weightCount), | 627 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "weight", std::to_string(weightCount), |
| @@ -563,49 +632,11 @@ bool GroupedMatmulSwigluQuantV2Tiling950::AnalyzeInputs() | |||
| 563 | "weightScale tensor list size must equal " | 632 | "weightScale tensor list size must equal " |
| 564 | "weight tensor list size"), | 633 | "weight tensor list size"), |
| 565 | return false); | 634 | return false); |
| 566 | - OP_CHECK_IF(!SetMKN(xShape, wShape), OP_LOGE(inputParams_.opName, "SetMKN failed."), return false); | 635 | + OP_CHECK_IF(!SetMKN(*xShape, *wShape), OP_LOGE(inputParams_.opName, "SetMKN failed."), return false); |
| 567 | - OP_CHECK_IF(!CheckDims(xShape, wShape), OP_LOGE(inputParams_.opName, "CheckDims failed."), return false); | 636 | + OP_CHECK_IF(!CheckDims(*xShape, *wShape), OP_LOGE(inputParams_.opName, "CheckDims failed."), return false); |
| 568 | if (inputParams_.bQuantMode == optiling::QuantMode::MX_PERGROUP_MODE) { | 637 | if (inputParams_.bQuantMode == optiling::QuantMode::MX_PERGROUP_MODE) { |
| 569 | - if (isMultiWeightNz) { | 638 | + if (!CheckMxPerGroupShape(*xScaleShape, wScaleShape, weightCount, isMultiWeightNz)) { |
| 570 | - auto expectedKDimValue = GroupedMatmul::CeilDiv(inputParams_.kSize, MXFP_BASEK_FACTOR); | 639 | + return false; |
| 571 | - uint64_t expectedWeightDim0 = inputParams_.transB ? inputParams_.nSize : inputParams_.kSize; | ||
| 572 | - uint64_t expectedWeightDim1 = inputParams_.transB ? inputParams_.kSize : inputParams_.nSize; | ||
| 573 | - uint64_t expectedScaleDim0 = inputParams_.transB ? inputParams_.nSize : expectedKDimValue; | ||
| 574 | - uint64_t expectedScaleDim1 = inputParams_.transB ? expectedKDimValue : inputParams_.nSize; | ||
| 575 | - for (size_t i = 0; i < weightCount; ++i) { | ||
| 576 | - auto curWStorageShape = context_->GetDynamicInputShape(WEIGHT_INDEX, i); | ||
| 577 | - auto curScaleStorageShape = context_->GetDynamicInputShape(SCALE_INDEX, i); | ||
| 578 | - OP_CHECK_IF(curWStorageShape == nullptr || curScaleStorageShape == nullptr, | ||
| 579 | - OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(inputParams_.opType, "weight/weight_scale", "nullptr", | ||
| 580 | - "dynamic weight and weightScale cannot be nullptr"), | ||
| 581 | - return false); | ||
| 582 | - const gert::Shape &curWShape = curWStorageShape->GetOriginShape(); | ||
| 583 | - const gert::Shape &curScaleShape = curScaleStorageShape->GetOriginShape(); | ||
| 584 | - OP_CHECK_IF(curWShape.GetDimNum() != MIN_WEIGHT_ORIGIN_SHAPE_DIM || | ||
| 585 | - static_cast<uint64_t>(curWShape.GetDim(0)) != expectedWeightDim0 || | ||
| 586 | - static_cast<uint64_t>(curWShape.GetDim(1)) != expectedWeightDim1, | ||
| 587 | - OP_LOGE_FOR_INVALID_SHAPE(inputParams_.opType, "weight", ShapeToString(curWShape), | ||
| 588 | - ShapeDimsToString(expectedWeightDim0, expectedWeightDim1)), | ||
| 589 | - return false); | ||
| 590 | - OP_CHECK_IF(curScaleShape.GetDimNum() != MX_MULTI_WEIGHT_SCALE_DIM || | ||
| 591 | - static_cast<uint64_t>(curScaleShape.GetDim(0)) != expectedScaleDim0 || | ||
| 592 | - static_cast<uint64_t>(curScaleShape.GetDim(1)) != expectedScaleDim1 || | ||
| 593 | - static_cast<uint64_t>(curScaleShape.GetDim(2)) != MXFP_MULTI_BASE_SIZE, | ||
| 594 | - OP_LOGE_FOR_INVALID_SHAPE( | ||
| 595 | - inputParams_.opType, "weight_scale", ShapeToString(curScaleShape), | ||
| 596 | - ShapeDimsToString(expectedScaleDim0, expectedScaleDim1, MXFP_MULTI_BASE_SIZE)), | ||
| 597 | - return false); | ||
| 598 | - } | ||
| 599 | - OP_CHECK_IF(static_cast<uint64_t>(xScaleShape.GetDim(0)) != inputParams_.mSize || | ||
| 600 | - static_cast<uint64_t>(xScaleShape.GetDim(1)) != expectedKDimValue || | ||
| 601 | - static_cast<uint64_t>(xScaleShape.GetDim(2)) != MXFP_MULTI_BASE_SIZE, | ||
| 602 | - OP_LOGE_FOR_INVALID_SHAPE( | ||
| 603 | - inputParams_.opType, "x_scale", ShapeToString(xScaleShape), | ||
| 604 | - ShapeDimsToString(inputParams_.mSize, expectedKDimValue, MXFP_MULTI_BASE_SIZE)), | ||
| 605 | - return false); | ||
| 606 | - } else { | ||
| 607 | - OP_CHECK_IF(!CheckQuantParamsForMXTypeM(xScaleShape, wScaleShape), | ||
| 608 | - OP_LOGE(inputParams_.opName, "CheckShapeForMxQuant failed."), return false); | ||
| 609 | } | 640 | } |
| 610 | } | 641 | } |
| 611 | return true; | 642 | return true; |
| @@ -799,14 +830,16 @@ void GroupedMatmulSwigluQuantV2Tiling950::ModifyWeightNzDepthForUnalign(uint64_t | |||
| 799 | } | 830 | } |
| 800 | } | 831 | } |
| 801 | 832 | ||
| 802 | -ge::graphStatus GroupedMatmulSwigluQuantV2Tiling950::CalWeightNzScaleFactors() | 833 | +ge::graphStatus GroupedMatmulSwigluQuantV2Tiling950::CalBaseSizesAndScaleInit(uint64_t &baseScaleASize, |
| 834 | + uint64_t &baseScaleBSize, | ||
| 835 | + uint32_t &scaleInit) | ||
| 803 | { | 836 | { |
| 804 | uint64_t baseASize = GetSizeWithDataType(basicTiling_.baseM * basicTiling_.baseK, inputParams_.aDtype); | 837 | uint64_t baseASize = GetSizeWithDataType(basicTiling_.baseM * basicTiling_.baseK, inputParams_.aDtype); |
| 805 | uint64_t baseBSize = GetSizeWithDataType(basicTiling_.baseN * basicTiling_.baseK, inputParams_.bDtype); | 838 | uint64_t baseBSize = GetSizeWithDataType(basicTiling_.baseN * basicTiling_.baseK, inputParams_.bDtype); |
| 806 | - uint64_t baseScaleASize = | 839 | + baseScaleASize = |
| 807 | GetSizeWithDataType(GroupedMatmul::CeilDiv(basicTiling_.baseK, MX_GROUP_SIZE) * basicTiling_.baseM, | 840 | GetSizeWithDataType(GroupedMatmul::CeilDiv(basicTiling_.baseK, MX_GROUP_SIZE) * basicTiling_.baseM, |
| 808 | inputParams_.perTokenScaleDtype); | 841 | inputParams_.perTokenScaleDtype); |
| 809 | - uint64_t baseScaleBSize = GetSizeWithDataType( | 842 | + baseScaleBSize = GetSizeWithDataType( |
| 810 | GroupedMatmul::CeilDiv(basicTiling_.baseK, MX_GROUP_SIZE) * basicTiling_.baseN, inputParams_.scaleDtype); | 843 | GroupedMatmul::CeilDiv(basicTiling_.baseK, MX_GROUP_SIZE) * basicTiling_.baseN, inputParams_.scaleDtype); |
| 811 | OP_CHECK_IF(baseScaleASize == 0 || baseScaleBSize == 0, | 844 | OP_CHECK_IF(baseScaleASize == 0 || baseScaleBSize == 0, |
| 812 | OP_LOGE(context_->GetNodeName(), | 845 | OP_LOGE(context_->GetNodeName(), |
| @@ -819,7 +852,7 @@ ge::graphStatus GroupedMatmulSwigluQuantV2Tiling950::CalWeightNzScaleFactors() | |||
| 819 | uint64_t baseBiasSize = inputParams_.hasBias ? basicTiling_.baseN * biasDtypeSize : 0; | 852 | uint64_t baseBiasSize = inputParams_.hasBias ? basicTiling_.baseN * biasDtypeSize : 0; |
| 820 | uint64_t leftL1Size = | 853 | uint64_t leftL1Size = |
| 821 | aicoreParams_.l1Size - (basicTiling_.depthA1 * baseASize + basicTiling_.depthB1 * baseBSize + baseBiasSize); | 854 | aicoreParams_.l1Size - (basicTiling_.depthA1 * baseASize + basicTiling_.depthB1 * baseBSize + baseBiasSize); |
| 822 | - uint32_t scaleInit = static_cast<uint32_t>( | 855 | + scaleInit = static_cast<uint32_t>( |
| 823 | leftL1Size / (std::max(basicTiling_.depthA1, basicTiling_.depthB1) * (baseScaleASize + baseScaleBSize))); | 856 | leftL1Size / (std::max(basicTiling_.depthA1, basicTiling_.depthB1) * (baseScaleASize + baseScaleBSize))); |
| 824 | OP_CHECK_IF( | 857 | OP_CHECK_IF( |
| 825 | scaleInit == 0, | 858 | scaleInit == 0, |
| @@ -827,7 +860,12 @@ ge::graphStatus GroupedMatmulSwigluQuantV2Tiling950::CalWeightNzScaleFactors() | |||
| 827 | "When m(%lu)/n(%lu)/k(%lu)/groupNum(%lu) in mx quant mode, scaleFactor should not be equal to 0.", | 860 | "When m(%lu)/n(%lu)/k(%lu)/groupNum(%lu) in mx quant mode, scaleFactor should not be equal to 0.", |
| 828 | inputParams_.mSize, inputParams_.nSize, inputParams_.kSize, inputParams_.groupNum), | 861 | inputParams_.mSize, inputParams_.nSize, inputParams_.kSize, inputParams_.groupNum), |
| 829 | return ge::GRAPH_FAILED); | 862 | return ge::GRAPH_FAILED); |
| 863 | + return ge::GRAPH_SUCCESS; | ||
| 864 | +} | ||
| 830 | 865 | ||
| 866 | +ge::graphStatus GroupedMatmulSwigluQuantV2Tiling950::CalScaleFactors(uint64_t baseScaleASize, uint64_t baseScaleBSize, | ||
| 867 | + uint32_t scaleInit) | ||
| 868 | +{ | ||
| 831 | uint32_t scaleFactorAMax = | 869 | uint32_t scaleFactorAMax = |
| 832 | std::min(static_cast<uint32_t>(MTE2_MIN_LOAD_SIZE_V120 / baseScaleASize), SCALER_FACTOR_MAX); | 870 | std::min(static_cast<uint32_t>(MTE2_MIN_LOAD_SIZE_V120 / baseScaleASize), SCALER_FACTOR_MAX); |
| 833 | uint32_t scaleFactorBMax = | 871 | uint32_t scaleFactorBMax = |
| @@ -857,6 +895,21 @@ ge::graphStatus GroupedMatmulSwigluQuantV2Tiling950::CalWeightNzScaleFactors() | |||
| 857 | basicTiling_.scaleFactorB = scaleInit; | 895 | basicTiling_.scaleFactorB = scaleInit; |
| 858 | } | 896 | } |
| 859 | } | 897 | } |
| 898 | + return ge::GRAPH_SUCCESS; | ||
| 899 | +} | ||
| 900 | + | ||
| 901 | +ge::graphStatus GroupedMatmulSwigluQuantV2Tiling950::CalWeightNzScaleFactors() | ||
| 902 | +{ | ||
| 903 | + uint64_t baseScaleASize = 0; | ||
| 904 | + uint64_t baseScaleBSize = 0; | ||
| 905 | + uint32_t scaleInit = 0; | ||
| 906 | + if (CalBaseSizesAndScaleInit(baseScaleASize, baseScaleBSize, scaleInit) != ge::GRAPH_SUCCESS) { | ||
| 907 | + return ge::GRAPH_FAILED; | ||
| 908 | + } | ||
| 909 | + | ||
| 910 | + if (CalScaleFactors(baseScaleASize, baseScaleBSize, scaleInit) != ge::GRAPH_SUCCESS) { | ||
| 911 | + return ge::GRAPH_FAILED; | ||
| 912 | + } | ||
| 860 | OP_CHECK_IF(basicTiling_.scaleFactorA < SCALER_FACTOR_MIN || basicTiling_.scaleFactorA > SCALER_FACTOR_MAX || | 913 | OP_CHECK_IF(basicTiling_.scaleFactorA < SCALER_FACTOR_MIN || basicTiling_.scaleFactorA > SCALER_FACTOR_MAX || |
| 861 | basicTiling_.scaleFactorB < SCALER_FACTOR_MIN || basicTiling_.scaleFactorB > SCALER_FACTOR_MAX, | 914 | basicTiling_.scaleFactorB < SCALER_FACTOR_MIN || basicTiling_.scaleFactorB > SCALER_FACTOR_MAX, |
| 862 | OP_LOGE(context_->GetNodeName(), | 915 | OP_LOGE(context_->GetNodeName(), |
| @@ -64,6 +64,10 @@ private: | |||
| 64 | bool AnalyzeAttrs() override; | 64 | bool AnalyzeAttrs() override; |
| 65 | bool AnalyzeDtype() override; | 65 | bool AnalyzeDtype() override; |
| 66 | bool AnalyzeInputs() override; | 66 | bool AnalyzeInputs() override; |
| 67 | + bool GetInputShapes(const gert::Shape *&xShape, const gert::Shape *&wShape, const gert::Shape *&wScaleShape); | ||
| 68 | + bool GetAndCheckXScaleShape(const gert::Shape *&xScaleShape); | ||
| 69 | + bool CheckMxPerGroupShape(const gert::Shape &xScaleShape, const gert::Shape &wScaleShape, size_t weightCount, | ||
| 70 | + bool isMultiWeightNz); | ||
| 67 | int64_t LogQuantParams(); | 71 | int64_t LogQuantParams(); |
| 68 | bool SetQuantModeForGMMSwigluQuant(const gert::Shape &wScaleShape, const gert::Shape &xScaleShape); | 72 | bool SetQuantModeForGMMSwigluQuant(const gert::Shape &wScaleShape, const gert::Shape &xScaleShape); |
| 69 | bool CheckShapeForMxQuant(const gert::Shape &x1ScaleShape, const gert::Shape &x2ScaleShape); | 73 | bool CheckShapeForMxQuant(const gert::Shape &x1ScaleShape, const gert::Shape &x2ScaleShape); |
| @@ -84,6 +88,8 @@ private: | |||
| 84 | void ModifyWeightNzDepthForUnalign(uint64_t leftL1Size, uint64_t baseASize, uint64_t baseBSize, | 88 | void ModifyWeightNzDepthForUnalign(uint64_t leftL1Size, uint64_t baseASize, uint64_t baseBSize, |
| 85 | uint64_t baseScaleABSize); | 89 | uint64_t baseScaleABSize); |
| 86 | ge::graphStatus CalWeightNzScaleFactors(); | 90 | ge::graphStatus CalWeightNzScaleFactors(); |
| 91 | + ge::graphStatus CalBaseSizesAndScaleInit(uint64_t &baseScaleASize, uint64_t &baseScaleBSize, uint32_t &scaleInit); | ||
| 92 | + ge::graphStatus CalScaleFactors(uint64_t baseScaleASize, uint64_t baseScaleBSize, uint32_t scaleInit); | ||
| 87 | // add for pertoken quant mode | 93 | // add for pertoken quant mode |
| 88 | bool AnalyzeAttrsPertoken(); | 94 | bool AnalyzeAttrsPertoken(); |
| 89 | bool IsB8(ge::DataType dtype); | 95 | bool IsB8(ge::DataType dtype); |
| @@ -278,7 +278,7 @@ static aclnnStatus SetTransViewShape(const aclTensor *&inputTensor, aclOpExecuto | |||
| 278 | { | 278 | { |
| 279 | op::Shape viewShape = inputTensor->GetViewShape(); | 279 | op::Shape viewShape = inputTensor->GetViewShape(); |
| 280 | uint32_t viewShapeDimsNum = viewShape.GetDimNum(); | 280 | uint32_t viewShapeDimsNum = viewShape.GetDimNum(); |
| 281 | - CHECK_RET(viewShapeDimsNum >= 2, ACLNN_ERR_PARAM_INVALID); | 281 | + CHECK_RET(viewShapeDimsNum >= 2, ACLNN_ERR_PARAM_INVALID); //矩阵转置操作要求 tensor 至少要有 2 个维度 |
| 282 | op::Shape shape; | 282 | op::Shape shape; |
| 283 | shape.SetScalar(); | 283 | shape.SetScalar(); |
| 284 | // 2: the second last dimension; in for-loops, it indicates dimensions before the second last remain unchanged. | 284 | // 2: the second last dimension; in for-loops, it indicates dimensions before the second last remain unchanged. |
| @@ -168,7 +168,7 @@ aclnnStatus AclnnQuantGroupedMatmulInplaceAddDAV3510Checker<T>::CheckHif8QuantPa | |||
| 168 | { | 168 | { |
| 169 | auto groupNum = gmmParams_.groupTensorOptional->GetViewShape().GetDim(0); | 169 | auto groupNum = gmmParams_.groupTensorOptional->GetViewShape().GetDim(0); |
| 170 | for (size_t i = 0; i < GetInputTensorSize(gmmParams_.weight); ++i) { | 170 | for (size_t i = 0; i < GetInputTensorSize(gmmParams_.weight); ++i) { |
| 171 | - auto weightDimNumber = GetInputTensor(gmmParams_.weight, i)->GetViewShape().GetDimNum(); | 171 | + //auto weightDimNumber = GetInputTensor(gmmParams_.weight, i)->GetViewShape().GetDimNum(); |
| 172 | auto scaleDimNumber = GetInputTensor(gmmParams_.scaleOptional, i)->GetViewShape().GetDimNum(); | 172 | auto scaleDimNumber = GetInputTensor(gmmParams_.scaleOptional, i)->GetViewShape().GetDimNum(); |
| 173 | auto perTokenDimNumber = GetInputTensor(gmmParams_.perTokenScaleOptional, i)->GetViewShape().GetDimNum(); | 173 | auto perTokenDimNumber = GetInputTensor(gmmParams_.perTokenScaleOptional, i)->GetViewShape().GetDimNum(); |
| 174 | const auto *perTokenScaleTensor = GetInputTensor(gmmParams_.perTokenScaleOptional, i); | 174 | const auto *perTokenScaleTensor = GetInputTensor(gmmParams_.perTokenScaleOptional, i); |
| @@ -32,6 +32,53 @@ constexpr size_t INDEX_OUTPUT_Y = 0; | |||
| 32 | constexpr size_t INDEX_ATTR_GROUP_LIST_TYPE = 0; | 32 | constexpr size_t INDEX_ATTR_GROUP_LIST_TYPE = 0; |
| 33 | constexpr size_t DIM_TWO = 2; | 33 | constexpr size_t DIM_TWO = 2; |
| 34 | 34 | ||
| 35 | +static bool BuildViewShapeAndStrides(const gert::Tensor *geTensor, std::vector<int64_t> &viewShape, | ||
| 36 | + std::vector<int64_t> &strides) | ||
| 37 | +{ | ||
| 38 | + auto origin_shape = geTensor->GetOriginShape(); | ||
| 39 | + for (size_t i = 0; i < origin_shape.GetDimNum(); ++i) { | ||
| 40 | + viewShape.push_back(origin_shape.GetDim(i)); | ||
| 41 | + } | ||
| 42 | + strides.assign(viewShape.size(), 1); | ||
| 43 | + // Compute the strides of contiguous tensor | ||
| 44 | + OP_CHECK_IF(viewShape.size() < DIM_TWO, | ||
| 45 | + OP_LOGE("QuantGroupedMatmulInplaceAdd aclnnfallback", | ||
| 46 | + "The dim num of viewshape should be greater than or equal to 2, but the actual is %zu.", | ||
| 47 | + viewShape.size()), | ||
| 48 | + return false); | ||
| 49 | + for (int64_t i = viewShape.size() - 2; i >= 0; i--) { | ||
| 50 | + strides[i] = viewShape[i + 1] * strides[i + 1]; | ||
| 51 | + } | ||
| 52 | + return true; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +static bool ApplyTranspose(size_t index, bool enableTranspose, ge::DataType dataType_ge, | ||
| 56 | + std::vector<int64_t> &viewShape, std::vector<int64_t> &strides) | ||
| 57 | +{ | ||
| 58 | + if (index == INDEX_INPUT_SCALE1 && dataType_ge == ge::DataType::DT_FLOAT8_E8M0 && enableTranspose) { | ||
| 59 | + OP_CHECK_IF(viewShape.size() < 3, OP_LOGE("aclnnfallback", "Mx tpyek wrong pertokenscale size"), return false); | ||
| 60 | + auto swap = viewShape[0]; | ||
| 61 | + viewShape[0] = viewShape[1]; | ||
| 62 | + viewShape[1] = swap; | ||
| 63 | + strides[0] = 2; // 2 in shape(k//64 + g, M, 2) | ||
| 64 | + strides[1] = viewShape[0] * 2; // since last dim is contiguous 2 | ||
| 65 | + strides[2] = 1; // last axis of stride with index 2 has velue 1 | ||
| 66 | + } else if (enableTranspose) { // when tensor is transposed, last two dims in strides and viewShape should swap | ||
| 67 | + // dimM the second-to-last dim, dimN the last dim | ||
| 68 | + auto dimM = viewShape.size() - 2; | ||
| 69 | + auto dimN = viewShape.size() - 1; | ||
| 70 | + if (viewShape[dimM] != 1 && viewShape[dimN] != 0) { | ||
| 71 | + auto swap = strides[dimN]; | ||
| 72 | + strides[dimN] = strides[dimM]; | ||
| 73 | + strides[dimM] = swap; | ||
| 74 | + swap = viewShape[dimN]; | ||
| 75 | + viewShape[dimN] = viewShape[dimM]; | ||
| 76 | + viewShape[dimM] = swap; | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + return true; | ||
| 80 | +} | ||
| 81 | + | ||
| 35 | static inline aclTensor *GeTensor2AclTensor(const gert::Tensor *geTensor, bool enableTranspose, size_t index) | 82 | static inline aclTensor *GeTensor2AclTensor(const gert::Tensor *geTensor, bool enableTranspose, size_t index) |
| 36 | { | 83 | { |
| 37 | if (geTensor == nullptr) { | 84 | if (geTensor == nullptr) { |
| @@ -56,43 +103,14 @@ static inline aclTensor *GeTensor2AclTensor(const gert::Tensor *geTensor, bool e | |||
| 56 | } else { | 103 | } else { |
| 57 | dataType = ToAclDataType(dataType_ge); | 104 | dataType = ToAclDataType(dataType_ge); |
| 58 | } | 105 | } |
| 59 | - auto origin_shape = geTensor->GetOriginShape(); | ||
| 60 | std::vector<int64_t> viewShape; | 106 | std::vector<int64_t> viewShape; |
| 61 | - for (size_t i = 0; i < origin_shape.GetDimNum(); ++i) { | 107 | + std::vector<int64_t> strides; |
| 62 | - viewShape.push_back(origin_shape.GetDim(i)); | 108 | + if (!BuildViewShapeAndStrides(geTensor, viewShape, strides)) { |
| 63 | - } | 109 | + return nullptr; |
| 64 | - std::vector<int64_t> strides(viewShape.size(), 1); | ||
| 65 | - // Compute the strides of contiguous tensor | ||
| 66 | - OP_CHECK_IF(viewShape.size() < DIM_TWO, | ||
| 67 | - OP_LOGE("QuantGroupedMatmulInplaceAdd aclnnfallback", | ||
| 68 | - "The dim num of viewshape should be greater than or equal to 2, but the actual is %zu.", | ||
| 69 | - viewShape.size()), | ||
| 70 | - return nullptr); | ||
| 71 | - for (int64_t i = viewShape.size() - 2; i >= 0; i--) { | ||
| 72 | - strides[i] = viewShape[i + 1] * strides[i + 1]; | ||
| 73 | } | 110 | } |
| 74 | 111 | ||
| 75 | - if (index == INDEX_INPUT_SCALE1 && dataType_ge == ge::DataType::DT_FLOAT8_E8M0 && enableTranspose) { | 112 | + if (!ApplyTranspose(index, enableTranspose, dataType_ge, viewShape, strides)) { |
| 76 | - OP_CHECK_IF(viewShape.size() < 3, OP_LOGE("aclnnfallback", "Mx tpyek wrong pertokenscale size"), | 113 | + return nullptr; |
| 77 | - return nullptr); | ||
| 78 | - auto swap = viewShape[0]; | ||
| 79 | - viewShape[0] = viewShape[1]; | ||
| 80 | - viewShape[1] = swap; | ||
| 81 | - strides[0] = 2; // 2 in shape(k//64 + g, M, 2) | ||
| 82 | - strides[1] = viewShape[0] * 2; // since last dim is contiguous 2 | ||
| 83 | - strides[2] = 1; // last axis of stride with index 2 has velue 1 | ||
| 84 | - } else if (enableTranspose) { // when tensor is transposed, last two dims in strides and viewShape should swap | ||
| 85 | - // dimM the second-to-last dim, dimN the last dim | ||
| 86 | - auto dimM = viewShape.size() - 2; | ||
| 87 | - auto dimN = viewShape.size() - 1; | ||
| 88 | - if (viewShape[dimM] != 1 && viewShape[dimN] != 0) { | ||
| 89 | - auto swap = strides[dimN]; | ||
| 90 | - strides[dimN] = strides[dimM]; | ||
| 91 | - strides[dimM] = swap; | ||
| 92 | - swap = viewShape[dimN]; | ||
| 93 | - viewShape[dimN] = viewShape[dimM]; | ||
| 94 | - viewShape[dimM] = swap; | ||
| 95 | - } | ||
| 96 | } | 114 | } |
| 97 | auto aclFormat = aclFormat::ACL_FORMAT_ND; | 115 | auto aclFormat = aclFormat::ACL_FORMAT_ND; |
| 98 | aclTensor *out = aclCreateTensor(viewShape.data(), viewShape.size(), dataType, strides.data(), 0, aclFormat, | 116 | aclTensor *out = aclCreateTensor(viewShape.data(), viewShape.size(), dataType, strides.data(), 0, aclFormat, |
| @@ -16,7 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | -#include <map> | 19 | +#include <cstdint> |
| 20 | 20 | ||
| 21 | namespace QuantGroupedMatmulInplaceAdd { | 21 | namespace QuantGroupedMatmulInplaceAdd { |
| 22 | constexpr uint32_t X_INDEX = 0; | 22 | constexpr uint32_t X_INDEX = 0; |