Onion Information
rocRAND -- ROCm RANDom number generator - GASERI
U nastavku koristimo kod iz repozitorija rocRAND (službena dokumentacija)
Onion Details
Page Clicks: 1
First Seen: 03/15/2024
Last Indexed: 09/18/2024
Onion Content
rocRAND: ROCm RANDom number generator - U nastavku koristimo kod iz repozitorija rocRAND ( službena dokumentacija ). rocRAND nudi funkcije za generiranje pseudoslučajnih i kvazislučajnih brojeva. Podržani generatori su: Pregled dostupne funkcionalnosti u rocRAND-u - Funkcije koje rade na domaćinu - (Za više informacija proučite rocRAND host API .) - Generiranje slučajnih cijelih brojeva: rocrand_generate() stvara uniformno distribuirane 32-bitne cijele brojeve - Generiranje slučajnih brojeva s pomičnim zarezom: rocrand_generate_log_normal() stvara 32-bitne logaritamski normalno distribuirane brojeve s pomičnim zarezom - rocrand_generate_normal() stvara 32-bitne normalno distribuirane brojeve s pomičnim zarezom - rocrand_generate_poisson() stvara 32-bitne Poissonovo distribuirane brojeve s pomičnim zarezom - rocrand_generate_uniform() stvara 32-bitne uniformno distribuirane brojeve s pomičnim zarezom - Ostale funkcije: Funkcije koje rade na uređaju - (Za više informacija proučite rocRAND device functions .) - Primjer korištenja - Službeni primjer benchmark/benchmark_rocrand_generate.cpp ( datoteka u repozitoriju rocRAND na GitHubu ) za prevođenje u izvršni kod zahtijeva i datoteku zaglavlja benchmark/cmdparser.hpp ( datoteka u repozitoriju rocRAND na GitHubu ). Dodatni primjer je benchmark/benchmark_rocrand_kernel.cpp ( datoteka u repozitoriju rocRAND na GitHubu ). Ovaj program prikazuje kako se koriste funkcije za generiranje slučajnih brojeva. Pogledajmo funkciju main() od koje program kreće: Program počinje inicijalizacijom varijable parser tipa cli::Parser koji je definiran u ranije spomenutoj datoteci cmdparser.hpp ; ta će se varijabla koristiti za rasčlanjivanje raznih vrsta naredbi. Postavljaju se konstante tipa std::string koje će pohranjivati informacije o razdiobama i generatorima i to tako da su informacije odvojene znakom razmaka. Posebno se postavljaju početak i kraj tog znakovnog niza pomoću funkcije std::accumulate (za više informacija proučite std::accumulate na cppreference.com ): Slijedi postavljanje informacija kao što su veličina, dimenzije, zadatci, razdiobe, generatori i lambda (čiju ćemo svrhu objasniti u nastavku) u rasčlanjivač naredbi. Kao zadnja naredba stoji pokretanje i izlaz u slučaju greške. Nastavljamo na dio koji puni vektore s imenima pogona za generiranje slučajnih brojeva engines i razdioba slučajnih brojeva distributions . Kao uvjet stoji da funkcija std::find (za više informacija proučite std::find na cppreference.com ), sa određenim početkom i krajem, traži sve elemente u vektoru koji nisu jednaki kao zadnji, da bi na taj način upisala sve generatore iz prethodno definiranog vektora all_engines u vektor engines . Jednake naredbe stoje i za popis razdioba: Vektori znakovnih nizova all_engines i all_distributions izvan funkcije main() su oblika: Slijedi provjera funkcijom ROCRAND_CHECK u kojoj se dobavlja verzija biblioteke putem funkcije rocrand_get_version() spomenute na početku. Uz ovu provjeru, slijede još tri HIP_CHECK koji dohvaćaju runtime verziju, identifikacijski broj uređaja i svojstava tog uređaja. Nakon što su se ispisale iznad navedene informacije, nastavlja se petlja for u kojoj se na temelju znakovnog niza određuje tip generatora koji će se koristiti. Za svaki pojedini pogon se izvodi mjerenje performansi sa svakom od razdioba, što vidimo u dodatnoj petlji for. Došli smo do kraja funkcije main() . Pogledajmo malo detaljnije funkciju koja se poziva u dvije petlje for opisane iznad, funkciju run_benchmarks() (uočite množinu): Ova je funkcija u kojoj se ispituje o kojoj je razdiobi riječ. Sastoji se od trinaest grananja naredbom if , svaka od kojih uspoređuje trenutnu vrijednost varijable distribution sa svakom vrijednosti iz liste all_distributions . Unutar svakog if -a poziva se funkcija generatora slučajnih brojeva koju ćemo detaljnije razmotriti u nastavku. Za primjer uzmimo naredbu if koja se odnosi na uniformnu razdiobu prirodnih brojeva: Da bi funkcija run_benchmark() (uočite jedninu) bila pozvana, mora biti zadovoljen uvjet usporedbe. Ako je uvjet zadovoljen, funkcija run_benchmark() poziva rocRAND funkciju rocrand_generate_...() s generatorom slučajnih brojeva gen tipa rocrand_generator , mjestom za pohranu podataka data i brojem slučajnih brojeva koji će biti generirani size . U ovom slučaju rocrand_generate() vratiti će nepredznačenu cjelobrojnu vrijednost obzirom da razdioba tako nalaže (za više informacija o uniformnoj cjelobrojnoj razdiobi pogledajte std::uniform_int_distribution na cppreference.com ). Ako malo obratite pozornost na svaku od razdioba, primjetiti ćete da svaka traži drugačiji tip vrijednosti: Ako pogledate svaku sljedeću, primjetiti ćete da se pojavljuju i tipovi "normal-half" , "normal-float" , "normal-double" (za više informacija o normalnoj razdiobi proučite std::normal_distribution na cppreference.com ). Ovdje se traži normalna razdioba 32-bitnih brojeva s pomičnim zarezom. Također, pojavljuju se znakovni nizovi "log-normal-*" s različitim tipovima koji označavaju logaritamsku normalnu razdiobu za brojeve s pomičnim zarezom (za više informacija o logaritamskoj normalnoj razdiobi proučite std::lognormal_distribution na cppreference.com ). Posljednja razdioba koji vidimo jest "poisson" , odnosno Poissonova. Poissonova razdioba se koristi za opis rijetkih događaja, odnosno događaja koji imaju veliki uzorak i malu vjerojatnost i ovisi samo o parametru lambda . Promjenom parametra lambda mijenja se oblik razdiobe (za više informacija o Poissonovoj razdiobi proučite std::poisson_distribution na cppreference.com ). Pogledajmo sada detaljnije funkciju run_benchmark : Ako pogledate pomnije u kod ovog programa, primjetiti ćete da je na početku samog koda definiran predložak: U deklaraciji funkcije run_benchmark stoji generate_func koji je proizašao upravo iz tog definiranog predloška, kojeg se koristi u nastavku koda. Slijedi definicija varijabli size0 , trials , dimensions i size gdje su svi dobiveni pomoću Parser dohvaćanja, osim veličine size koja je umnožak vrijednosti dimenzije i rezultata dijeljenja size0 i dimensions . Nastavljamo sa HIP_CHECK provjerom alocirane memorije, i ROCRAND_CHECK provjerom generatora, i tipa generiranog broja. Nakon toga definiramo status , čija će vrijednost biti jednaka rezultatu rocRAND funkcije rocrand_set_quasi_random_generator_dimensions koji je zapravo broj dimenzija generatora quasi-slučajnih brojeva. (Za više informacija o ovoj funkciji možete pogledati na početak ovog teksta): Slijedi provjera; ako vrijednost dobivena u status nije quasi-nasumičan broj, pokreće se ROCRAND_CHECK provjera za status . Sljedeće se pokreće petlja for u kojoj se provodi ROCRAND_CHECK provjera generirane funkcije. Započinje mjerenje vremena izvršavanja provjere u for petlji koja ovaj puta broji do vrijednosti trials , nakon čega slijedi HIP_CHECK provjera sinkronizacije uređaja: Nakon svega slijedi ispis svih dobivenih rezultata tokom ove funkcije u obliku definiranom putem std::setprecision (za više informacija o funkciji pogledajte std::setprecision na cppreference.com ): Za kraj funkcije uništava se generator, i oslobađa se prethodno alocirana memorija. Uspješno smo prošli primjer programa koji koristi funkcije biblioteke rocRAND. Author: Mia Doričić, Vedran Miletić