+ All Categories
Home > Documents > Python + CUDA = PyCUDA 15 -pycuda.… · ¿ Qué es Python? Lenguaje multipropósito (Web, GUI,...

Python + CUDA = PyCUDA 15 -pycuda.… · ¿ Qué es Python? Lenguaje multipropósito (Web, GUI,...

Date post: 19-Apr-2020
Category:
Upload: others
View: 41 times
Download: 0 times
Share this document with a friend
20
Python + CUDA = PyCUDA Clase 15, 01/06/2015 http://fisica.cab.cnea.gov.ar/gpgpu/index.php/en/icnpg/clases cp -a /share/apps/codigos/alumnos_icnpg2015/pycuda . http://bit.ly/1PZTg1B
Transcript

Python + CUDA = PyCUDA

Clase 15, 01/06/2015http://fisica.cab.cnea.gov.ar/gpgpu/index.php/en/icnpg/clases

cp -a /share/apps/codigos/alumnos_icnpg2015/pycuda .

http://bit.ly/1PZTg1B

¿ Qué es Python?

● Lenguaje multipropósito (Web, GUI, Scripting, cintífico).

● Orientado a Objetos.

● Interpretado.

● Producido para tener alta legibilidad y alta productividad.

Características:

● Todo en python es un objeto (de verdad, TODO).

● Shell interactiva.

● Multiplataforma.

● Varias implementaciones: CPython, Jython, PyPy.

● Incluye baterías.

Algunos usuarios:

Herramientas:

● Python tiene una de las comunidades de desarrolladores más grandes. Hay herramientas para casi todo.

● Desarrollo web: Django.

● Bibliotecas gráficas: wxPython, PyQt, PyOpenGL.

● Bases de datos: PyMySQL, pyodbc, ect.

● Cálculo científico: scipy, numpy, matplotlib, scikts.

● Cálculo paralelo: PyOpenCL, PyCUDA, scikts.cuda.

Interpretado vs. compilado

Edición

Compilación

Linkedición

Ejecución

Flujo de creación de un programa en C/Fortran:

Interpretado vs. compilado

Edición

Ejecución

Flujo de creación de un programa en Python:

Sintaxis

● Podemos trabajar en consola (en linux ya está instalado, simplemente escribir python) o bien en un script:

>>> print “Hola inmundo!”

● No hay que usar llaves, ni “;”. Los bloques se definen por indentación:

a = 3b = "hola manola"

if a == 3 and "manola" in b: # esto es un comentario

print b c = a*5else: b = "hola manola"

c = a/3.0

# esto ya esta afuera del if/elsed = "hola manola"

Tipos de datos

# stringsname = "Nicolas"

# multi-line stringbio = '''Mi nombre es Nicolás naci en Rafaela, Santa Fe'''

# another multi-line stringquote = """Sombondrolo la cantarpioaea - N.R."""

#enterosyear = 2015year = int("2015")

# floatspi = 3.14159265pi = float("3.14159265")

#listaslista1 = [] lista2 = [1,2,3,4,5,6,7,8,9,10]lista3 = ["hola","manola","pepe"]lista4 = [1, "hola", lista1, lista3]

# diccionariosperson = {}person['nicolas'] = 'Ingeniero'person.update({'favoritos':['Cortazar', 'Pink Floyd', 'Dolina'], 'genero':'male',})person[55] = 'numero'

# Nulldata = None

#tuplas (datos inmutables)a = (123,"hola") a[0] = "chau" ----> Error!

#booleanosthis_is_true = Truethis_is_also_true = bool("any object")this_is_false = False or 0 or "" or [] or {} or None

Ej: tipos.py

Algo de magia - Strings

animales = "liebre " + "perro "animales +="gato "#animales = "liebre perro gato"

animales = ", ".join(["liebre","perro", "gato"])# animales = liebre, perro, gato

fecha = "%d de %s, %d" % (1, 'Junio', 2015)# 1 de Junio, 2015

fecha = "%(nombre)s %(apellido)s" %{'nombre':'Nicolas', 'apellido':'Chiaraviglio'}# Nicolas Chiaraviglio

print 2 * "hola "# hola hola

Algo de magia - Iteradores

from random import randint

a = [randint(0,121) for i in range(0,1000)]

b = [i for i in a if not i%2]

b = [k**2 - j for j,k in enumerate(a) if not k%2 and j%2]

Algo de magia - Listas

for x in range(0,10): print x# 0 1 2 3 4 5 6 7 8 9

frutas = ['manzana', 'banana', 'pera', 'frutilla', 'vino tinto']for fr in fruta: print fr# manzana banana pera frutilla vino tinto

num = [1,2,3,4,5]for i,fr in zip(num,frutas): print i, fr# 1 manzana 2 banana 3 pera 4 frutilla 5 vino tinto

for i,fr in enumerate(frutas): print i, fr# 0 manzana 1 banana 2 pera 3 frutilla 4 vino tinto

Ej: iteradoresListas.py

También: funciones, generadores, clases

def fibonacci(n = 3): resultado =[]

a,b = 0,1

for i in range(0,n):

resultado.append(a)

a,b = b, a + b

return resultado

print fibonacci(10)# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

print fibonacci()# [0, 1, 1]

def fibonacci(n): a,b = 0,1

while True:

yield a

a,b = b, a + b

generador = fibonacci()for i in range(0,10): print generador.next()# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Ej: funcGeneradores.py

Numpy - Python para cálculo numérico

● Soporte de operaciones que actúan sobre arrays N-dimensionales (eficiencia).

● Herramientas para integración con C/C++ y Fortran.

● Funciones de álgebra lineal: Transformadas, integrales, números aleatorios.

● También incluye baterías

A los bifes:

● Definiciones: Vectores, Matrices, Tipos

● Operaciones entre vectores/matrices

● Sistemas de ecuaciones

● Reshape

● Broadcast

Demo: demoNumpy.py

Entonces... PyCUDA?

●PyCuda permite acceder al API de Cuda desde Python.

Pero... y la performance?

Manipulación de datosFlujo general del programa

Cálculo

I/O

Python Cuda

“Scripting for the brain, GPUs for inner loop”Klöckner

Flujo de trabajo de PyCUDA

Edición

Ejecución

Cache?

nvcc .cubin

Envío a GPU

Ejecución en GPU

Source Module (“...”)

no

Algunos ejemplos

import pycuda.driver as cudaimport pycuda.autoinit, pycuda.compilerimport numpy as np

a = np.random.randn(4,4).astype(np.float32)a_gpu = cuda.mem_alloc(a.nbytes)cuda.memcpy_htod(a_gpu,a)

mod = pycuda.compiler.SourceModule(""" __global__ void twice (float *a) { int tid = threadIdx.x + threadIdx.y * 4; a[tid] *= 2; } """)

func = mod.get_function("twice")func(a_gpu, block=(4,4,1))

a_doubled = np.empty_like(a)cuda.memcpy_dtoh(a_doubled,a_gpu)print a_doubledprint a

#include <stdlib.h>#include <stdio.h>#include <time.h>

__global__ void twice (float *a){ int tid = threadIdx.x + threadIdx.y * 4; a[tid] *= 2;}

int main( int argc, const char** argv ) { int N = 4; float *a, gpu_a*, *a_doubled;

a = (float *)malloc(sizeof(float) * N); a_doubled = (float *)malloc(sizeof(float) * N); cudaMalloc((void**)&gpu_a, sizeof(float) * N); srand(time(NULL)); for (int i = 0; i < N; i++) a[i] = random()/RAND_MAX; cudaMemcpy(gpu_a, a, sizeof(float) * N, cudaMemcpyHostToDevice); dim3 blockDim(N,N,1); dim3 gridDim(1,1,1); twice<<<gridDim,blockDim>>>(a); cudaMemcpy(a_doubled, gpu_a, sizeof(float) * N, cudaMemcpyHostToDevice);

for (int i = 0; i < N; i++) printf("%f\t",a_doubled[i]); for (int i = 0; i < N; i++) printf("%f\t",a[i]); return 0;}

Ejs: twice.cu - twice.py

Todavía escribimos mucho?- gpuarray

import numpyimport pycuda.autoinitimport pycuda.gpuarray as gpuarray

x = np.random.randn(4,4).astype(np.float32)a_gpu = gpuarray.to_gpu(x)

a_doubled = (2*a_gpu).get()print a_doubledprint a_gpu

Ej: twice2.py

Y algo más complicado?

from pycuda.curandom import rand as curand

a_gpu = curand((50,))b_gpu = curand((50,))

from pycuda.elementwise import ElementwiseKernellin_comb = ElementwiseKernel( " float a, float *x, float b, float *y, float *z", " z[i] = a * x[i] + b * y[i]")

c_gpu = gpuarray.empty_like(a_gpu)lin_comb(5, a_gpu, 6, b_gpu, c_gpu)

assert la.norm((c_gpu - (5 * a_gpu + 6 * b_gpu)).get()) < 1e-5

Ej: element.py

import numpy as npimport pycuda.autoinitimport pycuda.gpuarray as gpuarrayfrom pycuda.curandom import rand as curandfrom pycuda.reduction import ReductionKernel

dot = ReductionKernel(dtype_out = np.float32, neutral ="0", reduce_expr = "a+b", map_expr = "x[i] * y[i]",

arguments = "const float *x, const float *y")

x = curand((1000*1000), dtype = np.float32)y = curand((1000*1000), dtype = np.float32)

x_dot_y = dot(x,y).get()x_dor_y_cpu = np.dot(x.get(), y.get())

Ej: Reductions.py

Esta Charla

● Empresas que usan Python - http://bit.ly/1AvYbR2 ● Introducción a Python - http://bit.ly/1AvYo6V● Estructuras de datos en Python - http://bit.ly/1jPmL3p● Guía de Numpy/Scipy - http://bit.ly/1GGwAO2● Documentación PyCUDA - http://bit.ly/1J8SLMZ● Charla de A. Klöckner

sobre PyCUDA/PyOpenCL - http://bit.ly/1J8SLMZ● Repositorio de PyCUDA - http://bit.ly/1LLArt1● Guía de instalación de PyCUDA - http://bit.ly/1dzM6jH


Recommended