Программирование CUDA без стресса с использованием Go и C

программирование CUDA с помощью Идти немного сложнее, чем в других языках. Хотя есть несколько отличных пакетов, таких как mumaxдокументация плохая, не хватает примеров и ее трудно использовать.
CUDA для Стак что лучшая альтернатива — это использовать Командный cgo и вызвать внешнюю функцию с вашим Cuda Kernel, Это то, что я сделаю в этом примере, где я умножаю две матрицы, используя CUDA,
Если вы хотите узнать больше о CUDA программирование, прочитайте моя статья,

ядро

Я создал Простое ядро которая имеет функцию ядра и вспомогательную функцию, которая вызывается извне. Обратите внимание, что я использовал внешний C потому что это как ОЦП вызывает функции:
#include 
#include 
 

__global__ void vecmul(float *A, float* B, float *C, int size)
{
    // Row and Column indexes: 
    int row = blockIdx.y*blockDim.y+threadIdx.y;
    int col = blockIdx.x*blockDim.x+threadIdx.x;

    // Are they bellow the maximum?
    if (col < size && row < size) {
       float result = 0;
       for(int ix=0;ixextern "C" {

    void maxmul(float *A, float* B, float *C, int size) {

        int total = size*size;

        // Allocate device memory:
        float* gpu_A;
        float* gpu_B;
        float* gpu_C;
        int msize = total * sizeof(float);
        cudaMalloc((void**)&gpu_A, msize);
        cudaMemcpy(gpu_A,A,msize,cudaMemcpyHostToDevice);
        cudaMalloc((void**)&gpu_B, msize);
        cudaMemcpy(gpu_B,B,msize,cudaMemcpyHostToDevice);
        cudaMalloc((void**)&gpu_C,msize);

        // Blocks & grids:
        dim3 blocks(size,size);
        dim3 grid(1,1);

        // Call the kernel:
        vecmul<<>>(gpu_A,gpu_B,gpu_C,size);

        // Get the result Matrix:
        cudaMemcpy(C,gpu_C,msize,cudaMemcpyDeviceToHost);

        //Free device matrices
        cudaFree(gpu_A);
        cudaFree(gpu_B);
        cudaFree(gpu_C);
    }

}

vecmul () функция является ядром и maxmul () функция является помощником. Его функция заключается в выделении памяти в GPUскопируйте параметры, вызовите ядро ​​и скопируйте результат. Значения передаются по ссылке.

Перейти код

package main

/*
void maxmul(float *A, float* B, float *C, int size);
#cgo LDFLAGS: -L. -L./ -lmaxmul
*/
import "C"

import "fmt"

func Maxmul(a ()C.float, b ()C.float, c ()C.float, size int) {
	C.maxmul(&a(0), &b(0), &c(0), C.int(size))
}

func main() {
	//in := ()C.float{1.23, 4.56}
    //C.test(&in(0)) // C 1.230000 4.560000
	a := ()C.float{-1,2,4,0,5,3,6,2,1}
	b := ()C.float{3,0,2,3,4,5,4,7,2}
	var c ()C.float = make(()C.float, 9)
	Maxmul(a,b,c,3)
	fmt.Println(c)
}

Перед импортом С пакет, который позволяет вызывать внешние функции в чистом виде С код (extern C), я передаю конфигурацию ОЦПс указанием прототипа функции С путь к Lib и его имя.

Я должен был создать обертка функция в Идти код для вызова внешней функции, чтобы сделать вещи проще. Он просто передает ссылку на массивы (адрес первой позиции) и размер массива (в данном случае 3×3 = 9). В CUDA мы работаем с плоский матрицы.

Я использовал тип C.float создавать ломтики содержащий мои массивы (преобразованные в векторы). Затем я вызвал функцию. Обратите внимание, что я передал размер каждой строки (или столбца).

составление

Для компиляции С Код используйте команду:

nvcc --ptxas-options=-v --compiler-options '-fPIC' -o libmaxmul.so --shared maxmul.cu

Вам нужно установить CUDA и драйвер Nvidia!

Тогда просто запустите Идти код с командой:

go run maxmul.go
...
(19 36 16 27 41 31 28 15 24)

И это результат умножения матриц!



Источник: Программирование CUDA без стресса с использованием Go и C


Похожие материалы по теме: Программирование CUDA без стресса с использованием Go и C

Leave a comment