【问题标题】:Is it possible to pre-allocate a variable to CPU/GPU memory in the MexGateway code written in Visual Studio?是否可以在用 Visual Studio 编写的 MexGateway 代码中将变量预分配给 CPU/GPU 内存?
【发布时间】:2021-08-10 17:22:12
【问题描述】:

我正在尝试编写 MexGateway 代码以将 matlab 中的两个变量传递给编译后的 MexFile,将变量复制到 cuda 内核,进行处理并将结果返回到 Matlab。我需要在 matlab 的 for 循环中使用这个 MexFile。

问题在于:这两个输入对于我的应用程序来说是巨大的,并且只有其中一个(在下面的代码中称为 Device_Data)在每个循环中发生变化。所以,我正在寻找一种预先分配稳定输入的方法,这样它就不会在我的 for 循环的每次迭代中从 GPU 中删除。我还需要说,我真的需要在我的 Visual Studio 代码中执行此操作,并在 MexGateway 代码中执行此操作(我不想在 Matlab 中执行此操作)。有什么解决办法吗?

这是我的代码(我已经编译过了。它工作正常):

#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <stdio.h>
#include "cuda.h"
#include <iostream>
#include <mex.h>
#include "MexFunctions.cuh"




__global__ void add (int* Device_Data, int* Device_MediumX, int N) {
int TID = threadIdx.y * blockDim.x + threadIdx.x;
if (TID < N) {
    for (int i = 0; i < N; i++) {
        Device_Data[i] = Device_Data[i] + Device_MediumX[i];
    }
}
}
void mexFunction(int nlhs, mxArray* plhs[],
int nrhs, const mxArray* prhs[]) {

int N = 128;
int* MediumX;
int* Data;
int* Data_New;

MediumX = (int*)mxGetPr(prhs[0]);
Data = (int*)mxGetPr(prhs[1]);

plhs[0] = mxCreateNumericMatrix(N,1, mxINT32_CLASS, mxREAL);
Data_New = (int*)mxGetData(plhs[0]);


int ArrayByteSize = sizeof(int) * N;
int* Device_MediumX; // device pointer to the X coordinates of the medium
gpuErrchk(cudaMalloc((int**)&Device_MediumX, ArrayByteSize));
gpuErrchk(cudaMemcpy(Device_MediumX, MediumX, ArrayByteSize, cudaMemcpyHostToDevice));

int* Device_Data; // device pointer to the X coordinates of the medium
gpuErrchk(cudaMalloc((int**)&Device_Data, ArrayByteSize));
gpuErrchk(cudaMemcpy(Device_Data, Data, ArrayByteSize, cudaMemcpyHostToDevice));

dim3 block(N, 1);
dim3 grid(1);//SystemSetup.NumberOfTransmitter
add << <grid, block >> > (Device_Data, Device_MediumX, N);

(cudaMemcpy(Data_New, Device_Data, ArrayByteSize, cudaMemcpyDeviceToHost));


cudaDeviceReset();

}

【问题讨论】:

    标签: memory cuda mex


    【解决方案1】:

    可以,只要你有MATLAB的分布式计算工具箱/并行计算工具箱。

    该工具箱允许在普通 MATLAB 代码中使用名为 gpuArrays 的东西,但它也有一个 C 接口,您可以在其中获取和设置这些 MATLAB 数组 GPU 地址。

    您可以在此处找到文档:

    https://uk.mathworks.com/help/parallel-computing/gpu-cuda-and-mex-programming.html?s_tid=CRUX_lftnav

    例如,对于 mex 文件的第一个输入:

    mxGPUArray const *dataHandler= mxGPUCreateFromMxArray(prhs[0]); // Can be CPU or GPU, will copy to GPU if its not already there
    float  *  d_data = static_cast<float  *>( (float *)mxGPUGetDataReadOnly(dataHandler)); // get the pointer itself (assuming float data)
    

    【讨论】:

    • 谢谢。所以,如果我理解正确,我需要使用你的代码而不是“cudaMalloc”和“cudaMemcpy”。而且,在您的代码中,指针“d_data”将被放置在全局内存中,并且可以传递给内核。对吗?
    • @MoeinMozaffarzadeh 是的,mxGPUCreateFromMxArray 将对 GPU 执行 malloc 和 memcpy(如果需要)。 d_data 不会放在全局内存中,它只是一个 float *。对于您的应用程序,如果数据没有变化,最好的办法是在 MATLAB 端使用 my_data=gpuarray(my_data) 分配它,这样 malloc 和 memcpy 就已经完成了。
    • 好的。我刚刚尝试“Device_MediumX=gpuArray(MediumX);”将 MediumX 传输到 GPU,将 MediumX 传递给 MEXFile,但是当我运行它时它崩溃了。在我的网关代码中,我使用 Device_MediumX = (int*)mxGetPr(prhs[0]);并将“Device_MediumX”传递给内核。我在这里做错了吗?
    • 没有完整的代码和错误信息很难分辨。
    • 我了解到,如果将 Matlab 中定义的“gpuArray(MediumX)”分配给 MEX 代码中的“prhs[0]”,则您提供的两行代码运行良好。但是,Device_MediumX(这是不变变量)是否保留在 GPU 内存中?我的意思是,你的两行在我运行 MEXFunction 的每个循环中都会重复,如果我理解正确,它们正在对 GPU 执行 malloc 和 memcpy。您能对此发表评论吗?
    猜你喜欢
    • 2020-12-05
    • 1970-01-01
    • 2014-06-04
    • 2011-02-22
    • 2019-08-22
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2021-06-12
    相关资源
    最近更新 更多