diff --git a/Primitives/primitives.md b/Primitives/primitives.md index b38476b..6fa593b 100644 --- a/Primitives/primitives.md +++ b/Primitives/primitives.md @@ -113,4 +113,25 @@ FOR s = 1; s < get_global_size(0); s *= 2 DO: IF(ID = 0) THEN data[ID] = 0; ``` -A 2. feladathoz hasonlóan itt is feltételeztem, hogy a tömb mérete legfeljebb a workgroup megengedett maximális mérete. \ No newline at end of file +A 2. feladathoz hasonlóan itt is feltételeztem, hogy a tömb mérete legfeljebb a workgroup megengedett maximális mérete. + +## 4. Elemek számlálása compact operátorral + +A feladathoz tartozó host kód a `primitives/Compact.cpp` fájlban található. A Compact operátort a feladat specifikációja szerint három kernel összefűzésével készítettem el; + + * Map - A bementi vektor értékeihez nullát, vagy egyet rendel annak függvényében, hogy az kisebb-e 50-nél. + * Exkluzív scan - Az előbbi lépés kimenetét felhasználva kiszámítja, melyik indexre fognak kerülni a nem ritka eredménytömbben az 50-nél kisebb elemek. + * Scatter - Előző két lépés eredményeit felhasználva előállítja a nem ritka eredmény tömböt. + +Mivel az eredménytömb kisebb is lehet, mint a bemeneti, akkor ha az eddigiekhez hasonlóan a bemeneti tömb méretét olvasom vissza az OpenCL bufferből, felesleges adatokat is mozgatok. Ennek elkerülése érdekében végeztem pár módosítást a mellékelt pszeudokód által leírt algoritmuson. Az exkluzív scan lépésben a globálisan nulladik azonosítójú szál a tömb legutolsó elemével felülírja a saját értékét, így a tömb első eleme az 50-nél kisebb értékű elemek számát fogja jelezni. A későbbiekben a nulladik elem redundáns ebben a tömbben, hiszen ha a predikátum 0, nem kerül bele az eredménybe, ha viszont 1, garantáltam a 0. helyre fog bekerülni. Ennek megfelelően a scatter lépést is módosítottam, hogy ne legyen szükség a scan nulladik elemére; + +``` +ID := get_global_id(0) +VALUE := data[ID] +BARRIER +IF pred[ID] == 1 THEN + IF ID == 0 THEN + data[0] = VALUE + ELSE + data[prefSum[ID]] = VALUE +``` \ No newline at end of file