Julia CUDA使用CuArrays广播时报UndefVarError: parameters not defined求助
修复方案
1. 傅里叶基函数广播报错修复
报错根因:你定义的base是闭包数组,闭包捕获的循环变量i、全局变量L都是非恒定值,Julia类型推断无法确定函数返回值的具体类型,导致GPU广播时生成了元素类型为Any的数组,触发第一个报错。你后续给匿名函数加类型标注的写法在CUDA v2.6.2版本存在兼容性问题,会触发参数未定义的报错。另外你原代码中n的定义漏了乘号,需要修正为((-1)^i) * div(i,2)。
最优修复方案:避免使用闭包数组,直接写广播表达式
不需要提前定义base函数数组,需要计算第i个基在t上的取值时,直接执行如下代码即可:
res = @. exp(π * im * n[i] * t / L) / L
该写法完全规避了闭包捕获的类型不稳定问题,GPU可以正常推断出返回值为ComplexF64类型,广播不会报错。
兼容闭包写法的修复方案
如果你必须保留base函数数组的写法,可以用let块绑定捕获变量,保证类型稳定:
const L = 2.0 # 全局变量加const保证类型恒定 n = [((-1)^i) * div(i,2) for i in 1:grado] base = let L=L, n=n [let i=i; x -> exp(π * im * n[i] * x / L) / L end for i in eachindex(n)] end
不要给匿名函数加参数和返回值的强制类型标注,旧版本CUDA不支持这种写法在GPU侧执行。
2. 自定义积分函数报错修复
你的integra函数本身逻辑兼容CuArray,报错是因为你传入的arr参数是前面类型不稳定广播生成的非法CuArray,修复完傅里叶基的广播问题后,积分函数可以直接使用。如果要进一步适配GPU类型,可以给函数加类型约束:
function integra(inizio::Real, fine::Real, arr::CuArray{T}) where T<:Union{Float64, ComplexF64} N = size(arr, 1) h = (fine - inizio) / N integrale = sum(arr) integrale -= (first(arr) + last(arr)) / 2 return integrale * h end
额外注意事项
- 所有在GPU运算中用到的全局变量都要加
const修饰,避免类型不稳定 - Julia v1.6对应的CUDA v2.6.2版本对闭包的支持不完善,非必要不要在GPU广播中使用匿名函数数组
内容的提问来源于stack exchange,提问作者Marcello Fonda
相关产品推荐
相关产品推荐

