Repository: taichi-dev/taichi (language: python)

Issue:
Get `tmp2 already exists` with Vulkan backend
<!-- We've collected some common issue solutions in https://docs.taichi-lang.org/docs/install. Make sure you've check them out first. Hopefully they could address your problem. -->

**Describe the bug**
As title.

**To Reproduce**
Please post a **minimal sample code** to reproduce the bug.
The developer team will put a higher priority on bugs that can be reproduced within 20 lines of code. If you want a prompt reply, please keep the sample code **short** and **representative**.

```py
import taichi as ti
import taichi.math as tm

ti.init(arch=ti.vulkan)

Vec2Array = ti.types.ndarray(dtype=tm.vec2, field_dim=1)
Vec3Array = ti.types.ndarray(dtype=tm.vec3, field_dim=1)
ScalarArray = ti.types.ndarray(dtype=ti.f32, field_dim=1)
IntArray = ti.types.ndarray(dtype=ti.i32, field_dim=1)


@ti.func
def closest_collision_one_ee(
    verts, dt, pos: Vec3Array, vel: Vec3Array, proximity: ti.f32
):
    return 1, 0.0, ti.Vector([0.0, 0.0]), ti.Vector([0.0, 0.0, 0.0])


@ti.kernel
def closest_collision_all_ee(
    is_collided: IntArray,
    collision_t: ScalarArray,
    collision_w: Vec2Array,
    collision_normal: Vec3Array,
    dt: ti.f32,
    pos: Vec3Array,
    vel: Vec3Array,
    edge: IntArray,
    proximity: ti.f32,
):
    N = pos.shape[0]
    M = edge.shape[0] // 2
    for k in range(M * M):
        i = k // M
        j = k % M
        verts = [edge[2 * i + 0], edge[2 * i + 1], edge[2 * j + 0], edge[2 * j + 1]]

        (
            is_collided_temp,
            collision_t[k],
            collision_w[k],
            collision_normal[k],
        ) = closest_collision_one_ee(verts, dt, pos, vel, proximity)
        if is_collided_temp == 1 and is_collided[k] == 0:
            is_collided[k] = 1


N = 2
M = N - 1

pos = ti.Vector.ndarray(3, dtype=ti.f32, shape=N)
pos[0] = ti.Vector([0.0] * 3)
pos[1] = ti.Vector([1.1] * 3)

vel = ti.Vector.ndarray(3, dtype=ti.f32, shape=N)
vel[0] = ti.Vector([1.1] * 3)
vel[1] = ti.Vector([0.0] * 3)

edge = ti.ndarray(ti.i32, shape=M * 2)
edge[0] = 0
edge[1] = 1

max_pair_collision_size = M**2
is_collided = ti.ndarray(ti.i32, shape=max_pair_collision_size)
collision_t = ti.ndarray(ti.f32, shape=max_pair_collision_size)
collision_w = ti.Vector.ndarray(2, dtype=ti.f32, shape=max_pair_collision_size)
collision_normal = ti.Vector.ndarray(3, dtype=ti.f32, shape=max_pair_collision_size)

closest_collision_all_ee(
    is_collided, collision_t, collision_w, collision_normal, 2.0, pos, vel, edge, 1e-2
)

```

**Log/Screenshots**
Please post the **full log** of the program (instead of just a few lines around the error message, unless the log is > 1000 lines). This will help us diagnose what's happening. For example:

```
$ python my_sample_code.py
[Taichi] mode=release
[Taichi] version 0.6.29, llvm 10.0.0, commit b63f6663, linux, python 3.8.3
...
```

**Additional comments**
If possible, please also consider attaching the output of command `ti diagnose`. This produces the detailed environment information and hopefully helps us diagnose faster.

If you have local commits (e.g. compile fixes before you reproduce the bug), please make sure you first make a PR to fix the build errors and then report the bug.



Discussion / hints:
Thanks for catching the case!

Shortened the reproduction.

```Python
import taichi as ti

ti.init(arch=ti.vulkan)

IntArray = ti.types.ndarray(dtype=ti.i32, ndim=1)

@ti.kernel
def closest_collision_all_ee(
    edge: IntArray,
):
    M = edge.shape[0]
    for i, j in ti.ndrange(M, M):
        verts = ti.math.vec4(edge[i], edge[i + 1], edge[j], edge[j + 1])


M = 4

edge = ti.ndarray(ti.i32, shape=(M * M))

closest_collision_all_ee(
     edge
)
```

Fix patch:
diff --git a/taichi/codegen/spirv/spirv_codegen.cpp b/taichi/codegen/spirv/spirv_codegen.cpp
index aa9f1ea0d3c0d..f54ef856cba74 100644
--- a/taichi/codegen/spirv/spirv_codegen.cpp
+++ b/taichi/codegen/spirv/spirv_codegen.cpp
@@ -1782,6 +1782,14 @@ class TaskCodegen : public IRVisitor {
   }
 
   void gen_array_range(Stmt *stmt) {
+    /* Fix issue 7493
+     *
+     * Prevent repeated range generation for the same array
+     * when loop range has multiple dimensions.
+     */
+    if (ir_->check_value_existence(stmt->raw_name())) {
+      return;
+    }
     int num_operands = stmt->num_operands();
     for (int i = 0; i < num_operands; i++) {
       gen_array_range(stmt->operand(i));


Test patch:
diff --git a/tests/python/test_ndrange.py b/tests/python/test_ndrange.py
index d74405824e3a8..64de7a983ab86 100644
--- a/tests/python/test_ndrange.py
+++ b/tests/python/test_ndrange.py
@@ -329,3 +329,15 @@ def iter():
             match=
             "Ndrange for loop with number of the loop variables not equal to"):
         iter()
+
+
+@test_utils.test()
+def test_2d_loop_over_ndarray():
+    @ti.kernel
+    def foo(arr: ti.types.ndarray(dtype=ti.i32, ndim=1)):
+        M = arr.shape[0]
+        for i, j in ti.ndrange(M, M):
+            verts = ti.math.vec4(arr[i], arr[i + 1], arr[j], arr[j + 1])
+
+    array = ti.ndarray(ti.i32, shape=(16, ))
+    foo(array)