【学习AI-相关路程-工具使用-自我学习-cudavisco-开发工具尝试-基础样例 (2)】

本文主要是介绍【学习AI-相关路程-工具使用-自我学习-cudavisco-开发工具尝试-基础样例 (2)】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【学习AI-相关路程-工具使用-自我学习-cuda&visco-开发工具尝试-基础样例 (2)】

  • 1、前言
  • 2、环境说明
  • 3、总结说明
  • 4、工具安装
      • 0、验证cuda
      • 1、软件下载
      • 2、插件安装
  • 5、软件设置与编程练习
      • 1、创建目录
      • 2、编译软件进入目录&创建两个文件
      • 3、编写配置文件
      • 5、编写代码文件
      • 6、调试&验证
      • 7、代码解读
          • (1)包含头文件和定义CUDA内核
          • (2)主函数内的变量定义和内存分配
          • (3)初始化向量并复制到设备
          • (4)内核调用
          • (5)检查错误和回复结果
          • (6)验证结果
          • (7)清理内存
  • 6、代码链接
  • 7、细节部分
      • 1、问题1:一个错误
      • 2、问题:使用命令nvidia-smi,无法调出如下信息。
      • 3、Tasks:configure tasks,自动创建tasks.json
  • 8、总结

1、前言

我们之前安装了cuda,但是我们其实是无法直接使用cuda的,还需要编译器,类似前端,供我们输入代码,好让我们可以将思想延伸。

同时也本篇,也是续写上一篇,我们将在本篇安装开发工具,来写一个简单dome,调用cuda平台相关套件,相当hello world。

前文链接:【学习AI-相关路程-工具使用-自我学习-NVIDIA-cuda-工具安装 (1)】

2、环境说明

这里准备安装Visual Studio code 这个工具,可以看到,只用这个工具是支持不同系统的,visual studio,只是支持win下。

下载链接:https://visualstudio.microsoft.com/zh-hans/

在这里插入图片描述

当然如果使用运行cuda,还可以使用Python 语言,是使用另一个工具,目前自己刚学到这里,以后要是学了再写文章。

3、总结说明

(1)了解Visual Studio code
一般来说,想编写程序的话,或多或少,都会了解到这个工具,即使没用过,也会听过。更多的可以看文档。
链接文档:https://code.visualstudio.com/docs
在这里插入图片描述
如果因为不太好,可以选择一些翻译工具。

(2)装插件和cuda
安装好了编译工具后,就是安装插件工具,因为Visual Studio code本身支持很多,不是一起全部安装的,需要根据自己需求灵活选。

(3)练习代码
最后就是练习一下代码,调用对库,在编译好的软件,运行过程中,就是在使用GPU了。我们通过这个简单样例,来熟悉一下一些库。

4、工具安装

0、验证cuda

使用其他工具前,先要验证下,自己是否已经支持了cuda,或者说是否已经安装了cuda。

nvcc -V
或者
nvcc --version

一般来说安装好后,会出现如下信息。
在这里插入图片描述

1、软件下载

如下链接,选择一个自己合适的版本。

下载链接:https://visualstudio.microsoft.com/zh-hans/#vscode-section

在这里插入图片描述
安装命令:

sudo dpkg -i code_1.89.0-1714530869_amd64.deb

2、插件安装

如下图,我这里编写c/c++语言和cuda,一搜基本就会出来。
在这里插入图片描述

如下是我自己的选择的插件
在这里插入图片描述

5、软件设置与编程练习

1、创建目录

我们先在桌面创建一个文件夹,自己自己定就好,不必和我一致。

在这里插入图片描述

2、编译软件进入目录&创建两个文件

我们用Visual Studio code软件进入对应目录,然后创建两个文件。之后就是准备编写内容了。
在这里插入图片描述

3、编写配置文件

配置文件,顾名思义,就是告诉编译器,去哪里找工具,使用什么工具编译等等配置信息的文件。

{"version": "2.0.0","tasks": [{"label": "Build CUDA project","type": "shell","command": "/usr/local/cuda/bin/nvcc","args": ["-arch=sm_35", // 根据你的GPU架构适当修改"${file}","-o","${fileDirname}/${fileBasenameNoExtension}.out"],"group": {"kind": "build","isDefault": true},"problemMatcher": "$gcc"}]
}

如下为截图。
在这里插入图片描述

5、编写代码文件

代码文件,就是我们实际要编写代码的文件,也是我们想法延伸。

#include <stdio.h>// CUDA Kernel for Vector Addition
__global__ void vecAdd(float *A, float *B, float *C, int N) {int i = blockDim.x * blockIdx.x + threadIdx.x;if (i < N) {C[i] = A[i] + B[i];}
}int main() {int N = 1024; // Size of vectorsfloat *h_A, *h_B, *h_C; // Host vectorsfloat *d_A, *d_B, *d_C; // Device vectors// Allocate memory on hosth_A = (float *)malloc(N * sizeof(float));h_B = (float *)malloc(N * sizeof(float));h_C = (float *)malloc(N * sizeof(float));// Initialize host vectorsfor (int i = 0; i < N; i++) {h_A[i] = i;h_B[i] = i * 2;}// Allocate memory on devicecudaMalloc(&d_A, N * sizeof(float));cudaMalloc(&d_B, N * sizeof(float));cudaMalloc(&d_C, N * sizeof(float));// Copy host vectors to devicecudaMemcpy(d_A, h_A, N * sizeof(float), cudaMemcpyHostToDevice);cudaMemcpy(d_B, h_B, N * sizeof(float), cudaMemcpyHostToDevice);// Kernel launchint threadsPerBlock = 256;int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;vecAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, N);// Check for any errors launching the kernelcudaError_t err = cudaGetLastError();if (err != cudaSuccess) {fprintf(stderr, "Failed to launch vecAdd kernel (error code %s)!\n", cudaGetErrorString(err));exit(EXIT_FAILURE);}// Copy result back to hostcudaMemcpy(h_C, d_C, N * sizeof(float), cudaMemcpyDeviceToHost);// Check for any errors after the kernel launcherr = cudaGetLastError();if (err != cudaSuccess) {fprintf(stderr, "Failed to copy vector C from device after kernel execution (error code %s)!\n", cudaGetErrorString(err));exit(EXIT_FAILURE);}// Verify resultsbool success = true;for (int i = 0; i < N; i++) {if (h_C[i] != h_A[i] + h_B[i]) {printf("Error at position %d\n", i);success = false;break;}}if (success) {printf("Vector addition successful!\n");}// Free memoryfree(h_A);free(h_B);free(h_C);cudaFree(d_A);cudaFree(d_B);cudaFree(d_C);return 0;
}

以下为截图
在这里插入图片描述

6、调试&验证

自己在调试

(1)调试
在这里插入图片描述

(2)成功
在这里插入图片描述

7、代码解读

本代码是在网上找到一个样例,是一个使用CUDA进行向量加法的简单例子。

简单理解下,以后看多了大概就明白了。

(1)包含头文件和定义CUDA内核
#include <stdio.h>// CUDA Kernel for Vector Addition
__global__ void vecAdd(float *A, float *B, float *C, int N) {int i = blockDim.x * blockIdx.x + threadIdx.x;if (i < N) {C[i] = A[i] + B[i];}
}
(2)主函数内的变量定义和内存分配
int main() {int N = 1024; // Size of vectorsfloat *h_A, *h_B, *h_C; // Host vectorsfloat *d_A, *d_B, *d_C; // Device vectorsh_A = (float *)malloc(N * sizeof(float));h_B = (float *)malloc(N * sizeof(float));h_C = (float *)malloc(N * sizeof(float));cudaMalloc(&d_A, N * sizeof(float));cudaMalloc(&d_B, N * sizeof(float));cudaMalloc(&d_C, N * sizeof(float));
(3)初始化向量并复制到设备
    for (int i = 0; i < N; i++) {h_A[i] = i;h_B[i] = i * 2;}cudaMemcpy(d_A, h_A, N * sizeof(float), cudaMemcpyHostToDevice);cudaMemcpy(d_B, h_B, N * sizeof(float), cudaMemcpyHostToDevice);
(4)内核调用
    int threadsPerBlock = 256;int blocksPerGrid = (N + threadsPerBlock - 1) / threadsPerBlock;vecAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B, d_C, N);
(5)检查错误和回复结果
    cudaError_t err = cudaGetLastError();if (err != cudaSuccess) {fprintf(stderr, "Failed to launch vecAdd kernel (error code %s)!\n", cudaGetErrorString(err));exit(EXIT_FAILURE);}cudaMemcpy(h_C, d_C, N * sizeof(float), cudaMemcpyDeviceToHost);
(6)验证结果
    bool success = true;for (int i = 0; i < N; i++) {if (h_C[i] != h_A[i] + h_B[i]) {printf("Error at position %d\n", i);success = false;break;}}if (success) {printf("Vector addition successful!\n");}
(7)清理内存
    free(h_A);free(h_B);free(h_C);cudaFree(d_A);cudaFree(d_B);cudaFree(d_C);

6、代码链接

代码链接:https://download.csdn.net/download/qq_22146161/89273073

7、细节部分

1、问题1:一个错误

具体什么错误有点记不清了,这里记录下吧。
在这里插入图片描述

2、问题:使用命令nvidia-smi,无法调出如下信息。

在这里插入图片描述
如上图,自己在安装过程中,突然发现nvidia-smi命令,因为一直安装各种东西,应该是影响到了,不反馈信息,后重启解决了

3、Tasks:configure tasks,自动创建tasks.json

稍微有点时间,不过我没记错的话,使用 查看>>命令面板,可以直接创建这个tasks.json文件。
在这里插入图片描述
如下步骤

在这里插入图片描述
在这里插入图片描述

8、总结

很多时候,其实是无法理解每一步,只有常看,才能大致记住,更多调试,后续也会慢慢学习。

这篇关于【学习AI-相关路程-工具使用-自我学习-cudavisco-开发工具尝试-基础样例 (2)】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/966204

相关文章

java相关网站

https://www.jcp.org/en/home/index (Java社区流程 处理JSR:Java规范请求)https://docs.oracle.com/en/(oracle java官方文档)https://www.infoq.cn/(infoq )http://tutorials.jenkov.com/

java之反射工具类ReflectionUtil

import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ReflectionUtil {     /***      * 获取私有成员变量的值      *       */     publ

使用Array实现Java堆栈

本教程给出了使用Array 实现Stack数据结构的示例。堆栈提供将新对象放在堆栈上(方法push())并从堆栈中获取对象(方法pop())。堆栈根据后进先出(LIFO)返回对象。请注意,JDK提供了一个默认的Java堆栈实现作为类java.util.Stack。 适用于所有堆栈实现的两个强制操作是: push():数据项放置在堆栈指针指向的位置。pop():从堆栈指针指向的位置删除并返回数据

Spring Boot - 使用类类型信息获取所有已加载的bean

Spring启动会在内部加载大量bean,以最少的配置运行您的应用程序。在这个例子中,我们将学习如何找出所有那些Spring boot加载的bean及其类类型信息。 使用ApplicationContext获取所有已加载的bean 要自动执行方法,当应用程序完全加载时,我正在使用CommandLineRunner接口。CommandLineRunner用于指示bean 在Spring应用程序中

使用ThreadPoolExecutor创建线程池有哪些关键参数

1、ThreadPoolExecutor类的全参数构造方法: /*** Creates a new {@code ThreadPoolExecutor} with the given initial* parameters.** @param corePoolSize the number of threads to keep in the pool, even* if they

Linux命令学习之二

每日一结 ​               命令置换:是将一个命令的输出作为另一个命令的参数,命令格式如下: commond1 `command2` 其中,命令command2的输出将作为命令command1的参数,需要注意的是, 命令置换的单引号为ESC键下方的 ` 其意思就是说,先运行单引号内的命令,再将其命令作为

Linux命令学习之一

每日一结                                                                                        注:当用户不确定一个软件包的类型时, 可使用file命令查看文件类型

标准I/O相关函数

一、打开一个流 这三个函数的区别是: (1)fopen打开路径名由pathname指示的一个文件 (2)freopen常用于一个打开的流重新定向。比如stdout是标准输出,我们可以把它重定向到由path指定的一个文件。 (3)fdopen取一个现存的文件描述符,并使一个标准的I/O流与该描述符相结合。 总结如下: 二、一步步探究

文件I/O相关函数

一、文件描述符 对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描叙符。当读、写一个文件时,用open或creat返回的文件描述符标识该文件,将其作为参数传送给read或write。 按照惯例,UNIX shell使文件描述符0与进程的标准输入相结合,文件描述符1与标准输出相结合,文件描述符2与标准出

关于Java的数组的使用

关于一维数组的使用 代码示例一如下: package com;public class test_array {public static void main(String[] args){//1.如何定义 一个 数组//1.1数组的声明String[] names;int[] scores;//1.2数组的初始化://1.2.1静态初始化:初始化数组与数组元素赋值同时进行nam