Я пытаюсь следовать разделу B.12 https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html для атомарного добавления, которое работает с плавающей точкой. Простое копирование и вставка кода оттуда и изменение типов на плавающие не работает, потому что я не могу выполнить приведение указателя приведения из GLOBAL в PRIVATE, требуемый для операции atomicCAS. Чтобы преодолеть это, я решил использовать atomic_xchg (), потому что он работает с плавающей точкой, с дополнительным оператором if для достижения той же функциональности, что и atomicCAS. Тем не менее, при каждом сложении с большим вектором с плавающей запятой каждый раз я получаю разные ответы.
Я пытался выяснить, как преодолеть явное преобразование из GLOBAL в PRIVATE, но я, честно говоря, не знаю, как это сделать, чтобы при выполнении сложения аргумент адреса изменялся вместо некоторой временной переменной.
kernel void atomicAdd_2(volatile global float* address, float value)
{
float old = *address, assumed;
do {
assumed = old;
if (*address == assumed) {
old = atomic_xchg(address, value + assumed);
}
else{
old = *address;
}
// Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN)
} while (assumed != old);
}
Это моя реализация atomicAdd для чисел с плавающей запятой.
kernel void reduce_add(global const float* input, global float* output) {
float temp = 242.23f;
atomicAdd_floats(&output[0], temp);
printf(" %f ", output[0]);
}
Это функция, в которой я предоставляю аргументы для atomicAdd_floats. Обратите внимание, что мой входной аргумент содержит вектор с плавающей точкой, а выходной аргумент - это просто место, где я хочу сохранить результат, в частности, в первом элементе выходного вектора output [0]; но вместо этого, когда я printf ("% f", output [0]); он показывает мое значение инициализации по умолчанию 0.