You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Numba CUDA中集合推导式的SET_ADD不支持错误?

修复Numba CUDA函数中的SET_ADD不支持错误

错误原因

你遇到的UnsupportedError本质是两个问题:

  1. Numba CUDA后端不支持Python集合推导式(报错中的SET_ADD opcode对应集合的元素添加操作);
  2. itertools.combinations是Python标准库的迭代器实现,无法被编译到GPU执行,GPU函数中不能直接调用这类Python对象层的工具。

改写方案

核心思路是:将组合生成逻辑移到CPU端(itertools.combinations在CPU上效率足够),把筛选逻辑放到GPU上并行处理,同时用Numba支持的GPU兼容数据结构替代Python集合。

步骤1:CPU端生成所有待筛选的组合

先在CPU上生成需要的组合,转换为GPU可处理的NumPy数组:

from itertools import combinations
import numba as nb
import numpy as np

def generate_combs(size, theuniquegenes):
    limiter = size + 1
    lengths = [l + 1 for l in range(len(theuniquegenes)) if (l + 1 > 2) and (l + 1 < limiter)]
    new_combs = []
    for l in lengths:
        new_combs.extend(combinations(theuniquegenes, l))
    # 转换为NumPy数组(如果基因是字符串,建议先映射为整数ID,GPU对数值类型支持更好)
    return np.array(new_combs, dtype=np.int64)

步骤2:创建GPU兼容的哈希表用于快速查找

将原成对列表转换为Numba支持的typed.Dict,方便GPU快速查询:

def create_tuple_hash(tuplelist):
    # 根据你的tuplelist元素类型定义键类型,这里假设是整数二元组
    tuple_hash = nb.typed.Dict.empty(
        key_type=nb.types.UniTuple(nb.int64, 2),
        value_type=nb.types.bool_
    )
    for t in tuplelist:
        tuple_hash[t] = True
    return tuple_hash

步骤3:编写GPU并行筛选内核

用Numba CUDA内核并行检查每个组合的有效性(以size=3的三元组为例,可简化检查逻辑):

@nb.cuda.jit
def filter_valid_combs(combs, tuple_hash, result_mask):
    idx = nb.cuda.grid(1)
    if idx >= combs.shape[0]:
        return
    # 针对三元组的简化检查(如果size可变,可改为嵌套循环生成两两组合)
    a, b, c = combs[idx]
    # 检查所有两两组合是否存在于哈希表中
    result_mask[idx] = (a,b) in tuple_hash and (a,c) in tuple_hash and (b,c) in tuple_hash

步骤4:封装调用函数

整合CPU和GPU逻辑,完成最终的组合筛选与合并:

def combinator(size, theuniquegenes, tuplelist):
    # CPU生成待筛选组合
    combs = generate_combs(size, theuniquegenes)
    if len(combs) == 0:
        print(0)
        print(len(tuplelist))
        return tuplelist
    
    # 创建GPU可用的哈希表
    tuple_hash = create_tuple_hash(tuplelist)
    
    # 分配GPU内存存储结果掩码
    result_mask = nb.cuda.device_array(combs.shape[0], dtype=nb.boolean)
    
    # 启动GPU内核(按线程块调度)
    threads_per_block = 256
    blocks_per_grid = (combs.shape[0] + threads_per_block - 1) // threads_per_block
    filter_valid_combs[blocks_per_grid, threads_per_block](combs, tuple_hash, result_mask)
    
    # 将结果传回CPU,筛选有效组合
    valid_mask = result_mask.copy_to_host()
    valid_combs = combs[valid_mask].tolist()
    # 转换为集合去重(如果需要)
    correlations = set(tuple(c) for c in valid_combs)
    
    print(len(correlations))
    tuplelist = tuplelist + list(correlations)
    print(len(tuplelist))
    return tuplelist

# 调用方式不变
tuplelist = combinator(3, uniquegenes, tuplelist)

额外优化建议

  • 如果你的基因名称是字符串,建议先将其映射为唯一整数ID(比如用dict建立映射),GPU对数值类型的处理效率远高于字符串;
  • 若size固定为3,上述内核的简化检查逻辑比通用两两组合生成更高效,可大幅提升GPU处理速度。

内容的提问来源于stack exchange,提问作者Sanjiv Prasad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 20:30:54