Function CUDA上的Bessel函数在某些ε内

Function CUDA上的Bessel函数在某些ε内,function,cuda,bessel-functions,Function,Cuda,Bessel Functions,我尝试使用CUDA执行贝塞尔函数(以J0(x)为例)。 这是公式 我试图将结果控制在某个ε值内。这是代码 __device__ void Bessel_j0(int totalBlocks, int totalThreads, float z, float epsilon, float* result){ int n = 1; *result = 0; bool epsilonFlag = true;

我尝试使用CUDA执行贝塞尔函数(以J0(x)为例)。 这是公式

我试图将结果控制在某个ε值内。这是代码

    __device__ void Bessel_j0(int totalBlocks, int totalThreads, float z, float epsilon, float* result){
            int n = 1;
            *result = 0;

            bool epsilonFlag = true;

            int idx_start;
            int idx_end;

            while(epsilonFlag == true){ 
                initThreadBounds(&idx_start, &idx_end, n, totalBlocks, totalThreads);
                float a_k;
                for (int k = idx_start; k < idx_end; k++) {
                    a_k = m_power((-0.25 * z * z), k)/(m_factorial(k) * m_factorial(k)); 
                    *result += a_k;
                }
                if(a_k < epsilon){
                        epsilonFlag = false;
                }
                n++;
            }
        }

__global__ void J0(int totalBlocks, int totalThreads,  float x, float* result){
        float res = 0;

        Bessel_j0(totalBlocks, totalThreads, 10, 0.01, &res);
        result[(blockIdx.x*totalThreads + threadIdx.x)] = res;
}

__host__ void J0test(){

    const int blocksNum = 32;
    const int threadNum = 32;

    float   *device_resultf; //для устройства
    float   host_resultf[threadNum*blocksNum]   ={0};


    cudaMalloc((void**) &device_resultf, sizeof(float)*threadNum*blocksNum);

    J0<<<blocksNum, threadNum>>>(blocksNum, threadNum, 10, device_resultf); 
    cudaThreadSynchronize();

    cudaMemcpy(host_resultf, device_resultf, sizeof(float)*threadNum*blocksNum, cudaMemcpyDeviceToHost);

    float sum = 0;

    for (int i = 0; i != blocksNum*threadNum; ++i) {
        sum += host_resultf[i];
        printf ("result in %i cell = %f \n", i, host_resultf[i]);
    }
    printf ("Bessel res = %f \n", sum);
    cudaFree(device_resultf);
}
int main(int argc, char* argv[])
{
    J0test();   
}
\uuuuuu设备\uuuuuuu无效Bessel\uj0(int totalBlocks、int totalThreads、float z、float epsilon、float*result){
int n=1;
*结果=0;
bool epsilonFlag=真;
int idx_启动;
int idx_end;
而(epsilonFlag==true){
initThreadBounds(&idx_开始,&idx_结束,n,totalBlocks,totalThreads);
浮出水面;
对于(int k=idx_start;k

当我运行它时,它显示为黑屏,Windows说nVidia驱动程序没有响应,它恢复了它。在控制台输出中,
host\u resultf
数组中只有零。发生了什么?如何才能在一定的epsilon范围内正确执行函数?

这不太可能,但可能是您的内核执行达到了允许的内核执行时间限制。您的代码没有显示迭代次数的上限。epsilon可能永远无法到达,而您的内核会继续执行超过时间限制。这会有所帮助


在所有情况下,我都会给epsilon循环增加一个上限,永远不要让代码在没有迭代次数限制的情况下运行。

这不太可能,但可能是您的内核执行达到了允许的内核执行时间限制。您的代码没有显示迭代次数的上限。epsilon可能永远无法到达,而您的内核会继续执行超过时间限制。这会有所帮助


在所有情况下,我都会给epsilon循环增加一个上限,永远不要让代码在没有迭代次数限制的情况下运行。

您的程序执行时间太长,并且您遇到了windows TDR事件。这将卸载GPU驱动程序,从而停止程序执行。您应该看看您的程序是否有一些逻辑错误导致它花费很长时间,或者看看是否可以缩短内核执行时间。您可能还想尝试在CUDA GPU不是在windows下运行显示器的WDDM GPU的机器上运行它。WDDM GPU上运行的内核在您触发windows TDR事件之前的执行时间限制在2秒左右。请注意,CUDA库已经提供了第一类的贝塞尔函数j0、j1、jn,以及第二类的贝塞尔函数y0、y1、yn。@njuffa是的,我知道,但我有自己制作的任务-fa-在这种情况下,您可能需要考虑强度,减少级数计算,以显著减少计算时间,例如,在由AYK计算J0计算Ay(K+ 1)的情况下,乘以-**ZZ并除以KK。CUDA数学库遵循可能的标准(如C99)。POSIX定义了这组贝塞尔函数。我认为这与以下事实有关:通过一个众所周知的递归,0阶和1阶函数可以作为高阶函数的基础。您的程序执行时间太长,并且您遇到了windows TDR事件。这将卸载GPU驱动程序,从而停止程序执行。您应该看看您的程序是否有一些逻辑错误导致它花费很长时间,或者看看是否可以缩短内核执行时间。您可能还想尝试在CUDA GPU不是在windows下运行显示器的WDDM GPU的机器上运行它。WDDM GPU上运行的内核在您触发windows TDR事件之前的执行时间限制在2秒左右。请注意,CUDA库已经提供了第一类的贝塞尔函数j0、j1、jn,以及第二类的贝塞尔函数y0、y1、yn。@njuffa是的,我知道,但我有自己制作的任务-fa-在这种情况下,您可能需要考虑强度,减少级数计算,以显著减少计算时间,例如,在由AYK计算J0计算Ay(K+ 1)的情况下,乘以-**ZZ并除以KK。CUDA数学库遵循可能的标准(如C99)。POSIX定义了这组贝塞尔函数。我认为这与0阶和1阶的函数可以作为高阶函数的基础有关,通过一个众所周知的递归。哦,哇,这比我想象的要复杂哦,哇,这比我想象的要复杂