这个例子解线性方程组斧= 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代码,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是上三角矩阵。
对于像这样的功能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');结尾结尾结尾