命题:如果有一个n维行优先的数组的shape为 shapeo×shape1×...×shapen−1 ,对于线性索引为 L ,如果其满足 L=index0×stride0+index1×stride1+index2×stride2+...+indexn−1×striden−1 ,对于 index0 ,则有: index0=⌊stride0L⌋ 证明:
假如 index0>⌊stride0L⌋ ,不妨设 index0=⌊stride0L⌋+1 ,则有 index0∗stride0=(⌊stride0L⌋+1)∗stride0>L ,证明如下图:

这和 L=index0×stride0+index1×stride1+index2×stride2+...+indexn−1×striden−1 的前提相矛盾,故假设不成立。
假如 index0<⌊stride0L⌋ ,不妨设 index0=⌊stride0L⌋−1 ,则有 index0∗stride0+index1∗stride1+index2∗stride2+...+indexn−1∗striden−1=(⌊stride0L⌋−1)∗stride0+index1∗stride1+index2∗stride2+...+indexn−1∗striden−1
由于有 (⌊stride0L⌋−1)∗stride0≤L−stride0,故上式有:
(⌊stride0L⌋−1)∗stride0+index1∗stride1+index2∗stride2+...+indexn−1∗striden−1≤L−stride0+index1∗stride1+index2∗stride2+...+indexn−1∗striden−1 假如 index1...indexn−1 都取最大值,那么对于第k个维度而言,
由于 stridek=∏m=k+1n−1shapem ,所以有:
(shapek−1)stridek=(shapek−1)∏m=k+1n−1shapem=∏m=kn−1shapem−∏m=k+1n−1shapem,k≤n−2(shapek−1)stridek=shapen−1−1,k=n−1,注意最后一个维度的stride=1
故将第二个维度(假设数组维度大于2,如果维度为1或者2,那么可以直接验证)及其之后的维度的shape最大值及其stride相乘有下式:
∑k=1n−1(shapek−1)stridek=∑k=1n−2(∏m=kn−1shapem−∏m=k+1n−1shapem)+shapen−1−1=∏m=1n−1shapem−1<stride0 所以 L−stride0+index1∗stride1+index2∗stride2+...+indexn−1∗striden−1<L−stride0+∏m=1n−1shapem−1<L−stride0+stride0=L
亦即: (⌊stride0L⌋−1)∗stride0+index1∗stride1+index2∗stride2+...+indexn−1∗striden−1≤L−stride0+index1∗stride1+index2∗stride2+...+indexn−1∗striden−1<L 这和前提相矛盾,故假设不成立。
所以命题得证。
通过这个命题,我们可以从线性索引求得逻辑索引,首先通过 ⌊stride0L⌋ 求 index0 ,有:
L=⌊stride0L⌋×stride0+index1×stride1+index2×stride2+...+indexn−1×striden−1,
之后,设 offset=L−⌊stride0L⌋×stride0=L%stride0 ,则有:
offset=index1×stride1+index2×stride2+...+indexn−1×striden−1 用同样的方法,我们可以求得 index1、index2、.....indexn−1 。
这在写CUDA算子,如cat算子等的时候特别有用,从tid算得本线程要负责的元素的逻辑索引,从而进行相关拷贝操作。