@triton.autotune(configs=[triton.Config({'BLOCK_SIZE': 32}, num_warps=4),
    triton.Config({'BLOCK_SIZE': 64}, num_warps=8), triton.Config({
    'BLOCK_SIZE': 128}, num_warps=8), triton.Config({'BLOCK_SIZE': 256},
    num_warps=16)], key=['n_paths', 'n_cities'])
@triton.jit
def evaluate_paths_kernel(dist_matrix_ptr, paths_ptr, n_cities: tl.
    constexpr, next_power_of_2: tl.constexpr, n_paths: tl.constexpr,
    output_ptr, BLOCK_SIZE: tl.constexpr):
    """
    评估所有路径的距离，找出最短路径
    """
    pid = tl.program_id(axis=0)
    block_start = pid * BLOCK_SIZE
    offsets = block_start + tl.arange(0, BLOCK_SIZE)
    mask = offsets < n_paths
    path_start = offsets * n_cities
    city_offsets = tl.arange(0, next_power_of_2)
    city_mask = city_offsets < n_cities
    """
    利用广播机制，一次性加载一组路径的所有城市索引
    假设
    BLOCK_SIZE = 2
    n_cities = 3

    则可知
    path_start = [0, 3]

    则
    city_offsets = [0, 1, 2]
    path_start[:, None] = [[0],
                        [3]]
    city_offsets[None, :] = [[0, 1, 2]]

    加载当前城市的索引，广播运算：
    [[0, 1, 2],
    [3, 4, 5]]

    加载下一个城市的索引（模运算）：
    [[1, 2, 0],
    [4, 5, 3]]
    """
    curr_cities = tl.load(paths_ptr + path_start[:, None] + city_offsets[
        None, :], mask=mask[:, None] & city_mask[None, :])
    next_cities = tl.load(paths_ptr + path_start[:, None] + ((city_offsets +
        1) % n_cities)[None, :], mask=mask[:, None] & city_mask[None, :])
    dists = tl.load(dist_matrix_ptr + curr_cities * n_cities + next_cities,
        mask=mask[:, None])
    distances = tl.zeros([BLOCK_SIZE], dtype=tl.float32)
    distances = tl.sum(dists, axis=1)
    tl.store(output_ptr + offsets, distances, mask=mask)
