Напишите код умножения двух векторов, использовать pycuda. Сравните время с декоратором и без декоратора.
python
import pycuda.autoinit
import pycuda.driver as cuda
from pycuda.compiler import SourceModule
import numpy as np
import time
# Исходный код ядра CUDA для умножения векторов
kernel_code = """
__global__ void multiply_vectors(float *a, float *b, float *c, int size)
{
int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < size)
{
c[i] = a[i] * b[i];
}
}
"""
# Компилирование кода ядра CUDA
mod = SourceModule(kernel_code)
# Получение функции ядра CUDA
multiply_vectors = mod.get_function("multiply_vectors")
# Размер вектора
size = 1000000
# Создание хост-векторов
a = np.random.randn(size).astype(np.float32)
b = np.random.randn(size).astype(np.float32)
result = np.zeros_like(a)
# Выделение памяти на устройстве для векторов
a_gpu = cuda.mem_alloc(a.nbytes)
b_gpu = cuda.mem_alloc(b.nbytes)
result_gpu = cuda.mem_alloc(result.nbytes)
# Копирование данных из хост-векторов в устройственные векторы
cuda.memcpy_htod(a_gpu, a)
cuda.memcpy_htod(b_gpu, b)
# Настройка размерности выполнения ядра CUDA
blocksize = 256
gridsize = (size + blocksize - 1) // blocksize
# Установка параметров и запуск ядра CUDA
start_time = time.time()
multiply_vectors(a_gpu, b_gpu, result_gpu, np.int32(size), block=(blocksize, 1, 1), grid=(gridsize, 1))
end_time = time.time()
# Вывод времени выполнения
print("Время выполнения ядра CUDA: %.6f секунды" % (end_time - start_time))
# Копирование результата с устройства обратно на хост
cuda.memcpy_dtoh(result, result_gpu)
# Освобождение памяти на устройстве
a_gpu.free()
b_gpu.free()
result_gpu.free()
# Вывод результата
print("Результат умножения: ", result)
В данном примере мы сначала импортируем необходимые модули из библиотеки PyCUDA. Затем мы создаем контекст устройства CUDA с помощью `pycuda.autoinit`, автоматически выбирающего доступное устройство CUDA.
Затем мы определяем исходный код ядра CUDA для умножения векторов, используя строку `kernel_code`. Мы используем модуль `SourceModule`, чтобы скомпилировать этот исходный код в исполняемую функцию ядра CUDA.
Затем мы создаем хост-векторы `a` и `b` и выделяем память на устройстве для этих векторов с помощью функции `cuda.mem_alloc`. Затем мы копируем данные из хост-векторов в устройственные векторы с помощью функции `cuda.memcpy_htod`.
Затем мы определяем размерность выполнения ядра CUDA с помощью переменных `blocksize` и `gridsize`, и устанавливаем параметры для ядра CUDA.
Затем мы запускаем ядро CUDA с помощью функции `multiply_vectors`. Время выполнения ядра сохраняется в переменной `start_time` и `end_time`.
Затем мы копируем результат с устройства обратно на хост с помощью функции `cuda.memcpy_dtoh`.
Затем мы освобождаем память, занимаемую устройственными векторами, с помощью функции `.free()`.
Наконец, мы выводим результат умножения векторов.
Чтобы сравнить время выполнения с декоратором и без декоратора, можно модифицировать код следующим образом:
python
import time
# Декоратор для замера времени выполнения кода
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print("Время выполнения: %.6f секунды" % (end_time - start_time))
return result
return wrapper
# Оригинальная функция умножения векторов
def multiply_vectors(a, b):
result = np.multiply(a, b)
return result
# Создание хост-векторов
a = np.random.randn(size).astype(np.float32)
b = np.random.randn(size).astype(np.float32)
# Умножение векторов с использованием декоратора
@timer
def multiply_vectors_with_decorator(a, b):
return multiply_vectors(a, b)
# Умножение векторов без использования декоратора
def multiply_vectors_without_decorator(a, b):
return multiply_vectors(a, b)
# Умножение векторов с использованием декоратора
multiply_vectors_with_decorator(a, b)
# Умножение векторов без использования декоратора
start_time = time.time()
multiply_vectors_without_decorator(a, b)
end_time = time.time()
print("Время выполнения без декоратора: %.6f секунды" % (end_time - start_time))
В данном примере мы определяем декоратор `timer`, который замеряет время выполнения функции и выводит его. Затем мы определяем оригинальную функцию `multiply_vectors`, которая умножает векторы `a` и `b`.
Затем мы создаем хост-векторы `a` и `b`.
Затем мы определяем функцию `multiply_vectors_with_decorator`, которая использует декоратор `timer` для замера времени выполнения функции `multiply_vectors`. Затем мы умножаем векторы `a` и `b` с помощью этой функции.
Затем мы выполняем умножение векторов без использования декоратора, замеряя время выполнения до и после выполнения функции `multiply_vectors`. Выполнение функции выводит время выполнения без декоратора.
Таким образом, мы можем сравнить время выполнения с декоратором и без декоратора и увидеть, какой способ более эффективен.Нажимая «Регистрация» или «Войти через Google», вы соглашаетесь с Публичной офертой, даете Согласие на обработку персональных данных, а также подтверждаете что вам есть 18 лет
Нажимая «Регистрация» или «Войти через Google», вы соглашаетесь с Публичной офертой, даете Согласие на обработку персональных данных, а также подтверждаете что вам есть 18 лет