1. 程式人生 > >【CUDA】CUDA程式設計:基本框架

【CUDA】CUDA程式設計:基本框架

CUDA的kernel以關鍵字__global__進行宣告,執行kernel的執行緒配置在<<<...>>>中。每一個執行kernel的執行緒都有一個唯一的thread ID,用內建變數threadIdx表示。

下面的例子展示了兩個N個元素的向量相加。

首先定義kernel函式。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>

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

然後是主機端的資料準備和呼叫過程。

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

int main()
{
    const int arraySize = 5;
    const int a[arraySize] = { 1, 2, 3, 4, 5 };
    const int b[arraySize] = { 10, 20, 30, 40, 50 };
    int c[arraySize] = { 0 };

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

    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!");
        return 1;
    }

    return 0;
}

// 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;
}

列印輸出。

相關推薦

CUDACUDA程式設計基本框架

CUDA的kernel以關鍵字__global__進行宣告,執行kernel的執行緒配置在<<<...>>>中。每一個執行kernel的執行緒都有一個唯一的thread ID,用內建變數threadIdx表示。 下面的例子展示了兩個N個元

非同步程式設計Futures

關鍵點 dart是單執行緒語言 同步程式碼會阻塞你的程式 使用Future物件來執行非同步操作 在async函式裡使用await關鍵字來掛起執行知道一個Future操作完成 或者使用then()方法 在async函式裡使用try-catch表示式捕獲錯誤 或者

10Java集合基本體系概述

一、Java集合概述 1.1、什麼是集合? 集合就是將若干用途相同、近似的“資料”結合成一個整體。 1.2、集合的分類 集合從體系上分為三種:Set(集),List(列表),Map(對映) 列表(List):List集合區分元素的順序,允許包

OpenCLOpenCL程式設計主機與裝置的資料傳輸

主機和裝置之間資料傳輸最簡單的函式是clEnqueueReadBuffer和clEnqueueWriteBuffer。 另外還有clEnqueueReadImage和clEnqueueWriteImage。 和clEnqueueReadBufferRect和clE

day 11python程式設計從入門到實踐學習筆記-基於Django框架的Web開發-Django入門(二)

學習筆記目錄 第十八章 Django入門(二) 建立應用程式 django專案由一系列應用程式組成,他們協同工作,讓專案稱謂一個整體。首先我們執行命令python manage.py startapp learning_logs。 定義模型

day 15python程式設計從入門到實踐學習筆記-基於Django框架的Web開發-使用者賬戶(二)

學習筆記目錄 第十九章 使用者賬戶(二) 建立使用者賬戶 這一部分我們來建立使用者註冊和身份驗證系統。 應用程式users 首先使用命令python manage.py startapp users建立名為users的應用程式,現在你的目錄

day 12python程式設計從入門到實踐學習筆記-基於Django框架的Web開發-Django入門(三)

學習筆記目錄 第十八章 Django入門(三) 建立網頁:學習筆記主頁 使用django建立網頁通常分三個階段:定義URL、編寫檢視和編寫模板。 首先必須定義URL模式,其描述了URL是

演算法cuda 快排

核心程式碼: __global__ void cdp_simple_quicksort(unsigned int *data, int left, int right, int depth) { // If we're too deep or there are few el

AICUDA win10 安裝配置教程

《CUDA win10 安裝配置教程》 下載地址:https://developer.nvidia.com/cuda-toolkit-archive,打不開的話重試幾次。   

AICUDA+win10-1803安裝配置教程

CUDA安裝配置教程 下載CUDA 下載地址:https://developer.nvidia.com/cuda-toolkit-archive 打不開的話重試幾次。官網給出電腦驅動程式和CUDA的

轉載演講實錄百度大規模深度學習應用實踐和開源AI框架PaddlePaddle

導語:本文根據PaddlePaddle技術負責人、百度NLP技術委員會主席於佃海在今年英特爾人工智慧大會上的演講——《百度大規模深度學習應用實踐和開源AI框架PaddlePaddle》整理而成。 PaddlePaddle技術負責人、百度NLP技術委員會主席於佃海 正文: 很高興能

windows基礎應用程式程式設計(一)基本框架

從一開始程式設計時,大家面對著黑乎乎的控制檯視窗,就開始幻想什麼時候能進入windows下進行程式設計。能夠編寫出具有形形色色視窗的人往往都被我們認為是牛人。而從控制檯視窗進入windows下進行程式設計,對於初學者來講,絕對是一個很難跨越的坎。對此,自己也深有體會。因此,

sparkSpark運算元RDD基本轉換操作–map、flagMap、distinct

map將一個RDD中的每個資料項,通過map中的函式對映變為一個新的元素。 輸入分割槽與輸出分割槽一對一,即:有多少個輸入分割槽,就有多少個輸出分割槽。 hadoop fs -cat /tmp/lxw1234/1.txthello worldhello sparkhello

ucosii筆記1移植

err color border 工作 mrc pro read cfg mut 前言 ucosii的代碼,可以分為兩部分:與cpu無關的代碼,與cpu有關。移植的主要工作就是修改與cpu有關的部分代碼。 ucosii的代碼結構 與cpu無關的代碼

轉載Caffe學習運行caffe自帶的兩個簡單例子

0.00 練習 siam 其它 sudo 單例 復制 腳本 policy 原文:http://www.cnblogs.com/denny402/p/5075490.html 為了程序的簡潔,在caffe中是不帶練習數據的,因此需要自己去下載。但在caffe根目錄下的data

線下活動北京敏捷開發促進項目管理創新變革

經理 如何 image ext p s 優秀 pla cnblogs 項目經理 您在項目中是否經常遇到項目目標不清晰的問題?   您在項目中是否經常遇到項目需求不斷變更的難題?   您在項目中是否經常遇到跨部門跨專業溝通不暢的困惑?   您在項目的執行過程中是否面臨

javaString類的基本方法

lastindex bool bsp sta substr 方法 相等 當前 start Java的String類基本方法 一、構造函數 函數 返回值 作用 String(byte[] bytes) String 通過byte數組構造字符串對象 String(

springSpring Boot定制自己的starter

cat 交互 miss factor 如何 指定 boot.s 倉庫 dmi 概念 在學習Spring Boot的過程中,接觸最多的就是starter。可以認為starter是一種服務——使得使用某個功能的開發者不需要關註各種依賴庫的處理,不需要具體的配置信息,由

quickhybrid如何實現一個Hybrid框架

釘釘 都是 不足 快速 view 環境 視野 swe 開發 章節目錄 【quickhybrid】如何實現一個跨平臺Hybrid框架 【quick hybrid】架構一個Hybrid框架 【quick hybrid】H5和Native交互原理 【quick hybrid】J

Excel坐下,VLOOKUP基本操作

多說 bsp img image 找到 spa 單元格 詳細介紹 問題 坐下,VLOOKUP基本操作 VLOOKUP如何使用我就不在這裏詳細介紹了,簡單說一下好了。 如上圖,第一個填寫你要查找的值,第二個空選取你查找的範圍,第三個空填你要得到第幾列的值,最後