64 位原子操作在 AMD 卡上的 openCL 中有效吗?
Do 64bit atomic operations work in openCL on AMD cards?
在 STREAM blog 之后的 openCL 中模拟原子的实现非常适用于 CPU 以及 NVIDIA 和 AMD GPU 上的 32 位原子添加。
基于 cl_khr_int64_base_atomics
扩展的 64 位等价物似乎 运行 在(pocl 和英特尔)CPU 以及 NVIDIA openCL 驱动程序上正确
我无法在 AMD GPU 卡上实现 64 位工作——在 amdgpu-pro 和 rocm (3.5.0) 环境中,运行分别在 Radeon VII 和 Radeon Instinct MI50 上运行。
执行过程如下:
inline void atomicAdd(volatile __global double *addr, double val)
{
union {
long u64;
double f64;
} next, expected, current;
current.f64 = *addr;
do {
expected.f64 = current.f64;
next.f64 = expected.f64 + val;
current.u64 = atomic_cmpxchg(
(volatile __global long *)addr,
(long) expected.u64,
(long) next.u64);
} while( current.u64 != expected.u64 );
}
在不支持 double 类型的原子操作的情况下,我们的想法是利用强制转换,只要只需要存储值(不需要算术)。然后应该能够使用 long atom_cmpxchg(__global long *p, long cmp, long val)
中定义的 khronos manual for int64 base atomics.
我在两个 AMD 环境中收到的错误指向回退到 32 位版本,编译器似乎无法识别 64 位版本,尽管 #pragma
:
/tmp/comgr-0bdbdc/input/CompileSource:21:17: error: call to 'atomic_cmpxchg' is ambiguous
current.u64 = atomic_cmpxchg(
^~~~~~~~~~~~~~
[...]/centos_pipeline_job_3.5/rocm-rel-3.5/rocm-3.5-30-20200528/7.5/out/centos-7/7/build/amd_comgr/<stdin>:13468:12: note: candidate function
int __ovld atomic_cmpxchg(volatile __global int *p, int cmp, int val);
^
[...]/centos_pipeline_job_3.5/rocm-rel-3.5/rocm-3.5-30-20200528/7.5/out/centos-7/7/build/amd_comgr/<stdin>:13469:21: note: candidate function
unsigned int __ovld atomic_cmpxchg(volatile __global unsigned int *p, unsigned int cmp, unsigned int val);
^
1 error generated.
Error: Failed to compile opencl source (from CL or HIP source to LLVM IR).
我确实在 clinfo
扩展列表的两个环境中找到了对 cl_khr_int64_base_atomics
的支持。另外 cl_khr_int64_base
存在于 opencl 驱动程序二进制文件中。
有人知道这里可能出了什么问题吗?对 32 位使用相同的实现(int 和 float 而不是 long 和 double)对我来说完美无缺...
感谢任何提示。
对于 64 位,该函数称为 atom_cmpxchg
and not atomic_cmpxchg
。
在 STREAM blog 之后的 openCL 中模拟原子的实现非常适用于 CPU 以及 NVIDIA 和 AMD GPU 上的 32 位原子添加。
基于 cl_khr_int64_base_atomics
扩展的 64 位等价物似乎 运行 在(pocl 和英特尔)CPU 以及 NVIDIA openCL 驱动程序上正确
我无法在 AMD GPU 卡上实现 64 位工作——在 amdgpu-pro 和 rocm (3.5.0) 环境中,运行分别在 Radeon VII 和 Radeon Instinct MI50 上运行。
执行过程如下:
inline void atomicAdd(volatile __global double *addr, double val)
{
union {
long u64;
double f64;
} next, expected, current;
current.f64 = *addr;
do {
expected.f64 = current.f64;
next.f64 = expected.f64 + val;
current.u64 = atomic_cmpxchg(
(volatile __global long *)addr,
(long) expected.u64,
(long) next.u64);
} while( current.u64 != expected.u64 );
}
在不支持 double 类型的原子操作的情况下,我们的想法是利用强制转换,只要只需要存储值(不需要算术)。然后应该能够使用 long atom_cmpxchg(__global long *p, long cmp, long val)
中定义的 khronos manual for int64 base atomics.
我在两个 AMD 环境中收到的错误指向回退到 32 位版本,编译器似乎无法识别 64 位版本,尽管 #pragma
:
/tmp/comgr-0bdbdc/input/CompileSource:21:17: error: call to 'atomic_cmpxchg' is ambiguous
current.u64 = atomic_cmpxchg(
^~~~~~~~~~~~~~
[...]/centos_pipeline_job_3.5/rocm-rel-3.5/rocm-3.5-30-20200528/7.5/out/centos-7/7/build/amd_comgr/<stdin>:13468:12: note: candidate function
int __ovld atomic_cmpxchg(volatile __global int *p, int cmp, int val);
^
[...]/centos_pipeline_job_3.5/rocm-rel-3.5/rocm-3.5-30-20200528/7.5/out/centos-7/7/build/amd_comgr/<stdin>:13469:21: note: candidate function
unsigned int __ovld atomic_cmpxchg(volatile __global unsigned int *p, unsigned int cmp, unsigned int val);
^
1 error generated.
Error: Failed to compile opencl source (from CL or HIP source to LLVM IR).
我确实在 clinfo
扩展列表的两个环境中找到了对 cl_khr_int64_base_atomics
的支持。另外 cl_khr_int64_base
存在于 opencl 驱动程序二进制文件中。
有人知道这里可能出了什么问题吗?对 32 位使用相同的实现(int 和 float 而不是 long 和 double)对我来说完美无缺...
感谢任何提示。
对于 64 位,该函数称为 atom_cmpxchg
and not atomic_cmpxchg
。