Я считаю, что это связано с неразумным использованием типов данных с feval
.
Мне кажется, что feval
преобразует тип возвращаемого значения в тот же тип, что и тип параметра. Это имеет смысл, поскольку возвращаемый тип извлекается из указателя на переданный аргумент для этого параметра.
обратите внимание, что powf
принимает float
параметров и возвращает float
, а pow
принимает double
параметров и возвращает double
. int
количества не имеют отдельной функции (прототипа) в математическом API CUDA , поэтому, если вы используете их, они будут приводиться к типам с плавающей запятой и обратно.
Вот что я вижу в чистой CUDA C ++:
$ cat t32.cu
#include <math.h>
#include <stdio.h>
__global__ void Foo( int a, double b)
{
float res = powf((float)a, 2);
printf("powf_int: %d, %d, %f\n", a, (int)res, res);
res = powf((float)b, 2);
printf("powf_double: %f, %f, %f\n", b, (double)res, res);
double dres = pow((double)a, 2);
printf("pow_int: %d, %d, %f\n", a, (int)dres, dres);
dres = pow((double)b, 2);
printf("pow_double: %f, %f, %f\n", b, (double)dres, dres);
}
int main(){
Foo<<<1,1>>>(-5, -5);
cudaDeviceSynchronize();
}
$ nvcc -o t32 t32.cu
$ cuda-memcheck ./t32
========= CUDA-MEMCHECK
powf_int: -5, 24, 24.999998
powf_double: -5.000000, 24.999998, 24.999998
pow_int: -5, 25, 25.000000
pow_double: -5.000000, 25.000000, 25.000000
========= ERROR SUMMARY: 0 errors
$
Обратите внимание:
- CUDA
powf
возвращает 24,999998 для (-5,2)
- если мы конвертируем это в
int
, оно усекается до 24
- если мы преобразуем это значение в
double
, а затем округлим до 3 десятичных разрядов, правильно округленный результат будет равен 25.000, как показано в выходных данных matlab
Предложения:
- не делай этого
- не использовать целочисленные типы с функциями с плавающей точкой (особенно приведение результата)
- если вы хотите что-то возвести в квадрат, просто умножьте это на себя. Это определенно будет быстрее, чем использование
powf(x, 2)
и, возможно, будет более точным.
Если вы хотите знать, «почему CUDA powf(-5, 2)
возвращает 24.999998?», Пожалуйста, задайте это в отдельном вопросе. Точность определена в руководстве по программированию , и я уверен, что это находится в пределах опубликованных границ ошибки.