# TopK算子返回的全零的Tensor的解决

**1. 系统环境**

硬件环境\(Ascend/GPU/CPU\): GPU

软件环境: MindSpore 版本: 1.10.1

执行模式（静态图/动态图）： 动态图

Python 版本: 3.7.6

操作系统平台: linux

**2. 报错信息**

2.1 问题描述

在使用ops.top\_k算子进行计算时（详见下方用例），会出现计算结果错误。

预期结果

如果正确执行，输出应该类似于如下结果：

```
$ python3 run_topk.py 26756342
```

实际执行结果如下，返回的是一个全零的Tensor：

```
$ python3 run_topk.py 0
```

备注：经过一定数值范围的测试，发现在K值选取1\~128范围之间的返回结果有可能是正确的，或者两个打印模块同时打印输出结果也是正确的，唯独单次打印K值大于128的情况，返回结果异常。

2.2 脚本信息

```
# run_topk.py
import os
os.environ['GLOG_v']='4'
import numpy as np
import mindspore as ms
from mindspore import Tensor, ops, nn


class TopKNet(nn.Cell):
    def __init__(self):
        super().__init__()
        self.top_k = ops.top_k

    def construct(self, x, num):
        x, ids = self.top_k(x, num)
        return ids

np.random.seed(1)
input_x = Tensor(np.random.random((1, 648, 648)), ms.float16)
print (TopKNet()(input_x, 128).sum())
# print (TopKNet()(input_x, 129).sum())
```

直接运行上述用例，得到一个大的整数结果，这是正确场景；

注释第一个打印输出，取消第二个打印输出的注释，也就是选取前129个最大的值；

再次执行案例，得到的结果是0，或者是一个异常值。

**3. 根因分析**

这是因为在mindspore关于topk的cuda代码中，一个核函数在做数据交换的时候，发生了数据类型强转\(float和int\)。导致当index的数值较大时\(7 \* 2388 \* 2388+289\)，会出现精度损失。

**4. 解决方案**

第一个办法，可以将mindspore/ccsrc/plugin/device/gpu/kernel/cuda\_impl/topk\_lib.cuh这个位置下的58行进行修改

修改前

```
T b_tmp = b[i_1];
```

修改后

```
S b_tmp = b[i_1];
```

第二个办法是使用2.0版本的，这个更方便可靠。

