Python modul PyCUDA: rad s vektorskim tipovima podataka
PyCUDA, kao i CUDA, ima ugrađenu podršku za vektorske tipove: višedimenzionalni podaci s jednom do četiri komponente, adresirane kao .x
, .y
, .z
, .w
. Neki od postojećih predefiniranih vektorskih tipova podataka su:
struct uchar1
{
unsigned char x;
};
struct __align__(4) ushort2
{
unsigned short x, y;
};
struct uint3
{
unsigned int x, y, z;
};
struct __align__(16) float4
{
float x, y, z, w;
};
Uočimo funkciju __align__()
, koja se koristi za poravnanje podataka. Naime, GPU može iz memorije u jednoj instrukciji dohvatiti:
- 32 bita, odnosno 4 bajta, za što se koristi
__align(4)
, - 64 bita, odnosno 8 bajta, za što se koristi
__align(8)
, - 128 bita, odnosno 16 bajta, za što se koristi
__align(16)
.
Primjeri slučajeva korištenja vektorskih tipova podataka su:
- slike s 8-bitnom dubinom boje (
uchar3
) (RGB =>x
,y
,z
), - slike s 24-bitnom dubinom boje i transparencijom (
uint4
) (RGBA =>x
,y
,z
,w
), - sustavi fizikalnih objekata u prostoru (
float3
) (x
,y
,z
: prostorne koordinate), - sustavi fizikalnih objekata u prostorno-vremenskom kontinuumu (
float4
) (x
,y
,z
,w
: 3 prostorne koordinate i jedna vremenska).
Sa predefiniranim vektorskim tipovima podataka radimo na intuitivan način; zrno je oblika
#include <stdio.h>
__global__ void print_coordinates (float3 point)
{
printf ("x: %3.2f, y: %3.2f, z: %3.2f\\n", point.x, point.y, point.z);
}
Pridruženi Python kod je oblika
import pycuda.autoinit
import pycuda.driver as drv
import pycuda.gpuarray as ga
import numpy as np
from pycuda.compiler import SourceModule
mod = SourceModule(open("vector_types.cu").read())
print_coordinates = mod.get_function("print_coordinates")
point_in_space = ga.vec.make_float3(3.6, 5.4, 2.25)
print_coordinates(point_in_space, block=(1,1,1), grid=(1,1))
Zadatak
Na domaćinu definirajte tri točke u ravnini (točke će biti tipa float2
i imati dvije koordinate). Izračunajte površinu trokuta koji te tri točke zatvaraju korištenjem formule:
Zrno se izvodi bez korištenja paralelizacije, dakle kut se računa u jednom bloku s jednom niti po bloku. Za provjeru, isti izračun izvedite na domaćinu.
Zadatak
Kosinus kuta dvaju vektora \(a = (a_x, a_y)\) i \(b = (b_x, b_y)\) računa se po formuli
odnosno jednak je skalarnom produktu vektora podijeljenom s produktom normi vektora.
Dane su četiri točke u ravnini, tipa float2
. Definirajte:
- funkciju uređaja koja računa skalarni produkt, koju ćete uz predefiniranu funkciju
sqrt()
iskoristiti za izračun norme vektora, te - zrno koje računa kosinus kuta, pozivajući funkciju uređaja koja računa skalarni produkt,
Zrno se izvodi bez korištenja paralelizacije, dakle kut se računa u jednom bloku s jednom niti po bloku. Za provjeru, isti izračun izvedite na domaćinu.
Note
Prethodni zadaci ne koristi nikakvu vrstu paralelizacije, odnosno izvode se na jednoj jezgri uređaja. U narednim primjerima uključiti ćemo vektorske tipove podataka u širi kontekst i iskoristiti ih u paralelnim algoritmima.
Author: Vedran Miletić, Kristijan Lenković