• Ubuntu 安装 CUDA 与 OPENCL


            前言:最近需要做一些GPU并行计算,因而入坑CUDA和OPENCL,两者都有用到一些,刚好有点时间,同时记录一些学习过程,排掉一些坑,这篇是环境安装篇,基本跟着走就没什么问题,环境:ubuntu18.04 / ubuntu20.04 显卡:Nvidia

    一、CUDA安装

            1.查看电脑是否识别GPU
    lspci | grep -i nvidia
    

    在这里插入图片描述

            2.查看电脑可以安装的显卡驱动版本
      ubuntu-drivers devices
    

    在这里插入图片描述

            3.安装显卡驱动,选择上图的recommended
    1. sudo apt install nvidia-driver-XXX
    2. reboot #重启
            4.查看显卡信息
    nvidia-smi
    

    在这里插入图片描述

            5.安装CUDA

            到nivida官网下载自己可安装的版本

    在这里插入图片描述

            复制Base Installer的执行代码,下载脚本(3个多G,可能有点久)

    wget https://developer.download.nvidia.com/compute/cuda/11.4.0/local_installers/cuda_11.4.0_470.42.01_linux.run #选择自己的版本
    

            运行脚本进行安装cuda库

    sudo sh cuda_11.4.0_470.42.01_linux.run
    

            在弹出的安装界面中选“continue”,如果选了会跳出安装,就说明安装失败,给了失败日志的路径,可以自己查看原因。
    在这里插入图片描述

            进入下一步,输入accept

    在这里插入图片描述

            把Driver选项的X去掉,不然它会再给你装一次驱动,会冲突,报错。然后选择Install

    在这里插入图片描述

            等待安装,没什么问题就成功了。

            6.配置环境变量
    gedit ~/.bashrc
    

            最后一行增加

    1. export PATH=$PATH:/usr/local/cuda/bin
    2. export CUDA_HOME=$CUDA_HOME:/usr/local/cuda

            注意查看自己的cuda真是安装路径

            7.检查是否安装成功

            重新打开终端

    nvcc -V
    

    在这里插入图片描述

            8.添加cuda lib 路径

            注意自己的版本号

    1. sudo echo '/usr/local/cuda-11.4/lib64/' >> /etc/ld.so.conf
    2. sudo ldconfig

            CUDA安装成功之后会在终端当前所在目录库生成一个NVIDIA_CUDA-11.4_Samples的编程例子的文件夹,可以用来测试。直接进去目录里面make就行。

    二、OPENCL安装

            1.安装

            其实CUDA安装是包含了OPENCL的,但是你要使用OPENCL还需要配置一下。

            也可以单独安装头文件和库

    1. sudo apt install opencl-headers
    2. sudo apt install ocl-icd-libopencl1
    3. sudo apt install ocl-icd-opencl-dev
    4. sudo apt install clinfo
    5. #sudo apt install intel-opencl-icd #Install NEO OpenCL runtime for Intel GPU

            查看电脑当前安装信息

    clinfo
    

    在这里插入图片描述

            基本OK,接下来就可以愉快的写代码了。

            2.测试opencl
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <string.h>
    4. #ifdef MAC
    5. #include <OpenCL/cl.h>
    6. #else
    7. #include <CL/cl.h>
    8. #endif
    9. int main() {
    10. /* Host data structures */
    11. cl_platform_id *platforms;
    12. //每一个cl_platform_id 结构表示一个在主机上的OpenCL执行平台,就是指电脑中支持OpenCL的硬件,如nvidia显卡,intel CPU和显卡,AMD显卡和CPU等
    13. cl_uint num_platforms;
    14. cl_int i, err, platform_index = -1;
    15. /* Extension data */
    16. char* ext_data;
    17. size_t ext_size;
    18. const char icd_ext[] = "cl_khr_icd";
    19. //要使platform工作,需要两个步骤。1 需要为cl_platform_id结构分配内存空间。2 需要调用clGetPlatformIDs初始化这些数据结构。一般还需要步骤0:询问主机上有多少platforms
    20. /* Find number of platforms */
    21. //返回值如果为-1就说明调用函数失败,如果为0标明成功
    22. //第二个参数为NULL代表要咨询主机上有多少个platform,并使用num_platforms取得实际flatform数量。
    23. //第一个参数为1,代表我们需要取最多1个platform。可以改为任意大如:INT_MAX整数最大值。但是据说0,否则会报错,实际测试好像不会报错。下面是步骤0:询问主机有多少platforms
    24. err = clGetPlatformIDs(5, NULL, &num_platforms);
    25. if(err < 0) {
    26. perror("Couldn't find any platforms.");
    27. exit(1);
    28. }
    29. printf("I have platforms: %d\n", num_platforms); //本人计算机上显示为2,有intel和nvidia两个平台
    30. /* Access all installed platforms */
    31. //步骤1 创建cl_platform_id,并分配空间
    32. platforms = (cl_platform_id*)
    33. malloc(sizeof(cl_platform_id) * num_platforms);
    34. //步骤2 第二个参数用指针platforms存储platform
    35. clGetPlatformIDs(num_platforms, platforms, NULL);
    36. /* Find extensions of all platforms */
    37. //获取额外的平台信息。上面已经取得了平台id了,那么就可以进一步获取更加详细的信息了。
    38. //一个for循环获取所有的主机上的platforms信息
    39. for(i=0; i<num_platforms; i++)
    40. {
    41. /* Find size of extension data */
    42. //也是和前面一样,先设置第三和第四个参数为0NULL,然后就可以用第五个参数ext_size获取额外信息的长度了。
    43. err = clGetPlatformInfo(platforms[i],
    44. CL_PLATFORM_EXTENSIONS, 0, NULL, &ext_size);
    45. if(err < 0)
    46. {
    47. perror("Couldn't read extension data.");
    48. exit(1);
    49. }
    50. printf("The size of extension data is: %d\n", (int)ext_size);//我的计算机显示224.
    51. /* Access extension data */
    52. //这里的ext_data相当于一个缓存,存储相关信息。
    53. ext_data = (char*)malloc(ext_size);
    54. //这个函数就是获取相关信息的函数,第二个参数指明了需要什么样的信息,如这里的CL_PLATFORM_EXTENSIONS表示是opencl支持的扩展功能信息。我计算机输出一大串,机器比较新(专门为了学图形学而购置的电脑),支持的东西比较多。
    55. clGetPlatformInfo(platforms[i], CL_PLATFORM_EXTENSIONS,
    56. ext_size, ext_data, NULL);
    57. printf("Platform %d supports extensions: %s\n", i, ext_data);
    58. //这里是输出生产商的名字,比如我显卡信息是:NVIDIA CUDA
    59. char *name = (char*)malloc(ext_size);
    60. clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME,
    61. ext_size, name, NULL);
    62. printf("Platform %d name: %s\n", i, name);
    63. //这里是供应商信息,我显卡信息:NVIDIA Corporation
    64. char *vendor = (char*)malloc(ext_size);
    65. clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR,
    66. ext_size, vendor, NULL);
    67. printf("Platform %d vendor: %s\n", i, vendor);
    68. //最高支持的OpenCL版本,本机显示:OpenCL1.1 CUDA 4.2.1
    69. char *version = (char*)malloc(ext_size);
    70. clGetPlatformInfo(platforms[i], CL_PLATFORM_VERSION,
    71. ext_size, version, NULL);
    72. printf("Platform %d version: %s\n", i, version);
    73. //这个只有两个值:full profile 和 embeded profile
    74. char *profile = (char*)malloc(ext_size);
    75. clGetPlatformInfo(platforms[i], CL_PLATFORM_PROFILE,
    76. ext_size, profile, NULL);
    77. printf("Platform %d full profile or embeded profile?: %s\n", i, profile);
    78. /* Look for ICD extension */
    79. //如果支持ICD这一扩展功能的platform,输出显示,本机的Intel和Nvidia都支持这一扩展功能
    80. if(strstr(ext_data, icd_ext) != NULL)
    81. platform_index = i;
    82. //std::cout<<"Platform_index = "<<platform_index<<std::endl;
    83. printf("Platform_index is: %d\n", platform_index);
    84. /* Display whether ICD extension is supported */
    85. if(platform_index > -1)
    86. printf("Platform %d supports the %s extension.\n",
    87. platform_index, icd_ext);
    88. //释放空间
    89. free(ext_data);
    90. free(name);
    91. free(vendor);
    92. free(version);
    93. free(profile);
    94. }
    95. if(platform_index <= -1)
    96. printf("No platforms support the %s extension.\n", icd_ext);
    97. /* Deallocate resources */
    98. free(platforms);
    99. return 0;
    100. }

            用gcc编译以上程序:

    gcc opencl_hello.c -o opencl_hello -lOpenCL
    

            若有类似如下输出,则表示opencl配置正确:
    在这里插入图片描述

  • 相关阅读:
    柴油发电机测试的工作原理
    数组 [数据结构][Java]
    5、nerf++(pytorch)
    nginx location / 区别
    深入浅出学习透析Nginx服务器的基本原理和配置指南「初级实践篇 」
    STM32简介
    JavaWeb Mybatis-01-Mybatis的简介:用对话的方式让你明白为什么要使用Mybatis
    php比特教务选排课系统的设计与实现毕业设计源码301826
    虚拟机与主机互传文件方法分享
    pg distinct 改写递归优化(德哥的思路)
  • 原文地址:https://blog.csdn.net/qq_19734597/article/details/133084203