HTML

Az élet kódjai

Csináld maga. Senki nem csinálja meg helyetted.

Friss topikok

  • sdani: Sajnos nekem is hasonló érzéseim vannak az R kiszorulásával kapcsolatban. Remélem jobban fogja tar... (2024.04.29. 10:48) R meetup
  • sdani: Nagyon jók ezek a bejegyzések! Feszültséggel teli, fordulatos, mint egy jobb krimi. :D Abba ne hag... (2024.04.29. 10:35) Wgel CTF
  • sdani: @Travis.CG: Egy kis szerencse sosem árt. :D (2024.03.01. 13:19) A bioinformatika helyzete 2024-ben
  • Travis.CG: Szóval az akadémiai szféra mazochistává tett, amit a Pinephone-al élek ki? Hmm, érdekes összefüggé... (2023.10.05. 18:23) Új barátom az Informatikai titkárságról
  • Travis.CG: Túl nagy a hype körülötte, ezért túlzó elvárások vannak vele szembe. Ha a korábbi chatbotokhoz kép... (2023.02.28. 06:28) chatGPT, a bioinformatikus

Bioscope folyamatok futtatása

2011.04.19. 15:52 Travis.CG

Korábban azt írtam, hogy csak egy bonyolult script segítségével tudtam több folyamatot egymás után futtatni. Ez a script folyamatosan cserélgette az .ini fájlokat.

Szerencsére van más módszer is, amivel parancssorban egy folyamatot tudunk összeállítani a Bioscope részére.

Létre kell hozni egy .plan kiterjesztésű állományt. Ez tartalmazza a folyamat egyes elemeit. Az elemek pedig a futtatni kívánt programok ini állományai. Tehát ha egy szekvenálás eredményét először illesztjük a referenciához, majd .bam állománnyá konvertáljuk, akkor a következő sorok szerepelhetnek a .plan állományban:

mapping.ini

matobam.ini

Létre kell hozni a két ini állományt, és a dokumentáció szerint kitölteni a paraméterekkel. Csakhogy, nincs lehetőség ciklusok és változók használatára. Tehát ha van nyolc szekvenálásunk, akkor nyolc ini fájlt kell létrehozni, még akkor is, ha csak egy sor eltérés van bennük.

Trükként lehet használni a global kulcsszót az ini fájlok elején. Ennek célja, hogy bizonyos változókat kiemeljen, amelyek több ini állományban is ugyan olyan értéket vesznek fel.

Amint készen van a .plan fájlunk, nem kell mást tenni, mint elindítani a bioscope-t:

bioscope.sh -l logfile sajat.plan

Szólj hozzá!

Címkék: bioinformatika

LaTeX hackelések

2011.04.18. 11:31 Travis.CG

Egy Microsoft központú világban nem használni Office terméket ( beleértve az ingyenes klónokat is) eretnekség. A diplomadolgozat elkészítése után váltam eretnekké, ahol annyi problémával szembesültem, hogy úgy döntöttem mellőzöm ezeket a programokat az életemből.

A dokumentációkat ettől a pillanattól kezdve LaTeX-ban készítettem, mit sem törődve a főnökök siránkozásával, hogy nem tudják szerkeszteni az általam átküldött anyagokat. Nem vagyok nagy felhasználó, de még az én szintemen is sokkal könnyebben boldogultam vele, mint annak idején a klikkelős szöveg formázó rendszerekkel.

Mikor eljött a doktori dolgozat elkészítésének ideje, nem volt kérdéses számomra, hogy LaTeX-ben fog készülni. A döntésem helyes volta rendszeresen visszaköszönt, ahogy láttam mások mennyi szenvedés árán csinálják dolgozatukat. Persze az így elkészült dolgozatról már messziről látszott, hogy ez valami eretnek termék. A betűk szépek, nincsenek hullámvonalas hosszú ő és ű-k, az oldalak elrendezése esztétikus, és a referenciák teljesen egységes felépítést mutatnak. Ez pedig csak valami gonosz műve lehet.

Rögtön bele is kötöttek házi védésnél, hogy a referenciák a műszaki tudományoknál megszokott módon vannak formázva. Ennek kijavítása rendkívül egyszerű volt. Betöltöttem a natbib csomagot, és az összes \cite parancsot \citep-re cseréltem. Mivel Linux alatt dolgoztam, ez egy sed paranccsal megoldható. Csakhogy, a \citep-nél a szerzők neve között "and" szerepelt "és" helyett. Hirtelen nem találtam rá semmilyen megoldást. Mások is szenvedtek hasonló problémákkal. Egy oldalon pedig olyan bonyolult tex megoldás szerepelt, hogy nem értettem belőle semmit.

Az idő fogyott, nekem pedig nem volt megoldásom rá. A hívők kajánul mosolyogtak nyomoromon, hogy bezzeg a Wordben bármilyen szót ki lehet cserélni, bármikor. LaTeX-ben nem. A LaTeX sok kis szövegfájlból állítja elő DVI v. PDF kimenetet, ami már nem szerkeszthető egyszerű módon. Tehát nekiálltam megkeresni azt a szövegfájlt, ami a problémát okozza. A gondot a bibtex/bst/natbib könyvtár stílusfájljai okozták. Ezekbe bele van égetve az "and" kulcsszó a format.names, format.full.names, format.lab.names függvényekbe. Tehát ezeket kell csak kicserélni és máris mindenhol magyarul jelenik meg az elválasztás. Mindenhol? Igen. Még az irodalomjegyzékben is. Ez viszont nem jó. Ha a format.names-t visszaírjuk, akkor már jó lesz. Csúnya hack, de működik.

A másik problémám a szekeszthetőség volt. Ezt a LaTeX2rtf programmal oldottam meg. Ennek viszont volt egy komoly problémája. Én ugynis UTF8-ban készítettem a dokumentumot, a program viszont csak Latin1-t volt képes kezelni, sok formázást nem volt képes maga elvégezni, ezért a következőképp kell használni:

  1. LaTeX-el hozzuk létre a dokumentumot. A folyamat során létrejönnek az átmeneti állományok.
  2. iconv segítségével alakítsuk át a programok kódolását. Én az alábbi kis scripttel oldottam meg: for i in *; do iconv -f UTF8 -t Windows-1251 $i >tmp; mv tmp $i; done
  3. Futtassuk a LaTeX2rtf programot. Ha szerencsénk van, csak a hosszú ő és ű lesz ronda. Egyéb karakterkódolással lehet kísérletezni. A teljes fordítás soha nem lesz tökéletes.

Nekem a táblázat hivatkozások, fejezet címek (chapter fejezet helyett) soha nem jelentek meg tökéletesen. De az RTF úgysem publikálásra készül, hanem arra, hogy belejavítsanak, tehát sok időt nem szabad vele foglalkozni.

Egy majd hetven oldalas dokumentumnál összesen két probléma. Ez töredéke annak, ami egy Word dokumentumnál fellép. A nyomtatás pedig PDF-ből gyerekjáték, míg Word esetén katasztrófa, ha egy másik gépre kell átvinni. Megéri eretneknek lenni.

Szólj hozzá!

Címkék: biztonság életmód

Szakmák, amikhez mindenki ért: Külcsin

2011.04.14. 14:41 Travis.CG

Ez a szakma elég megfoghatatlan számomra. Először is, mert véleményem szerint nem lehet tanulni. Ha lehetne, akkor már rég megtanultam volna és Grasst, a csapat grafikusát kirúgtam volna :-) Kétségtelen, hogy fejlesztető, de kell hozzá valami megfoghatatlan érzék, ami nekem nincs meg.

Másokban sincs meg, de őket ez nem tántorítja el, hogy meghatározzák a formáját teszem azt egy weboldalnak.

Történt ugyanis, hogy elvállaltam egy weboldal elkészítését, ráadásul teljesen ingyen, mert a szegény szervezetnek nincs pénze, nekem meg számlám, amit adhatnék. Azt viszont kikötöttem, hogy a külalakot, színeket, arányokat nem fogom megmondani, ahhoz szerezzenek egy grafikust. Én ugyanis olyan vagyok, mint a Commodore 64, csak 16 színt ismerek.

Viszont különböző furmányos okok miatt nem sikerült grafikust találni. Ekkor megkérdeztem Grasst, van-e kedve beszállni a jótékonykodási akcióba. Volt neki. Már ismerem annyira, hogy tudjam, mit szeret és mit nem, ezért elmondtam a megbízóimnak, hogy ő csak azzal a feltétellel hajlandó dolgozni, ha nem szólnak bele, hogy mit hogyan csináljon: Ő a szakember. Ebbe a feltételbe bele is mentek.

Grass elkészítette a látványtervet, ami meg kell mondjam, nagyon jól sikerült. A megbízók szerint nem. Válaszul küldtek egy színmintát (5 színből), amiből Grass válogathatott kedvére.

Más grafikusok is hasonló esetekről mesélnek. Például egy játékiparban dolgozó ismerősöm mondta, hogy a főnöke neki is rendre beleszól a látványtervekbe. Olyan szinten, hogy rámutat egy elemre az összképen és kijelenti, hogy az legyen kék. Ettől felborul a színegyensúly, nem fognak harmonizálni az árnyalatok, a kép szétesik.

Tehát egy grafikusnak nem az a szerepe, hogy megtervezzen valamit, hanem gondolatolvasóként kitalálja, hogy mit akar az ügyfél. A gondolatolvasás pedig nagyon rosszul működik. Néha még akkor is, ha hangosan kimondjuk őket.

Ha pedig ennyire markáns véleménye van a megrendelőnek, miért nem csinálja meg ő? Szerintem azért nem, mert nincs halvány elképzelése sem arról, mit is akar. Még akkor sincs, ha azt mondja, hogy van. Például a cég, ahol dolgozom, kiment egy konferenciára. Vittek "white paper"-t, "pop-up wall"-t és egyéb marketing szempontból lényeges dolgokat, amiknek nincs normális magyar nevük, vagy ha van is, inkább nem használják. Ezeknek a tartalmaknak a kreatív voltát egyetlen szóval fogalmazhatom meg: Stockphoto. Innen összevásárolva lett egy csomó nagyszerű fotójuk, csak éppen az ötlet hiányzott, hogy mihez is kellene felhasználni. Végül mégsem használták a képeket, mert kiderült, hogy a többi kiállító is a kreativitás eme kútjából merít.

Lelki szemeim előtt látom is, amint egy hatalmas csarnokban megelevenedik a Stockphoto egy kulcsszavának első találati oldala.

Bizony, nehéz eldönteni, hogy mi néz ki jól. Azt kitalálni, hogy másnak mi néz ki jól, pedig még nehezebb. Egy weboldalnál pedig ez a cél. A többi embernek legyen szép. A nézőknek, hogy szívesen visszajárjanak.

Egy korábbi munkahelyemen ezért cseréltük le a weboldalt. Az első verzió olyan volt, ami nekünk, a dolgozóknak tetszett. Fekete háttér, nagy kontrasztú színekkel. Csináltunk egy rövid felmérést, mire kiderült, hogy az oldal látogatóinak bizony nem tetszett. Ezért lecseréltük szép világosra.

Szólj hozzá!

Címkék: filozofálás

Framebuffer és Textúra

2011.03.29. 18:27 Travis.CG

Korábban bemutattam, hogyan lehet egy OpenGL keretrendszert létrehozni X11 alatt. Most röviden bemutatom, hogyan használom a Framebuffert, hogy ne csak a képernyőre rajzoljak. Miért lehet szükség arra, hogy ne a képernyőre rajzoljunk, hanem a memóriába? Először is, azért, mert további műveleteket végezhetünk a memóriában tárolt képen, mielőtt a nézők szeme elé tárulna a látvány.

Az egyik ilyen művelet az élsimítás, de a deferred rendering nevű eljárás is ezen alapul. Hosszú távon nekem ez utóbbi a célom. Amint elég tapasztalatom lesz a témával kapcsolatban, arról is írok egy bejegyzést. A környezet továbbra is OpenGL 4.1

Inicializálás

Az első lépés, hogy hozzuk létre saját framebufferünket a glGenFramebuffers segítségével. Nagyon hasonló, mint amit textúránál is csinálunk. Rögtön utána kössük is magunkhoz a glBindFramebuffer segítségével. Az első paraméter általában GL_FRAMEBUFFER lesz. Akár mit is akarunk kezdeni a framebufferünkkel, egészen biztos, hogy szükségünk lesz egy mélységi pufferre. Ha ezt nem hozzuk létre, a takarásban lévő és látható pixelek összekeverednek és nagyon ronda eredményt adnak. Tehát kell egy mélységi puffer.

A glGenRenderbuffers hasonlóan működik, mint a glGenFramebuffers. Ezt is kössük (glBindRenderbuffer), majd meghatározzuk a méretét. a glRenderbufferStorage-val. Az első paraméter a két utolsó függvénynél GL_RENDERBUFFER lesz. Más nem is lehet. Mivel mélységi puffert akarunk, ezért a glRenderbufferStorage második paramétere GL_DEPTH_COMPONENT lesz.

glGenRenderbuffers(1, &rb);
glBindRenderbuffer(GL_RENDERBUFFER, rb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, szelesseg, magassag);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);

Az utolsó lépésben a frissen keletkezett pufferünket hozzárendeljük a framebufferhez. A gyakorlatban csak a második és utolsó paramétert szokták változtatni, ha esetleg más komponenshez is puffert rendelnek. Más komponenshez? Igen! Lehetőségünk van több szín, mélység és stencil pufferbe tárolni információt. A színpufferek száma implementáció függő, a GL_MAX_COLOR_ATTACHMENTS ad róla információt.

Bár minden fórumon és blogban azt olvastam, hogy ahol csak lehet, használjunk renderbuffereket, véleményem szerint a mélységi komponens kivételével (sőt, deferred shading esetén ott sem) ne használjunk renderbuffert. Mégpedig azért ne, mert az ott tárolt információt csak arra használhatjuk, hogy kitegyük a képernyőre. Márpedig egy demóban még sokat kell játszani a képpel, hogy azt ki merjük rakni a képernyőre. De akkor hogy lehet utólagos effekteket rárakni a tárolt pufferre? A renderbuffer mellett van egy másik lehetőségünk. Textúrát is köthetünk a framebufferhez! A textúra pedig könnyedén bemenete lehet egy shadernek, amivel már megbolondíthatjuk a képet. Ezért gondolom úgy, hogy nem érdemes renderbufferekkel foglalkozni.

Textúrák hozzákötése kísértetiesen hasonlít a renderbufferek kötéséhez:

glGenTextures(1, &t);
glBindTexture(GL_TEXTURE_2D, t);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, szelesseg, magassag, 0, GL_RGBA, GL_UNSGINED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t, 0);

Természetesen a textúrák esetén még nagyon sok paramétert be lehet állítani, de azokat kihagytam, mert tele velük az internet. Amire itt felhívnám a figyelmet, az a GL_COLOR_ATTACHMENT0. Ez azt mondja meg, hogy a számtalan színpuffer körül mi az elsőt kötjük össze a megadott textúrával. Ennyi.

Használat

Amennyiben használni szeretnénk pufferünket, tegyük a következőt:

glUseProgram(puffershader);
glBindFramebuffer(fb);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
...rajzoló rutinok...

Természetesen a képernyőn nagy feketeség fog megjelenni. Régen, mikor még nem voltak pufferjeink, akkor is tudtunk textúrába renderelni, majd négyszöget rajzoltunk, ami lefedte a képernyőt és ráhúztuk a textúrát. Ennek vége. (Igazából nem. Sok esetben még mindig egyszerűbb így rajzolni) A pufferünket egy lépésben (pontosabban három, ha az utasítások számát nézzük) a képernyőre rakhatjuk a glBlitFramebuffer segítségével.

glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
glBindFramebuffer(GL_WRITE_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, szelesseg, magassag, 0, 0, szelesseg, magassag, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_LINEAR);

Mint a paraméterekből kikövetkeztethető, nem muszáj a teljes képernyőt kitölteni. Ez érdekes effekt ötleteket adhat az embernek. A 0 jelű framebuffert tartja fenn a rendszer a képernyőn megjelenő képnek. Lehet több framebufferünk is, a fenti megoldással tetszőleges két framebuffer között tudunk másolni.

Szólj hozzá!

Címkék: programozás demoscene

A szerencse gyermeke

2011.03.22. 22:16 Travis.CG

Ma felhívott egy ismeretlen szám, hogy nyertem valami mobil cég és egy bank közös nyereményjátékán. Közjegyző előtt kisorsoltak és nyertem 250 ezer forintot.

- Nagyszerű - mondtam.

- Nem hallom a hangjában az örömöt.

Nem csoda, hogy nem hallotta, hiszen teljesen nyugodt voltam. Miért is kellett volna meglepődnöm ezen? Én a szerencse gyermeke vagyok. Csupa váratlan áldás szokott rám hullani. Múlt hónapban egy, az olvasók emésztésével foglalkozó lap (angol néven, hogy ne vegye el az étvágyat) nyereményjátékán nyertem, vagy legalábbis elég közel voltam a nyereményhez. Csak vissza kellett küldeni egy válaszborítékot, amiben nyerési dokumentumokat, gyorsaság bónusz kártyát és valami kaparós jegyet kellett beletenni. Ez utóbbi egy autó kódját tartalmazta, amiből teljesen véletlenül pont a sportkocsit nyertem.

A szerencse mindenhova elkísér. Egy átlagos weboldalt sem tudok úgy megtekinteni, hogy ne én legyek a 10ezredik látogató. A levelezésemben naponta átlagosan 3 nyereményről tájékoztató levél van. Annyit nyertem már, hogy a spam szűrő is nehezen bírkózik meg ezzel az áradattal.

Miért kellene meglepődnöm? Meg is mondtam neki, hogy én nagyon sokat nyertem már az interneten, ezért nem lepődök meg.

- Úgy érzem, ön szkeptikus.

Bámulatos volt a figura. Megint rátapintott a lényegre. Nem is tehettem mást, mint egyetértettem vele. Ezután letegezett, felszólított, hogy végezzek el egy jóga gyakorlatot, amiben a szám és az intim szférám is érintett volt, majd lecsapta, Úgy látszik a pénzkeresés is olyan tevékenység, amit nem csinálnak meg helyettünk. Lehet, hogy mégsem vagyok szerencsés?

Szólj hozzá!

Címkék: biztonság életmód

Bioscope 1.3

2011.03.19. 15:05 Travis.CG

A "nyílt forráskódú" bioscope verzió után megnéztem a kereskedelmi verziót is. Ezt elsősorban elosztott rendszereken lehet használni, webes felületen. Van lehetőség parancssoros futtatásra is, ami némiképp idegen lehet attól, aki rendszeresen futtat GNU/Linux alól parancssoros programokat.

A program nagy előnye, hogy szemben más alkalmazásokkal, itt az egyes programokat "összefűzhetjük" és kötegelt elemzéseket csinálhatunk anélkül, hogy összetett paranscsori szkripteket írnánk és a különböző formátumok között konvertálnánk. A webes környezet használatára nem térek ki, mert az amolyan klikkelj és futtass filozófiát követ.

Parancssorban teljesen más a helyzet. A rendszer rendelkezésünre bocsát egy demos könyvtárat, amiben az összes műveleti lépés készen várja, hogy elindítsuk. Az egyes paramétereket .ini fájlokon keresztül lehet beállítani, mint Windows 3.1 alatt. Igyekeztek mindent úgy elkészíteni, hogy a lehető legkevesebb erőforrás segítségével lehessen használni a programot. Az ini fájlok testreszabása után csak egy ./run.sh parancsot kell kiadni és az elemzés elindul.

Sajnos pont ezzel sikerült megfosztani a felhasználót a folyamatok összefűzésének lehetőségétől. Nagyon elszánt felhasználók talán átnézhetnék a run.sh parancsfájlt, aminek felépítéséről nincs semmi sem a dokumentációban. Sajnos nem volt annyi időm, hogy ezt megtegyem, ezért én úgy fűztem össze a programokat, hogy egy .ini állomány másoló programot készítettem. Nem a legjobb választás, de célnak megfelelt.

A Bioscope programjait továbbra is gyengének találom. Ezt valószínűleg a készítők is érezhetik, mivel például a readek referenciára illesztésére inkább a BFast-ot ajánlják, mint saját fejlesztésű programjukat.

Az egyetlen előnye a Bioscope-nak, hogy elfedi a felhasználó elöl az elosztott gépek indításával és leállításával, az adatok mozgatásával járó bonyodalmakat.  A végpontokról gyakorlatilag semmilyen információt nem kellett tudnom, mikor futtattam a programokat. Ez mindenképp pozitívum. Sajnos a telepítés nehézségeiről nincsenek információim, tehát nem tudom, hogy mennyivel nehezebb, mint ha valaki Condort, Oracle Grid Engine-t vagy Hadoopot használna.

Szólj hozzá!

Címkék: bioinformatika

A mérkőzés

2011.03.09. 10:20 Travis.CG

Jó estét, jó szurkolást. Mai félnehéz súlyú mérkőzésünkön két igazi nagyágyú méri össze tudását. A tét nem kevesebb, mint a CLCBio Genomics Workbench elindítása. A mérkőzés helyszínét az Amazon biztosítja. Az idő szokás szerint felhős.

A kék sarokban a címvédő Windows Server 2008. Régi játékos már, számtalan apró fogást ismer, amivel nem egy kiváló játékost küldött padlóra. A piros sarokban a kihívó, Travis. Nem sokat tudunk erről az új játékosról. Korábbi meccsein szívós és kitartó volt. Majd meglátjuk, hogy a sok Linuxos meccs után mit kezd egy számára ismeretlen ellenféllel. Google edző a ringen kívül figyeli a mérkőzést.

Megszólal a gong, a játékosok a ring közepén vannak! Óvatosan kerülgetik egymást. Windows arcáról semmit nem lehet leolvasni. Travis RDesktoppal kapcsolódik, Windows beengedi, de semmi komoly nem történik. Travis kezdeményez, megnyitja a böngészőt. Internet Explorer feljön. Windows arcán halvány mosoly fut át, mint aki számított erre a lépésre. Travis megpróbálja letölteni a Workbench-et! Merész lépés volt egy kezdőtől. De nem fut a JavaScript! A letöltés meghiúsult! Ügyesen védett Windows. Még sok meglepetést fog tartogatni nekünk ez a mérkőzés, biztos vagyok benne! Travis rezignáltan veszi tudomásul. Az oldal forráskódjából kiszedi a kívánt címet, és már meg is kezdi a program letöltését. Pontosabban kezdené, mert Windows megtiltja a futtatható állományok letöltését!

Travis fogást keres ellenfelén. Vezérlőpult, Internet beállítások körül forgolódik az egérrel. Igen, jó helyen keresgél. Engedélyezi a letöltést. Windows néhány popup ablakkal vág vissza, de mindez csak elterelés. A letöltés ezután sem megy. Még zöldfülü ez a fiú!. De nem, az UAC háza táján turkál. Igen, igen. Micsoda jobb horog! Az UAC kikapcsolva. Windows láthatóan megtántorodik. A bíró közbelép és újraindítást rendel el. Windows úgy támolyog a sarokba. Travis magabiztosan mosolyog.

Második menet.

A második menetben Travis magabiztosan kezd. Ismét megkezdi a letöltést. Nem veszi észre, hogy a kikapcsolt UAC ellenére a JavaScript továbbra sem aktív a böngészőjében. Ez nagy hiba, csak a győzelmét látja, az intő jeleket nem. Letöltés, és UAC ide-vagy oda, az továbbra sem megy. Travis kezdi elveszíteni a türelmét, ami szintén arra utal, hogy tapasztalatlan játékos. Ismét az Internet beállítások körül ólálkodik. Mindent engedélyez, amin piros jel van és biztonsági problémára figyelmeztet. Nem gondolkodik, csak klikkel. Második hiba a mérkőzés során! Miután bezárja a Vezérlőpultot, váratlanul újra megnyitja. Már kezdi kapisgálni, úgy látom. Windows az első menetben hátrányba került, de most mosolyog. Igen, van is rá oka. A változtatások ellenére a Vezérlőpulton, mintha nem is állítottak volna át semmit. Travis sem érti. Leengedi a karját, mire Windows hatalmasat üt állcsúcsára. Travis elveszti egyensúlyát. A bíró közbelép. Hármat számol, de Travis feláll, készen, hogy folytassa a mérkőzést. A gong ismételten egy menet végét jelzi. Travis a sarokba tántorog. Google edző folyamatosan súg neki, bárcsak hallanánk, hogy mit!

Harmadik menet

Travis sokkal nyugodtabb. Ha most látnánk először, még azt is hihetnénk, hogy profi játékos. Ismét az internet beállítások felől támad. Most alapértelmezetté teszi a változtatásokat és nem csak az alapértelmezett profilban, hanem mindenhol. Nem elegáns, nagyon nem elegáns. Olyan, mintha már személyes ügy lenne. Már nem a győzelem a cél, hanem az ellenfél szétzilálása. Windows erőtlenül figyelmeztető üzeneteket küld, de ezeknek már nincs semmi hatása. Windows hátrál, mintha nem tudna mit kezdeni ennyi támadással. Travis letölti a CLCBio bővítményét, és sikeresen beilleszti a Workbenchbe. Újraindítja azt. És most jön Windows ellencsapása! A bővítményt a neten keresztül kellene hitelesíteni, de mivel Travis távoli asztalról jelentkezett be, ezért Windows ezt egy hibaüzenettel meggátolja. Bumm! Travis a padlón.

Most értette meg, hogy nincs esélye a győzelemre. Amazon ringben csak távolról lehet bejelentkezni. A hitelesítési problémáról pedig a CLC is tud, ezért nem is támogatják a Windows Server semmilyen verzióját! Minden lépés csak trükk volt Windows részéről, hiszen biztos volt, hogy ő győz. Mégis játszotta a sérült, beteg, gyenge ellenfelet. Ezt nevezem én versenyrutinnak! Most a boldogan sétál a ringben és ünnepelteti magát a tömeggel. De mi ez? Travis felkel. A bíró közbe akar lépni, de ellökik! Travis terminálja a virtuális gépet! Windows eltűnik, mint egy szappanbuborék. A közönség elhülve figyeli a sportszerűtlen magatartást. A szövetség biztosan eltiltja ezt a fiút a további Windows mérkőzéstől. Travis, mintha nem is bánná...

Szólj hozzá!

Címkék: biztonság cloud computing

Képregény

2011.03.02. 14:36 Travis.CG

Véletlenül akardtam rá a PHDComics-ra, de azonnal rákaptam. Sejtettem már Asimov regényéből is, hogy a PhD hallgatók élete a föld különböző pontjain annyira nem is különböznek egymástól. Így egyben olvasni és nevetni rajta egyszerűen felemelő érzés.

Rögtön eszembe jutottak a rég elfeledett problémák, melyek akkor a világot jelentették és szembesültem azokkal a problémák, melyeket most élek át. Ajánlom mindenkinek.

Szólj hozzá!

Címkék: életmód

OpenGL apróságok

2011.02.26. 21:45 Travis.CG

A legújabb demónknál elhatároztam, hogy OpenGL 4.1-t fogok használni. Az interneten fellelhető dokumentációk jelentős része még a régebbi verziószámú rendszerre érhető el, ezért előfordul, hogy értetlenül nézek a képernyőre és nem értem, miért nem jelenik meg semmi.

Most, hogy a korábbi módszerek helyett minden shaderből megy, egyrészt jó, mert megadja azt a szabadságot, amit elvárhatok a rendszertől, másrészt elvesz néhány kényelmi szolgáltatást. Értem ez alatt a glRotate (forgatás) és glTranslate (eltolás) függvényeket. Mivel nem erős oldalam a matematika, ezek elvesztése fájt.

A három dimenziós alakzatokat puffereken keresztül lehet megadni, ahol később mi magunk mondjuk meg, hogy az adott puffer milyen szerepet töltsön be. Tehát vázlatosan valami ilyesmi kódot lát az ember:

glGenBuffer...
glBindBuffer...
glBufferData...

Ezzel nem is volt különösebb problémám. Megadunk egy puffert az alakzatunk csúcspontjának, a normálvektor irányának és a textúrák koordinátájának. Ezt szépen össze lehet fogni olyan függvényekbe, mint loadMesh() és utána minden demóban lehet használni. Ahol nekem most problémám akadt, mindezt hogyan mondjuk meg a shaderünknek?

A dokumentáció és a példaalkalmazások alapján előttem két út rajzolódott ki:

  1. A shader linkelése előtt explicit megadjuk, hogy hányadik puffer melyik shader változónak felel meg, a glBindAttribLocation() függvény segítségével.
  2. Linkelés után lekérdezzük a shader változó azonosítóját (glGetAttribLocation), majd hozzákapcsoljuk a megfelelő puffert (glBindBuffer, glVertexAttribPointer, glEnableVertexAttribArray).

Az első megoldás kényelmes, de én egy általános shader betöltőt akartam írni, ami nem foglalkozik azzal, hogy milyen változók vannak a shaderben és azoknak mi a szerepe. Csak betölti a shadert valami loadShader() függvénnyel, ami egyedül a fájl nevét kapja meg. Megjegyzem, még ebben az esetben is lehet használni az első módszert, de a glBindAttribLocation() meghívása után ki kell adni egy glLinkProgram() utasítást is. Tehát valami ilyesmi kódunk lesz:

shaderprg = loadShader("winnershader.vert", "winnershader.frag"); // van benne glLinkProgram
glBindAttribLocation(shaerprg, 0, "coolvariable");
glLinkProgram(shaderprg);

Ez viszont nem tetszik. Miért hívjak meg többször egy függvényt? A második módszer jobban tetszett. Meg is írtam a rutint. És nem működött. Ez azért is érdekes, mert Norbert Nopper kollégának működött. Már kezdtem azt hinni, hogy kénytelen leszek a béna első módszert használni, amikor Nopper programját tüzetesen megvizsgálva észrevettem a megoldást. Nevezetesen ki kell adni a glBindVertexArray-t is. Utólag belegondolva logikus is, hiszen több VertexArray-el is dolgozhatunk.

A módosítás hatására a program az elvárt végeredményt mutatta.

Ugyancsak fontos, hogy megfelelő időben aktiváljuk shader programunkat. A glUseProgram mindig előzze meg a glGetUniformLocation és glUniform parancsokat, különben GL_IVALID_OPERATION hibaüzenetet kapunk, amit nehéz felderíteni.

Szólj hozzá!

Címkék: programozás demoscene opengl

Bölcsességek

2011.02.23. 11:47 Travis.CG

Néhány bölcsesség:

  • Ne bízz abban a bioinformatikusban, aki nem tudja mennyi memória van a gépében.
  • A bioinformatikus legnagyobb ellensége a Word fájlban átadott szekvencia.
  • Kerüld azt a programozót, aki kiadványszerkesztőben ír programot és kézzel színezi a kulcsszavakat.
  • Hamar cikkírás ritkán impaktos.
  • Vigyázz azzal a bioinformatikussal, aki Windowst használ! Vagy kókler (nem tud Linuxot használni), vagy nagyon profi (úgy használja a Windowst, mint más a Linuxot)
  • Soha ne sértegess Machintosos bioinformatikust.
  • A jó bioinformatikus nem tudja, mi az Excel fájl.
  • Ha a jó bioinformatikus tudja is, mi az Excel fájl, soha nem fog neked készíteni egyet sem.
  • A PowerPoint nem poszter készítő program.
  • A Word nem képszerkesztő.
  • A Word nem honlap készítő.
  • Az Excel nem adatbázis.
  • A rossz bioinformatikus minden feladatra legalább két programot használ.
  • A még rosszabb bioinformatikus az összes feladatra egy programot használ.
  • Aki még ennél is rosszabb, az mindenre Microsoft Office programokat használ.
  • Ne taníts olyan bioinformatikust, aki ezt kérdezi: "Ez a kódolás, ez muszály?"
  • Ha sok statisztikai tesztet futtatsz, mindig használj többszörös teszt korrekciót.
  • Ha azt kérik, hogy ne használj többszörös teszt korrekciót (mert nincs elég szignifikáns eredmény), akkor is használd.
  • A főnök sürgetése nem lehet indok az új módszerek meg nem ismerésére.
  • Ha tudod, hogy rossz a bemeneti adat, akkor is bizonyítsd. Több a meló vele, de könnyebben elfogadják.
  • Ne félj hibázni. A hibától való félelem csak paralizál, míg a hibából tanulhatsz.

A listát frissíteni fogom.

Szólj hozzá!

Címkék: filozofálás bioinformatika

CUDA (5. rész)

2011.02.21. 12:11 Travis.CG

Elérkeztünk az utolsó részhez. Több gyakorlatot nem terveztem, de lesznek még CUDA-val kapcsolatos bejegyzések. Elég a bevezetőből, vágjunk bele.

A kódunk még messze nem tökéletes. Először csak rövid optimalizációkat végzünk. A szögfüggvényeknek például van a CUDA magokon futó változata. Ezt a math_functions.h fejléc állományban elfedik előlünk, hogy könnyű legyen a kód migrálása, de jobb, ha ezt magunk csináljuk, nem bízzuk egy fordítóra, amit nem mi írtunk :-) Ezért nézzük át a device_functions.h fejlécállományt. Találunk ott egy érdekes függvényt: __sincosf(). Tehát egy lépésben kiszámolhatjuk a színuszát és a koszinuszát ugyan annak a szögnek.

Általánosságban elmondható, hogy a két aláhúzással jelzett függvények eszköz kódok. Amikor csak tehetjük, használjuk őket. Szorzás helyett is nyugodtan használhatjuk az __fmul_rn függvényt. Ezek alapján az új distance függvényünk a következőképp fog kinézni:

__device__ float distance(float2 p1, float2 p2){
   float dx = p1.x - p2.x;
   float dy = p1.y - p2.y;
   float x2 = __fmul_rn(dx,dx);
   float y2 = __fmul_rn(dy,dy);
   float su = __fadd_rn(x2,y2);
   return( __fsqrt_rn(su) );
}

 

Megmondom őszintén, nem tudom, mit jelent a függvények végén az _rn. Van másik három rz, rd, ru is, nem tudom, hogy mi a különbség közöttük. Amint lesz róla információm, kijavítom ezt a bejegyzést.

__device__ void collision(float2 *p1, float2 *p2, float angle){
   float p1x2 = __fmul_rn( p1[0].x, p1[0].x );
   float p2x2 = __fmul_rn( p2[0].x, p2[0].x);
   float p1y2 = __fmul_rn( p1[0].y, p1[0].y);
   float p2y2 = __fmul_rn( p2[0].y, p2[0].y);

   float m1 = __fsqrt_rn( p1x2 + p1y2);
   float m2 = __fsqrt_rn( p2x2 + p2y2);
   float d1 = atan2f( p1[0].y, p1[0].x);
   float d2 = atan2f( p2[0].y, p2[0].x);

   float sa, ca, sb, cb; /* sin and cos of d1 - angle */

   __sincosf(d1 - angle, &sa, &ca);
   __sincosf(d2 - angle, &sb, &cb);

   float p1newx = __fmul_rn(m1,ca);
   float p1newy = __fmul_rn(m1,sa);
   float p2newx = __fmul_rn(m2,cb);
   float p2newy = __fmul_rn(m2,sb);

   __sincosf(angle + 3.14f / 2.0f, &sa, &ca);
   __sincosf(angle, &sb, &cb);

   p1[0].x = __fmul_rn(cb,p2newx) + __fmul_rn(ca, p1newy);
   p1[0].y = __fmul_rn(sb,p2newx) + __fmul_rn(sa, p1newy);
   p2[0].x = __fmul_rn(cb,p1newx) + __fmul_rn(ca, p2newy);
   p2[0].y = __fmul_rn(sb,p1newx) + __fmul_rn(sa, p2newy);
}

 

A collision függvényünket is megváltoztathatjuk. Itt ráadásul áttekinthetőbbé tettük a paramétereket. A mutatók tömbként való használata nem véletlen, ha másképp használjuk őket, akkor "error: expression must have class type" hibaüzenetet kapunk fordítási időben.

Utolsóként a calcParticlePos függvényünk következik. A globális memória elérése nem túl ideális, egyrészt a lassabb elérés miatt, másrészt a konfliktusok miatt. Előfordulhat ugyanis, hogy több szál próbál meg módosítani egy memória területet.

A memória elérés gyorsítására lehet használni a megosztott memóriát. Annak bemutatására most nem vállalkozom.

Szólj hozzá!

Címkék: programozás

Kutatók és programozás

2011.02.19. 19:08 Travis.CG

Egy érdekes cikkre bukkantam a Nature hasábjain (itt). Röviden a lényege, hogy a kutatók többsége képtelen normális kódot írni. Nem ellenőrzi, dokumentálják a programosorokat, ezért a vége jobb esetben nem működő program, rosszabb esetben hibás eredmény, amit neves újságok hasábjain publikálnak.

Szeretném hinni, hogy én nem tartozom közéjük, amire az ad okot, hogy dolgoztam programozóként is, nem csak kutatóként. Ha viszont az itt feltüntetett kódjaimban vagy a demóim forráskódjában valaki oltári nagy ostobaságot talál, akkor annak a cikkben leírtak az okai.

Komolyra fordítva. A munkám során én is találkoztam ilyen esetekkel. Az első egy hipergeometrikus eloszlást számolt GO azonosítókra. Azt vettük észre, hogy a program meglepően lassú. Megnéztem a forráskódot és meglepődve tapasztaltam, hogy minden egyes rendezés során az adatokat fájlba írta. Ez elég rossz hír volt, de a mégrosszabb az volt, hogy a program szerzője nem ismerte a hasítótáblákat, helyette tömböt használt. Minden egyes alkalommal végigjárta a teljes tömböt, ha egy elemet meg akart találni. Természetesen ezt is fájlba írta, majd visszaolvasta onnan. Mondanom sem kell, hogy a fenti két hiba kijavítása után 40-szeres sebességnövekedést értünk el.

A másik esetben a Java program tartalmazott C programrészletet, aminél súlyos memóriaszivárgás volt. Ez csak bizonyos hosszúságú szekvenciáknál okozott szegmentációs hibát. Az utolsó esetben olyan programmal találkoztam, ami gyakorlatilag érthetetlen volt a számomra. Bonyolult volt a matematikai modell is, amit alkalmazott (legalábbis nekem), de a program felépítése ezt tovább bonyolította. Az összetettséget jól példázza, hogy bárki, aki a kódhoz nyúlt és javított benne valamit, két másik hibát ejtett.

A cikkben említett jelenséget tehát én is megtapasztaltam. Kérdés, hogy mit lehet tenni ellene. Először is, ne tegyünk fel mindent egy lapra. Ha egy program kiadott egy eredményt, ne higgyük, hogy most miénk lesz a Nobel-díj. Használjunk több programot. Ahogy a laboratóriumi munkában sem fogadják el, ha csak Chip-kísérletet végznek és nem validáljuk azt QT-PCR-al, mi se dőljünk hátra, ha egyetlen program, egyetlen beálításokkal kiad egy eredményt.

Most Blastot fordítok, ezért van némi időm sztorizgatni. Például egy baktérium szekvenálása során kaptunk egy gént, ami elé egyedi volt, hogy a Blast ne adjon egyértelmű ereményt, ezért halvány sejtelmünk sem volt róla, hogy mi lehet a szerepe. Több prediktáló programot is kipróbáltunk, míg végül egyszer csak azt kaptuk, hogy transzmembrán proteint kódol. Ez sem volt egyértelmű, mert amint megváltoztattuk kicsit a program paramétereit, rögtön eltűnt az eredmény. Természetesen hozzá kell tennem, hogy ezt az eredményt kísérletesen ellenőriztük és olyan szerencsénk volt, hogy igazolni tudtuk.

Végezetül még egy tanács. Ha mi magunk írunk programokat, ne féljünk tanulni. Ne higgyük, hogy csak azért, mert elméleti algoritmusokat vagyunk képesek működő programkóddá varázsolni, máris mi vagyunk a programozás nagymesterei. Ha pedig hibás programra bukkanunk, javítsuk ki, vagy írjunk újat, mert senki nem csinálja meg helyettünk.

Szólj hozzá! · 1 trackback

Címkék: programozás filozofálás bioinformatika

Efika

2011.02.18. 13:00 Travis.CG

Még 2007 tavaszán, a SceneCon nevű demoshown láttam meg az Efikát és mondhatom szerelem volt az első látásra. Egy csendes, alacsony fogyasztású, mérsékelt (mások szerint gyenge) teljesítményű számítógép, ami a legegyszerűbb igényeket kielégíti.

Több, mint két évet kellett várnom rá, hogy az enyém legyen. Ez alatt az idő alatt az emberek többsége elpártolt a kedves kis géptől, a gyártását beszüntették. Használtan jutottam hozzá (egy váláson már túl volt), haza is vittem. Mint a kapcsolatok többségénél, itt is igaz volt, hogy lakva ismeri meg a másikat az ember. A filigrán kis házból hiányoztak a csavarok, amerikai típusú hálózati csatlakozót kaptam hozzá és két olyan videokártyát, amelyik közül egyikkel sem ment.

A legegyszerűbben a hálózati csatlakozó problémáját oldottam meg. A gép energiaellátásáról egy laptop tápegység gondoskodik (mondtam, hogy alacsony fogyasztású), ezért használtan vettem egy három ágú tápkábelt, amivel máris megetethettem árammal.

A videokártyákkal is voltak problémák. Mint említettem, kettőt kaptam. Egy Nvidia GeForce MX440-t és egy Ati Radeon 9200-t. Az Nvidiás belefért a kis házba, de nem volt hűtése és képtelen volt elviselni azt a felbontást, amit a Linuxos telepítő beállított neki. Az Ati kártya képes lett volna rá, de az nem fért bele a házba, sőt igazából az alaplap néhány kivezetése is akadályozta. Kellett szerezni egy vékonyabb kártyát. Újabb használt cikk keresés. Végül szert tettem egy Ati 9250-re, ami már illett a kisasszonyhoz. Akitől vettem, nem tudott feles takaró lemezt adni hozzá, ezért kedvenc többfunkciós fogómmal addig faragtam a lemezt, amíg a nem illeszkedett a házba.

A gép két USB-t tartalmaz. Az egyik értelemszerűen a telepítés során a pendrive-t fogadja, a billentyűzetnek és az egérnek már csak egy marad. Szereztem egy USB elosztót is, de az alacsony áramfelvételű gép USB-je nem ad elegendő feszültséget, hogy egy USB elosztót üzemeltessen (aminek nincs saját áramforrása). Ekkor felvettem macsó modoromat és kijelentettem, hogy nem kap új USB elosztót, enélkül fogok boldogulni.

Első körben Linuxot akartam rá telepíteni. A Genesi elérhetővé tett egy Debian-t, amit állítólag könnyedén lehet telepíteni a gépre, Sajnos a hálózatról akarta leszedni a szükséges kernelt, ami ennyi idő távlatából már sehol nincs fent, a telepítés ezen lépését pedig nem tudtam megkerülni. Második jelentkező a Slackware volt. Ez a a partíciók formázásánál nem tudott tovább lépni.

Végül a MorphOS mellett döntöttem. Akár milyen hihetetlen, ezt sem tudtam telepíteni. A grafikus környezetet csak billentyűvel kezeltem, a TAB és a nyilak gyors váltogatásával, de a telepítés gomb valami miatt nem volt aktív, ezért ezzel a rendszerrel is befürödtem.

Azt csak mellékesen jegyzem meg, hogy elsőre soha nem ismerte fel a rendszerindítás után a pendrive-ot. Kétszer-háromszor kellett neki kiadni az uboot parancsokat, hogy felismerje, amit fel kell ismernie.

Végül bármennyire is nem szeretem, a Suse Linux mellett döntöttem, ami még könnyebb telepítést tesz lehetővé. A dokumentáció részletesen leírja, hogy mit kell csinálni a telepítés során. Követtem is a lépéseket, de az már nem derült ki, hogy újraindítás után mit kell csinálni. A merevlemezen volt a rendszer én pedig ültem a gép előtt és azon gondolkodtam, mi legyen a következő lépés.

Természetesen a boot hd:0 boot/efika sorokkal kezdtem. Ez minden áron kereste a nem létező /dev/sda3-t. Volt még két másik kernel is a boot partíción efika19 és efika19genesi. Ezek csak kernel pánikoltak. Végül egy fórumban fedeztem fel a lényeget: root=/dev/sda1. Persze, magamtól is kitalálhattam volna.

Elindítottam a rendszert, szépen be is jött az üdvözlő képernyő, majd rájöttem, hogy nem tudom sem a felhasználói nevet, sem annak jelszavát, amivel beléphetek. Ha lenne egy CD meghajtó, máris indítanám a Knoppixot, de így? A helyzet korántsem olyan reménytelen. A rendszerfájlok ugyanis megvannak egy tömörített állományban. Ezt kicsmagoltam, és máris böngésztem az /etc/passwd állományt. Meg is találtam, amit kerestem: felhasználónév: genesi, jelszó: genesi. A rendszergazdai jogosultságnak is ez a jelszava! Hurrá!

A kis hölgy ellenállását sikerült megtörni. Most már olyan, mint egy kezes bárány. Alacsony fogyasztásának hála rengeteg lehetőség van benne. Első lépésként kíváncsi vagyok, hogy megy-e a TV kimenet a videokártyán (10.3 Suse miatt nagy rá az esély, hogy nem). Utána megnézem, mennyire szereti a webkamerákat.

Szólj hozzá!

Címkék: rendszergazda

Visz'lát SRA

2011.02.16. 12:12 Travis.CG

Nem kétséges, hogy azoka, akik tesztelési és elemzési célra újgenerációs szekvenálási adatokat akartak szerezni, először a SRA-t keresték fel. A pénzügyi problémák viszont utólérték ezt a szervezetet is, mint az ebből a blogból kiderül. Valószínű, hogy bezárják ezt az adatbázist.

Miért is jelent ez problémát? Először is, az újgenerációs szekvenálás hatalmas mennyiségű adatot termel. A marketing szövegeken túl ugyanis elég rossz minőségű szekvenciákat produkálnak ezek a készülékek (legalábbis a régi típusú Sanger szekvenáláshoz képest), amit úgy próbálnak orvosolni, hogy többször szekvenálnak meg valamit. Ezt hívják lefedettségnek. Egy 10-szeres lefedettségű emberi szekvencia elérheti a 30GB-ot is, tömörítve. Érthető módon senki nem szeret a munkaállomásán ekkora mennyiségű adatot tárolni. Ehhez még hozzájönnek az elemzések során kelektkezett állományok, és máris ott tartunk, hogy feléltük egy átlagos merevlemez kapacitását.

A másik probléma, hogy ezeknek az adatoknak elérhetőnek kell lennie mások számára is. Egyrészt, hogy ellenőrizhessék azokat, másrészt további vizsgálatokat végezhessenek. Ezért nem elég, ha ezek az adatok ott porosodnak bármilyen adathordozón, az interneten elérhetőeknek kell lenniük.

Ez a hely pedig sokáig az SRA volt. Rajta kívül van még az ENA, de engem személy szerint nem nyűgözött le a megtalálható adatok mennyiségével, bár akadnak érdekes szolgáltatásaik is.

Mit lehet tenni, hogy kiváltsuk az SRA-t? Két fő csapásirány lehetséges. Az egyik a centralizált adatbázis, a másik a decentralizált.

Centralizált megoldások

  • Jön egy új szervezet, megszámlálhatatlan mennyiségű tárhellyel és egyszerűen átveszi az SRA helyét. Például a fent említett ENA
  • Mindent felhő alapú gépekre helyezünk, például az Amazonra.

Decentralizált megoldások

  • Biotorrent. Nem csak a legújabb Hollywoodi filmeket szerezhetnénk be a hírhedt fájlcserélő szolgáltatáson keresztül, hanem kedvenc szekvenciánkat is. Csak legyen, aki seedel. :-)
  • dCache-szerű rendszer fejlesztése. A fizikusok is sok adatot termelnek, és ők ezzel oldották meg az adatelérést.

 

Szólj hozzá!

Címkék: bioinformatika

CUDA (4. rész)

2011.02.04. 12:27 Travis.CG

Őszintén szólva, az előző programunkban több hiba is van, de talán segít megérteni, hogy a CUDA programozás új gondolkodást kíván. Nem elég, hogy a ciklusokat kernelekre cseréljük. Az ütközős program a struktúrális programozás szellemében készült. Nem csak programhiba, hanem metodikai hiba is van benne. Most nézzük, hogyan tudjuk kijavítani ezeket.

Az SDK tartalmaz egy hibakereső programot cuda-gdb néven. A --device-debug opció segítségével hibakereső információk kerülnek a fordított kódba, szintje 0-3-ig terjedhet. Ezután használhatjuk a cuda-gdb programot, ami szintén az SDK része. Sajnos grafikus alkalmazásoknál nem használható, így használatától el kell tekintenünk.

A második, diagnosztikai módszer, amit minden bizonnyal mindenki ismert, a megjegyzések elhintése vagy a képernyőre vagy egy fájlba. A CUDA SDK tartalmaz egy simplePrintf példaprogramot, amivel üzeneteket helyezhetünk a képernyőre. Személy szerint nem kedvelem, de ettől még lehet, hogy jó hasznát veszi az ember.

Kreatív módszerekkel viszont élhetünk. Még annak idején, amikor nem voltak ilyen nagyszerű shader debugger programok, a programozók a beépített OpenGL változóknak adtak feltűnő értékeket, ha valami gyanús történt. Pl. fragment shader esetén vörös színt, vertex shader esetén a csúcspontot eltolták jobbra. Hasonló módszert mi is alkalmazhatunk. Adjunk hozzá még egy cudaGraphicsResource-t, amiben mondjuk a színeket tároljuk. Ha valami furcsaság történik, változtassuk meg a részecske színét!

A teljes programsort most nem írom ide, majd ha mégis igény lesz rá, akkor belinkelem. A kernelt viszont bemásolom. A lényegi műveleteket úgyis az végzi. A c tömbben a színeket tárolom:

__global__ void calcParticlePos(float2 *p, float2 *v, float3 *c){
   int index = threadIdx.x;
   int i;

   /* Collision with the wall */
   if(p[index].x > 1.0f){
      p[index].x = 1.0f;
      v[index].x *= -1.0f;
   }

   if(p[index].x < -1.0f){
      p[index].x = -1.0f;
      v[index].x *= -1.0f;
   }

   if(p[index].y > 1.0f){
      p[index].y = 1.0f;
      v[index].y *= -1.0f;
   }

   if(p[index].y < -1.0f){
      p[index].y = -1.0f;
      v[index].y *= -1.0f;
   }

   /* Collision with each other */
   for(i = 0; i < PARTICLENUM; i++){
      if(i == index) continue;
      if(distance(p[i].x, p[i].y, p[index].x, p[index].y) < COLLIDEDIST){
         c[i].x = 1.0f;
         c[i].y += 0.01f;
         c[i].z += 0.01f;
         c[index].x = 1.0f;
         c[index].y += 0.01f;
         c[index].z += 0.01f;
         float angle = atan2f(p[i].y - p[index].y, p[i].x - p[index].x);
         collision(&v[i].x, &v[i].y, &v[index].x, &v[index].y, angle);
      }
   }

   p[index].x = p[index].x + v[index].x;
   p[index].y = p[index].y + v[index].y;

}

A program futása után már érezhető a probléma. A részecskék a kelleténél többször ütköznek. Ahelyett, hogy a részecskék 100 ütközés után érnék el a fehér színt, már az első ütközés alkalmával kifehérednek. Ennek az oka, hogy a CUDA magok igaz párhuzamosan futnak, de nem azonos idő alatt fejezik be a futást. A másik ok, amit szemfülesebb olvasók már bizonyára észrevettek, hogy a ciklusunk rossz! Minden egyes ütközés kétszer zajlik le. Tegyük fel, hogy a 231. részecske és a 42. részecske ütközését vizsgáljuk. Először lefut a 42. CUDA kernel, ahol a ciklus segítségével megtalálja az 231. részecskét, amivel ütközött. De a 231. CUDA kernel is lefut, és ő is megtalálja a 42. részecskét, amivel ütközik. A vizsgálat kétszer lesz igaz. Írjuk át a for ciklust a következőkre: for(i = index + 1; i < PARTICLENUM; i++). Ezzel az utána következő sorban található feltételt is kiváltottuk.

Ha lefuttatjuk a módosított kódot, akkor egy másik anomáliával találkozhatunk: egyes részecskék "összeragadnak" és egymás körül keringenek. Ez azért van, mert az ütközés után nem tudnak elég távol kerülni egymástól, ezért a következő ciklusban is ütköznek.

Mint említettem, az egyes szálak nem azonos sebességgel futnak. A fenti kódunkban ez okozhat problémákat. Kiküszöbölésükre találták ki a __syncthreads() függvényt. Használata csökkenti a teljesítményt, de segítségével elérhetjük, hogy a szálak nem versenyezzenek. Közös memóriaterület használata esetén nagyon hasznos tud lenni. Helyezzünk el egy ilyen függvényt nyugodtan a ciklus előtt.

A következő részben optimalizálni fogjuk a programunkat.

Szólj hozzá!

Címkék: programozás

Divat és genomika

2011.02.02. 15:49 Travis.CG

A kütyük számának emelkedésével egyre több olyan eszköz van nálunk, amit nem haszálunk ki teljesen. Értem én ez alatt, hogy több különböző eszköz is képes ellátni egy bizonyos feladatot, csak más hatékonysággal, ami már elég ahhoz, hogy mind a kettőt cipelni kelljen. Konkrétumokat említve, itt vannak az okos telefonok. Tárolnak neveket, címeket, fényképeznek, megjelenítik a népszerű irodai programcsomagok állományait, pdf-t. Lejátszák a zenét és a videókat. Azután ott vannak a e-book olvasók. Ezek is megjelenítenek pdf-t, némelyikük zenét is lejátszik. A laptopok is olvasnak minden állományt, lejátszanak zenét, filmet. Tárolhatnak címeket, telefonszámokat. Újdonság, hogy már tábla gépek is vannak. Filmnézés, zene hallgatás, dokumentumok olvasása, e-book megjelenítés, adattárolás, fényképezés mind szerepel a repertoárjukba.

Ezért gondolom, hogy a tábla gépek és az utánuk piacra lépő jövendőbeli kütyüknek inkább divat felhangja van, mint tényleges haszna. Így éreztem akkor is, mikor megjelent az iPad. Erre is rácuppant kicsi és nagy, bizonygatták internet szerte a hasznát és haszontalanságát egyaránt. Viszont néha előfordul, hogy valaki képes megtalálni ezen eszközök potenciális hasznát. Olyan hasznot, amit más kütyüvel nem vagyunk képesek elérni.

Például nem lenne nagyszerű, ha egy ilyen tábla gépen nézegethetné valaki az általa vizsgált genomot? Mentesülne a laptopon való szerencsétlenkedéstől, a mobiltelefon apró kijelzőjétől. Csak megérintené a genomot...

Pontosan ez motiválta a JBrowse programozóit is, akik elkészítették a programjuk iPad kompatibilis verzióját

Szólj hozzá!

Címkék: életmód bioinformatika

CUDA (3. rész)

2011.01.27. 14:30 Travis.CG

Az eddigi példaprogramok, valljuk be, nem voltak túl látványosak. Joggal kérdezhetnék tőlem, hogy miféle demoscene ember az, aki csak ilyen unalmas példaprogramokat tud bemutatni. Teljes mértékben igazat kell adnom. Ezennek törlesztem adósságom, és egy olyan programot készítünk, ami OpenGL-t is használ. Méghozzá egy csomó pontot fogunk dobálni a képernyőn. Ez nem nagy kaland még a CPU-nak sem, de megbolondítjuk azzal, hogy minden pont ütközhet egymással, nem csak a fallal. Ez már elég érdekesen hangzik? Ha igen, akkor vágjunk bele.

#define GL_GLEXT_PROTOTYPES
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <cuda_gl_interop.h>

#define WIDTH 1024
#define HEIGHT 768
#define PARTICLENUM 500
#define COLLIDEDIST 0.005f

GLuint pointBuff;
struct cudaGraphicsResource *pointBuff_CUDA;
float4 *particles;

/* Calculate distance of the points */
__device__ float distance(float x1, float y1, float x2, float y2){
   return( sqrtf( (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) );
}

__device__ void collision(float *p1x, float *p1y, float *p2x, float *p2y, float angle){
   float m1 = sqrtf(*p1x**p1x + *p1y**p1y);
   float m2 = sqrtf(*p2x**p2x + *p2y**p2y);
   float d1 = atan2f(*p1y, *p1x);
   float d2 = atan2f(*p2y, *p2x);
   float p1newx = m1 * cos(d1 - angle);
   float p1newy = m1 * sin(d1 - angle);
   float p2newx = m2 * cos(d2 - angle);
   float p2newy = m2 * sin(d2 - angle);

   *p1x = cos(angle) * p2newx + cos(angle + 3.14f / 2.0f) * p1newy;
   *p1y = sin(angle) * p2newx + sin(angle + 3.14f / 2.0f) * p1newy;
   *p2x = cos(angle) * p1newx + cos(angle + 3.14f / 2.0f) * p2newy;
   *p2y = sin(angle) * p1newx + sin(angle + 3.14f / 2.0f) * p2newy;
}

__global__ void calcParticlePos(float4 *p){
   int index = threadIdx.x;
   int i;

   /* Collision with the wall */
   if(p[index].x > 1.0f){
      p[index].x = 1.0f;
      p[index].z *= -1.0f;
   }

   if(p[index].x < -1.0f){
      p[index].x = -1.0f;
      p[index].z *= -1.0f;
   }

   if(p[index].y > 1.0f){
      p[index].y = 1.0f;
      p[index].w *= -1.0f;
   }

   if(p[index].y < -1.0f){
      p[index].y = -1.0f;
      p[index].w *= -1.0f;
   }

   /* Collision with each other */
   for(i = 0; i < PARTICLENUM; i++){
      if(i == index) continue; /*Prevent self collision */

      if(distance(p[i].x, p[i].y, p[index].x, p[index].y) < COLLIDEDIST){
         float angle = atan2f(p[i].y - p[index].y, p[i].x - p[index].x);
         collision(&p[i].z, &p[i].w, &p[index].z, &p[index].w, angle);
      }
   }

   p[index].x = p[index].x + p[index].z;
   p[index].y = p[index].y + p[index].w;

}

/* Handle the keyboard */
void keyboard( unsigned char key, int x, int y){
   switch(key){
      case 27:
         free(particles);
         exit(0);
         break;
   }
}

/* Show the show */
void display(){
   float4 *ppos;

   cudaGraphicsMapResources(1, &pointBuff_CUDA, 0);
   cudaGraphicsResourceGetMappedPointer( (void**)&ppos, NULL, pointBuff_CUDA);

   calcParticlePos<<< 1, PARTICLENUM>>>(ppos);
   cudaGraphicsUnmapResources(1, &pointBuff_CUDA, 0);

   glClear(GL_COLOR_BUFFER_BIT);
   glBindBuffer(GL_ARRAY_BUFFER, pointBuff);
   glVertexPointer(2, GL_FLOAT, 0, NULL);
   glDrawArrays(GL_POINTS, 0, PARTICLENUM);
   glutSwapBuffers();
   glutPostRedisplay();
}

/* Init a draw buffer and link it to the CUDA system */
void initOpenGL(){
   int i;

   particles = (float4*)malloc(sizeof(float4) * PARTICLENUM);
   for( i = 0; i < PARTICLENUM; i++){
      /* Postitions */
      particles[i].x = drand48() * 2.0f - 1.0f;
      particles[i].y = drand48() * 2.0f - 1.0f;
      /* Velocity */
      particles[i].z = (drand48() - 0.5f) / 1000.0f;
      particles[i].w = (drand48() - 0.5f) / 1000.0f;
   }

   glGenBuffers(1, &pointBuff);
   glBindBuffer(GL_ARRAY_BUFFER, pointBuff);
   glBufferData(GL_ARRAY_BUFFER, sizeof(float4) * PARTICLENUM,
                particles,
                GL_DYNAMIC_DRAW);
   cudaGraphicsGLRegisterBuffer(&pointBuff_CUDA, pointBuff,
                                cudaGraphicsMapFlagsWriteDiscard);


   glPointSize(5);
   glEnableClientState(GL_VERTEX_ARRAY);
   glColor3f(1.0, 0.0, 0.0);
}

int main(int argc, char **argv){
  
   /* Init cuda with opengl */
   cudaGLSetGLDevice(0);

   /* opegl window creation process */
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
   glutInitWindowSize(WIDTH, HEIGHT);
   glutCreateWindow("Collision test in CUDA");
   glutDisplayFunc(display);
   glutKeyboardFunc(keyboard);

   initOpenGL();

   glutMainLoop();

   return(0);
}

A program GLUT-ot használ és OpenGL 2.0-t. Először közöljük a rendszerrel, hogy OpenGL-t is kívánunk használni. Erre szolgál a cudaGLSetGLDevice. Ismételten figyelmeztetek mindenkit, hogy nem vizsgálom le a visszatérési értékeket! A példaprogramban egy vertex buffert (pointBuff) hozunk létre, ami tárolja az ütköző részecskék koordinátáit. A cudaGraphicsGLRegisterBuffer segítségével létrehozunk egy CUDA azonosítót, és összekapcsoljuk az OpenGL pufferét a CUDA-éval. Erre azért van szükség, mert mindkét erőforrás a grafikus kártyán van, nincs szükség a mozgatására. Az érdekes lépések a display függvényben vannak. Először létrehozunk egy mutatót a pufferünkre (cudaGraphicsResourceGetMappedPointer), majd ezt a mutatót használjuk a kernelben. Mikor végeztünk a munkával, a cudaGraphicsUnmapResource segítségével elérhetővé tesszük a puffert az OpenGL számára.

Az ütközés vizsgálat nem saját találmány, azt a Emanuelle Feronato weboldaláról lestem le. Annyi változtatást eszközöltem, hogy nálam egyenlő súlyúak a pontok, ezért az impulzusok számításánál az ütköző részecskék tömegének arányára nincs szükségem. Aki kedvet érez, végezze el a módosításokat.

Ha valaki kipróbálja a fenti kódot, nagyon meg fog lepődni. Néhány helyen rendben lezajlanak az ütközések, de sok helyen a golyók átsüvítenek egymáson! A programban hiba van. A következő részben a hibakeresést és felderítést fogom bemutatni.

Szólj hozzá!

Címkék: programozás

GLX és OpenGL 4.1

2011.01.23. 21:47 Travis.CG

Ahogy egyre fejlettebb és fejlettebb lesz kedvenc 3D API-m, úgy kell egyre újabb és újabb keretrendszert készíteni a demóimnak, hogy lépést tartsak a fejlődéssel.

GNU/Linux alatt az OpenGL és az ablak kezelő rendszer kapcsolatáról a GLX gondoskodik. Ez tekinthető a legalacsonyabb rétegnek. A népszerű, kereszt platformos könyvtárak, mint amilyen az SDL vagy a GLUT, mind erre építenek. Mivel én szeretem, ha minél kevesebb réteg van köztem és az általam programozott eszköz között, ezért nem volt kérdés számomra, hogy meg kell ismernem a GLX használatát.

Az első demó, ami erre épült, a csúfos kudarcomnak tekinthető Aeronautism volt. Itt csak OpenGL 2.0 támogatás volt. Az internetet végigöngészve csak 3.0 és 3.1 keretrendszerre találtam példákat. Vagy feleslegesen elbonyolított, vagy hibáktól hemzsegő verziót találtam, de végül sikerült készítenem egy elég türhető rendszert. Röviden bemutatom:

#define GL_GLEXT_PROTOTYPES
#define GLX_GLXEXT_PROTOTYPES
#include <GL/glx.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <stdio.h>

#define WIDTH 1024
#define HEIGHT 768

Display *display;
Window   window;
XEvent   event;
KeySym   ks;
GLXContext context;

int main(){
   int conf[] = {GLX_DOUBLEBUFFER, True,
                 GLX_DEPTH_SIZE, 12,
                 GLX_RED_SIZE,    4,
                 GLX_BLUE_SIZE,   4,
                 GLX_GREEN_SIZE,  4,
                 GLX_ALPHA_SIZE,  4,
                 None};

   int gl4attr[] = {GLX_CONTEXT_MAJOR_VERSION_ARB, 4, /* OpenGL major version number */
                    GLX_CONTEXT_MINOR_VERSION_ARB, 1, /* OpenGL minor version number */
                    GLX_CONTEXT_FLAGS_ARB,
                    GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
                    None};
   GLXFBConfig *fbc;
   int fbcount;
   XSetWindowAttributes swa;
   XVisualInfo *visual;

   int isrunning = 1;

   display = XOpenDisplay(NULL);
   fbc = glXChooseFBConfig(display, DefaultScreen(display), conf, &fbcount);
   visual = glXGetVisualFromFBConfig(display, fbc[0]);
   swa.background_pixel = 0;
   swa.border_pixel     = 0;
   swa.colormap         = XCreateColormap(display, RootWindow(display, visual->screen), visual->visual, AllocNone);
   swa.event_mask       = StructureNotifyMask | ExposureMask | KeyPressMask;
   window = XCreateWindow(display, RootWindow(display, visual->screen), 0, 0, WIDTH, HEIGHT, 0, visual->depth, InputOutput, visual->visual, CWBorderPixel | CWColormap | CWEventMask, &swa);
   context = glXCreateContextAttribsARB(display, fbc[0], NULL, True, gl4attr);
   XMapWindow(display, window);
   glXMakeCurrent(display, window, context);
   free(fbc);
   XFree(visual);

   /* Other OpenGL related initialization stuff here */

   while(isrunning){
      while(XPending(display) > 0){
         XNextEvent(display, &event);
         if(event.type == Expose) break;
         if(event.type == KeyPress){
            ks = XLookupKeysym((XKeyEvent*)&event, 0);
            if(ks == XK_Escape) isrunning = 0;
         }
      }

      /* OpenGL drawing stuff here */

      glXSwapBuffers(display, window);
   }

   /* Free resources */
   glXMakeCurrent(display, 0, 0);
   glXDestroyContext(display, context);
   XDestroyWindow(display, window);
   XCloseDisplay(display);
   return(0);
}

A legújabb OpenGL támogatás kiegészítésként érhető el a GLX rendszerben, ezért a GL_GLEXT_PROTOTYPES és GLX_GLXEXT_PROTOTYPES segítségével definiáljuk, hogy mi használni kívánjuk ezeket a kiegészítéseket. A létre hozni kívánt jellemzőket egészeket tartalmazó tömbként kell átadni, ezek láthatóak a conf és gl4attr változóknál. A tömb végét mindkét esetben egy None jelzi.

Az első komoly műveletet az XOpenDisplay végzi. Kapcsolódik az alapértelmezett X kiszolgálóhoz. Minden további műveletben az itt visszakapott mutatóval dolgozunk. A kapcsolat végén az XCloseDisplay szabadítja fel a lefoglalt erőforrást.

A következő lépésnél két lehetőségünk van, hogy megkapjuk az XVisualInfo-t. Az első, régebbi és ezért szélesebb körben elterjedt módszer, egy GLXPixelmap-en keresztül valósítja meg a kapcsolatot a grafikus kártyával. A függvény a glXChooseVisual. Sokat nem akarok róla írni. Hátránya, hogy a grafikus kártya képét még egyszer leképezi a fizikai memóriában.

Amit itt használunk, az a pixel buffer módszer, ahol közvetlenül érjük el a gpu-t. Hátránya, hogy csak újabb meghajtóprogramokkal érhető el, de mivel a demók többsége modern eszközökön fut, ez nem probléma. A glXChooseFBConfig segítségével kiválasztjuk a megfelelő puffert, ami egyezik az igényeinkkel. Ezeket a conf változóban soroltuk fel. Ha nincs ilyen puffer, a függvény visszatérési értéke NULL.

Általában több puffer is megfelelhet az igényeinknek. Választásunkat a glXGetVisualFromFBConfig függvénnyel jelöljük. Mi most egyszerűen csak az elsőt választjuk, de aki akarja ezen kód alapján kiválaszthatja magának a legjobb XVisualInfot.

XCreateWindow-al elkészítjük az ablakunkat, ahol majd ki akarjuk rajzolni a demót. Ami érdekes számunkra, a GLXContext struktúra. a glXCreateContextAttribsARB kiegészítés segítségével fogjuk elkészíteni OpenGL-es közegünket. Igényeinket a gl4attr tömbbel adjuk át. Amennyiben grafikus kártyánk nem támogatja a megadott OpenGL verziószámot, NULL-t kapunk vissza.

A rendszer minden darabja megvan, már csak össze kell kötni őket. Az XMapWindow elhelyezi az ablakunkat, a glXMakeCurrent pedig összeköti a közeget és az ablakot. Mostantól birtokba vehetjük az OpenGL-t. A példaprogram tartalmaz egy viszonylag primitív billentyű leütés figyelést és a kettős puffereléshez elengedhetetlen lapcserét (glXSwapBuffers).

Amennyiben a felhasználó kilép, a program felszabadítja a lefoglalt erőforrásokat. Már csak egy dologgal vagyok adós, a fordítással:

gcc -lX11 -lGL test.c -o test

Megjegyzés: A program jelenlegi formájában egyetlen visszatérési értéket sem vizsgál, ezért ha hibával tér vissza egy függvény, akkor a program tovább megy és olyan függvénynél áll le, ami látszólag jó. Probléma esetén csökkentsük az OpenGL verziószámot vagy a színeknek fenntartott méretet. Az is előfordulhat, hogy a Mesa az automatikus frissítés során felülírja az NVidia meghajtót, amitől egyetlen GLX alapú program sem fog menni.

Szólj hozzá!

Címkék: programozás demoscene opengl

Szakmák, amikhez mindenki ért: Gyógyászat

2011.01.18. 11:16 Travis.CG

Egy orvos 6 évig tanul az egyetemen. Utána két év rezidenskedés vagy 3 év PhD fokozat szerzés következik, Ez akatt az idő alatt megtanulják az emberi szervezet felépítését olyan szinten, hogy a csontokon található apró dudorok nevét is megtanulják latinul. Megismerik a biokémiai hátterét a sejtfolyamatoknak és a gyógyszerek hatásmechanizmusát.

Ennek ellenére az emberek (és itt én is gyakran ebbe a hibába esem) úgy gondolják, hogy mivel az ő testükről van szó, az orvos ebbe nem lehet kompetens. A másik ok vélhetőleg az, hogy egyes orvosok hibákat követnek el, amitől az a téves következtetés él az emberekben, hogy az orvos nem ért semmihez. De vajon tényleg jobban értünk saját testünkhöz?  A következőkben leírok néhány esetet, aminek a fültanúja voltam.

A gyógyszerek mindenhatóságáról eléggé megoszlanak a vélemények. A tömegközlekedésen üldögélve egy néni például azt kifogásolta, hogy akár hányszor elmegy az orvoshoz, az új gyógyszereket ír fel neki. Ezért mikor megkapta őket, az ablaka alatt csipegető madaraknak szórta azokat. A madarak szépen fel is eszegették valamennyit, majd annak rendje és módja szerint fel is fordultak. A néni tudományos alapossággal levonta a következtetést: milyen jó, hogy nem ő ette meg őket.

A másik esetben egy ritka betegségben szenvedő ember kifogásolta, hogy az orvos nem avatja be őt a kezelés döntésmechanizmusába. Ugyanis a beteg elmondása szerint minden szakirodalmat elolvasott, ami az adott betegséggel kapcsolatos. Hozzáteszem, biológiai képzettsége még nálam is rosszabb, tehát eléggé kétségesnek érzem, hogy mit értett meg az angol nyelvű szakirodalomból. (Különösen azok után, hogy elkezdte nekem magyarázni az epigenetikát, mert szerinte én azt nem ismerhetem, az annyira új "valami". Maradjunk annyiban, hogy több volt a hiba a mondandójában, mint a tény.)

A harmadik eset még megdöbbentőbb. Egy idős bácsi betegségéből kifolyólag sok gyógyszert szed. A gyógyszerek egy része a többi gyógyszer mellékhatásait mérsékli. A bonyolult szedési sorok betartásában a bácsi egy közeli ismerőse segít. Eddig nem is lenne baj, de a segítség ennél tovább megy. Történetesen az orvos előírásának enyhe módosításán. Az oka, hogy elolvasták a betegtájékoztatót, ahol az szerepel, hogy hozzászokás esetén növelni kell az adagot. Ezt megakadályozandó, ez a gyógyszer kimarad néha. Az persze senkinek nem tűnik fel, hogy ha rendesen szedik a gyógyszert, a bácsi tünetmentes, de a segítő szándákú módosítások időszakában köhög, légzési nehézségekkel küzd.

Persze nem ilyen fekete és fehér a helyzet. A bácsi is szokott segíteni ismerősének. Mikor annak fájt a lába, a bácsi nyugodtan felajánlotta fájdalomcsillapítóját, amit csak vényre lehetett kapni, de marad még. Az egyetlen probléma, hogy az a fájdalomcsillapító szívfájdalomra volt. Ne tudjuk meg, milyen hatása volt.

Vannak mások, akik saját képességeiket túlértékelik. Ők úgy gondolják, hogy a valóság megegyezik a TV sorozatokban bemutatott világgal, tehát a gyógyítás érdekében az ott leírtakat kell alkalmazni. Tehát ha valaki a Dr. House-t nézi, azt gondolja, hogy a gyógyítás egyfajta nyomozó munka. Például volt egy ismerősöm, aki vesegörcsökkel küzdött, sokat járt orvoshoz. Főnöke erre leszúrta, hogy miért nem maga próbálja meg meggyógyítani magát, hiszen csak meg kell keresni a kiváltó okot. A főnök példát is adott. Mikor lázas volt, sokat böfögött. Empirikusan kiderítette, hogy ennek oka a megnövekedett nyálelválasztása volt, amit le kellett nyelnie. A nyeléssel jelentős mennyiségű levegő is a gyomrába jutott, aminek ugye valahol távoznia kellett. Tehát, ha valaki kitalálja mitől böfög, az a vesebetegséget is gyógyítani tudja.

A lényeg, hogy gondoljuk végig: mi mit szólnánk hozzá, ha egy nem szakmabeli felülbírálná a döntesünket szakmai kérdésben? Nem kérdeznénk meg tőle, hogy akkor miért nem csinálja maga?

Szólj hozzá!

Címkék: életmód

Dalban mondom el

2011.01.16. 10:10 Travis.CG

A mai nap érdekes felfedezést tettem. A csapatom neve egy dalban is megtalálható:

A dalszöveget nem tudom ki írta az oldalra, de a youtube verziót meghallgatva sokkal inkább ezt lehet érteni:

"..cybernetic genetics genetic replenish with scars on the tendings.."

Ráadásul ennek még értelme is van.

Szólj hozzá!

Címkék: demoscene

CUDA (2. rész)

2011.01.13. 15:37 Travis.CG

Nyilván mindenki túl van a teljes dokumentáció átolvasásán, a példaprogramok végignézésén és talán már 5-6 programot is írtak hiba nélkül. Én nem tartozom közéjük. A példáprogramokat megnéztem. Különösen sok időt töltöttem el egy füst animációt bemutató programnál.

A dokumentációban leírtakat nem akarom megismételni. Nézzünk néhány teljesítmény mutatót. A CUDA magok sebességéről is elég sok tesztet lehet látni, ezért inkább a memória használatot mutatnám be.

A tesztprogramunk a következő:

 #include <stdio.h> #define SIZE 3000

int main(int argc, char **argv){
   float *gpustuff;
   cudaError_t error;
   int i;

   printf("Memoria foglalas GPU\n");

   for(i = 0; i < SIZE * 6; i++){

      error = cudaMalloc(&gpustuff, SIZE * sizeof(float));
      if(error != cudaSuccess){
         printf("Hiba %s\n", cudaGetErrorString(error));
         return(-1);
      }

      error = cudaFree(gpustuff);

      if(error != cudaSuccess){
         printf("Hiba %s\n", cudaGetErrorString(error));
         return(-1);
      }

   }

   printf("Minden rendben\n");
   return(0);
}

A teszt program egy Intel Celeron D 320-on 1 GB ram(kéretik nem hangosan felnevetni) Nvidia Quadro 600. Mivel tartottam attól, hogy a CUDA környezet inicializálása sok időt vesz igénybe, ami torzíthatja a mérést, ezért a programot többször futtattam a for ciklus méretének változtatásával. A CPU verziót nem közlöm, azt mindenki írja meg maga :-) A táblázat első oszlopa azt mutatja, hányszor futott le a for ciklus. A második oszlop a Linuxos time paranccsal mennyi időt mértem. A harmadik oszlop a CPU verzió ideje, szintén time paranccsal.

3000 1.159 0.005
6000 2.090 0.004
9000 3.215 0.004
12000 4.032 0.005
15000 6.793 0.005
18000 6.819 0.004

Ugyan ez a teszt egy másik gépen (AMD Athlon X2 4400, 4GB ram, Nvidia Geforce 8500) a következő eredményt adta:

3000 0.970 0.003
6000 1.875 0.003
9000 2.770 0.003
12000 3.688 0.002
15000 4.588 0.004
18000 5.506 0.004

Tehát a memória foglalás rendkívül költséges művelet.

Szólj hozzá!

Címkék: programozás

CUDA (1. rész)

2011.01.09. 10:00 Travis.CG

Nem minden nap esik meg az emberrel, hogy a munkája és a hobbija keresztezi egymást. Legalábbis két olyan távoli terület esetében, mint a demoscene és a biológia. Most viszont bekövetkezett a lehetetlen, GPU gyorsított bioinformatikai algoritmusokat kell készítenem. A feladatot értelemszerűen nem fogom bemutatni, de néhány általános érvényű, hasznos tudást megpróbálok megosztani az olvasókkal. Az itt megszerzett tudást remélem nem csak a munkám során, de a demók készítésénél is felhasználhatom.

A CUDA programozást én GNU/Linux (Slackware 13 64bit) rendszer alatt fogom végezni, ami valószínűleg több fejfájást fog okozni, mintha ugyan ezt Microsoft Windows alatt tenném. A videókártya egy Geforce 8500 GT. A cikk írásának idején sem volt a legújabb. Az elvek megismeréséhez viszont elég lesz.

Kezdjük is mindjárt a telepítéssel. Telepítettem a 260.19.26 jelű 64 bites NVidia meghajtóprogramot, abból is a "devdriver" jelűt. Aki használt már Linuxot és a fenti gyártó meghajtóprogramját, annak nem lesz nehézsége a telepítéssel. Aki még nem csinált ilyet, annak gyorsan leírom, mit kell tennie: Kilépni az X-ből, futási jogot adni a letöltött fájlnak, majd elindítani. Ha valaki nem Slackware-t használ, szüksége lehet a kernel fejlécállományokra.

A második lépést a programozói környezet (SDK) telepítése. Ez a CUDA Toolkit 3.2.16 64 bites verzió. Mivel a Slackware nem támogatott, ezért a Fedorás csomagot töltöttem le. Gyakorlatilag csak kibont egy tömörített állományt a megadott könyvtárba, esetemben az /usr/local/cuda-ba. Be kell állítani az elérési útba az /usr/local/cuda/bin-t (én az /etc/profiles.d/cuda.sh fájlt hoztam létre, beleírtam, hogy PATH="$PATH:/usr/local/cuda/bin"). Ha nem akarjuk újraindítani a gépet, akkor futtassuk a következő módon a cuda.sh-t:: . cuda.sh. A pont után hagyjunk szünetet! Ez a soruce-olás, amire nem tudok megfelelő magyar szót.

A programozói könyvtárak használatához pedig szerkeszteni kell az /etc/ld.so.conf állományt. Felvettem az /usr/local/cuda/lib64 sort, majd szerkesztés után rendszergazdai jogokkal futtassuk az ldconfig-t.

Az /usr/local/cuda/doc könyvtár rengeteg hasznos dokumentációt tartalmaz PDF formátumban. Egy kezdő programozónak viszont példaprogramokra van szüksége. Szerencsére ezeket is be lehet szerezni az NVidia oldaláról. Ez a korábbiakban megismert módon telepíthető. A felhasználó könyvtárába kitömöríti az állomány tartalmát.

Fordítsuk le a példákat! Lépjünk be a példák könyvtárának C alkönyvtárába és adjuk ki a make parancsot. Egy kis ideig eltart, mire a példák lefordulnak. Ha a fenti lépések hibátlanok, akkor a fordítás során csak figyelmeztetések tömkelegét kapjuk. Nézegessük a példákat, én is ezt fogom tenni.

Kiegészítés:

Mivel technikailag ide illik, ezért leírom, hogy a fenti folyamatot Fedora 14 alatt is végigjátszottam. Mint is mondjak? Nagyon más a telepítés menete. Először is, a Fedora tartalmaz egy nouveau kernel modult, ami megfigyeléseim szerint egy igen alacsony szintű képernyő meghajtó. Gyakorlatilag az initrd betöltése óta ott figyel a memóriában és minden képernyő kezeléssel kapcsolatos feladatot átvesz. Még a framebuffer vezérléséből is kiveszi a részét.

Ezért a telepítési lépéseket úgy kell kezdeni, hogy átírjuk a grub.conf-ot a /boot/grub könyvtárban. A kernel sor végére a következőt kell írni: rdblacklist=nouveau nouveau.modeset=0. Ez megakadályozza a kernel modul betöltését. A másik lépés, hogy az /etc/inittab fájlba a legutolsó sort (id:5:initdefault:) az 5-öst 3-asra átírjuk. Ennek célja, hogy megakadályozzuk a Fedorát, hogy elindítsa az X kiszolgálót. Indítsuk újra a rendszert. Csodáljuk meg a puritán bejelentkező képernyőt, majd lépjünk be root-ként és hajtsuk végre a fent leírtakat. Miután végeztünk, ne felejtsük el az /etc/inittab-ot 5-re visszaírni.

Szólj hozzá!

Címkék: programozás

Táncoló árnyak

2010.12.16. 15:50 Travis.CG

Nagymamám épp süteményeket csomagolta nekem, hogy hazaérve is élvezhessem azt az egyedülálló ízvilágot, ami csak az ő édességeire volt jellemző. Bármilyen ételt is készített, annak mindig ugyan olyan íze volt. Sokszor gondolkodtam rajta, vajon miként képes ellensúlyozni az alapanyagok folyton változó minőségét.

Nagypapám szótlanul ült ugyan azon a széken, ahol mindig is ülni szokott. Görnyedt háttal, némán hintázott a szék első két lábán, mivel lábai csak úgy érték el a földet, ha kicsit megbillentette a széket. A hosszú idő alatt kis rovátkákat vágott a PVC padlóba és redőket nagymamám homlokára eme mutatványával. De nem most. Most a csomagolás volt a legfontosabb.

A süteményeket néztem. Eszembe sem jutottak sem feleségem, sem gyerekeim és én abban a pillanatban nem is csodálkoztam ezen, holott máskor minden gondolatom körülöttük forgott. Most viszont mindennek a középpontjában én voltam, mintha újra gyerek lennék, akinek más dolga sincs, mint magába szívja azt a sok szeretetet és gondoskodást, ami feléje áramlik. Egy ember, bármennyi idős is legyen, csak a nagyszülei mellett lehet teljesen gyerek. A szülők, akiknek nap, mint nap a nevelés nehézségeivel is szembe kell nézniük, nem tudják azt a fajta kényeztetést biztosítani, amit egy nagyszülő.

Ezt a helyzetet magam is megtapasztaltam gyerekként, most átélem felnőttként. Remélem, eljön az idő, amikor nagyszülőként a harmadik oldalt is megismerhetem.

Néztem, ahogy a ráncos kezek hatalmas szeretettel egymáshoz illesztik a kis sütemény darabokat, mintha tészta-téglák lennének. Néztem a gondoskodás megnyilvánulását, majd arra gondoltam, hogy mondhatott olyat a húgom, hogy Mama meghalt. Otromba tréfa volt. A legrosszabb, hogy másoknak is tovább adtam ezt a képtelenséget, akik ha rájönnek hazugságomra, ugyan olyan mérgesek lesznek rám, mint ahogy én a testvéremre.

- Csomagolok almát is - mondta Mama. Én nem viszakoztam. Még az illendőség is megkívánta volna, hogy legalább a látszat kedvéért elhárítsam a kedvességet és belebonyolódjunk egy olyan vitába, aminek a végeredménye úgyis az, hogy elhozom az almákat is. Nem tettem. Álltam mosolyogva, mint egy ünnepelt királyfi, akit nem győznek elhalmozni ajándékokkal.

Tökéletes pillanat volt minden szempontból. Mindenki boldog volt és örült. Úgy éreztem, hogy ez a sok kedvesség, mint egy öngerjesztő folyamat, elér egy pontot, és valami olyat teszek, amit nem szoktam. Ugrálni kezdek, megölelem nagyszüleimet, ostobán vihogok, mint egy öt éves, aki nem tudja türtőztetni magát.

Az óra hangja irreálisnak tűnt ebben a pillanatban. Irreálisnak, mégis ez volt az egyetlen valóságos elem, de ezt csak akkor értettem meg, amikor kinyitottam a szemem. Megpillantottam a mennyezetet és azonnal tudtam, hogy nincs alma, nem várnak sütemények és senki nem fog kényeztetni, mert nagyszüleim sincsenek. Húgom igazat mondott. Az eszem mindig is tudta ezt, de érzékeim számára a valóság attól függ, hogy nyitva van-e a szemem vagy csukva.

Kikapcsoltam az órát és kikeltem az ágyból. A halottak pedig nyugodjanak békében.

Szólj hozzá!

Címkék: irodalom

GATK variáció analízis

2010.12.08. 10:05 Travis.CG

A mai nap egy újabb hiányos dokumentációjú, rendkívül bonyolult programmal, vagy inkább program családdal fogunk megismerkedni. A Broad Institute GATK2 programjával, annak is a genetikai variációk felderítésére szolgáló folyamatával.

Az új generációs szekvenálási eljárások következtében ugyanis rá kellett jönnünk, hogy a genetikai változékonyság korábban nem sejtett módokon is felbukkanhat. Ezek feltérképezése nem egyszerű feladat, mert akár ki akármit is mond, ezek a szekvenálási eljárások sok hibát ejtenek. Elég csak arra gondolni, hogy a megkapott szekvenciák fele nem téképeződik a referencia genomra. Tehát van egy csomó, hibáktól hemzsegő adatsorunk, amit hozzá kell illeszteni egy szabványnak kikiáltott szekvenciához és ráadásul meg is kell mondanunk, hogy mi a hiba, és mi az, ami csak az egyéni különbségekből adódó eltérés.

Erre számtalan program van, abból most nézzük meg a GATK2-t. A program telepítése meglehetősen egyszerű. A mi esetünkben két Javas JAR fájlra lesz szükség: AnalyzeCovariates.jar és GenomeAnalysisTK.jar. Ezen felül a jól ismert SamTools programcsomag is kell, vagy annak Javasított változata a Picard. Ezek telepítésére nem térek ki, elég egyszerűek, probléma nincs velük. Szükséges továbbá egy térképező program, ami a short read-eket a referencia genomon elhelyezi. Fontos, hogy a program BAM outputot generáljon (ezt a SAM kimenetből egy paranccsal könnyen átalakíthatjuk BAM-á), mert a GATK2 csak ezt hajlandó megenni. (Mint látni fogjuk, elég kényes a gyomra.)

A folyamat elrettentésül itt látható. Ezt, és a dokumentációt követve a következő kiegészítéseket teszem:

  • A referencia faj szekvenciája .fasta kiterjesztésű legyen. Természetesen a formátuma is, de az .fna kiterjesztés esetén a program megáll.
  • A létező variációkat tartalmazó fájl .rod-ra végződjön.
  • A dupikációk kezelése előtt rendezzük a BAM állományt koordináták szerint növekvő módon.
  • Minden egyes lépés kéri, hogy a BAM állomány tartalmazzon egy úgynevezett read groupot. A GenomeAnalysisTK.jar tartalmaz opciót, amivel megadhatunk neki alapértelmezett nevet (--default_read_group), de a későbbi programoknál ez hiányzik. Jobb mindjárt az elején a fejlécben elhelyezni ezt, és minden egyes sorban szintén kell a read group tag.
  • A szekvenáló platform nevét is meg kell adni. Itt is van opció rá, ugyan csak a lépés elején használt programnál (--default_platform). Később nincs.
  • A TableRecalibration lépésnél nincs -outputBam. Helyett --out opciót kell használni.
  • Használjuk nyugodtan a -U ALLOW_UNINDEXED_BAM opciót. Sok kényelmetlenségtől kíméljük meg magunkat. (Vagy indexeljük BAM állományunkat)

Sok mappelő program nem készít korrekt SAM állományt. Ezt mindig ellenőrizzük, mert a program nagyon nem szereti a nem szabványos, illetve hiányos állományt. A leggyakoribb hiány a ReadGroup (@RG) mind a fejlécben, mint az egyes sorok végén.

Munkám során eddig egy érdekes jelenséget tapasztaltam, mégpedig azt, hogy az összes variáció guanin vagy citozin. Még nem tudom megmagyarázni, hogy mi a hiba oka, de ha megtaláltam, majd beszámolok róla itt.

A programcsomag Windows alatt furcsa jelenséget produkál. Minden alkalommal, amikor olvas a referencia fájlból, létrehoz egy fai kiterjesztésű állományt, ha még nem létezne. Windows alatt viszont valószínű egy Java szál fogva tartja ezt a fájlt és amint egy másik folyamat írni akar bele, azonnal elszáll.

Szólj hozzá!

Címkék: bioinformatika

SSH alagút kicsit bonyolultabban

2010.12.01. 20:26 Travis.CG

Történt, hogy szükségem volt több gigányi bioinformatikai anyagra egy szerveren, amit nem volt könnyű megközelíteni. Először is csak bizonyos tartományokról lehetett kapcsolódni hozzá, de ez volt a kisebb baj. A nagyobb probléma az volt, hogy a célszerver (legyen a neve storage), csak két másik szerveren keresztül volt elérhető. (Legyen a nevük gate és barrier)

A belépés valami ilyesmi volt:

local> ssh gate

gate> ssh barrier

barrier> ssh storage

Ez igen kellemetlen, ha adatokat akarok lementeni róla, hiszen sok scp lépésre van szükség. Arról nem is beszélve, hogy sem a gate, sem a barrier nem tartalmaz annyi tárhelyet, hogy átmenetileg ott tároljam az adatokat. Szükség lenne egy olyan lépésre, ami segítségével egyből elérhetném a storage-t.

Itt jönnek képbe az ssh alagutak. Nem vagyok nagy szakértő, én is innen tanultam meg a lépéseket. Viszont itt egyszerűbb eset volt vázolva, mint amire nekem szükségem lett volna. Ha két gépen is át kell menni, akkor a következő konfigurációs állomány jöhet szóba:

Host gate
HostName gate.ize.com
User Travis
LocalForward 22000 barrier.ize.com:22
Host barrier
HostName localhost
User Travis
Port 22000
LocalForward 22001 storage.ize.com:22
Host storage
HostName localhost
User Travis
Port 22001

Ennyi. A kapcsolódás is módosul kissé:

localhost> ssh -N -f -q gate

localhost> ssh -N -f -q barrier

localhost> ssh storage

Bent vagyunk! Az utolsó ssh-t scp-re is cserélhetjük, és már másolhatjuk is az adatokat.

Szólj hozzá!

Címkék: biztonság rendszergazda

süti beállítások módosítása