post

CUDA

 cuda person encoding in laptop
Photo by Lukas on Pexels.com

CUDA (Compute Unified Device Architecture) es una tecnología de NVIDIA, por lo que si tienes una tarjeta gráfica de otro fabricante, como AMD, no sería compatible con CUDA. Se debe explorar alternativas, como OpenCL, que es un estándar abierto de programación para plataformas heterogéneas.

CUDA ha sido ampliamente adoptado en la comunidad de desarrollo, especialmente en áreas que se benefician de la capacidad de procesamiento masivamente paralelo de las GPUs. Además, otras compañías y proyectos han desarrollado tecnologías similares, pero CUDA es específico de las GPUs de NVIDIA.

A continuación se tiene un ejemplo sencillo en CUDA que realiza la suma de dos vectores. Este ejemplo se puede ejecutar en una GPU compatible con CUDA.

Código

#include <stdio.h>

// Kernel CUDA para sumar dos vectores
__global__ void vectorSum(float *a, float *b, float *result, int size) {
    int index = blockIdx.x * blockDim.x + threadIdx.x;
    if (index < size) {
        result[index] = a[index] + b[index];
    }
}

int main() {
    const int size = 1024;  // Tamaño de los vectores
    const int threadsPerBlock = 256;
    const int blocksPerGrid = (size + threadsPerBlock - 1) / threadsPerBlock;

    // Declaración de vectores en el host
    float hostVectorA[size], hostVectorB[size], hostResult[size];

    // Inicialización de los vectores en el host
    for (int i = 0; i < size; ++i) {
        hostVectorA[i] = i;
        hostVectorB[i] = 2 * i;
    }

    // Declaración de punteros para los vectores en el dispositivo (GPU)
    float *deviceVectorA, *deviceVectorB, *deviceResult;

    // Reserva de memoria en el dispositivo
    cudaMalloc((void **)&deviceVectorA, size * sizeof(float));
    cudaMalloc((void **)&deviceVectorB, size * sizeof(float));
    cudaMalloc((void **)&deviceResult, size * sizeof(float));

    // Copia de datos desde el host al dispositivo
    cudaMemcpy(deviceVectorA, hostVectorA, size * sizeof(float), cudaMemcpyHostToDevice);
    cudaMemcpy(deviceVectorB, hostVectorB, size * sizeof(float), cudaMemcpyHostToDevice);

    // Lanzamiento del kernel CUDA
    vectorSum<<<blocksPerGrid, threadsPerBlock>>>(deviceVectorA, deviceVectorB, deviceResult, size);

    // Copia de resultados desde el dispositivo al host
    cudaMemcpy(hostResult, deviceResult, size * sizeof(float), cudaMemcpyDeviceToHost);

    // Impresión de resultados
    for (int i = 0; i < size; ++i) {
        printf("%f + %f = %f\n", hostVectorA[i], hostVectorB[i], hostResult[i]);
    }

    // Liberación de memoria en el dispositivo
    cudaFree(deviceVectorA);
    cudaFree(deviceVectorB);
    cudaFree(deviceResult);

    return 0;
}

Este programa realiza la suma de dos vectores en paralelo utilizando. Se debe de tener en cuenta que este es un ejemplo básico y que el desarrollo puede involucrar consideraciones adicionales, como la optimización del tamaño de los bloques y la gestión de la memoria en el dispositivo.

Bibliotecas en python

Para ejecutarse desde Python, existen varias bibliotecas y herramientas que permiten integrarlas en programas escritos en Python

PyCUDA

PyCUDA es una biblioteca que proporciona enlaces de Python para CUDA. Permite escribir y aprovechar las capacidades de cómputo en paralelo de las GPUs de NVIDIA. Se puede instalar PyCUDA utilizando pip

pip install pycuda

Numba

Numba es una biblioteca de Python que permite la compilación JIT (Just-In-Time) de funciones Python para ejecución en GPU. Puedes utilizar la funcionalidad @cuda.jit para decorar funciones que se ejecutarán en la GPU.

from numba import cuda

@cuda.jit
def vector_sum(a, b, result):
    idx = cuda.grid(1)
    if idx < len(a):
        result[idx] = a[idx] + b[idx]

CuPy

CuPy es una biblioteca similar a NumPy pero diseñada para ejecutarse en GPU. Proporciona una interfaz familiar para realizar operaciones en GPU y puede ser una alternativa eficiente para cálculos numéricos.

import cupy as cp

# Crear arrays en GPU
a_gpu = cp.array([1, 2, 3])
b_gpu = cp.array([4, 5, 6])

# Realizar la suma en GPU
result_gpu = a_gpu + b_gpu

# Transferir el resultado de vuelta a la CPU si es necesario
result_cpu = cp.asnumpy(result_gpu)

Estas bibliotecas permiten integrar código CUDA directamente en programas Python, facilitando el desarrollo de aplicaciones de cómputo en paralelo. Hay que tener en cuenta que, al utilizarlas en Python, aún se necesitará tener instalado el Toolkit de CUDA de NVIDIA y controladores compatibles con tu GPU.

Leave a Reply

Your email address will not be published. Required fields are marked *