GPU -programmering med Python

GPU -programmering med Python
I denne artikkelen vil vi dykke inn i GPU -programmering med Python. Ved hjelp av Python kan du låse opp den utrolige datakraften til skjermkortets GPU (Graphics Processing Unit). I dette eksemplet vil vi jobbe med Nvidias CUDA -bibliotek.

Krav

For denne øvelsen trenger du enten en fysisk maskin med Linux og en NVIDIA-basert GPU, eller lansere en GPU-basert forekomst på Amazon Web Services. Enten skal fungere bra, men hvis du velger å bruke en fysisk maskin, må du sørge for at du har installert NVIDIA proprietære drivere, se instruksjoner: https: // linuxhint.com/install-nvidia-drivers-linux

Du trenger også CUDA -verktøyet installert. Dette eksemplet bruker Ubuntu 16.04 LTS spesifikt, men det er nedlastinger tilgjengelig for de fleste store Linux -distribusjoner på følgende URL: https: // utvikler.nvidia.com/cuda-downloads

Jeg foretrekker .Deb -basert nedlasting, og disse eksemplene vil anta at du valgte den ruten. Filen du laster ned er en .Deb -pakken, men har ikke en .Deb -forlengelse, så å gi nytt navn til å ha en .Deb på slutten hans nyttig. Så installerer du den med:

sudo dpkg -i package -name.Deb

Hvis du blir bedt om å installere en GPG -nøkkel, kan du følge instruksjonene som er gitt for å gjøre det.

Nå må du installere selve CUDA -pakken. Å gjøre det, løp:

sudo apt-get oppdatering
sudo apt -get installer cuda -y

Denne delen kan ta en stund, så det kan være lurt å ta en kopp kaffe. Når det er gjort, anbefaler jeg å starte på nytt for å sikre at alle moduler blir lastet på riktig måte.

Deretter trenger du Anaconda Python -distribusjonen. Du kan laste ned det her: https: // www.Anaconda.com/download/#linux

Ta tak i 64-biters versjonen og installer den slik:

sh anaconda*.sh

(Stjernen i kommandoen ovenfor vil sikre at kommandoen kjøres uavhengig av den mindre versjonen)

Standardinstallasjonsstedet skal være bra, og i denne opplæringen bruker vi den. Som standard installerer den til ~/anaconda3

På slutten av installasjonen blir du bedt om å bestemme om du ønsker å legge Anaconda til din vei. Svar ja her for å gjøre det enklere å kjøre de nødvendige kommandoene. For å sikre at denne endringen finner sted, etter at installasjonsprogrammet er ferdig, logg ut og deretter logge inn på kontoen din.

Mer info om installasjon av Anaconda: https: // linuxhint.com/install-anaconda-python-on-ubuntu/

Endelig må vi installere numba. Numba bruker LLVM -kompilatoren for å kompilere Python til maskinkode. Dette forbedrer ikke bare ytelsen til vanlig Python -kode, men gir også limet som er nødvendig for å sende instruksjoner til GPU i binær form. Å gjøre dette, løp:

conda installer numba

Begrensninger og fordeler med GPU -programmering

Det er fristende å tenke at vi kan konvertere ethvert Python-program til et GPU-basert program, og dramatisk akselererer ytelsen. Imidlertid fungerer GPU på et skjermkort betydelig annerledes enn en standard CPU på en datamaskin.

CPUer håndterer mange forskjellige innganger og utganger og har et bredt utvalg av instruksjoner for å håndtere disse situasjonene. De er også ansvarlige for å få tilgang til minne, håndtere systembussen, håndtere beskyttelsesringer, segmentering og input/output -funksjonalitet. De er ekstreme multitaskere uten spesifikt fokus.

GPUer er derimot bygget for å behandle enkle funksjoner med blendende rask hastighet. For å oppnå dette, forventer de en mer ensartet tilstand av inngang og output. Ved å spesialisere seg i skalarfunksjoner. En skalarfunksjon tar en eller flere innganger, men returnerer bare en enkelt utgang. Disse verdiene må være typer forhåndsdefinert av Numpy.

Eksempelkode

I dette eksemplet lager vi en enkel funksjon som tar en liste over verdier, legger dem sammen og returnerer summen. For å demonstrere kraften til GPU, kjører vi en av disse funksjonene på CPU og en på GPU og viser tidene. Den dokumenterte koden er nedenfor:

Importer numpy som NP
fra TIMEIT IMPORT FEDLISTE_TIMER SOM TIMER
fra numba importvektorisering
# Dette skal være en vesentlig høy verdi. På testmaskinen min tok dette
# 33 sekunder å løpe via CPU og litt over 3 sekunder på GPU.
Num_elements = 100000000
# Dette er CPU -versjonen.
def vector_add_cpu (a, b):
C = NP.Zeros (num_elements, dtype = np.float32)
for jeg i rekkevidde (num_elements):
c [i] = a [i] + b [i]
retur c
# Dette er GPU -versjonen. Legg merke til @vektoriseringsdekoratøren. Dette forteller
# numba for å gjøre dette til en GPU -vektorisert funksjon.
@Vectorize (["Float32 (Float32, Float32)"], Target = 'Cuda')
def vector_add_gpu (a, b):
returner A + B;
def main ():
a_source = np.de (num_elements, dtype = np.float32)
b_source = np.de (num_elements, dtype = np.float32)
# Tid CPU -funksjonen
start = timer ()
VECTOR_ADD_CPU (A_SOURCE, B_SOURCE)
Vector_add_cpu_time = Timer () - Start
# Tid GPU -funksjonen
start = timer ()
VECTOR_ADD_GPU (A_SOURCE, B_SOURCE)
Vector_add_gpu_time = Timer () - Start
# Rapporter tider
Print ("CPU -funksjonen tok %F sekunder." % vector_add_cpu_time)
Print ("GPU -funksjonen tok %F sekunder." % vector_add_gpu_time)
retur 0
if __name__ == "__main__":
hoved()

For å kjøre eksemplet, skriv: Skriv:

Python GPU-Eksempel.py

Merk: Hvis du får problemer når du kjører programmet ditt, kan du prøve å bruke "Conda Install Accelerate".

Som du ser, kjører CPU -versjonen betydelig saktere.

Hvis ikke, er iterasjonene dine for små. Juster num_elementene til en større verdi (på meg, Breakeven -merket så ut til å være rundt 100 millioner). Dette er fordi oppsettet av GPU tar en liten, men merkbar tid, så for å gjøre operasjonen verdt det, er det nødvendig med en høyere arbeidsmengde. Når du har løftet den over terskelen for maskinen din, vil du merke betydelige ytelsesforbedringer av GPU -versjonen over CPU -versjonen.

Konklusjon

Jeg håper du har hatt glede av vår grunnleggende introduksjon til GPU -programmering med Python. Selv om eksemplet over er trivielt, gir det rammene du trenger for å ta ideene dine videre ved å bruke kraften til din GPU.