cuda内核不工作当一个数据传输到GPU。任何问题与我的网关墨西哥人代码?

38视图(30天)
你好,
我试图转移KUDA内核数据,做一些职能并输出回Matlab。我已经评估了内核在visual studio和它的工作原理。然而,当我做一个墨西哥人文件的代码,它不提供我我期望的输出。这是我的墨西哥人网关代码:
#包括“cuda_runtime.h”
#包括“device_launch_parameters.h”
#包括“cuda.h”
使用名称空间性病;
#包括< mex.h >
__global__无效kernel_Reconstruction2 (int, int * ReconstructedImage_GPU int * Dev_RfData传输,int NStart_Transmit) {
intTID = threadIdx。y * blockDim。x + threadIdx.x;
intBlockOFFset = blockDim。x * blockDim。y * blockIdx.x;
intRowOFFset = blockDim。x * blockDim。y * gridDim。x * blockIdx.y;
intGID = RowOFFset + BlockOFFset + TID;
}
无效mexFunction (int nlhs mxArray * plhs [],
intnrhs,常量mxArray * prhs []) {
int * RfData;/ /射频数据;一个固定内存是专用的
int * ReconstructedImage_GPU;
RfData = (int *) mxGetPr (prhs [0]);
plhs [0] = mxCreateNumericMatrix (1 64 * 64 mxINT32_CLASS mxREAL);
ReconstructedImage_GPU = (int *) mxGetData (plhs [0]);
intArrayByteSize_RfData = sizeof (int) * (96 * 96 * 4096);
intBYTES_PER_STREAM = ArrayByteSize_RfData / 96;
/ /内存分配:RfData;我们发送射频数据与流媒体设备
int * Device_RfData;/ /设备指针射频数据。
(cudaMalloc ((int * *) &Device_RfData ArrayByteSize_RfData));
int * Device_ReconstructedImage_GPU;/ /设备指针重建的图像
intArrayByteSize_ReconstructedImage_GPU = sizeof (int) * (96 * 96);
(cudaMalloc ((int * *) &Device_ReconstructedImage_GPU ArrayByteSize_ReconstructedImage_GPU));
printf (“CUDA重建开始……\ n”);
dim3块(1024 1);
dim3网格(64 * 64,96),/ / SystemSetup.NumberOfTransmitter
cudaStream_t *流= new cudaStream_t [96];/ / SystemSetup.NumberOfTransmitter
intNStart_Transmit {};
(int传输= 0;传输< 96;传输+ +){
cudaStreamCreate(流(传输));
NStart_Transmit =传输* (96 * 4096);
cudaMemcpyAsync (&Device_RfData NStart_Transmit, &RfData NStart_Transmit, BYTES_PER_STREAM, cudaMemcpyHostToDevice,流(传输));
kernel_Reconstruction2< < <网格块0流(传输)> > > (&Device_RfData NStart_Transmit, Device_ReconstructedImage_GPU,传输,NStart_Transmit);
(cudaPeekAtLastError ());
}
(int传输= 0;传输< 96;传输+ +){cudaStreamDestroy(流(传输));}/ /破坏
删除[]流;
cudaDeviceSynchronize ();
(cudaMemcpy (ReconstructedImage_GPU Device_ReconstructedImage_GPU、ArrayByteSize_ReconstructedImage_GPU cudaMemcpyDeviceToHost));
(cudaFree (Device_RfData));
(cudaFree (Device_ReconstructedImage_GPU));
}
我还检查如果“RfData”包含在主机或没有实际值;都是好的。所以,我认为有问题的“Device_RfData”值。有什么我错过什么?
问候,
Moein。
2的评论
Moein Mozaffarzadeh”class=
Moein Mozaffarzadeh 2021年3月22日
你好理查德,
会儿解释,ReconstructedImage_GPU是一个图像。对于每一个像素的图像,我需要总结一些Dev_RfData样本。这是发生在我的内核,我提供的是我的代码的简化版本。她到底发生了什么:
__global__无效kernel_Reconstruction2(设置* SetupLoaded_p、浮* MediumZ_p * MediumX_p浮动,浮动* TRansducerCorrZ_p, * TRansducerCorrX_p浮动
int, int * RfData int * DirDir_Size,intReconstruct_SoundSpeedint, int * ReconstructedImage_GPU传输,intNStart_Transmit,int大小、浮点数* Device_ConvArrivalTime) {
intTID = threadIdx。y * blockDim。x + threadIdx.x;
intBlockOFFset = blockDim。x * blockDim。y * blockIdx.x;
intRowOFFset = blockDim。x * blockDim。y * gridDim。x * blockIdx.y;
intGID = RowOFFset + BlockOFFset + TID;
intGID_RowBased = BlockOFFset + TID;
intD1D2,山姆,Pz_man Px_man,接收、RoundTripSample, IndexingReceive, IndexingTransmit;
浮动ReceiveTime、RoundTripTime TransmitTime;
如果(GID_RowBased <大小){
Px_man = (GID_RowBased)% (SetupLoaded_p - > Nx);
Pz_man = (GID_RowBased) / (SetupLoaded_p - > Nx);
收到= blockIdx.y;
IndexingReceive =接收* Dir_Size + (GID_RowBased);
IndexingTransmit =传输* Dir_Size + (GID_RowBased);
TransmitTime = (sqrtf (((TRansducerCorrX_p(传输)——MediumX_p [Px_man]) * (TRansducerCorrX_p(传输)——MediumX_p [Px_man])) + ((TRansducerCorrZ_p(传输)——MediumZ_p [Pz_man]) * (TRansducerCorrZ_p(传输)——MediumZ_p [Pz_man])))) / Reconstruct_SoundSpeed;
ReceiveTime = (sqrtf (((TRansducerCorrX_p[接受]——MediumX_p [Px_man]) * (TRansducerCorrX_p[接受]——MediumX_p [Px_man])) + ((TRansducerCorrZ_p[接受]——MediumZ_p [Pz_man]) * (TRansducerCorrZ_p[接受]——MediumZ_p [Pz_man])))) / Reconstruct_SoundSpeed;
RoundTripTime = (TransmitTime + ReceiveTime);
RoundTripTime+ = (SetupLoaded_p - > TransmissionOffset);
RoundTripSample = lroundf (RoundTripTime * SetupLoaded_p - > Fs) 1;
ReconstructedImage_GPU [GID_RowBased] + = ((RfData [RoundTripSample +((接收)* SetupLoaded_p - > NumberOfSamples)))
* (Dir (IndexingReceive) * Dir [IndexingTransmit]));
}
}
当然,我需要复制所有的数组预先在内核中使用 cudaMemcpy。 对不起如果我不匹配与网关墨西哥人代码(我试图提供一个compileable代码在我的第一篇文章)。
我确信内核工作正常,因为它给了我正确的形象在我的Visual Studio项目(抱歉如果我不把这里所有的代码,因为它需要很多的变量和一个大型数据集)。
我认为,Matlab不正确启动内核。你知道什么是错的呢?
Moein。

登录置评。

接受的答案

理查德。”class=
理查德。 2021年3月24日
编辑:理查德。 2021年3月24日
嗨Moein,
没有办法直接固定CUDA内存分配MATLAB数组。输入一个墨西哥人由MATLAB函数总是会分配的内存管理器。
你应该能够分配自己的固定主机内存和mxArray的数据复制到它之前使用流的异步复制设备。复制问题吗?看看交换机我不知道这些额外的日志将比储蓄更昂贵的使用流。
在我的测试中,我使用一个基本的调用mexcuda:
mexcudaTUI_CUDA。铜MexFunctions.cu
您可能还想叫墨西哥人设置,以确保你已经选择了相同的编译器在您使用MATLAB在VS。
我不认为这是你看到的差异可能是由于编译器标志。我认为这是更好的专注于验证输入,然后处理步骤输出匹配你的VS版本和MATLAB版本。
看到与输出可视化问题,两者之间的内存数组的顺序是不同的。显然有一个2 d(甚至3 d)输入数据结构,和你处理它的内核设计工作一片在其中的一个维度。但是输入数组1 d。是输入数据通过从MATLAB绝对正确导入吗?如果涉及到二维矩阵在某个阶段还有可能是转置失踪。你试过调整(N-by-ntransmitters)图像的输入检查两个一维流看起来有预期的结构吗?
当你有核实输入数据流是相同的,那么你将需要看具体位置在内核处理出现偏差。它可能会很有帮助如果你能制定一个示例输入要小得多,这样你有更少的数据项之间的追踪和比较两个系统当你这样做。逐步减少代码(暂时)的内核,直到输出匹配尝试另一种方法——你甚至可以在内核仅仅输出线程指数作为一个基本的测试来证明每个方法执行相同的内核。
理查德。
9日评论
Moein Mozaffarzadeh”class=
Moein Mozaffarzadeh 2021年5月24日
你好理查德,
你好理查德,非常感谢你的解释。是的,我认为你是对的一份文件,支持gpuArrays。万博1manbetx所以,我将切换到使用这feasure Matlab。
我刚刚发现有一个MEXGateway代码的内存管理问题。使用gpuArrays的第一步是把“cudaResetDevice”结束时我的代码(但仍拥有所有的记忆删除),以确保我完全控制整个代码定义的记忆我(我不丢失的东西)。然而,MexFunction不正确的输出(输出几乎翻了一倍我每次在Matlab运行MexFunction);我第一次运行MexFunction,得到输出我希望一切都好。这个问题,以下链接中提供的代码是:
既然你已经熟悉我的编码和项目:),我将感激你的评论和支持。万博1manbetx提前谢谢。
Moein。

登录置评。

答案(1)

理查德。”class=
理查德。 2021年3月22日
编辑:理查德。 2021年3月22日
Moein,有一些问题,我在代码中可以看到。
第一个问题是,它并不以任何方式初始化GPU设备。最简单的方法是添加一个调用mxInitGPU中记录 //www.tianjin-qmedu.com/help/parallel-computing/mxinitgpu.html 。这将使用MATLAB的正常规则来选择默认的GPU。我添加了一个简单的任务线在内核中产生模拟输出值,我也观察到没有返回,然后确认添加一个调用mxInitGPU mexFunction初()引起的预期值返回(重启后MATLAB解决GPU的状态)。
第二个问题是,代码示例似乎以数组界限当复制从Device_ReconstructedImage_GPU ReconstructedImage_GPU。创建输出mxArray 1——(64 x64)矩阵,但在设备上使用数组大小是1 - (96 x96)。这可能会导致MATLAB崩溃——输出mxArray需要匹配的GPU设备阵列大小。
7评论
Moein Mozaffarzadeh”class=
Moein Mozaffarzadeh 2021年3月23日
理查德,
添加更多的我以前的评论,我也检查我的代码的版本不需要固定内存。它的作用很好,在那里我CUDA在visual studio项目,但又不与墨西哥人文件。
我猜:编译我的墨西哥人在visual studio代码。它有什么不同在Matlab编译呢?如果是这样的话,你能提供我的代码需要使用Matlab ?
我已经用这个:
mexcudaCOMPFLAGS = ' COMPFLAGS美元——use-local-env -maxrregcount = 0——机64 -compatibleArrayDims——编译-cudart静态-Xptxas -dlcm = cg -use_fast_math -DWIN32 -DWIN64 -DNDEBUG -D_CONSOLE -D_MBCS -Xcompiler”TUI_Main。铜MexFunctions.cuCudaKernels.cu
但同样的错误的图像生成。
Moein。

登录置评。

社区寻宝

找到宝藏在MATLAB中央,发现社区如何帮助你!

开始狩猎!