利用cuda加速MATLAB程序

2023-11-11

利用cuda加速MATLAB程序

  最近因为要做张量的模态积,所以要考虑使用cuda来进行并行的编程,但是c++实在太麻烦,尤其是在有MATLAB的时候,写c++简直就是一种“浪费时间”的行为。如果能用MATLAB调用cuda的程序那该是一件多么美好的事情呀。
  确实,这件事情非常美好,但是配置开发环境的过程却是非常痛苦,我花了将近一个星期的时间才把这个问题解决,希望读者能在看完本文后节约宝贵的时间。
  如果你用的是版本比较老的VS(比如2005)和matlab,那么这个问题其实很好办,只要调用nvmex函数就好了,但是据stackoverflow的网友说,自MATLAB2010a开始,nvmex就不被支持了,因此网上有很多答案讨论如何改nvmex函数使得能在更高版本的MATLAB运行,但我试了很多源码都不成功,于是乎放弃。好在MATLAB出了个比较新的MATLABR2015b的版本,这个版本有个mexcuda函数, 用起来相当舒心,只要一两句代码就能调用.cu程序,唯一的不足就在于传入的数组必须是GPUARRay的形式,而且重新下载MATLAB再安装也是挺不舒服的。另外一个要注意的就是在mathworks的releasenote里有说哪个版本的MATLAB支持哪个版本的cuda。所以重装什么的绝对不是一个最好的办法呀。下面就给出两个解决办法:
  

1、参考木子超的办法

  这个办法写得很完整也很细致,我所遇到的问题和他遇到的问题几乎是一样的,读者只要对照着去做就好,我亲自测试过,测试环境是MATLAB_R2014a+VS2010+cuda7.5。还有一点值得注意的是,木子超所给出的代码有的地方是有点瑕疵的,需要读者自己完善,这里我就不说了。以下给出链接:
  http://blog.csdn.net/endlch/article/details/44561535

2、参考Tomheaven的方法

  这个方法我也亲自测试过,测试环境同上,作者写得非常好,就是有个小细节要注意
  

COMPFLAGS="-gencode=arch=compute_20,code=sm_20 -gencode=arch=compute_30,code=sm_30 -gencode=arch=compute_50,code=\"sm_50,compute_50\" --compiler-options=/c,/GR,/W3,/EHs,/nologo,/MD"

  在上面这个地方,如果你是cuda7.5的版本一定要把第一行第一个出现的arch和code后面的那个数字都改成20了(我记得cuda5.5这俩数字都是13),不然会出现nvcc报错,也就是我第一段说的MATLAB找不到它支持的编译器的架构的问题。以下是链接:
  http://blog.csdn.net/hanlin_tan/article/details/48790273
  
  
%%%%%%%%%%%% 2018年更新 %%%%%%%%%%%%%%
上面讲述了如何在MATLAB2014下进行配置,时间来到了2018年,可能Mathwork公司已经意识到深度学习的火热和大家配置Cuda+MATLAB开发环境的痛苦,所以最新版本的MATLAB(据我所知是MATLAB2016a之后的版本)定义了一个新的语句:”mexcuda”。这个语句使用起来相当方便,比如你有一个向量相加的程序(VectorAdd.cu),你只需要按照编译C++ mex 文件的方法去编译就行了,直接敲击mexcuda VectorAdd.cu, 等待一会,就可以生成你想要的可执行文件了。注意MATLAB官方给了一个模板,但你其实不需要按照它给的函数传递方法去定义GPUArray,传统的mex方法依旧可行。为了方便大家的理解,我给出以下的一个例子:


#include "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include\cuda_runtime.h"
#include "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include\device_launch_parameters.h"
#include <mex.h>
#include <stdio.h>

cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);

__global__ void addKernel(int *c, const int *a, const int *b)
{
    int i = threadIdx.x;
    c[i] = a[i] + b[i];
}


void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // initialize
    int *array_A = (int*)mxGetPr(prhs[0]);
    int *array_b = (int*)mxGetPr(prhs[1]);
    const int arraySize = 5;
    int c[arraySize] = { 0 };

       // Add vectors in parallel.
    cudaError_t cudaStatus = addWithCuda(c, array_A, array_b, arraySize);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "addWithCuda failed!");
    }

    printf("{1,2,3,4,5} + {10,20,30,40,50} = {%d,%d,%d,%d,%d}\n",
        c[0], c[1], c[2], c[3], c[4]);

    // cudaDeviceReset must be called before exiting in order for profiling and
    // tracing tools such as Nsight and Visual Profiler to show complete traces.
    cudaStatus = cudaDeviceReset();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceReset failed!");
    }
}

// Helper function for using CUDA to add vectors in parallel.
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)
{
    int *dev_a = 0;
    int *dev_b = 0;
    int *dev_c = 0;
    cudaError_t cudaStatus;

    // Choose which GPU to run on, change this on a multi-GPU system.
    cudaStatus = cudaSetDevice(0);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
        goto Error;
    }

    // Allocate GPU buffers for three vectors (two input, one output)    .
    cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int));
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMalloc failed!");
        goto Error;
    }

    // Copy input vectors from host memory to GPU buffers.
    cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }

    cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }

    // Launch a kernel on the GPU with one thread for each element.
    addKernel<<<1, size>>>(dev_c, dev_a, dev_b);

    // Check for any errors launching the kernel
    cudaStatus = cudaGetLastError();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));
        goto Error;
    }

    // cudaDeviceSynchronize waits for the kernel to finish, and returns
    // any errors encountered during the launch.
    cudaStatus = cudaDeviceSynchronize();
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
        goto Error;
    }

    // Copy output vector from GPU buffer to host memory.
    cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);
    if (cudaStatus != cudaSuccess) {
        fprintf(stderr, "cudaMemcpy failed!");
        goto Error;
    }

Error:
    cudaFree(dev_c);
    cudaFree(dev_a);
    cudaFree(dev_b);

    return cudaStatus;
}

注意开头的两行对应的是相应的Cuda安装目录,如果你懒得管,你在安装Cuda的时候只要一路点击确定就行了。

还有另外一个问题,相信大家都注意到了,那就是版本的问题,据我所知,Cuda已经出到了9.1,但是MATLAB还是有一定滞后的,但是我们也不能一辈子使用Cuda7.5和VS2012, 我上Mathwork的官方论坛和Stackoverflow搜索了以下,得到了以下网友的回复:

引用块内容
This is how to compile (mexcuda) with Visual Studio 2015 and Cuda 8.0 :
1:Go to: “\toolbox\distcomp\gpu\extern\src\mex\win64”
2:Copy files and rename 2013 to 2015: { “nvcc_msvcpp2013.xml” , “nvcc_msvcpp2013_dynamic.xml”}
3:Replace inside those files “7.5” to “8.0” and “12” to “14”.
4:Done.

我今天实验以下,如果成功了,我再来更新。


3、引用

[1]: http://blog.csdn.net/endlch/article/details/44561535
[2]: http://blog.csdn.net/hanlin_tan/article/details/48790273

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用cuda加速MATLAB程序 的相关文章

  • 如何在 Linux 中分析 PyCuda 代码?

    我有一个简单的 经过测试的 pycuda 应用程序 正在尝试对其进行分析 我尝试过 NVidia 的 Compute Visual Profiler 它运行该程序 11 次 然后发出以下错误 NV Warning Ignoring the
  • cuda中的count3非常慢

    我在 CUDA 中编写了一个小程序 用于计算 C 数组中有多少个 3 并打印它们 include
  • 是否可以在设备函数中调用cufft库调用?

    我在主机代码中使用 cuFFT 库调用 它们工作正常 但我想从内核调用 cuFFT 库 早期版本的 CUDA 没有这种支持 但是有了动态并行性 这可能吗 如果有任何关于如何实现这一目标的示例 那就太好了 尽管在 Kepler cc 3 5
  • cudaMemcpyToSymbol 与 cudaMemcpy [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我试图找出
  • 如何将CUDA时钟周期转换为毫秒?

    我想用一些代码来测量时间within我的内核需要 我已经关注了这个问题 https stackoverflow com questions 11209228 timing different sections in cuda kernel连
  • cudaMemcpyToSymbol 的问题

    我正在尝试复制到恒定内存 但我不能 因为我对 cudaMemcpyToSymbol 函数的用法有误解 我正在努力追随this http developer download nvidia com compute cuda 4 1 rel t
  • 同时使用 2 个 GPU 调用 cudaMalloc 时性能较差

    我有一个应用程序 可以在用户系统上的 GPU 之间分配处理负载 基本上 每个 GPU 都有一个 CPU 线程来启动一个GPU处理间隔当由主应用程序线程定期触发时 考虑以下图像 使用 NVIDIA 的 CUDA 分析器工具生成 作为示例GPU
  • cuda 共享内存 - 结果不一致

    我正在尝试并行缩减以对 CUDA 中的数组求和 目前我传递一个数组来存储每个块中元素的总和 这是我的代码 include
  • 仅使用 CUDA 进行奇异值计算

    我正在尝试使用新的cusolverDnSgesvdCUDA 7 0 用于计算奇异值的例程 完整代码如下 include cuda runtime h include device launch parameters h include
  • 如何在 CUDA 中执行多个矩阵乘法?

    我有一个方阵数组int M 10 以便M i 定位第一个元素i th 矩阵 我想将所有矩阵相乘M i 通过另一个矩阵N 这样我就收到了方阵数组int P 10 作为输出 我看到有不同的可能性 分配不同元素的计算M i 到不同的线程 例如 我
  • 设置最大 CUDA 资源

    我想知道是否可以设置 CUDA 应用程序的最大 GPU 资源 例如 如果我有一个 4GB GPU 但希望给定的应用程序只能访问 2GB 如果它尝试分配更多 就会失败 理想情况下 这可以在进程级别或 CUDA 上下文级别上设置 不 目前没有允
  • CUDA 常量内存是否应该被均匀地访问?

    我的 CUDA 应用程序的恒定内存小于 8KB 既然它都会被缓存 我是否需要担心每个线程访问相同的地址以进行优化 如果是 如何确保所有线程同时访问同一地址 既然它都会被缓存 我是否需要担心每个线程访问相同的地址以进行优化 是的 这缓存本身每
  • 使用 CUDA 进行逐元素向量乘法

    我已经在 CUDA 中构建了一个基本内核来执行逐元素两个复向量的向量 向量乘法 内核代码插入如下 multiplyElementwise 它工作正常 但由于我注意到其他看似简单的操作 如缩放向量 在 CUBLAS 或 CULA 等库中进行了
  • CUDA 矩阵加法时序,按行与按行比较按栏目

    我目前正在学习 CUDA 并正在做一些练习 其中之一是实现以 3 种不同方式添加矩阵的内核 每个元素 1 个线程 每行 1 个线程和每列 1 个线程 矩阵是方阵 并被实现为一维向量 我只需用以下命令对其进行索引 A N row col 直觉
  • cudaSetDevice() 对 CUDA 设备的上下文堆栈有何作用?

    假设我有一个与设备关联的活动 CUDA 上下文i 我现在打电话cudaSetDevice i 会发生什么 Nothing 主上下文取代了堆栈顶部 主上下文被压入堆栈 事实上 这似乎是不一致的 我编写了这个程序 在具有单个设备的机器上运行 i
  • 在 cudaFree() 之前需要 cudaDeviceSynchronize() 吗?

    CUDA 版本 10 1 帕斯卡 GPU 所有命令都发送到默认流 void ptr cudaMalloc ptr launch kernel lt lt lt gt gt gt ptr cudaDeviceSynchronize Is th
  • 有没有一种有效的方法来优化我的序列化代码?

    这个问题缺乏细节 因此 我决定创建另一个问题而不是编辑这个问题 新问题在这里 我可以并行化我的代码吗 还是不值得 https stackoverflow com questions 17937438 can i parallelize my
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 无法在内存位置找到异常源:cudaError_enum

    我正在尝试确定 Microsoft C 异常的来源 test fft exe 中 0x770ab9bc 处的第一次机会异常 Microsoft C 异常 内存位置 0x016cf234 处的 cudaError enum 我的构建环境是 I
  • CUDA 中指令重放的其他原因

    这是我从 nvprof CUDA 5 5 获得的输出 Invocations Metric Name Metric Description Min Max Avg Device Tesla K40c 0 Kernel MyKernel do

随机推荐

  • Kendo UI开发教程(12): Kendo MVVM 数据绑定(一) attr

    Kendo UI MVVM数据绑定支持的绑定属性有 attr checked click custom disabled enabled events html invisible style text value visible 这些属性
  • 储存测试

    declare result code varchar2 400 result info varchar2 400 begin for i in 20170420 20170430 loop 循环体 P JH AUDIT ECS ALL i
  • 找出总分最高的学生

    找出总分最高的学生 TOC 给定N个学生的基本信息 包括学号 由5个数字组成的字符串 姓名 长度小于10的不包含空白字符的非空字符串 和3门课程的成绩 0 100 区间内的整数 要求输出总分最高学生的姓名 学号和总分 输入格式 输入在一行中
  • AOSP预置第三方应用

    一 选择需要编译的aosp版本 下载源码并进行编译 这里可以自行自行参考网络上的文章进行操作AOSP 镜像使用帮助 进入aosp目录 初始化编译环境 选择对应的版本 没有实体机 直接编译运行在虚拟机的版本 source build envs
  • 使用宏来简化,在Nordic52832 的sdk17.0.2中添加自定义Service和attribute

    sdk17 0 2附带的example中 各种类型和函数等都过度包装了 一个很简单的东西 定义了一层又一层 很容易让人看的头皮发麻 为了降低添加Service和处理各种handler的难度 使用宏来简化添加自定义Service和attrib
  • 区块链技术相关论文、文档

    索引 Angaroa的实现 repo Understanding Serenity Part I Abstraction 中文翻译 Understanding Serenity Part 2 Casper 中文翻译 隔离见证技术 set w
  • 华为资深工程师:码农很多,但程序员并不多......

    本文来自 华为人 转载请注明出处 作者 于志国 期间一位驰骋商界多年的老友问 你现在在华为做什么工作呀 我很骄傲地说 系统架构师 可是他却愣了很久 但当我老婆在旁边补上一句 码农 时 老友瞬间秒懂 却把我受伤的心孤独地留在风中凌乱 作为与
  • 组个最小数

    给定数字0 9各若干个 你可以以任意顺序排列这些数字 但必须全部使用 目标是使得最后得到的数尽可能小 注意0不能做首位 例如 给定两个0 两个1 三个5 一个8 我们得到的最小的数就是10015558 现给定数字 请编写程序输出能够组成的最
  • Postman抓包网页请求

    安装postman Interceptor谷歌插件 1 点击软件右下角Capture 2 启用代理 设置端口 3 手动点开谷歌插件 开始获取 4 获取结果可以点击进入详情页 查看接口信息
  • 深入理解计算机系统(第3版) 第十一章 网络编程

    1 客户端 服务器编程模型 采用这个模型 一个应用是由一个服务器进程和一个或者多个客户端进程组成 服务器管理某种资源 并通过操作这种资源来为它的客户端提供某种服务 客户端 服务器模型中的基本操作是事务 transacton 一个客户端 服务
  • 前端面试必备知识点总结(持续更新)

    这篇博客是对前端面试所必须掌握的知识点的总结 并且这篇博客正在持续更新中 面试复习 1 JavaScript 基础 1 执行上下文 作用域 闭包 1 什么是执行上下文 执行上下文是评估和执行JavaScript代码环境的抽象概念 每当Jav
  • 示例代码TestCpp中场景操作浅分析

    参考http blog csdn net honghaier article details 8130947 controller h cpp 示例场景管理类TestController 用于显示所有示例的菜单 testBasic h cp
  • 元宇宙+教育,正在引发哪些剧烈变革?机会在哪里?丨圆桌实录

    图片来源 由无界AI绘画工具生成 2月23日 温州元宇宙创新中心为2023年第一批申请入驻的项目企业举办了签约仪式 温州临境网络科技有限公司 温州好玩文化产业有限公司 温州云兮科技有限公司 筹 等企业完成签约 这意味着 温州当地的文创 教育
  • L2-4 哲哲打游戏PTA

    哲哲是一位硬核游戏玩家 最近一款名叫 达诺达诺 的新游戏刚刚上市 哲哲自然要快速攻略游戏 守护硬核游戏玩家的一切 为简化模型 我们不妨假设游戏有 N 个剧情点 通过游戏里不同的操作或选择可以从某个剧情点去往另外一个剧情点 此外 游戏还设置了
  • Linux网络程序设计-TCP网络编程

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 TCP IP协议是什么 二 端口 三 socket端口 1 两个重要的数据类型sockaddr和sockaddr in 2 基于TCP协议的客户端 服务器
  • GitHub 优秀的 Android 开源项目第二篇——转自多篇网络文章

    原文地址为http www trinea cn Android android open source projects view 作者Trinea 主要介绍那些不错个性化的View 包括ListView ActionBar Menu Vi
  • weex scroller滚动的小烦恼

    背景 前几天的需求开发中 需要完成这样一个功能 这还不简单 一个横向滚动的tag选择功能 一个横向scroller搞定问题 但是做为一个对自己有 要求 的程序员 怎么可能会接受一个死气沉沉的滚动条 为了勾起用户的点击欲望 我毫不犹豫的增加了
  • 微信开发提示未绑定网页开发者

    加入一下就可以了
  • input上边框有阴影(iPhone手机)

    做移动端 发现在苹果手机上input显示有问题 上边框一直有阴影 input的border初始化 box shadow也做了处理 box shadow 0 0 0 fff 在手机端都无效 如图 解决方案 input outline none
  • 利用cuda加速MATLAB程序

    利用cuda加速MATLAB程序 利用cuda加速MATLAB程序 1参考木子超的办法 2参考Tomheaven的方法 3引用 最近因为要做张量的模态积 所以要考虑使用cuda来进行并行的编程 但是c 实在太麻烦 尤其是在有MATLAB的时