gpgpu

Upload: mehrez-essafi

Post on 07-Jan-2016

214 views

Category:

Documents


0 download

DESCRIPTION

GPGPU

TRANSCRIPT

  • GPGPU

    Implmentation dun simple oprateur algbrique linaire sur

    GPU: saxpy()

  • 2Objectif

    Lopration saxpy() : un exemple simple

    ne require pratiquement aucun background en algbre linaire

    illustre trs bien les concepts GPGPU.

    Consiste calculer y = y + alpha * x avec x et y vecteurs de longueur N et alpha une

    valeur scalaire

  • 3Configuration de OpenGL-GLUT

    GLUT (OpenGL Utility Toolkit), : fournit des fonctions pour grer les vnements windows

    Permet de crer de simples menus

    etc. (voir http://raphaello.univ-fcomte.fr/ig/opengl/Glut.htm)

    Nous lutiliserons pour configurer un OpenGL valide afin daccder au priphrique graphique, travers lAPI GL, avec le minimum de ligne de code possible

    #include // inclue le fichier header GLUT

    // A appeler partir du main()void initGLUT(int argc, char **argv) {

    glutInit ( &argc, argv );glutCreateWindow(" TEST SAXPY");

    }

  • 4Configuration de OpenGL-GLEW

    La plupart des mcanismes requis pour faire du GPGPU ne font pas partie du noyau dOpenGL

    GLEW (OpenGL Extension Wrangler) est une libraire qui tend OpenGL pour avoir plus de contrle sur le matriel travers lAPI OpenGL

    Dautres extensions OpenGL sont disponibles ladresse http://www.opengl.org/registry/

    Il est possible dexplorer les extensions supportes par la carte graphique avec les outils : glewinfo (qui est fournit avec GLEW) OpenGL extension viewer GPU Caps Viewer Etc.

  • 5Interface minimalistique

    void initGLEW (void) {

    // initialiser GLEW et obtenir les pointeurs sur les fonctionsint err = glewInit();// Attention : Ce code ne teste pas si lextension est supporte par le matriel // dans le cas chant glewInit() sera gale NULLif (err!=GLEW_OK)

    {printf((char*)glewGetErrorString(err));exit(ERROR_GLEW);

    } }

  • 6Prparation de OpenGL pour un rendu offscreen

    Dhabitude, le pipeline graphique se termine au niveau du frame buffer

    La taille max des donnes du frame buffer est de 32 bit (RGBA) soit 8 bit par couleur 16 millions de couleurs Chaque couleur prend une valeur entre 0 et 256

    Pour pouvoir avec des rels on peut stocker des donnes au format IEEE 32-bit :SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF=(-1)s2e-1271.f

    Lextension OpenGL appele EXT_framebuffer_object permet dutiliser un offscreen buffer (FBO) pour stocker les vecteurs des rendus

  • 7Utilisation de lextension EXT_framebuffer_object

    GLuint fb;

    void initFBO(void) {

    // crer un FBO (off-screen framebuffer)glGenFramebuffersEXT(1, &fb);

    // se brancher sur offscreen buffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

    }

  • 8GPGPU concept 1: tableaux = textures

    Pour le CPU : nativement sur une seule dimension accds moyennant des indices a[i][j]=a[i*M+j]

    Pour le GPU : nativement sur 2 dimensions supporte 1 et 3 dimensions mais implique des pnalits sur les

    performances Laccs se fait moyennant des coordonnes de textures appels textures ou texture samplers les dimensions des textures sont limites (peuvent tre obtenues

    par une requte OpenGL une fois GLUT initialis)

    int maxtexsize;glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxtexsize);printf("GL_MAX_TEXTURE_SIZE, %d\n",maxtexsize);

  • 9Cration des tableaux sur CPU

    Rappelons que lon souhaite calculer

    y = y + alpha * x

    Nous avons besoin de 2 tableaux de rels X et Y de taille N et dun rel alpha

    Ces donnes seront allous et initialiss par le CPU malgr que le calcul sera effectu sur GPU

    float* dataX = (float*)malloc(N*sizeof(float));float* dataY = (float*)malloc(N*sizeof(float));float alpha;

  • 10

    Cration de textures avec des nombres virgule flottante sur GPU On va limiter la prsentation 2 texture 2D :

    La texture traditionnelle dans OpenGL : GL_TEXTURE_2D

    Lextension OpenGL : ARB_texture_rectangle plus facile utiliser par des non graphistes)

    Texture2D Texture rectangle

    Texture cible GL_TEXTURE_2D GL_TEXTURE_RECTANGLE_ARB

    Coordonnes des textures

    Doivent tre normalises lintervalle [0,1] sur [0,1] indpendament de la dimension [0,M] sur [0,N] de la texture

    Ne sont pas normaliss

    Dimensions des textures

    Doivent tre une puissance de 2 sauf si le pilote supporte lextension ARB_non_power_of_two ou quil prsente OpenGL 2.0

    Les dimensions peuvent tre arbitraires

  • 11

    Format des textures

    Le GPU permet le traitement simultan de : Scalaires : GL_LUMINANCE est le format de texture

    adapt pour stocker une seule valeur en virgule flottante par texel 32 bits / texel

    Tuples

    Triples

    Quadriples : GL_RGBA est le format de texture adapt pour stocker quatre valeur en virgule flottante par texel 128 bits / texel

  • 12

    Formats internes pour les textures

    Il existe 3 extensions OpenGL qui prsentent des formats pour les nombres virgule flottante pour les textures : NV_float_buffer

    ATI_texture_float

    ARB_texture_float

    Chaque extension dfinit un ensemble dnumrants (ex. : GL_FLOAT_R32_NV) et des symboles (ex. 0x8880) qui peuvent tre utiliss pour dfinir et allouer les textures

  • 13

    Enumrants

    Les numrants des 2 formats de textures auxquels nous nous intressons sont : GL_FLOAT_R32_NV : informe le GL que nous souhaitons

    stocker un seul nombre virgule flottante par texel GL_FLOAT_RGBA32_NV : stocke un 4-tuplet de nombres

    virgule flottante

    Les 2 extensions ATI_texture_float et ARB_texture_float sont identiques sauf quils dfinissent diffrents numrant pour

    le mme symbol (cest une question de prfrences) sont supportes par les carte GeForce 6 (ou +) et ATI ont pour numrants respectifs

    GL_LUMINANCE_FLOAT32_ATI GL_RGBA_FLOAT32_ATI GL_LUMINANCE32F_ARB GL_RGBA32F_ARB

  • 14

    Mapping CPU-GPU

    Comment associer un vecteur (CPU) une texture (GPU) ? La solution la plus simple :

    Pour les formats LUMINANCE : Associer un vecteur de taille N (on suppose que N est une puissance de 2) une texture de taille sqrt(N) par sqrt(N)

    Pour les formats RGBA : Associer un vecteur de taille N une texture de taille sqrt(N/4) par sqrt(N/4). On suppose que N correspond une taille qui soit adapte pour tresupporte par la texture (ex. N=1024^2 peut tre stocke dans une texture de taille 512 sur 512). La valeur correspondante sera stocke dans texSize.

  • 15

    Rcap.

    NVIDIA GeForce FX (NV3x)

    NV4x, G7x, G8x (RECT)

    NV4x, G7x, G8x (2D)

    ATI

    Cible texture rectangle texture rectangle

    texture2D texture2D et texture rectangle

    Format LUMINANCE et RGBA (et RG et RGB)

    Attention : ces formats sont supports en tant que textures mais pas comme cible de rendu

    Format

    interne

    NV_float_buffer NV_float_buffer ATI_texture_float NV_float_buffer

  • 16

    Allocation pour les textures

    Il suffit de connatre : La texture cible :

    GL_TEXTURE_2D GL_TEXTURE_RECTANGLE_ARB

    Le format de la texture GL_LUMINANCE GL_RGBA

    Le format interne que lon souhaite utiliser NV_float_buffer ATI_texture_float ARB_texture_float

  • 17

    Code pour lallocation de la texture

    // crer un nouveau id pour une textureGLuint texID;glGenTextures (1, &texID);// associer lid de la texture une texture cibleglBindTexture(texture_target,texID);// Arrter le filtrage et configurer le wrap mode// (obligatoire pour les texures de rels)glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP);// Configurer le texenv REPLACE la place de la valeur par dfaut MODULATEglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);// Allouer la mmoire graphiqueglTexImage2D(texture_target, 0, internal_format, texSize, texSize, 0, texture_format, GL_FLOAT, 0);

  • 18

    Association index tableau-coordonnes texture

    Dans la suite, nous allons chercher modifier les donnes stockes dans les textures par les donnes du rendu.

    Pour pouvoir contrler quel lment traiter ou accder dans la mmoire texture, on a besoin : deffectuer une projection qui permet de passer des coordonnes du

    modle 3D en coordonnes daffichage 2D projection orthogonale en plus dun mapping 1:1 entre coordonnes gomtriques (utilises

    dans le rendering), les coordonnes de textures (donnes accder pou traitement : entre) et les coordonnes des pixels (rsultat du rendu : sortie) utiliser un bon viewport

    Le mapping se base sur la taille (dans chaque dimension) utilise pour allouer les textures.

    Pour configurer le mapping on met la valeur de z 0 dans les coordonnes du modle et on applique un mapping 1:1

    Les lignes suivant peuvent tre ajout la routine initFBO()

  • 19

    viewport pour un mapping 1:1

    // viewport pour un mapping 1:1 pixel=texel=geometryglMatrixMode(GL_PROJECTION);glLoadIdentity();//gluOrtho2D(0.0, texSize, 0.0, texSize);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glViewport(0, 0, texSize, texSize);

  • 20

    Utilisation des textures comme cible (sortie)

    Lextension framebuffer_object permet de renvoyer le rendu directement dans une texture.

    Le problme cest que les textures sont soit en mode lecture soit criture.

    Que faire pour y = y + alpha * x ?

    Pour utiliser une texture comme cible il faut attacher la texture au FBO en supposant que le framebuffer est dj mis en offscreen

    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, //jusqu 4 attachements par FBOtexture_target, texID, 0);

  • 21

    Transfert de donnes tableau (CPU)texture (GPU)

    Pour transfrer les donnes vers les textures il faut les associer des textures cibles et ordonnancer le transfert avec des appels OpenGL.

    glBindTexture(texture_target, texID);glTexSubImage2D(texture_target,0,0,0,texSize,texSize,

    texture_format,GL_FLOAT,data);

  • 22

    Transfert de donnes texture (GPU) tableau (CPU)

    Il y a 2 faons pour implmenter le transfert des textures GPU vers des tableaux CPU Lapproche traditionnelle OpenGL moyennant un

    appel glGetTexImage() qui permet dassocier une texture une texture cible

    Si la texture rcuprer est dj attache un FBO, il est possible dutiliser la technique de redirection

    glBindTexture(texture_target,texID);glGetTexImage(texture_target,0,texture_format,GL_FLOAT,data);

    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);glReadPixels(0,0,texSize,texSize,texture_format,GL_FLOAT,data);

  • 23

    // initialiser les paramtres de la textureglTexParameteri(GL_TEXTURE_RECTANGLE_ARB,

    GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,

    GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,

    GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,

    GL_TEXTURE_WRAP_T, GL_CLAMP);// dfinir la texture avec le format floating pointglTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,GL_RGBA32F_ARB,

    texSize,texSize,0,GL_RGBA,GL_FLOAT,0);// attacher la textureglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,

    GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,tex,0);

    // transfrer la donne data textureglTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB,0,0,0,texSize,texSize,

    GL_RGBA,GL_FLOAT,data);// faire un read backglReadBuffer(GL_COLOR_ATTACHMENT0_EXT);glReadPixels(0, 0, texSize, texSize,GL_RGBA,GL_FLOAT,result);// imprimer le rsultaprintf("Data before roundtrip:\n");for (int i=0; i

  • Pages de rfrence OpenGL

    24

  • GPGPU concept 2 :kernel = shader

    y = y + alpha * x

    Avec un vecteur de N processeur, pas besoin de boucles (paradigme SIMD)

    Kernel : y_new[i] = y_old[i] + alpha * x[i] Le traitement est divis sur lensemble des units de calculs

    disponibles

    25

    for (int i=0; i

  • Cration dun shader avec Cg

    26

    float saxpy ( float2 coords : TEXCOORD0, uniform sampler2D textureY, uniform sampler2D textureX, uniform float alpha ) : COLOR {

    float result; float y = tex2D(textureY,coords); //float yval=y_old[i];float x = tex2D(textureX,coords); //float xval=x[i];result = y + alpha * x; //y_new[i]=yval+alpha*xval;return result;

    }

    Texture cible : texture2D

  • Cration dun shader avec Cg version 4-tuples en parallle

    27

    float4 saxpy ( float2 coords : TEXCOORD0, uniform samplerRECTtextureY, uniform samplerRECT textureX, uniform float alpha ) : COLOR {

    float4 result; float4 y = texRECT(textureY,coords); float4 x = texRECT(textureX,coords); result = y + alpha*x; // equivalent: result.rgba=y.rgba+alpha*x.rgba return result;

    }

    Texture cible : texture rectangle

  • O placer le shader ?

    Le code source dun shader peut tre stock dans une chane de caractres ou bien dans un fichier .cg et il sera accd par OpenGL via le Cg runtime

    28

  • Configuration du runtime Cg

    Inclure lentte Cg

    Ajouter les librairies pour ldition des liens

    Dclaration de certains variables

    29

    #include // Cg Header#include // Header spcifique Cg OpenGL

    #pragma comment( lib, "cg.lib")#pragma comment( lib, "cggl.lib")

    CGcontext cgContext; //point dentre pou le runtime CgCGprofile fragmentProfile; //on sintresse au pixel pipelineCGprogram fragmentProgram; //conteneur pour le programmeCGparameter yParam, xParam, alphaParam; char* program_source = "float saxpy( [....] return result; } ";

  • Initialisation du runtime Cg

    30

    void initCG(void) {// set up CgcgContext = cgCreateContext();fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);cgGLSetOptimalOptions(fragmentProfile);// create fragment programfragmentProgram = cgCreateProgram (

    cgContext,CG_SOURCE,program_source, fragmentProfile,"saxpy",NULL);

    // load programcgGLLoadProgram (fragmentProgram);// and get parameter handles by nameyParam = cgGetNamedParameter (fragmentProgram,"textureY");xParam = cgGetNamedParameter (fragmentProgram,"textureX");alphaParam = cgGetNamedParameter (fragmentProgram,"alpha");

    }

  • GPGPU concept 3 : Calculer = dessiner

    Quatre tapes sont ncessaires : Activation du noyaux en utilisant le Cg

    runtime

    Assignation des tableaux d entre et de sortie au shader runtime Cg

    Dclenchement du traitement

    31

  • Etape 1 : Activation du noyau

    Pour activer le noyau en utilisant le Cg runtime : Le fragment profile doit tre activ

    Le shader dj crit et charg est attach

    On ne peut activer quun seul shader du mme type la fois

    Lactivation est assure par le code suivant :

    32

    // Activer le profil fragment cgGLEnableProfile(fragmentProfile); // Associer le programme saxpycgGLBindProgram(fragmentProgram);

  • Etape 2 : Configuration des entres tableaux textures

    33

    // Activer la texture y_old (lecture seule) cgGLSetTextureParameter(yParam, y_oldTexID); cgGLEnableTextureParameter(yParam); // Activer la texture x (lecture seule) cgGLSetTextureParameter(xParam, xTexID); cgGLEnableTextureParameter(xParam); // Activer le scalaire alpha cgSetParameter1f(alphaParam, alpha);

  • Etape 3 : Configuration des sorties tableaux textures

    34

    // Attacher la texture cible au premier point dattachmentglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texture_target, y_newTexID, 0); // Configurer la texture comme cible de renduglDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);

  • Etape 4 : Traitement Rappelons ce que nous avons fait.

    Activ un mapping 1:1 entre les pixels cibles, les coordonnes de texture et la gomtrie

    Prpar un fragment shader excuter sur chaque fragment

    Ce qui reste faire : tre sr que chaque donne t transfr correctement dans un

    fragment Ceci est relativement facile grce aux settings de la projection et du viewport

    Tout ce dont on a besoin cest un carr (quad) qui couvre la totalit du viewport (dfinissable grce au standard OpenGL)

    on dfinit 4 vertices coins du carr

    On assigne les coordonnes de texture comme attributs des 4 vertices (les vertices seront transforms en espace cran)

    La rastrisation (fonction fixe du pipeline) qui se trouve entre le vertex et le fragment pipeline se chargera du de lassociation entre pixel et coordonnes texture pour gnrer un fragment pour chaque pixel couvert par le carr

    Chaque valeur sera passe automatiquement au fragment shader

    Le quad sert comme un gnrateur de flux de donnes pour le program shader

    35

  • j avec une texture rectangles

    Les coordonnes de textures sont identiques aux coordonnes des pixels

    36

    // make quad filled to hit every pixel/texelglPolygonMode(GL_FRONT,GL_FILL); // and render quad glBegin(GL_QUADS);

    glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0); glTexCoord2f(texSize, 0.0); glVertex2f(texSize, 0.0); glTexCoord2f(texSize, texSize); glVertex2f(texSize, texSize); glTexCoord2f(0.0, texSize); glVertex2f(0.0, texSize);

    glEnd();

  • j avec une texture 2D

    Les coordonnes de textures sont normalises

    37

    // make quad filled to hit every pixel/texel glPolygonMode(GL_FRONT,GL_FILL); // and render quad glBegin(GL_QUADS);

    glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex2f(texSize, 0.0); glTexCoord2f(1.0, 1.0); glVertex2f(texSize, texSize); glTexCoord2f(0.0, 1.0); glVertex2f(0.0, texSize);

    glEnd();