Programowanie współbieżne i rozproszone

Podobne dokumenty
Programowanie Równoległe wykład 12. Thrust C Maciej Matyka Instytut Fizyki Teoretycznej

Algorytmy w C++ dla opornych!

Programowanie Obiektowo Zorientowane w języku C++ Biblioteka STL

Programowanie Komponentowe Zarządzanie obiektami: kontenery

STL: kontenery. STL: kontenery. STL: kontenery. Typy kontenerów STL. STL: kontenery. STL: kontenery. multimap. Kontener map: przykład zadanie:

STL: algorytmy sortujące. STL: algorytmy sortujące. STL: algorytmy sortujące. STL: algorytmy sortujące. STL: algorytmy sortujące

STL: algorytmy sortujące. STL: algorytmy sortujące. STL: algorytmy sortujące. STL: algorytmy sortujące. STL: algorytmy sortujące

Programowanie i struktury danych

Programowanie w C++ Wykład 6. Katarzyna Grzelak. 1 kwietnia K.Grzelak (Wykład 6) Programowanie w C++ 1 / 43

Programowanie w C++ Wykład 7. Katarzyna Grzelak. 23 kwietnia K.Grzelak (Wykład 7) Programowanie w C++ 1 / 40

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Wykład 5 Wybrane zagadnienia programowania w C++ (c.d.)

Paradygmaty programowania

Zaawansowane programowanie w języku C++ Biblioteka standardowa

Algorytmy, iteratory, kolekcje niestandardowe

Kontenery i iteratory. Wykorzystanie kontenerów w praktyce.

Aby uzyskać zaliczenie w pierwszym terminie (do 30 stycznia 2018) rozliczyć trzeba co najmniej 8 projektów, po 4 z każdej z części: C++ oraz Python.

Wykład 1. Program przedmiotu. Programowanie (język C++) Literatura. Program przedmiotu c.d.:

Definicja szablonu klasy. Korzystanie z szablonu. Specjalizacja metody szablonu.

Style programowania - krótki przeglad

W przypadku STL w specyfikacji nazwy pliku nagłówkowego brak rozszerzenia tj. <string> <string.h> zamiast

Algorytmy sortujące. sortowanie kubełkowe, sortowanie grzebieniowe

STL: Lekcja 1&2. Filozofia STL

Wykład 1 Wprowadzenie do algorytmów. Zawartość wykładu 1. Wstęp do algorytmów i struktur danych 2. Algorytmy z rozgałęzieniami.

Szablony funkcji i szablony klas

STL: kontenery C++: STL: kontenery. STL: kontenery. STL: kontenery. STL: kontenery. Fabryka obiektów. Fabryka obiektów

Dla każdej operacji łącznie tworzenia danych i zapisu ich do pliku przeprowadzić pomiar czasu wykonania polecenia. Wyniki przedstawić w tabelce.

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Porównanie wydajności CUDA i OpenCL na przykładzie równoległego algorytmu wyznaczania wartości funkcji celu dla problemu gniazdowego

int tab[5]; tab[1]; ciągły obszar pamięci, w którym umieszczone są elementy tego samego typu macierz [ ] - dwuargumentowy operator indeksowania

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

Paradygmaty programowania

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

STL Standardt Template Library (wprowadzenie)

Wstęp do programowania

EGZAMIN MATURALNY 2011 INFORMATYKA

Programowanie obiektowe W3

Wprowadzenie do szablonów szablony funkcji

Algorytmy sortujące i wyszukujące

Wstęp do Techniki Cyfrowej... Teoria automatów

Język C zajęcia nr 11. Funkcje

Style programowania - krótki przeglad

Definicja. Ciąg wejściowy: Funkcja uporządkowująca: Sortowanie polega na: a 1, a 2,, a n-1, a n. f(a 1 ) f(a 2 ) f(a n )

Wykład 3 Składnia języka C# (cz. 2)

Wstęp do programowania obiektowego. STL - Standard Template Library

Wprowadzenie do szablonów szablony funkcji

Programowanie w elektronice: Podstawy C

Algorytmy i Struktury Danych. Anna Paszyńska

Tablicę 2-wymiarową można przedstawić jako pewien zestaw tablic 1-wymiarowych np.:

Szablony funkcji i klas (templates)

Zaawansowane programowanie w języku C++ Funkcje uogólnione - wzorce

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

Wstęp do programowania

Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

Szablony klas, zastosowanie szablonów w programach

Język C++ część 9 szablony klas. Jarosław Gramacki Instytut Informatyki i Elektroniki. szablony funkcji

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

Grzegorz Paweł Korbaś. Podstawy C++ Zbiór zadań z rozwiązaniami. Opole 2011 wydanie pierwsze wydawnictwo czytnia.pl

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Technologie programowania Wykład 4. Szablony funkcji Notes. Szablony funkcji Notes. Szablony funkcji Notes. Notes. Przemek Błaśkiewicz.

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Warto też w tym miejscu powiedzieć, że w C zero jest rozpoznawane jako fałsz, a wszystkie pozostałe wartości jako prawda.

Programowanie w języku Java. Kolekcje

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Języki i techniki programowania Ćwiczenia 2

Technologie cyfrowe semestr letni 2018/2019

Języki programowania obiektowego Nieobiektowe elementy języka C++

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 7 maja K.Grzelak (Wykład 8) Programowanie w C++ 1 / 31

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

Java Collections Framework

ang. file) Pojęcie pliku (ang( Typy plików Atrybuty pliku Fragmentacja wewnętrzna w systemie plików Struktura pliku

TOPIT Załącznik nr 3 Programowanie aplikacji internetowych

Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Struktury Danych i Złożoność Obliczeniowa

Rekurencja (rekursja)

Programowanie Równoległe Wykład, CUDA praktycznie 1. Maciej Matyka Instytut Fizyki Teoretycznej

Spis treści. Wprowadzenie 15

Klasy Obiekty Dziedziczenie i zaawansowane cechy Objective-C

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

Zajęcia nr 5 Algorytmy i wskaźniki. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Programowanie w języku C++

Wydajność użycia funktorów z biblioteką STL języka C++

Literatura. adów w cyfrowych. Projektowanie układ. Technika cyfrowa. Technika cyfrowa. Bramki logiczne i przerzutniki.

Języki programowania. Przetwarzanie tablic znaków. Część druga. Autorzy Tomasz Xięski Roman Simiński

Algorytmy i struktury danych. Co dziś? Tytułem przypomnienia metoda dziel i zwyciężaj. Wykład VIII Elementarne techniki algorytmiczne

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Zadanie 2: Arytmetyka symboli

Proste algorytmy w języku C

Prof. Danuta Makowiec Instytut Fizyki Teoretycznej i Astrofizyki pok. 353, tel danuta.makowiec at gmail.com

Pojemniki Pojemnik to obiekt, którego zadaniem jest przechowywanie innych obiektów.

Transkrypt:

Programowanie współbieżne i rozproszone WYKŁAD 5 Jan Kazimirski 1

Programowanie GPU 2/2 2

Thrust Język CUDA C bazuje na języku C języku o dosyć niskim poziomie abstrakcji ( macro assembler) Implementowanie złożonych problemów w CUDA C jest kłopotliwe CUDA C wymaga podejmowania decyzji związanych z niskopoziomową reprezentacją problemu (bloki, wątki, sposoby alokacji pamięci itd.) 3

Thrust c.d. Thrust jest biblioteką wysokiego poziomu opartą o system szablonów C++. Używa modelu znanego z biblioteki STL (kontenery i algorytmy) Ukrywa szczegóły sprzętowe i niskopoziomowe Pozwala skoncentrować się na problemie, a nie na szczegółach jego implementacji Pozwala na szybkie tworzenie kodu 4

Thrust c.d. Thrust jest częścią tool-kitu dostępnego na stronie NVIDIA Kompilacja nie wymaga dodatkowych narzędzi Programy wykorzystujące Thrust muszą włączać odpowiednie pliki nagłówkowe Dokumentację API można znaleźć pod adresem: http://docs.thrust.googlecode.com/hg/index.html 5

Thrust - Przykład programu suma wektorów 1/2 #include <thrust/host_vector.h> #include <thrust/device_vector.h> #include <stdio.h> #include <thrust/functional.h> #include <thrust/fill.h> #include <thrust/transform.h> #define N 100 void show(thrust::host_vector<int> v) { int i; for(i=0;i<n;i++) printf("%d ",v[i]); printf("\n"); } 6

Thrust - Przykład programu suma wektorów 1/2 int main(void) { thrust::device_vector<int> d_va(n); thrust::device_vector<int> d_vb(n); thrust::device_vector<int> d_vc(n); thrust::fill(d_va.begin(),d_va.end(),1); thrust::fill(d_vb.begin(),d_vb.end(),2); } thrust::plus<int> op; thrust::transform( d_va.begin(), d_va.end(), d_vb.begin(), d_vc.begin(),op); thrust::host_vector<int> h_vc = d_vc; show(h_vc); return 0; 7

Elementy Thrust Kontenery pozwalają na przechowywanie danych dowolnego typu Iteratory udostępniają dane kontenera Algorytmy przetwarzają dane z kontenerów Obiekty funkcyjne wykorzystywane do definiowania operacji używanych w algorytmach Generator pseudolosowy 8

Kontenery Thrust definiuje jeden typ kontenera w dwóch wersjach. Kontener ten odpowiada STL-owemu kontenerowi vector. Klasa thrust::host_vector kontener alokowany w pamięci hosta Klasa thrust::device_vector kontener alokowany w pamięci urządzenia Funkcjonalność tych kontenerów odpowiada funkcjonalności STL-owego wektora

Kontenery c.d. Kopiowanie danych między hostem i urządzeniem jest bardzo łatwe używa się operatora przypisania: thrust::host_vector<int> hvec(100); thrust::device_vector<int> dvec(100); dvec = hvec; //... hvec = dvec;

Kontenery c.d. Klasy wektorów Thrust definiują wiele wygodnych metod do manipulowania danymi (tworzenie, usuwanie oraz dostęp do elementów). Elementy wektorów dostępne są poprzez operator indeksowania [] (Uwaga! Dla vector_device niewydajne). Wektorami zwykle manipulujemy za pomocą iteratorów.

Iteratory Przetwarzanie danych z kontenerów wymaga zwykle podanie zakresu. Metody begin() i end() wektora zwracają iterator do pierwszego i ostatniego elementu wektora. Iteratory implementują również metody pozwalające na dostęp do dowolnego elementu i wyliczanie odstępu między elementami.

Iteratory - przykład #include <thrust/host_vector.h> #include <thrust/device_vector.h> #include <iostream> int main(void) { thrust::device_vector<int>::iterator iter; thrust::host_vector<int> hvec(10,5); thrust::device_vector<int> dvec(10); dvec = hvec; for(iter=dvec.begin();iter<dvec.end();iter++) std::cout << *iter << std::endl; } return 0;

Iteratory c.d. Iteratory zawierają informację o typie wskaźnika (device, host) te same algorytmy mogą działać na obu typach Thrust zawiera metody do konwersji gołego wskaźnika CUDA (cudamalloc) na iterator i odwrotnie.

Wybrane algorytmy Thrust implementuje zbiór algorytmów analogicznych do algorytmów STL. Algorytmy Thrust mogą działać na wektorach na hoście, jak i na urządzeniu (zależnie od użytego iteratora) Sposób korzystania z algorytmów Thrust bardzo przypomina używanie algorytmów STL.

Wybrane algorytmy c.d. Wyszukiwanie Kopiowanie Redukcja Sortowanie Partycjonowanie Łączenie Operacje teorii mnogości Transformacje

Wyszukiwanie Funkcje związane z wyszukiwaniem: find wyszukuje podany element w zbiorze. find_if, find_if_not wyszukuje w zbiorze element spełniający lub niespełniający danego warunku mismatch porównuje dwa zbiory elementów i zwraca pozycję pierwszej różnicy elementów

find 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <iostream> 04: 05: int main(void) { 06: int arr[] = {1,3,5,2,6,9,11,32,4,99}; 07: thrust::host_vector<int> hvec(arr,arr+10); 08: thrust::device_vector<int> dvec = hvec; 09: thrust::device_vector<int>::iterator iter; 10: 11: iter = thrust::find(dvec.begin(),dvec.end(),5); 12: std::cout << iter-dvec.begin() << std::endl; 13: iter = thrust::find(dvec.begin(),dvec.end(),33); 14: std::cout << iter-dvec.begin() << std::endl; 15: 16: return 0; 17: }

find_if 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <iostream> 04: 05: struct pred { 06: device bool operator()(int x) { 07: return x>10; 08: } 09: }; 10: 11: int main(void) { 12: int arr[] = {1,3,5,2,6,9,11,32,4,99}; 13: thrust::host_vector<int> hvec(arr,arr+10); 14: thrust::device_vector<int> dvec = hvec; 15: thrust::device_vector<int>::iterator iter; 16: 17: iter = thrust::find_if(dvec.begin(),dvec.end(),pred()); 18: std::cout << iter-dvec.begin() << std::endl; 19: 20: return 0; 21: }

mismatch 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <iostream> 04: 05: int main(void) { 06: int arr1[] = {1,3,5,2,6,9,11,32,4,99}; 07: int arr2[] = {1,3,5,2,6,11,8,30,22,15}; 08: thrust::device_vector<int> dvec1(arr1,arr1+10); 09: thrust::device_vector<int> dvec2(arr2,arr2+10); 10: typedef thrust::device_vector<int>::iterator Iterator; 11: thrust::pair<iterator,iterator> result; 12: result = thrust::mismatch(dvec1.begin(), dvec1.end(), dvec2.begin()); 13: 14: std::cout << *result.first << std::endl << 15: *result.second << std::endl << 16: result.first-dvec1.begin() << std::endl; 17: 18: return 0; 19: }

Kopiowanie Funkcje związane z kopiowaniem danych: copy kopiuje elementy z jednego zbioru do drugiego copy_n kopiuje n elementów z jednego zbioru do drugiego swap_ranges Wymienia elementy dwóch zbiorów między sobą.

copy 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <iostream> 04: 05: int main(void) { 06: int arr1[] = {1,3,5,2,6,9,11,32,4,99}; 07: thrust::device_vector<int> dvec1(arr1,arr1+10); 08: thrust::device_vector<int> dvec2(10); 09: 10: thrust::copy(dvec1.begin(),dvec1.end(),dvec2.begin()); 11: 12: for(int i=0;i<10;i++) std::cout << dvec2[i] << " "; 13: std::cout << std::endl; 14: 15: return 0; 16: }

swap_ranges 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <iostream> 04: 05: int main(void) { 06: int arr1[] = {1,3,5,2,6,9,11,32,4,99}; 07: int arr2[] = {1,1,1,1,1,1,1,1,1,1}; 08: thrust::device_vector<int> dvec1(arr1,arr1+10); 09: thrust::device_vector<int> dvec2(arr2,arr2+10); 10: 11: thrust::swap_ranges(dvec1.begin()+2,dvec1.begin()+5,dvec2.begin()+2); 12: 13: for(int i=0;i<10;i++) std::cout << dvec2[i] << " "; 14: std::cout << std::endl; 15: 16: return 0; 17: }

Kopiowanie c.d. Funkcje gather i scatter pozwalają na kopiowanie elementów pomiędzy zbiorami zgodnie z określoną mapą Alternatywne wersje powyższych funkcji gather_if i scatter_if pozwalają dodatkowo okreslić warunek jaki muszą spełniać kopiowane elementy

Redukcja Algorytmy związane z redukcją możemy podzielić na kilka grup: Redukcja za pomocą określonej operacji Zliczanie elementów Redukcja oparta o porównanie Wyszukiwanie wartości ekstremalnych Redukcje z transformacją Redukcje oparte o operacje logiczne Redukcje na podstawie własności zbioru

Redukcja za pomocą określonej operacji Funkcja reduce pozwala przekształcić zbiór wejściowy w pojedynczą wartość Zależnie od wariantu funkcji możemy zastosować sumowanie lub inną operację Uwaga! Wektoryzacja powoduje, że elementy mogą być przetwarzane w innej niż podana kolejności.

reduce 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <iostream> 04: 05: int main(void) { 06: int arr1[] = {1,2,3,4,5,6,7,8,9,10}; 07: thrust::device_vector<int> dvec1(arr1,arr1+10); 08: 09: std::cout << thrust::reduce(dvec1.begin(),dvec1.end()) << std::endl; 10: std::cout << thrust::reduce(dvec1.begin(),dvec1.end(),10) << std::endl; 11: 12: return 0; 13: }

Zliczanie elementów Funkcja count zlicza ile elementów w podanym zakresie jest równe danej wartości Funkcja count_if zlicza dla ilu elementów w podanym zakresie podane wyrażenie jest prawdziwe.

count 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/count.h> 04: #include <iostream> 05: 06: int main(void) { 07: int arr1[] = {1,2,3,4,5,6,7,8,9,1}; 08: thrust::device_vector<int> dvec1(arr1,arr1+10); 09: 10: std::cout << thrust::count(dvec1.begin(),dvec1.end(),1) << std::endl; 11: std::cout << thrust::count(dvec1.begin(),dvec1.end(),11) << std::endl; 12: 13: return 0; 14: }

Redukcja oparta o porównanie Funkcja equal pozwala sprawdzić czy elementy dwóch podanych zakresów są takie same. Funkcja jest też dostępna w wariancie umożliwiającym podanie funkcji stosowanej do porównywania elementów.

Wyszukiwanie wartości ekstremalnych Dostępne funkcje: min_element znajduje najmniejszy element zbioru max_element znajduje największy element zbioru minmax_element znajduje parę elementów: największy i najmniejszy Funkcje dostępne są też w wersji pozwalającej na dostarczenie własnej funkcji porównującej.

minmax_element 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/count.h> 04: #include <iostream> 05: 06: int main(void) { 07: int arr1[] = {1,2,3,4,5,6,7,8,9,1}; 08: thrust::device_vector<int> dvec1(arr1,arr1+10); 09: typedef thrust::device_vector<int>::iterator Iterator; 10: 11: thrust::pair<iterator,iterator> result = thrust::minmax_element(dvec1.begin(),dvec1.end()); 12: 13: std::cout << *result.first << " " << result.first-dvec1.begin() << std::endl; 14: std::cout << *result.second << " " << result.second-dvec1.begin() << std::endl; 15: 16: return 0; 17: }

Redukcje z transformacją Funkcja inner_product liczy iloczyn skalarny dla danego zbioru Funkcja transform_reduce pozwala połączyć redukcję z transformacją zbioru za pomocą określonej operacji

Redukcje oparte o operacje logiczne Wykorzystują operacje logiczne na zbiorach. Dostępne funkcje: all_of sprawdza czy wszystkie elementy spełniają dany warunek any_of sprawdza czy jakikolwiek element spełnia dany warunek none_of sprawdza czy żaden element nie spełnia danego warunku.

any_f, all_of 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/count.h> 04: #include <thrust/logical.h> 05: #include <iostream> 06: 07: struct is_one { 08: device bool operator()(int x) { 09: return x==1; 10: } 11: }; 12: 13: int main(void) { 14: int arr1[] = {1,2,3,4,5,6,7,8,9,1}; 15: thrust::device_vector<int> dvec1(arr1,arr1+10); 16: 17: 18: std::cout << thrust::any_of(dvec1.begin(),dvec1.end(),is_one()) << std::endl; 19: std::cout << thrust::all_of(dvec1.begin(),dvec1.end(),is_one()) << std::endl; 20: 21: return 0; 22: }

Redukcje na podstawie własności zbioru Funkcje: is_partitioned sprawdza czy zbiór jest podzielony na elementy spełniające i niespełniające danego warunku is_sorted sprawdza czy zbiór jest posortowany is_sorted_until zwraca liczbę elementów zbioru, które są posortowane.

Sortowanie Algorytm sortowania zbioru występuje w dwóch wariantach sort i stable_sort. Funkcja stable_sort zachowuje porządek elementów równorzędnych Funkcja sort_by_key pozwala sortować dane w postaci par klucz-wartość. Zamiast domyślnego operatora porównania można do sortowania użyć własnej funkcji porównującej.

sort 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/sort.h> 04: #include <iostream> 05: 06: 07: int main(void) { 08: int arr1[] = {1,2,3,4,5,6,7,8,9,1}; 09: thrust::device_vector<int> dvec1(arr1,arr1+10); 10: 11: thrust::sort(dvec1.begin(),dvec1.end()); 12: 13: for(int i=0;i<10;i++) std::cout << dvec1[i] << " "; 14: std::cout << std::endl; 15: 16: return 0; 17: }

Partycjonowanie Algorytmy te pozwalają na częściowe uporządkowanie zbioru tzn. osobno elementy spełniające i niespełniające warunku Funkcje: partition podział zbioru zgodnie z warunkiem partition_copy podział zbioru i umieszczenie rezultatu w innym miejscu stable_partition, stable_partition_copy stabilne wersje powyższych algorytmów

Łączenie Funkcja merge pozwala połączyć dwa posortowane zbiory w jeden zbiór wynikowy Dostępna jest wersja funkcji merge pozwalająca dostarczyć własny operator porównania zamiast domyślnego

Operacje teoriomnogościowe Dostępne operacje teoriomnogościowe: set_difference różnica zbiorów set_intersection cześć wspólna zbiorów set_symmetric_difference różnica symetryczna set_union suma zbiorów Powyższe funkcje wymagają posortowanych zbiorów. Alternatywne wersje funkcji pozwalają dostarczyć własną funkcję porównującą.

Transformacje Thrust dysponuje algorytmami pozwalającymi na różnorodne transformacje zbioru wejściowego Podstawowe grupy transformacji: Generowanie zbioru Wypełnianie zbioru Transformacje zbioru wejściowego w wyjściowy Przetwarzanie każdego elementu zbioru Zastępowanie elementów zbioru

Generowanie zbioru Funkcja generate wypełnia kontener w podanym zakresie wartościami wyliczonymi za pomocą podanej funkcji generującej. Funkcja generate_n j.w. ale podaje się ile elementów ma być utworzonych. Funkcja sequence wypełnia kontener wartościami tworzącymi sekwencję.

generate 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/generate.h> 04: #include <iostream> 05: 06: struct five { 07: device int operator()() { 08: return 5; 09: } 10: }; 11: 12: int main(void) { 13: thrust::device_vector<int> dvec1(10); 14: 15: thrust::generate(dvec1.begin(),dvec1.end(),five()); 16: 17: for(int i=0;i<10;i++) std::cout << dvec1[i] << " "; 18: std::cout << std::endl; 19: 20: return 0; 21: }

sequence 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/sequence.h> 04: #include <iostream> 05: 06: int main(void) { 07: thrust::device_vector<int> dvec1(10); 08: 09: thrust::sequence(dvec1.begin(),dvec1.end()); 10: 11: for(int i=0;i<10;i++) std::cout << dvec1[i] << " "; 12: std::cout << std::endl; 13: 14: return 0; 15: }

Wypełnianie zbioru Funkcja fill Wypełnia kontener w podanym zakresie określoną wartością Funkcja fill_n Jak fill, ale podaje się liczbę elementów do wypełnienia.

fill 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/fill.h> 04: #include <iostream> 05: 06: int main(void) { 07: thrust::device_vector<int> dvec1(10); 08: 09: thrust::fill(dvec1.begin(),dvec1.end(),11); 10: 11: for(int i=0;i<10;i++) std::cout << dvec1[i] << " "; 12: std::cout << std::endl; 13: 14: return 0; 15: }

Transformacje zbioru wejściowego w wyjściowy Funkcja transform dokonuje transformacji zbioru (lub 2 zbiorów) wejściowych na zbiór wyjściowy według zadanej funkcji. Funkcja transform_if Podobna do transform, ale pozwala dokonać transformacji warunkowej na podstawie danych wejściowych lub dodatkowej mapy.

transform 01: #include <thrust/host_vector.h> 02: #include <thrust/device_vector.h> 03: #include <thrust/transform.h> 04: #include <iostream> 05: 06: int main(void) { 07: int arr1[] = {1,3,5,2,6,9,11,32,4,99}; 08: int arr2[] = {1,1,1,1,1,1,1,1,1,1}; 09: thrust::device_vector<int> dvec1(arr1,arr1+10); 10: thrust::device_vector<int> dvec2(arr2,arr2+10); 11: thrust::device_vector<int> dvec3(10); 12: 13: thrust::plus<int> op; 14: thrust::transform(dvec1.begin(),dvec1.end(),dvec2.begin(),dvec3.begin(),op); 15: 16: for(int i=0;i<10;i++) std::cout << dvec3[i] << " "; 17: std::cout << std::endl; 18: 19: return 0; 20: }

Przetwarzanie każdego elementu zbioru Funkcja for_each wykonuje określoną operację na zbiorze w podanym zakresie. Funkcja for_each_n Podobna do for_each, ale podaje się liczbę elementów do przetworzenia

Zastępowanie elementów zbioru Funkcja replace pozwala zastąpić w zbiorze podany element nową wartością. Funkcja replace_if jw. ale podaje się warunek jaki muszą spełnić zastępowane wartości. Funkcja replace_copy, replace_copy_if ten wariant funkcji replace wykonuje zastępowanie z jednoczesnym kopiowaniem do innego zbioru.

Zaawansowane iteratory Thrust definiuje dodatkowe specjalne iteratory pozwalające zwiększyć możliwości algorytmów. Algorytm nie widzi różnicy między zwykłym a specjalnym iteratorem. Specjalne iteratory: constant_iterator counting_iterator transform_iterator permutation_iterator zip_iterator

constant_iterator Reprezentuje zbiór złożony z jednej wartości Może być wykorzystany do wypełniania kontenerów danymi. Funkcja make_constant_iterator może być użyta do łatwego utworzenia iteratora jako parametru algorytmu (nie wymaga podania dokładnego typu iteratora)

counting_iterator Reprezentuje zbiór będący sekwencją rosnących wartości. Pozwala na łatwe tworzenie sekwencji lub wykonywanie operacji z udziałem sekwencji Dostępna jest funkcja make_counting_iterator

transform_iterator Reprezentuje zbiór będący przedziałem wartości po przetworzeniu przez funkcję (transformacja) Połączony z innym algorytmem pozwala połączyć wywołania jądra zwiększając wydajność Dostępna jest funkcja make_transform_iterator

permutation_iterator Reprezentuje zbiór danych będący podzbiorem podanego przedziału, ale z wartościami przestawionymi zgodnie z podanym schematem Wygodny przy operacjach typu scatter/gather Dostępna jest funkcja generująca make_permutation_iterator

zip_iterator Łączy kilka sekwencji wejściowych w jedną sekwencję Użyteczny gdy wymagana jest operacja na bardziej złożonych danych (np.. wielowymiarowych). Umożliwia algorytmom pracę na wielu strumieniach danych z użyciem tylko jednego iteratora. Dodatkowe funkcje: make_tuple, make_zip_iterator

Obiekty funkcyjne Większość algorytmów pozwala na dostarczenie własnej wersji funkcji wykorzystywanej do przetwarzania danych. Thrust udostępnia predefiniowane funkcje w postaci tzw. obiektów funkcyjnych dla różnych typów operacji: arytmetycznych, porównania, logicznych, bitowych i innych. Predefiniowane obiekty funkcyjne dostarczane są w postaci szablonów.

Predefiniowane obiekty funkcyjne Operatory arytmetyczne: plus<t>, minus<t>, multiplies<t>, divides<t>, modulus<t>, negate<t> Operatory porównania: equal_to<t>, not_equal_to<t>, greater<t>, less<t>, greater_equal<t>, less_equal<t> Operatory logiczne: logical_and<t>, logical_or<t>, logical_not<t> Operatory bitowe: bit_and<t>, bit_or<t>, bit_xor<t>