主要内容

Cusolver示例

这个例子解线性方程组斧= B.为了X使用Cusolver库。矩阵一种B.必须具有相同数量的行。如果一种那是一个标量A \ B.相当于A. \ B..如果一种是一个n × n的方阵B.是一个带有n行的矩阵,然后x = a \ b是等式的解决方案A * x =,如果它存在。matlab.®实施反斜杠是:

函数[x] =反斜杠(A,B)如果(ISSCALAR(A))x = CODER.NULLCOPY(零(大小(b)));别的x = coder.nullcopy(0(大小(A, 2),大小(b, 2)));结尾x = a \ b;结尾

准备反斜杠内核创建

GPU Coder™不需要特殊的pragma来生成对库的调用。和前面一样,有两种方法来生成CUDA®仁 -coder.gpu.kernelfun.coder.gpu.kernel..在本例中,我们使用coder.gpu.kernelfun.Pragma生成CUDA内核。修改了反斜杠功能是:

函数[x] =反斜杠(A,B)%#codegen.如果(ISSCALAR(A))x = CODER.NULLCOPY(零(大小(b)));别的x = coder.nullcopy(0(大小(A, 2),大小(b, 2)));结尾coder.gpu.kernelfun()x = a \ b;结尾

笔记

使用cuSOLVER库实现替换数学运算符和函数时,需要输入数据的最小大小。最小阈值是128个元素。

生成的CUDA.代码

当你生成CUDA代码,GPU Coder创建函数调用初始化cuSOLVER库,执行莫德利维操作,并发布Cusolver库使用的硬件资源。生成的CUDA代码的片段是:

cusolverensureinitialization();/ *版权所有2017 The Mathworks,Inc。* / Cudamemcpy(B_GPU_A,A,1152UL,CudamEmcyHostTodevice);Blackslash_kernel1 <<< DIM3(1U,1U,1U),DIM3(160U,1U,1U)>>>(B_GPU_A,GPU_A);Cudamemcpy(B_A,GPU_A,1152UL,CudamEmcpyDevicetohost);cusolverdndgetrf_buffersize(cusolverglobalhandle,12,12和gpu_a [0],12,&cusolverworkspacereq);cusolverworkspacetypesize = 8;cusolverinitWorkspace();cudamemcpy(gpu_a,b_a,1152ul,cudamemcyhostodevice);cusolverdndgetrf(cusolverglobalhandle,12,12,&gpu_a [0],12,(real_t *)cusolverworkspacebuff,&gpu_iniv_t [0],gpu_info_t);a_dirtyongpu = true; cudaMemcpy(&info_t, gpu_info_t, 4UL, cudaMemcpyDeviceToHost);

初始化Cusolver库并创建句柄到Cusolver库上下文,功能cusolversensureinitialization()呼叫cusolverdncreate()cuSOLVER API。为主机和设备分配硬件资源。

静电void cusolverensureinitialization(空白){if(cusolverglobalhandle == null){cusolverdncreate(&cusolverglobalhandle);}}

backslash_kernel1.零填充矩阵一种.此内核通过单个512个线程启动。

static __global__ __launch_bounds__(160, 1) void backslash_kernel1(const real_T * A, real_T *b_A) {int32_T threaddid;;;threadId = (int32_T) (((gridDim。x * gridDim。y * blockIdx。z + gridDim。X* blockIdx.y) + blockIdx.x) * (blockDim.x * blockDim.y * blockDim.z) + (int32_T)((threadIdx.z * blockDim.x * blockDim.y + threadIdx.y * blockDim.x) + threadIdx.x)); if (!(threadId >= 144)) { /* Copyright 2017 The MathWorks, Inc. */ b_A[threadId] = A[threadId]; } }

打电话Cudamemcpy.转移矩阵一种从主机到设备。功能cusolverDnDgetrf计算M×N矩阵的LU分解:

p * a = l * u

其中A是M×N矩阵,P是置换矩阵,L是具有单元对角线的较低三角形矩阵,并且U是上三角矩阵。

Cusolver独立代码

对于像这样的功能QR.仅在Cusolver中只有部分支持,GPU编码金宝app器在必要时使用Lapack库。对于MEX函数,代码生成器使用MATLAB附带的LAPACK库。对于独立代码,代码生成器使用您指定的LAPACK库。要指定Lapack库:

  • 在命令行中,定义您自己的Coder.LapackCallback.类包含Lapack库信息并将其分配给CustomLAPACKCallback属性的。

  • 在GPU编码器应用程序中,设置自定义LAPACK库回调到你的LAPACK库。

例如,要生成独立的可执行文件,可以使用以下代码生成脚本。在这里mylapack.是自定义的名称Coder.LapackCallback.类包含LAPACK库信息。

cfg = coder.gpuconfig('EXE文件');cfg.customlapackcallback =.'mylapack';cfg.genereExamplemain ='generatecodeandcompile';Classdef.myLAPACK <编码器。LAPACKCallback方法(静止的)函数hn = getheaderfilename()hn ='lapacke.h';结尾函数updateBuildInfo(buildInfo, buildctx) [~,linkLibExt] = buildctx. getstdlibinfo ();cudaPath = getenv (“CUDA_PATH”);libPath =lib \ x64的;buildinfo.addincludpaths(fullfile(cudapath,'包括'));libname =“cusolver”;libPath = fullfile (cudaPath libPath);buildInfo。libPath addLinkObjects([库名linkLibExt),......'',真的,真的);lapacklocation =“C: \ LAPACK \ win64”;%指定LAPACK库的路径includePath = fullfile (lapackLocation,'包括');buildinfo.addincludepaths(IncludePath);libpath = fullfile(lapacklocation,'lib');libname ='mlrapack';buildInfo。libPath addLinkObjects([库名linkLibExt),......'',真的,真的);buildinfo.addefines('have_lapack_config_h');buildinfo.addefines('lapack_complex_structure');结尾结尾结尾
有关更多信息,请参阅使用LAPACK调用在生成独立代码中加速线性代数