You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用CUDA动态库无法获取正确结果的问题求助

CUDA与Python交互返回全0问题的修复方案

我在Python中调用CUDA生成的DLL时无法获取正确结果,但CUDA脚本单独测试能返回正确结果:

  • CU端正确输出:[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
  • Python端错误输出:[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

核心错误点及修复

1. C++函数中输出指针赋值错误

原代码中out = C;仅修改了函数形参的指针指向,并未将计算结果复制到Python传入的内存缓冲区。需替换为内存复制操作:

// 替换原有的 out = C;
memcpy(out, C, sizeof(double) * 24); // 24为输出数组固定长度

2. CUDA内存释放错误

原代码中cudaFree(cellbox);释放的是栈上数组,而非cudaMalloc分配的设备内存cellbox_d,会导致未定义行为,修正为:

cudaFree(cellbox_d); // 替换 cudaFree(cellbox);

3. 缺少CUDA同步与错误检查

Kernel启动后需等待执行完成,且应检查所有CUDA操作的错误,避免隐性失败:

  • 添加错误检查宏(放在代码开头):
#define CHECK_CUDA_ERROR(err) \
    if (err != cudaSuccess) { \
        fprintf(stderr, "CUDA error at %s:%d: %s\n", __FILE__, __LINE__, cudaGetErrorString(err)); \
        exit(EXIT_FAILURE); \
    }
  • 在Kernel调用后添加同步,并为所有CUDA操作添加错误检查:
MatAdd<<<1,blockDim>>>(cellbox_d, verticess_d, C_d, halfcells_d  , rows, cols);
CHECK_CUDA_ERROR(cudaDeviceSynchronize()); // 等待Kernel执行完成

4. Python端参数错误

原代码中sv = np.array(cellboxsize).astype('double')错误地将cellbox的大小赋值给verticess的大小参数,修正为:

sv = np.array(verticesssize).astype('double')

修正后的完整代码

修正后的CUDA代码

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include<iostream>
#include <cstring>
using namespace std;

#define CHECK_CUDA_ERROR(err) \
    if (err != cudaSuccess) { \
        fprintf(stderr, "CUDA error at %s:%d: %s\n", __FILE__, __LINE__, cudaGetErrorString(err)); \
        exit(EXIT_FAILURE); \
    }

#define DELLEXPORT extern "C" __declspec(dllexport)

__global__ void MatAdd(const double *cellbox, const double *verticess, double *C,
                    const double *halfcells,int rows, int cols)
{
    int cellboxidy = threadIdx.y;
    int verticessidx = threadIdx.x;

    const double mincell [3] = {cellbox[cellboxidy * 3] - halfcells[0],
                               cellbox[cellboxidy * 3 + 1] - halfcells[1],
                               cellbox[cellboxidy * 3 + 2] - halfcells[2]};
    const double maxcell [3] = {cellbox[cellboxidy * 3] + halfcells[0],
                               cellbox[cellboxidy * 3 + 1] + halfcells[1],
                               cellbox[cellboxidy * 3 + 2] + halfcells[2]};

    if (verticess[verticessidx * 3] >= mincell[0] && verticess[verticessidx * 3] <= maxcell[0]  
        && verticess[verticessidx * 3 + 1] >= mincell[1] && verticess[verticessidx * 3 + 1] <= maxcell[1] 
        && verticess[verticessidx * 3 + 2] >= mincell[2] && verticess[verticessidx * 3 + 2] <= maxcell[2]){
    
        C[cellboxidy * 3] = 1;
        C[cellboxidy * 3 + 1] = 1;
        C[cellboxidy * 3 + 2] = 1;
    }
}

DELLEXPORT void twodarray(double *out , double *celb ,double *ve , double *hfc , 
double *sizecellbox , double *sizeverticess)
{    
    double cellbox [24] = {0};
    for(int i = 0 ; i<int(*sizecellbox) ; i++){
        cellbox[(i*3)] = celb[(i*3)];
        cellbox[(i*3) + 1] = celb[(i*3) + 1];
        cellbox[(i*3) + 2] = celb[(i*3) + 2];
    }

    double verticess [24] = {0};
    for(int i = 0 ; i<int(*sizeverticess) ; i++){
        verticess[(i*3)] = ve[(i*3)];
        verticess[(i*3) + 1] = ve[(i*3) + 1];
        verticess[(i*3) + 2] = ve[(i*3) + 2];
    }

    const int N = *sizecellbox;
    int M = *sizeverticess;

    double halfcells[3] = {};
    halfcells[0] = hfc[0];
    halfcells[1] = hfc[1];
    halfcells[2] = hfc[2];

    double *C;
    double *cellbox_d = 0, *verticess_d = 0 , *halfcells_d = 0 , *C_d = 0;
    int rows = N;
    int cols = M;

    dim3 blockDim(*sizecellbox, *sizeverticess);

    C = (double *)malloc(sizeof(*C)*100);
    CHECK_CUDA_ERROR(cudaMalloc((void**)&C_d, sizeof(*C_d)*100));
    CHECK_CUDA_ERROR(cudaMalloc((void**)&cellbox_d, sizeof(*cellbox_d)*100));
    CHECK_CUDA_ERROR(cudaMalloc((void**)&verticess_d, sizeof(*verticess_d)*100));
    CHECK_CUDA_ERROR(cudaMalloc((void**)&halfcells_d, sizeof(*halfcells_d)*3));

    CHECK_CUDA_ERROR(cudaMemcpy(cellbox_d, cellbox, sizeof(*cellbox_d)*100, cudaMemcpyHostToDevice));
    CHECK_CUDA_ERROR(cudaMemcpy(verticess_d, verticess, sizeof(*verticess_d)*100, cudaMemcpyHostToDevice));
    CHECK_CUDA_ERROR(cudaMemcpy(halfcells_d, halfcells, sizeof(*halfcells_d)*3, cudaMemcpyHostToDevice));

    MatAdd<<<1,blockDim>>>(cellbox_d, verticess_d, C_d, halfcells_d  , rows, cols);
    CHECK_CUDA_ERROR(cudaDeviceSynchronize());

    CHECK_CUDA_ERROR(cudaMemcpy(C, C_d, sizeof(*C)*100, cudaMemcpyDeviceToHost));

    memcpy(out, C, sizeof(double)*24);

    cudaFree(cellbox_d);
    cudaFree(verticess_d);
    cudaFree(C_d);
    cudaFree(halfcells_d);
    free(C);
}
// 编译命令:nvcc -Xcompiler -fPIC -shared -o 2darray3.dll 2darray3.cu

修正后的Python代码

import numpy as np
import ctypes
from ctypes import * 

def get_cuda_square():
    dll = ctypes.windll.LoadLibrary("C:\\Users\\Ali\\Desktop\\test9\\cuda_remember\\with link python\\2darray3.dll") 
    func = dll.twodarray
    func.argtypes = [POINTER(c_double), POINTER(c_double), POINTER(c_double), 
POINTER(c_double),POINTER(c_double) , POINTER(c_double)] 
    return func

__cuda_square = get_cuda_square()

size = int(24)

cellbox_array = [[-0.35263609886169434, -0.35263609886169434, -0.35263609886169434] , 
[0.35263609886169434, -0.35263609886169434, -0.35263609886169434] , 
[-0.35263609886169434, 0.35263609886169434, -0.35263609886169434] , 
[0.35263609886169434, 0.35263609886169434, -0.35263609886169434],[-0.35263609886169434, 
-0.35263609886169434, 0.35263609886169434] , [0.35263609886169434, -0.35263609886169434, 
0.35263609886169434],[-0.35263609886169434, 0.35263609886169434, 0.35263609886169434] , 
[0.35263609886169434, 0.35263609886169434, 0.35263609886169434]]
cellboxsize = c_double(len(cellbox_array))

verticess_array = [[0.1, 0.2, 0.3] , [0.4, 0.5, 0.6] ,[0.7, 0.8, 0.9] , [0.10, 0.11, 
0.12],[0.13, 0.14, 0.15] , [0.16, 0.17, 0.18],[0.19, 0.20, 0.21] , [0.22, 0.23, 0.24]]
verticesssize = c_double(len(verticess_array))

hfc_array = [1.7546,1.4456,1.4545544]
cellbox = np.array(cellbox_array).astype('double')
verticess = np.array(verticess_array).astype('double')
hfc = np.array(hfc_array).astype('double')
sc = np.array(cellboxsize).astype('double')
sv = np.array(verticesssize).astype('double')

output = np.zeros(size).astype('double')

a_p = output.ctypes.data_as(POINTER(c_double))
c_p = cellbox.ctypes.data_as(POINTER(c_double))
v_p = verticess.ctypes.data_as(POINTER(c_double))
h_p = hfc.ctypes.data_as(POINTER(c_double))
sc_p = sc.ctypes.data_as(POINTER(c_double))
sv_p = sv.ctypes.data_as(POINTER(c_double))

__cuda_square(a_p, c_p, v_p , h_p,sc_p , sv_p)
print(output)

内容的提问来源于stack exchange,提问作者user5963087

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 21:54:36