已合并
FEAT: A5 CTRL寄存器接口补充 #5135
yiming创建于 16 天前
FEAT: A5 CTRL寄存器接口补充 #5135
已合并
共 16 个文件变更+885-0
| @@ -23,6 +23,10 @@ | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 26 | 30 | ||
| 27 | // ==========asc_icache_preload========== | 31 | // ==========asc_icache_preload========== |
| 28 | __aicore__ inline void asc_icache_preload(const void* addr, int64_t prefetch_len) | 32 | __aicore__ inline void asc_icache_preload(const void* addr, int64_t prefetch_len) |
| @@ -53,6 +57,30 @@ __aicore__ inline int64_t asc_get_icache_preload_status() { return asc_get_icach | |||
| 53 | //==============asc_dci=============== | 57 | //==============asc_dci=============== |
| 54 | __aicore__ inline void asc_dci() { asc_dci_impl(); } | 58 | __aicore__ inline void asc_dci() { asc_dci_impl(); } |
| 55 | 59 | ||
| 60 | + | ||
| 61 | +//==============asc_set_scalar_cache_mode=============== | ||
| 62 | +__aicore__ inline void asc_set_scalar_cache_mode(asc_load_l2_cache_mode l2_cache_mode) | ||
| 63 | +{ | ||
毛 | |||
| 64 | + asc_set_scalar_cache_mode_impl(l2_cache_mode); | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +__aicore__ inline void asc_set_scalar_cache_mode(asc_store_l2_cache_mode l2_cache_mode) | ||
| 68 | +{ | ||
| 69 | + asc_set_scalar_cache_mode_impl(l2_cache_mode); | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +//==============asc_get_scalar_load/store_cache_mode=============== | ||
| 73 | +__aicore__ inline asc_load_l2_cache_mode asc_get_scalar_load_cache_mode() | ||
| 74 | +{ | ||
| 75 | + return asc_get_scalar_load_cache_mode_impl(); | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +__aicore__ inline asc_store_l2_cache_mode asc_get_scalar_store_cache_mode() | ||
| 79 | +{ | ||
| 80 | + return asc_get_scalar_store_cache_mode_impl(); | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | + | ||
| 56 | 84 | ||
| 57 | 85 | ||
| 58 | 86 | ||
| @@ -0,0 +1,48 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software; you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/* ! | ||
| 12 | + * \file asc_get_scalar_cache_mode_impl.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + "impl/c_api/instr_impl/npu_arch_3510/cache_ctrl_impl/asc_get_scalar_cache_mode_impl.h is an internal header file and must not be used directly. Functions or variables defined in this file maybe removed in the future. Please use " | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +// Enum underlying values match HW encodings; cast is used as-is (illegal codes are not normalized). | ||
| 29 | +__aicore__ inline asc_load_l2_cache_mode asc_get_scalar_load_cache_mode_impl() | ||
| 30 | +{ | ||
| 31 | + constexpr uint8_t start_bit = 16; // READ mode: CTRL[19:16] | ||
| 32 | + uint8_t cache_bits = static_cast<uint8_t>((get_ctrl() >> start_bit) & 0xF); | ||
| 33 | + return static_cast<asc_load_l2_cache_mode>(cache_bits); | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +__aicore__ inline asc_store_l2_cache_mode asc_get_scalar_store_cache_mode_impl() | ||
| 37 | +{ | ||
| 38 | + constexpr uint8_t start_bit = 20; // WRITE mode: CTRL[23:20] | ||
| 39 | + uint8_t cache_bits = static_cast<uint8_t>((get_ctrl() >> start_bit) & 0xF); | ||
| 40 | + return static_cast<asc_store_l2_cache_mode>(cache_bits); | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + | ||
| @@ -0,0 +1,59 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software; you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/* ! | ||
| 12 | + * \file asc_set_scalar_cache_mode_impl.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + "impl/c_api/instr_impl/npu_arch_3510/cache_ctrl_impl/asc_set_scalar_cache_mode_impl.h is an internal header file and must not be used directly. Functions or variables defined in this file maybe removed in the future. Please use " | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +union ctrl_scalar_cache_bits { | ||
| 29 | + uint64_t value; | ||
| 30 | + struct { | ||
| 31 | + uint64_t reserved0 : 16; | ||
| 32 | + uint64_t scalar_load_cache_mode : 4; | ||
| 33 | + uint64_t scalar_store_cache_mode : 4; | ||
| 34 | + uint64_t reserved1 : 40; | ||
| 35 | + }; | ||
| 36 | +}; | ||
| 37 | + | ||
| 38 | +__aicore__ inline void asc_set_scalar_cache_mode_impl(asc_load_l2_cache_mode l2_cache_mode) | ||
| 39 | +{ | ||
| 40 | + ctrl_scalar_cache_bits ctrl; | ||
| 41 | + ctrl.value = static_cast<uint64_t>(get_ctrl()); | ||
| 42 | + ctrl.scalar_load_cache_mode = static_cast<uint8_t>(l2_cache_mode); | ||
| 43 | + set_ctrl(static_cast<int64_t>(ctrl.value)); | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +__aicore__ inline void asc_set_scalar_cache_mode_impl(asc_store_l2_cache_mode l2_cache_mode) | ||
| 47 | +{ | ||
| 48 | + ctrl_scalar_cache_bits ctrl; | ||
| 49 | + ctrl.value = static_cast<uint64_t>(get_ctrl()); | ||
| 50 | + ctrl.scalar_store_cache_mode = static_cast<uint8_t>(l2_cache_mode); | ||
| 51 | + set_ctrl(static_cast<int64_t>(ctrl.value)); | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | + | ||
| 55 | + | ||
| 56 | + | ||
| 57 | + | ||
| 58 | + | ||
| 59 | + | ||
| @@ -42,6 +42,12 @@ | |||
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | + | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + | ||
| 49 | + | ||
| 50 | + | ||
| 45 | 51 | ||
| 46 | [[deprecated("NOTICE: asc_get_ar_spr is deprecated. " | 52 | [[deprecated("NOTICE: asc_get_ar_spr is deprecated. " |
| 47 | "Please use asc_get_squeeze_status instead.")]] __aicore__ inline int64_t | 53 | "Please use asc_get_squeeze_status instead.")]] __aicore__ inline int64_t |
| @@ -130,6 +136,25 @@ __aicore__ inline int64_t asc_get_status() { return asc_get_status_impl(); } | |||
| 130 | 136 | ||
| 131 | __aicore__ inline int64_t asc_get_sys_virtual_base() { return asc_get_sys_virtual_base_impl(); } | 137 | __aicore__ inline int64_t asc_get_sys_virtual_base() { return asc_get_sys_virtual_base_impl(); } |
| 132 | 138 | ||
| 139 | + | ||
| 140 | +__aicore__ inline void asc_set_saturation_flag(asc_saturation_mode saturation_mode, bool enable_sat) | ||
| 141 | +{ | ||
| 142 | + asc_set_saturation_flag_impl(saturation_mode, enable_sat); | ||
| 143 | +} | ||
| 144 | + | ||
| 145 | +__aicore__ inline bool asc_get_saturation_flag(asc_saturation_mode saturation_mode) | ||
| 146 | +{ | ||
| 147 | + return asc_get_saturation_flag_impl(saturation_mode); | ||
| 148 | +} | ||
| 149 | + | ||
| 150 | +__aicore__ inline void asc_set_saturation_strategy(asc_override_strategy strategy) | ||
| 151 | +{ | ||
| 152 | + asc_set_saturation_strategy_impl(strategy); | ||
| 153 | +} | ||
| 154 | + | ||
| 155 | +__aicore__ inline asc_override_strategy asc_get_saturation_strategy() { return asc_get_saturation_strategy_impl(); } | ||
| 156 | + | ||
| 157 | + | ||
| 133 | 158 | ||
| 134 | 159 | ||
| 135 | 160 | ||
| @@ -0,0 +1,41 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file asc_get_saturation_flag_impl.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + "impl/c_api/instr_impl/npu_arch_3510/sys_var_impl/asc_get_saturation_flag_impl.h is an internal header file and must not be used directly. Functions or variables defined in this file maybe removed in the future. Please use " | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +__aicore__ inline bool asc_get_saturation_flag_impl(asc_saturation_mode saturation_mode) | ||
| 29 | +{ | ||
| 30 | + // Enum underlying values are CTRL bit indices. INT: 1=sat; FLOAT/FLOAT8/CAST: 0=sat. | ||
| 31 | + const uint8_t bit = static_cast<uint8_t>(saturation_mode); | ||
| 32 | + const bool is_bit_set = ((get_ctrl() >> bit) & 1) != 0; | ||
| 33 | + return (saturation_mode == asc_saturation_mode::INT) ? is_bit_set : !is_bit_set; | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + | ||
| 41 | + | ||
| @@ -0,0 +1,40 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file asc_get_saturation_strategy_impl.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + "impl/c_api/instr_impl/npu_arch_3510/sys_var_impl/asc_get_saturation_strategy_impl.h is an internal header file and must not be used directly. Functions or variables defined in this file maybe removed in the future. Please use " | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +__aicore__ inline asc_override_strategy asc_get_saturation_strategy_impl() | ||
| 29 | +{ | ||
| 30 | + // CTRL[60]: 0 => USE_API, 1 => USE_GLOBAL. Aligns with AscendC::GetSaturationStrategy. | ||
| 31 | + int64_t value = (get_ctrl() >> 60) & 1; | ||
| 32 | + return value == 0 ? asc_override_strategy::USE_API : asc_override_strategy::USE_GLOBAL; | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + | ||
| @@ -0,0 +1,41 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file asc_set_saturation_flag_impl.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + "impl/c_api/instr_impl/npu_arch_3510/sys_var_impl/asc_set_saturation_flag_impl.h is an internal header file and must not be used directly. Functions or variables defined in this file maybe removed in the future. Please use " | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +__aicore__ inline void asc_set_saturation_flag_impl(asc_saturation_mode saturation_mode, bool enable_sat) | ||
| 29 | +{ | ||
| 30 | + // Enum underlying values are CTRL bit indices. INT: 1=sat; FLOAT/FLOAT8/CAST: 0=sat. | ||
| 31 | + const int64_t bit = static_cast<int64_t>(saturation_mode); | ||
| 32 | + const bool is_bit_set = (saturation_mode == asc_saturation_mode::INT) ? enable_sat : !enable_sat; | ||
| 33 | + set_ctrl(is_bit_set ? sbitset1(get_ctrl(), bit) : sbitset0(get_ctrl(), bit)); | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + | ||
| 41 | + | ||
| @@ -0,0 +1,40 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/*! | ||
| 12 | + * \file asc_set_saturation_strategy_impl.h | ||
| 13 | + * \brief | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + "impl/c_api/instr_impl/npu_arch_3510/sys_var_impl/asc_set_saturation_strategy_impl.h is an internal header file and must not be used directly. Functions or variables defined in this file maybe removed in the future. Please use " | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +__aicore__ inline void asc_set_saturation_strategy_impl(asc_override_strategy strategy) | ||
| 29 | +{ | ||
| 30 | + // CTRL[60]: 0 => USE_API, 1 => USE_GLOBAL. Aligns with AscendC::SetSaturationStrategy. | ||
| 31 | + int64_t ctrl_value = get_ctrl(); | ||
| 32 | + set_ctrl(strategy == asc_override_strategy::USE_API ? sbitset0(ctrl_value, 60) : sbitset1(ctrl_value, 60)); | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + | ||
| @@ -53,6 +53,14 @@ __aicore__ inline void asc_datacache_preload(__gm__ uint64_t* address, int64_t o | |||
| 53 | 53 | ||
| 54 | __aicore__ inline void asc_dci(); | 54 | __aicore__ inline void asc_dci(); |
| 55 | 55 | ||
| 56 | +__aicore__ inline void asc_set_scalar_cache_mode(asc_load_l2_cache_mode l2_cache_mode); | ||
| 57 | + | ||
| 58 | +__aicore__ inline void asc_set_scalar_cache_mode(asc_store_l2_cache_mode l2_cache_mode); | ||
| 59 | + | ||
| 60 | +__aicore__ inline asc_load_l2_cache_mode asc_get_scalar_load_cache_mode(); | ||
| 61 | + | ||
| 62 | +__aicore__ inline asc_store_l2_cache_mode asc_get_scalar_store_cache_mode(); | ||
| 63 | + | ||
| 56 | 64 | ||
| 57 | 65 | ||
| 58 | 66 | ||
| @@ -36,6 +36,18 @@ enum class asc_hf32_round_mode : uint8_t { | |||
| 36 | NEAREST_ZERO = NEAREST_AWAY // Compatible with the old name; the actual behavior is equivalent to NEAREST_AWAY. | 36 | NEAREST_ZERO = NEAREST_AWAY // Compatible with the old name; the actual behavior is equivalent to NEAREST_AWAY. |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | +enum class asc_saturation_mode : uint8_t { | ||
| 40 | + FLOAT = 48, // 浮点数计算和浮点数精度转换饱和模式 | ||
| 41 | + FLOAT8 = 50, // 浮点数精度转换时NaN饱和模式 | ||
| 42 | + INT = 53, // 整数计算指令饱和模式 | ||
| 43 | + CAST = 59 // 浮点数转整数或整数转整数精度转换饱和模式 | ||
| 44 | +}; | ||
| 45 | + | ||
| 46 | +enum class asc_override_strategy : uint8_t { | ||
| 47 | + USE_API = 0, // 饱和模式为单指令设置饱和 | ||
| 48 | + USE_GLOBAL = 1 // 饱和模式为全局设置饱和 | ||
| 49 | +}; | ||
| 50 | + | ||
| 39 | enum class asc_position_mode { EVEN = 0, ODD }; | 51 | enum class asc_position_mode { EVEN = 0, ODD }; |
| 40 | 52 | ||
| 41 | constexpr std::integral_constant<asc_position_mode, asc_position_mode::EVEN> ASC_POSITION_EVEN; | 53 | constexpr std::integral_constant<asc_position_mode, asc_position_mode::EVEN> ASC_POSITION_EVEN; |
| @@ -37,6 +37,11 @@ __aicore__ inline int64_t asc_get_squeeze_status(); | |||
| 37 | "Please use asc_get_squeeze_status instead.")]] | 37 | "Please use asc_get_squeeze_status instead.")]] |
| 38 | __aicore__ inline int64_t asc_get_ar_spr(); | 38 | __aicore__ inline int64_t asc_get_ar_spr(); |
| 39 | 39 | ||
| 40 | +__aicore__ inline void asc_set_saturation_flag(asc_saturation_mode saturation_mode, bool enable_sat); | ||
| 41 | +__aicore__ inline bool asc_get_saturation_flag(asc_saturation_mode saturation_mode); | ||
| 42 | +__aicore__ inline void asc_set_saturation_strategy(asc_override_strategy strategy); | ||
| 43 | +__aicore__ inline asc_override_strategy asc_get_saturation_strategy(); | ||
| 44 | + | ||
| 40 | 45 | ||
| 41 | 46 | ||
| 42 | 47 | ||
| @@ -19,7 +19,10 @@ static void test_host_c_api_cache_ctrl_0() | |||
| 19 | using ::asc_dcci_entire_ub; | 19 | using ::asc_dcci_entire_ub; |
| 20 | using ::asc_dci; | 20 | using ::asc_dci; |
| 21 | using ::asc_get_icache_preload_status; | 21 | using ::asc_get_icache_preload_status; |
| 22 | + using ::asc_get_scalar_load_cache_mode; | ||
| 23 | + using ::asc_get_scalar_store_cache_mode; | ||
| 22 | using ::asc_icache_preload; | 24 | using ::asc_icache_preload; |
| 25 | + using ::asc_set_scalar_cache_mode; | ||
| 23 | using ::asc_ub_dcci_single; | 26 | using ::asc_ub_dcci_single; |
| 24 | using __asc_aicore::asc_dcci_single; | 27 | using __asc_aicore::asc_dcci_single; |
| 25 | } | 28 | } |
| @@ -23,6 +23,8 @@ static void test_host_c_api_sys_var_0() | |||
| 23 | using ::asc_get_phy_buf_addr; | 23 | using ::asc_get_phy_buf_addr; |
| 24 | using ::asc_get_phy_stack_base; | 24 | using ::asc_get_phy_stack_base; |
| 25 | using ::asc_get_program_counter; | 25 | using ::asc_get_program_counter; |
| 26 | + using ::asc_get_saturation_flag; | ||
| 27 | + using ::asc_get_saturation_strategy; | ||
| 26 | using ::asc_get_smmu_tag_version; | 28 | using ::asc_get_smmu_tag_version; |
| 27 | using ::asc_get_squeeze_status; | 29 | using ::asc_get_squeeze_status; |
| 28 | using ::asc_get_status; | 30 | using ::asc_get_status; |
| @@ -33,4 +35,6 @@ static void test_host_c_api_sys_var_0() | |||
| 33 | using ::asc_get_vf_len; | 35 | using ::asc_get_vf_len; |
| 34 | using ::asc_set_ctrl; | 36 | using ::asc_set_ctrl; |
| 35 | using ::asc_set_ffts_base_addr; | 37 | using ::asc_set_ffts_base_addr; |
| 38 | + using ::asc_set_saturation_flag; | ||
| 39 | + using ::asc_set_saturation_strategy; | ||
| 36 | } | 40 | } |
| @@ -0,0 +1,348 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software; you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +class TestScalarCacheModeCAPI : public testing::Test { | ||
| 17 | +protected: | ||
| 18 | + void SetUp() {} | ||
| 19 | + void TearDown() {} | ||
| 20 | +}; | ||
| 21 | + | ||
| 22 | +namespace { | ||
| 23 | +int64_t g_ctrlValue = 0; | ||
| 24 | + | ||
| 25 | +int64_t get_ctrl_stub() { return g_ctrlValue; } | ||
| 26 | + | ||
| 27 | +void set_ctrl_stub(uint64_t config) { g_ctrlValue = static_cast<int64_t>(config); } | ||
| 28 | +} // namespace | ||
| 29 | + | ||
| 30 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_load_cache_mode_normal_first_victim) | ||
| 31 | +{ | ||
| 32 | + g_ctrlValue = 0; | ||
| 33 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 34 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 35 | + | ||
| 36 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NORMAL_FIRST_VICTIM); | ||
| 37 | + | ||
| 38 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 16) & 0xF); | ||
| 39 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_load_l2_cache_mode::NORMAL_FIRST_VICTIM)); | ||
| 40 | + GlobalMockObject::verify(); | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_load_cache_mode_normal_last_victim) | ||
| 44 | +{ | ||
| 45 | + g_ctrlValue = 0; | ||
| 46 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 47 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 48 | + | ||
| 49 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NORMAL_LAST_VICTIM); | ||
| 50 | + | ||
| 51 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 16) & 0xF); | ||
| 52 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_load_l2_cache_mode::NORMAL_LAST_VICTIM)); | ||
| 53 | + GlobalMockObject::verify(); | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_load_cache_mode_normal_persistent) | ||
| 57 | +{ | ||
| 58 | + g_ctrlValue = 0; | ||
| 59 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 60 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 61 | + | ||
| 62 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 63 | + | ||
| 64 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 16) & 0xF); | ||
| 65 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_load_l2_cache_mode::NORMAL_PERSISTENT)); | ||
| 66 | + GlobalMockObject::verify(); | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_load_cache_mode_notalloc_keep) | ||
| 70 | +{ | ||
| 71 | + g_ctrlValue = 0; | ||
| 72 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 73 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 74 | + | ||
| 75 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NOTALLOC_KEEP); | ||
| 76 | + | ||
| 77 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 16) & 0xF); | ||
| 78 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_load_l2_cache_mode::NOTALLOC_KEEP)); | ||
| 79 | + GlobalMockObject::verify(); | ||
| 80 | +} | ||
| 81 | + | ||
| 82 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_load_cache_mode_notalloc_clean) | ||
| 83 | +{ | ||
| 84 | + g_ctrlValue = 0; | ||
| 85 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 86 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 87 | + | ||
| 88 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NOTALLOC_CLEAN); | ||
| 89 | + | ||
| 90 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 16) & 0xF); | ||
| 91 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_load_l2_cache_mode::NOTALLOC_CLEAN)); | ||
| 92 | + GlobalMockObject::verify(); | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_load_cache_mode_notalloc_drop) | ||
| 96 | +{ | ||
| 97 | + g_ctrlValue = 0; | ||
| 98 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 99 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 100 | + | ||
| 101 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NOTALLOC_DROP); | ||
| 102 | + | ||
| 103 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 16) & 0xF); | ||
| 104 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_load_l2_cache_mode::NOTALLOC_DROP)); | ||
| 105 | + GlobalMockObject::verify(); | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_load_cache_mode_preserve_other_bits) | ||
| 109 | +{ | ||
| 110 | + g_ctrlValue = static_cast<int64_t>(0xDEAD) << 32; | ||
| 111 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 112 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 113 | + | ||
| 114 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 115 | + | ||
| 116 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 16) & 0xF); | ||
| 117 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_load_l2_cache_mode::NORMAL_PERSISTENT)); | ||
| 118 | + int64_t preservedBits = g_ctrlValue & (~(0xFLL << 16)); | ||
| 119 | + EXPECT_EQ(preservedBits, static_cast<int64_t>(0xDEAD) << 32); | ||
| 120 | + GlobalMockObject::verify(); | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_store_cache_mode_normal_first_victim) | ||
| 124 | +{ | ||
| 125 | + g_ctrlValue = 0; | ||
| 126 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 127 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 128 | + | ||
| 129 | + asc_set_scalar_cache_mode(asc_store_l2_cache_mode::NORMAL_FIRST_VICTIM); | ||
| 130 | + | ||
| 131 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 20) & 0xF); | ||
| 132 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_store_l2_cache_mode::NORMAL_FIRST_VICTIM)); | ||
| 133 | + GlobalMockObject::verify(); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_store_cache_mode_normal_last_victim) | ||
| 137 | +{ | ||
| 138 | + g_ctrlValue = 0; | ||
| 139 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 140 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 141 | + | ||
| 142 | + asc_set_scalar_cache_mode(asc_store_l2_cache_mode::NORMAL_LAST_VICTIM); | ||
| 143 | + | ||
| 144 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 20) & 0xF); | ||
| 145 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_store_l2_cache_mode::NORMAL_LAST_VICTIM)); | ||
| 146 | + GlobalMockObject::verify(); | ||
| 147 | +} | ||
| 148 | + | ||
| 149 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_store_cache_mode_normal_persistent) | ||
| 150 | +{ | ||
| 151 | + g_ctrlValue = 0; | ||
| 152 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 153 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 154 | + | ||
| 155 | + asc_set_scalar_cache_mode(asc_store_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 156 | + | ||
| 157 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 20) & 0xF); | ||
| 158 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_store_l2_cache_mode::NORMAL_PERSISTENT)); | ||
| 159 | + GlobalMockObject::verify(); | ||
| 160 | +} | ||
| 161 | + | ||
| 162 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_store_cache_mode_notalloc_clean) | ||
| 163 | +{ | ||
| 164 | + g_ctrlValue = 0; | ||
| 165 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 166 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 167 | + | ||
| 168 | + asc_set_scalar_cache_mode(asc_store_l2_cache_mode::NOTALLOC_CLEAN); | ||
| 169 | + | ||
| 170 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 20) & 0xF); | ||
| 171 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_store_l2_cache_mode::NOTALLOC_CLEAN)); | ||
| 172 | + GlobalMockObject::verify(); | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_scalar_store_cache_mode_preserve_other_bits) | ||
| 176 | +{ | ||
| 177 | + g_ctrlValue = static_cast<int64_t>(0xDEAD) << 32; | ||
| 178 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 179 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 180 | + | ||
| 181 | + asc_set_scalar_cache_mode(asc_store_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 182 | + | ||
| 183 | + uint8_t cacheBits = static_cast<uint8_t>((g_ctrlValue >> 20) & 0xF); | ||
| 184 | + EXPECT_EQ(cacheBits, static_cast<uint8_t>(asc_store_l2_cache_mode::NORMAL_PERSISTENT)); | ||
| 185 | + int64_t preservedBits = g_ctrlValue & (~(0xFLL << 20)); | ||
| 186 | + EXPECT_EQ(preservedBits, static_cast<int64_t>(0xDEAD) << 32); | ||
| 187 | + GlobalMockObject::verify(); | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_load_cache_mode_normal_first_victim) | ||
| 191 | +{ | ||
| 192 | + g_ctrlValue = 0; | ||
| 193 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 194 | + | ||
| 195 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 196 | + EXPECT_EQ(mode, asc_load_l2_cache_mode::NORMAL_FIRST_VICTIM); | ||
| 197 | + GlobalMockObject::verify(); | ||
| 198 | +} | ||
| 199 | + | ||
| 200 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_load_cache_mode_normal_last_victim) | ||
| 201 | +{ | ||
| 202 | + g_ctrlValue = static_cast<int64_t>(1) << 16; | ||
| 203 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 204 | + | ||
| 205 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 206 | + EXPECT_EQ(mode, asc_load_l2_cache_mode::NORMAL_LAST_VICTIM); | ||
| 207 | + GlobalMockObject::verify(); | ||
| 208 | +} | ||
| 209 | + | ||
| 210 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_load_cache_mode_normal_persistent) | ||
| 211 | +{ | ||
| 212 | + g_ctrlValue = static_cast<int64_t>(2) << 16; | ||
| 213 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 214 | + | ||
| 215 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 216 | + EXPECT_EQ(mode, asc_load_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 217 | + GlobalMockObject::verify(); | ||
| 218 | +} | ||
| 219 | + | ||
| 220 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_load_cache_mode_notalloc_keep) | ||
| 221 | +{ | ||
| 222 | + g_ctrlValue = static_cast<int64_t>(4) << 16; | ||
| 223 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 224 | + | ||
| 225 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 226 | + EXPECT_EQ(mode, asc_load_l2_cache_mode::NOTALLOC_KEEP); | ||
| 227 | + GlobalMockObject::verify(); | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_load_cache_mode_notalloc_clean) | ||
| 231 | +{ | ||
| 232 | + g_ctrlValue = static_cast<int64_t>(5) << 16; | ||
| 233 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 234 | + | ||
| 235 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 236 | + EXPECT_EQ(mode, asc_load_l2_cache_mode::NOTALLOC_CLEAN); | ||
| 237 | + GlobalMockObject::verify(); | ||
| 238 | +} | ||
| 239 | + | ||
| 240 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_load_cache_mode_notalloc_drop) | ||
| 241 | +{ | ||
| 242 | + g_ctrlValue = static_cast<int64_t>(6) << 16; | ||
| 243 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 244 | + | ||
| 245 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 246 | + EXPECT_EQ(mode, asc_load_l2_cache_mode::NOTALLOC_DROP); | ||
| 247 | + GlobalMockObject::verify(); | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_load_cache_mode_passthrough_illegal_encoding) | ||
| 251 | +{ | ||
| 252 | + g_ctrlValue = static_cast<int64_t>(3) << 16; | ||
| 253 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 254 | + | ||
| 255 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 256 | + EXPECT_EQ(mode, static_cast<asc_load_l2_cache_mode>(3)); | ||
| 257 | + GlobalMockObject::verify(); | ||
| 258 | +} | ||
| 259 | + | ||
| 260 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_store_cache_mode_normal_first_victim) | ||
| 261 | +{ | ||
| 262 | + g_ctrlValue = 0; | ||
| 263 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 264 | + | ||
| 265 | + auto mode = asc_get_scalar_store_cache_mode(); | ||
| 266 | + EXPECT_EQ(mode, asc_store_l2_cache_mode::NORMAL_FIRST_VICTIM); | ||
| 267 | + GlobalMockObject::verify(); | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_store_cache_mode_normal_last_victim) | ||
| 271 | +{ | ||
| 272 | + g_ctrlValue = static_cast<int64_t>(1) << 20; | ||
| 273 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 274 | + | ||
| 275 | + auto mode = asc_get_scalar_store_cache_mode(); | ||
| 276 | + EXPECT_EQ(mode, asc_store_l2_cache_mode::NORMAL_LAST_VICTIM); | ||
| 277 | + GlobalMockObject::verify(); | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_store_cache_mode_normal_persistent) | ||
| 281 | +{ | ||
| 282 | + g_ctrlValue = static_cast<int64_t>(2) << 20; | ||
| 283 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 284 | + | ||
| 285 | + auto mode = asc_get_scalar_store_cache_mode(); | ||
| 286 | + EXPECT_EQ(mode, asc_store_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 287 | + GlobalMockObject::verify(); | ||
| 288 | +} | ||
| 289 | + | ||
| 290 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_store_cache_mode_notalloc_clean) | ||
| 291 | +{ | ||
| 292 | + g_ctrlValue = static_cast<int64_t>(4) << 20; | ||
| 293 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 294 | + | ||
| 295 | + auto mode = asc_get_scalar_store_cache_mode(); | ||
| 296 | + EXPECT_EQ(mode, asc_store_l2_cache_mode::NOTALLOC_CLEAN); | ||
| 297 | + GlobalMockObject::verify(); | ||
| 298 | +} | ||
| 299 | + | ||
| 300 | +TEST_F(TestScalarCacheModeCAPI, c_api_get_scalar_store_cache_mode_passthrough_illegal_encoding) | ||
| 301 | +{ | ||
| 302 | + g_ctrlValue = static_cast<int64_t>(3) << 20; | ||
| 303 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(1).will(invoke(get_ctrl_stub)); | ||
| 304 | + | ||
| 305 | + auto mode = asc_get_scalar_store_cache_mode(); | ||
| 306 | + EXPECT_EQ(mode, static_cast<asc_store_l2_cache_mode>(3)); | ||
| 307 | + GlobalMockObject::verify(); | ||
| 308 | +} | ||
| 309 | + | ||
| 310 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_and_get_scalar_load_cache_mode_roundtrip) | ||
| 311 | +{ | ||
| 312 | + g_ctrlValue = 0; | ||
| 313 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(2).will(invoke(get_ctrl_stub)); | ||
| 314 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 315 | + | ||
| 316 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NOTALLOC_DROP); | ||
| 317 | + auto mode = asc_get_scalar_load_cache_mode(); | ||
| 318 | + EXPECT_EQ(mode, asc_load_l2_cache_mode::NOTALLOC_DROP); | ||
| 319 | + GlobalMockObject::verify(); | ||
| 320 | +} | ||
| 321 | + | ||
| 322 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_and_get_scalar_store_cache_mode_roundtrip) | ||
| 323 | +{ | ||
| 324 | + g_ctrlValue = 0; | ||
| 325 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(2).will(invoke(get_ctrl_stub)); | ||
| 326 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(1).will(invoke(set_ctrl_stub)); | ||
| 327 | + | ||
| 328 | + asc_set_scalar_cache_mode(asc_store_l2_cache_mode::NOTALLOC_CLEAN); | ||
| 329 | + auto mode = asc_get_scalar_store_cache_mode(); | ||
| 330 | + EXPECT_EQ(mode, asc_store_l2_cache_mode::NOTALLOC_CLEAN); | ||
| 331 | + GlobalMockObject::verify(); | ||
| 332 | +} | ||
| 333 | + | ||
| 334 | +TEST_F(TestScalarCacheModeCAPI, c_api_set_load_and_store_cache_mode_independent) | ||
| 335 | +{ | ||
| 336 | + g_ctrlValue = 0; | ||
| 337 | + MOCKER_CPP(get_ctrl, int64_t(void)).times(4).will(invoke(get_ctrl_stub)); | ||
| 338 | + MOCKER_CPP(set_ctrl, void(uint64_t)).times(2).will(invoke(set_ctrl_stub)); | ||
| 339 | + | ||
| 340 | + asc_set_scalar_cache_mode(asc_load_l2_cache_mode::NORMAL_LAST_VICTIM); | ||
| 341 | + asc_set_scalar_cache_mode(asc_store_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 342 | + | ||
| 343 | + auto loadMode = asc_get_scalar_load_cache_mode(); | ||
| 344 | + auto storeMode = asc_get_scalar_store_cache_mode(); | ||
| 345 | + EXPECT_EQ(loadMode, asc_load_l2_cache_mode::NORMAL_LAST_VICTIM); | ||
| 346 | + EXPECT_EQ(storeMode, asc_store_l2_cache_mode::NORMAL_PERSISTENT); | ||
| 347 | + GlobalMockObject::verify(); | ||
| 348 | +} | ||
| @@ -0,0 +1,84 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +class TestSaturationFlagCAPI : public testing::Test { | ||
| 17 | +protected: | ||
| 18 | + void SetUp() {} | ||
| 19 | + void TearDown() { GlobalMockObject::verify(); } | ||
| 20 | +}; | ||
| 21 | + | ||
| 22 | +namespace { | ||
| 23 | +int64_t g_ctrlValue = 0; | ||
| 24 | + | ||
| 25 | +int64_t get_ctrl_stub() { return g_ctrlValue; } | ||
| 26 | + | ||
| 27 | +void set_ctrl_stub(uint64_t config) { g_ctrlValue = static_cast<int64_t>(config); } | ||
| 28 | + | ||
| 29 | +uint64_t sbitset0_stub(uint64_t bits, int64_t idx) { return bits & ~(static_cast<uint64_t>(1) << idx); } | ||
| 30 | + | ||
| 31 | +uint64_t sbitset1_stub(uint64_t bits, int64_t idx) { return bits | (static_cast<uint64_t>(1) << idx); } | ||
| 32 | + | ||
| 33 | +void MockCtrlRw() | ||
| 34 | +{ | ||
| 35 | + MOCKER_CPP(get_ctrl, int64_t(void)).stubs().will(invoke(get_ctrl_stub)); | ||
| 36 | + MOCKER_CPP(set_ctrl, void(uint64_t)).stubs().will(invoke(set_ctrl_stub)); | ||
| 37 | + MOCKER_CPP(sbitset0, uint64_t(uint64_t, int64_t)).stubs().will(invoke(sbitset0_stub)); | ||
| 38 | + MOCKER_CPP(sbitset1, uint64_t(uint64_t, int64_t)).stubs().will(invoke(sbitset1_stub)); | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +int64_t GetCtrlBit(int8_t bit) { return (g_ctrlValue >> bit) & 1; } | ||
| 42 | + | ||
| 43 | +void CheckSaturationFlag(asc_saturation_mode mode, int8_t ctrlBit, int64_t enabledValue, int64_t disabledValue) | ||
| 44 | +{ | ||
| 45 | + g_ctrlValue = 0; | ||
| 46 | + MockCtrlRw(); | ||
| 47 | + | ||
| 48 | + asc_set_saturation_flag(mode, true); | ||
| 49 | + EXPECT_EQ(asc_get_saturation_flag(mode), true); | ||
| 50 | + EXPECT_EQ(GetCtrlBit(ctrlBit), enabledValue); | ||
| 51 | + | ||
| 52 | + asc_set_saturation_flag(mode, false); | ||
| 53 | + EXPECT_EQ(asc_get_saturation_flag(mode), false); | ||
| 54 | + EXPECT_EQ(GetCtrlBit(ctrlBit), disabledValue); | ||
| 55 | + | ||
| 56 | + asc_set_saturation_flag(mode, true); | ||
| 57 | + EXPECT_EQ(asc_get_saturation_flag(mode), true); | ||
| 58 | + EXPECT_EQ(GetCtrlBit(ctrlBit), enabledValue); | ||
| 59 | +} | ||
| 60 | +} // namespace | ||
| 61 | + | ||
| 62 | +TEST_F(TestSaturationFlagCAPI, FloatMode) | ||
| 63 | +{ | ||
| 64 | + // FLOAT: CTRL[48], 0=sat, 1=no sat | ||
| 65 | + CheckSaturationFlag(asc_saturation_mode::FLOAT, 48, 0, 1); | ||
| 66 | +} | ||
| 67 | + | ||
| 68 | +TEST_F(TestSaturationFlagCAPI, Float8Mode) | ||
| 69 | +{ | ||
| 70 | + // FLOAT8: CTRL[50], 0=sat, 1=no sat | ||
| 71 | + CheckSaturationFlag(asc_saturation_mode::FLOAT8, 50, 0, 1); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +TEST_F(TestSaturationFlagCAPI, IntMode) | ||
| 75 | +{ | ||
| 76 | + // INT: CTRL[53], 1=sat, 0=truncation | ||
| 77 | + CheckSaturationFlag(asc_saturation_mode::INT, 53, 1, 0); | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +TEST_F(TestSaturationFlagCAPI, CastMode) | ||
| 81 | +{ | ||
| 82 | + // CAST: CTRL[59], 0=sat, 1=truncation | ||
| 83 | + CheckSaturationFlag(asc_saturation_mode::CAST, 59, 0, 1); | ||
| 84 | +} | ||
| @@ -0,0 +1,99 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +class TestSaturationStrategyCAPI : public testing::Test { | ||
| 17 | +protected: | ||
| 18 | + void SetUp() {} | ||
| 19 | + void TearDown() { GlobalMockObject::verify(); } | ||
| 20 | +}; | ||
| 21 | + | ||
| 22 | +namespace { | ||
| 23 | +int64_t g_ctrlValue = 0; | ||
| 24 | + | ||
| 25 | +int64_t get_ctrl_stub() { return g_ctrlValue; } | ||
| 26 | + | ||
| 27 | +void set_ctrl_stub(uint64_t config) { g_ctrlValue = static_cast<int64_t>(config); } | ||
| 28 | + | ||
| 29 | +uint64_t sbitset0_stub(uint64_t bits, int64_t idx) { return bits & ~(static_cast<uint64_t>(1) << idx); } | ||
| 30 | + | ||
| 31 | +uint64_t sbitset1_stub(uint64_t bits, int64_t idx) { return bits | (static_cast<uint64_t>(1) << idx); } | ||
| 32 | + | ||
| 33 | +void MockCtrlRw() | ||
| 34 | +{ | ||
| 35 | + MOCKER_CPP(get_ctrl, int64_t(void)).stubs().will(invoke(get_ctrl_stub)); | ||
| 36 | + MOCKER_CPP(set_ctrl, void(uint64_t)).stubs().will(invoke(set_ctrl_stub)); | ||
| 37 | + MOCKER_CPP(sbitset0, uint64_t(uint64_t, int64_t)).stubs().will(invoke(sbitset0_stub)); | ||
| 38 | + MOCKER_CPP(sbitset1, uint64_t(uint64_t, int64_t)).stubs().will(invoke(sbitset1_stub)); | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +int64_t GetCtrlBit(int8_t bit) { return (g_ctrlValue >> bit) & 1; } | ||
| 42 | +} // namespace | ||
| 43 | + | ||
| 44 | +TEST_F(TestSaturationStrategyCAPI, UseApi) | ||
| 45 | +{ | ||
| 46 | + // USE_API: CTRL[60]=0 | ||
| 47 | + g_ctrlValue = 0; | ||
| 48 | + MockCtrlRw(); | ||
| 49 | + | ||
| 50 | + asc_set_saturation_strategy(asc_override_strategy::USE_API); | ||
| 51 | + EXPECT_EQ(asc_get_saturation_strategy(), asc_override_strategy::USE_API); | ||
| 52 | + EXPECT_EQ(GetCtrlBit(60), 0); | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +TEST_F(TestSaturationStrategyCAPI, UseGlobal) | ||
| 56 | +{ | ||
| 57 | + // USE_GLOBAL: CTRL[60]=1 | ||
| 58 | + g_ctrlValue = 0; | ||
| 59 | + MockCtrlRw(); | ||
| 60 | + | ||
| 61 | + asc_set_saturation_strategy(asc_override_strategy::USE_GLOBAL); | ||
| 62 | + EXPECT_EQ(asc_get_saturation_strategy(), asc_override_strategy::USE_GLOBAL); | ||
| 63 | + EXPECT_EQ(GetCtrlBit(60), 1); | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +TEST_F(TestSaturationStrategyCAPI, RoundTrip) | ||
| 67 | +{ | ||
| 68 | + g_ctrlValue = 0; | ||
| 69 | + MockCtrlRw(); | ||
| 70 | + | ||
| 71 | + asc_set_saturation_strategy(asc_override_strategy::USE_API); | ||
| 72 | + EXPECT_EQ(asc_get_saturation_strategy(), asc_override_strategy::USE_API); | ||
| 73 | + EXPECT_EQ(GetCtrlBit(60), 0); | ||
| 74 | + | ||
| 75 | + asc_set_saturation_strategy(asc_override_strategy::USE_GLOBAL); | ||
| 76 | + EXPECT_EQ(asc_get_saturation_strategy(), asc_override_strategy::USE_GLOBAL); | ||
| 77 | + EXPECT_EQ(GetCtrlBit(60), 1); | ||
| 78 | + | ||
| 79 | + asc_set_saturation_strategy(asc_override_strategy::USE_API); | ||
| 80 | + EXPECT_EQ(asc_get_saturation_strategy(), asc_override_strategy::USE_API); | ||
| 81 | + EXPECT_EQ(GetCtrlBit(60), 0); | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +TEST_F(TestSaturationStrategyCAPI, PreserveOtherBits) | ||
| 85 | +{ | ||
| 86 | + // Pre-set CTRL[48], ensure strategy only touches bit60. | ||
| 87 | + g_ctrlValue = static_cast<int64_t>(1) << 48; | ||
| 88 | + MockCtrlRw(); | ||
| 89 | + | ||
| 90 | + asc_set_saturation_strategy(asc_override_strategy::USE_GLOBAL); | ||
| 91 | + EXPECT_EQ(asc_get_saturation_strategy(), asc_override_strategy::USE_GLOBAL); | ||
| 92 | + EXPECT_EQ(GetCtrlBit(60), 1); | ||
| 93 | + EXPECT_EQ(GetCtrlBit(48), 1); | ||
| 94 | + | ||
| 95 | + asc_set_saturation_strategy(asc_override_strategy::USE_API); | ||
| 96 | + EXPECT_EQ(asc_get_saturation_strategy(), asc_override_strategy::USE_API); | ||
| 97 | + EXPECT_EQ(GetCtrlBit(60), 0); | ||
| 98 | + EXPECT_EQ(GetCtrlBit(48), 1); | ||
| 99 | +} | ||
这里调用impl函数的部分用版本宏进行隔离