πŸ”₯ Как пСрСнСсти вычислСния Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python: совСты ΠΈ руководство

ΠŸΠ΅Ρ€Π΅Π½Π΅ΡΡ‚ΠΈ вычислСния Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ использования Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ CUDA ΠΈ языка программирования CUDA C/C++. Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

import numpy as np
from numba import jit, cuda

# ОбъявлСниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ…ΠΎΡ‚ΠΈΠΌ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ
@jit(target="cuda")
def calculate():
    # Π’Π°Ρˆ ΠΊΠΎΠ΄ вычислСний

# Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅
calculate()

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ использовали Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ NumPy ΠΈ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @jit(target="cuda") ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ numba, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, пСрСнСся Π΅Π΅ Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ. Однако, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ CUDA, Π²Π°ΠΌ потрСбуСтся ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ NVIDIA GPU ΠΈ Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€Ρ‹ CUDA.

Π”Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚

Как пСрСнСсти вычислСния Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python

ΠŸΠ΅Ρ€Π΅Π½ΠΎΡ вычислСний Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡, особСнно Ρ‚Π΅Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… объСмов Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ слоТных матСматичСских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ рассмотрим нСсколько ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² ΠΊ пСрСносу вычислСний Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python с использованиСм Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ CUDA.

1. Установка Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ CUDA

ΠŸΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ Π½Π°Ρ‡Π°Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ CUDA, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ. ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π°, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ΡΡŒ ΠΊ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ NVIDIA для получСния инструкций ΠΏΠΎ установкС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ CUDA.

2. Установка Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ PyCUDA

PyCUDA - это Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰Π°Ρ простой интСрфСйс для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с CUDA Π½Π° Python. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ PyCUDA, Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:


pip install pycuda
  

3. ИспользованиС PyCUDA для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… вычислСний

PyCUDA позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ мощности Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρ‹ для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… вычислСний. Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ вычислСния суммы элСмСнтов Π²Π΅ΠΊΡ‚ΠΎΡ€Π° Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅:


import numpy as np
import pycuda.autoinit
import pycuda.gpuarray as gpuarray
from pycuda.reduction import sum

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ случайного Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
vector = np.random.randn(1000000).astype(np.float32)

# ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Π΅ΠΊΡ‚ΠΎΡ€Π° Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ
gpu_vector = gpuarray.to_gpu(vector)

# ВычислСниС суммы элСмСнтов Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅
sum_gpu = sum(gpu_vector).get()

print(sum_gpu)
  

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ сначала создаСм случайный Π²Π΅ΠΊΡ‚ΠΎΡ€ Π½Π° CPU, Π·Π°Ρ‚Π΅ΠΌ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Π΅Π³ΠΎ Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ `to_gpu` ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ PyCUDA. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ вычисляСм сумму элСмСнтов Π²Π΅ΠΊΡ‚ΠΎΡ€Π° Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ `sum` ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° `get`.

4. ИспользованиС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Numba для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… вычислСний

Π•Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΊ пСрСносу вычислСний Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python - использованиС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Numba. Numba - это компилятор ΠΈ JIT (just-in-time) компилятор для Python, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСтся Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅.

Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования Numba для вычислСния суммы элСмСнтов Π²Π΅ΠΊΡ‚ΠΎΡ€Π° Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅:


import numpy as np
from numba import cuda

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ случайного Π²Π΅ΠΊΡ‚ΠΎΡ€Π°
vector = np.random.randn(1000000).astype(np.float32)

# ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Π΅ΠΊΡ‚ΠΎΡ€Π° Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ
d_vector = cuda.to_device(vector)

# ВычислСниС суммы элСмСнтов Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅
@cuda.jit
def sum_gpu(d_vector):
    tid = cuda.threadIdx.x + cuda.blockDim.x * cuda.blockIdx.x
    stride = cuda.blockDim.x * cuda.gridDim.x

    sum_partial = 0.0
    for i in range(tid, len(d_vector), stride):
        sum_partial += d_vector[i]

    cuda.atomic.add(sum_gpu, 0, sum_partial)

sum_gpu[64, 64](d_vector)

result = np.zeros(1, dtype=np.float32)
cuda.memcpy_dtoh(result, sum_gpu)

print(result[0])
  

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ сначала создаСм случайный Π²Π΅ΠΊΡ‚ΠΎΡ€ Π½Π° CPU, Π·Π°Ρ‚Π΅ΠΌ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Π΅Π³ΠΎ Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ `to_device` ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Numba. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ опрСдСляСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ `sum_gpu`, которая выполняСт вычислСниС суммы элСмСнтов Π²Π΅ΠΊΡ‚ΠΎΡ€Π° Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅.

ΠœΡ‹ Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΡƒΠ΅ΠΌ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° `@cuda.jit`, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Numba, Ρ‡Ρ‚ΠΎ это функция, которая Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Ρ€Π°Π·Π±ΠΈΠ²Π°Π΅ΠΌ вычислСния Π½Π° Π±Π»ΠΎΠΊΠΈ ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ индСксов `threadIdx` ΠΈ `blockIdx`.

Π’ ΠΊΠΎΠ½Ρ†Π΅ ΠΌΡ‹ выполняСм вычислСниС суммы Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ синтаксиса `sum_gpu[64, 64]`, Π³Π΄Π΅ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ число ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ количСство Π±Π»ΠΎΠΊΠΎΠ², Π° Π²Ρ‚ΠΎΡ€ΠΎΠ΅ - количСство ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π±Π»ΠΎΠΊΠ΅. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π½Π° CPU ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ Π΅Π³ΠΎ.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ΠŸΠ΅Ρ€Π΅Π½ΠΎΡ вычислСний Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡. ΠœΡ‹ рассмотрСли Π΄Π²Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°: использованиС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ PyCUDA ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Numba. ΠŸΡ€ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΉ настройкС ΠΈ использовании этих Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, Π²Ρ‹ смоТСтС максимально эффСктивно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ возмоТности вашСй Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρ‹ Π² Python.

Π’ΠΈΠ΄Π΅ΠΎ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅

Начни Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π½Π΅ΠΉΡ€ΠΎΠ½Π½Ρ‹Π΅ сСти Ρƒ сСбя Π΄ΠΎΠΌΠ° (CUDA+Tensorflow Π½Π° Windows)

ВычислСния Π½Π° GPU ΠΈΠ· Python

Π’Π΅Π±ΠΈΠ½Π°Ρ€ «ВычисляСм Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Π°Ρ…. ВСхнология OpenCLΒ»

ΠŸΠΎΡ…ΠΎΠΆΠΈΠ΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ:

πŸ”’ Как Ρ€Π°Π·Π»ΠΎΠΆΠΈΡ‚ΡŒ число Π½Π° Ρ†ΠΈΡ„Ρ€Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Python: простой способ

✨Как ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ†ΠΈΠΊΠ» дСйствий Π² ΠŸΠΈΡ‚ΠΎΠ½Π΅: пошаговоС Ρ€ΡƒΠΊΠΎΠ²ΠΎΠ΄ΡΡ‚Π²ΠΎβœ¨

πŸ”Ž Как ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ логичСскиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² Python: пошаговоС руководство

πŸ”₯ Как пСрСнСсти вычислСния Π½Π° Π²ΠΈΠ΄Π΅ΠΎΠΊΠ°Ρ€Ρ‚Ρƒ Π² Python: совСты ΠΈ руководство

πŸ“… Как ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ дСнь Π½Π΅Π΄Π΅Π»ΠΈ ΠΏΠΎ Π΄Π°Ρ‚Π΅ Π² Python: пошаговоС руководство

πŸ”Ž Как Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ€Π°Π½Π΄ΠΎΠΌΠ°ΠΉΠ·Π΅Ρ€ Π½Π° ΠŸΠΈΡ‚ΠΎΠ½Π΅ β€” простая инструкция с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ

Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ссли Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ошибка invalid syntax Π² Python? 🐍