clear
Table of Contents
cuda
巻末のREADMEでエヌビディアを取り上げたんで、そこら辺の技術を探ってみる。
CUDAプログラミング第一歩 とっても面倒そうなので、普通は PyTorch なんかの革をまとうのかな。
GPUサーバのインターコネクト:InfiniBand vs イーサネット完全解説
v シェーダー for Vlang グラフィックの入口で良く聞くな
module main import gg import gx fn main() { mut context := gg.new_context( bg_color: gx.rgb(174, 198, 255) width: 600 height: 400 window_title: 'Polygons' frame_fn: frame ) context.run() } fn frame(mut ctx gg.Context) { ctx.begin() ctx.draw_convex_poly([f32(100.0), 100.0, 200.0, 100.0, 300.0, 200.0, 200.0, 300.0, 100.0, 300.0], gx.blue) ctx.draw_poly_empty([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gx.black) ctx.draw_triangle_filled(450, 142, 530, 280, 370, 280, gx.red) ctx.end() }
OpenGLをかすかに思い出した。これが発展してくと描画エンジンがグラフィック・ボード の載る。サイズの変更やら回転が高速で可能。回転なんてのは行列で定義されてる。 しかるに、グラボがAI用の計算エンジンになるんじゃねぇ。だったら使い易いソフトも 一緒に提供しよう。その名称は、cuda。更にAIに特化したライブラリィーも提供 しよう。その名称は、cuDNN。
河豚板の真似
鬼門だったインストール時のdiskの扱いが河豚板のusbfadmを読み解いて理解 できたので手動でやってみる。今はGPTの時代ですからねぇ。毎度のMBRだけじゃ 脳が無いです。まずは、4Gのファイルをddで作成しとく。それをvnconfigで diskに見立てる所から始まる。
ob# vnconfig vnd0 /home/sakae/mydisk ob# fdisk -igy vnd0 ;; MBR付きでGPT形式にする Writing GPT. ob# fdisk -e vnd0 ;; diskを編集するぞ Enter 'help' for information vnd0: 1> p ;; 現状の確認 Disk: vnd0 Usable LBA: 34 to 8191966 [8192000 Sectors] GUID: 27be0eb0-1a15-40bb-99e3-561f6e04690b #: type [ start: size ] guid name ------------------------------------------------------------------------ 0: OpenBSD [ 64: 8191903 ] 10f9df02-719d-4ba8-9cc4-c24dc9a052c7 OpenBSD Area vnd0: 1> edit 0 ;; 0番さんを開放 #: type [ start: size ] ------------------------------------------------------------------------ 0: OpenBSD [ 64: 8191903 ] Partition id ('0' to disable) [01 - FF, <uuid>]: [A6] (? for help) 0 Partition 0 is disabled. vnd0*: 1> edit 1 ;; 1番さんにBIOSでも理解できるエリアを作成 #: type [ start: size ] ------------------------------------------------------------------------ 1: Unused [ 0: 1 ] Partition id ('0' to disable) [01 - FF, <uuid>]: [00] (? for help) EF Partition offset [34 - 8191966]: [34] Partition size [1 - 8191933]: [8191933] 500m Partition name: [] boot vnd0*: 1> edit 2 ;; 2番さんにDOSエリアを設定。他OSとの回廊用 #: type [ start: size ] ------------------------------------------------------------------------ 2: Unused [ 0: 1 ] Partition id ('0' to disable) [01 - FF, <uuid>]: [00] (? for help) c Partition offset [34 - 8191966]: [1024034] Partition size [1 - 7167933]: [7167933] 500m Partition name: [] dos vnd0*: 1> edit 3 ;; 最後はOpenBSDのエリア #: type [ start: size ] ------------------------------------------------------------------------ 3: Unused [ 0: 1 ] Partition id ('0' to disable) [01 - FF, <uuid>]: [00] (? for help) a6 Partition offset [34 - 8191966]: [2048034] Partition size [1 - 6143933]: [6143933] Partition name: [] bsd vnd0*: 1> p ;; 編集の成果 Disk: vnd0 Usable LBA: 34 to 8191966 [8192000 Sectors] GUID: 27be0eb0-1a15-40bb-99e3-561f6e04690b #: type [ start: size ] guid name ------------------------------------------------------------------------ 1: EFI Sys [ 34: 1024000 ] fedfde66-5289-41c4-8466-ab0ec7b27eaa boot 2: Microsoft basic data [ 1024034: 1024000 ] 6ea9e9bf-1161-4841-accd-a4259458bf10 dos 3: OpenBSD [ 2048034: 6143933 ] d696fbde-808c-46f2-90d5-28208eddea71 bsd vnd0*: 1> w ;; 書き込んで終了 Writing GPT. vnd0: 1> quit
次はOpenBSD用のエリアの区画を用意してく
ob# disklabel -E vnd0 Label editor (enter '?' for help at any prompt) vnd0> p ;; OpenBSDからは、こんな風にdiskが認識されてる。 OpenBSD area: 2048034-8191967; size: 6143933; free: 59 # size offset fstype [fsize bsize cpg] c: 8192000 0 unused i: 1024000 34 MSDOS j: 1024000 1024034 MSDOS vnd0*> a b ;; 小さなswapエリアを用意 offset: [2048034] size: [6143933] 128m FS type: [swap] vnd0*> a a ;; 残りをOpenBSD用に割り当て offset: [2310200] size: [5881767] FS type: [4.2BSD] vnd0*> p OpenBSD area: 2048034-8191967; size: 6143933; free: 39 # size offset fstype [fsize bsize cpg] a: 5881728 2310208 4.2BSD 2048 16384 1 b: 262166 2048034 swap c: 8192000 0 unused i: 1024000 34 MSDOS j: 1024000 1024034 MSDOS vnd0*> w ;; 書き込んでから終了 vnd0> q No label changes.
最後に、aパーテションを整地する。
ob# newfs vnd0a /dev/rvnd0a: 2871.9MB in 5881728 sectors of 512 bytes 15 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each super-block backups (for fsck -b #) at: 160, 414880, 829600, 1244320, 1659040, 2073760, 2488480, 2903200, 3317920, 3732640, 4147360, 4562080, 4976800, 5391520, 5806240, ob# mount /dev/vnd0a /mnt ;; マウントできればOK ob# df -k Filesystem 1K-blocks Used Avail Capacity Mounted on : /dev/vnd0a 2843102 2 2700946 1% /mnt
clear, tput
前回やった端末をクリアーするコマンドが通常用になってたので確認してみる。
ob$ which clear /usr/bin/clear ob$ file /usr/bin/clear /usr/bin/clear: ELF 32-bit LSB shared object, Intel 80386, version 1 ob$ ls -l /usr/bin/clear -r-xr-xr-x 2 root bin 22272 Sep 30 2024 /usr/bin/clear*
シェルスクリプトかと思ったら違ってたバイナリーでしかも他とリンクしてた。 そんなに立派なものか? 取りあえずソースに対面してみるか。。んが、そんなソース は無いぞ。他のコマンドに紛れ込んでいるんだな。iノードが同一なコマンドを 探してみるか。いや、今回は別な方法で行ってみる。
ob$ cd /usr/src/usr.bin ob$ find . -name Makefile | xargs grep clear ./tput/Makefile:SRCS= clear_cmd.c reset_cmd.c tparm_type.c tput.c transform.c \ ./tput/Makefile:LINKS= ${BINDIR}/tput ${BINDIR}/clear ./tput/Makefile:MAN= tput.1 clear.1
見つけた。tputの類縁なのね。久しぶりにgdb出来る様にコンパイル。libcursesが内部的 に使われている。でそのcursesが端末情報のデータベースであるterminfoのラッパー みたいな位置付け。dbなんで元データを復元してソースレベルで取り込みたい。 んなもんで、ticなんてののお世話になっている。
ob$ doas make cc -g -O0 -I/usr/src/usr.bin/tput/../../lib/libcurses -I/usr/src/usr.bin/tput/../tic -I/usr/src/usr.bin/tput -I. -Werror-implicit-function-declaration -MD -MP -c /usr/src/usr.bin/tput/../tic/clear_cmd.c cc -g -O0 -I/usr/src/usr.bin/tput/../../lib/libcurses -I/usr/src/usr.bin/tput/../tic -I/usr/src/usr.bin/tput -I. -Werror-implicit-function-declaration -MD -MP -c /usr/src/usr.bin/tput/../tic/reset_cmd.c cc -g -O0 -I/usr/src/usr.bin/tput/../../lib/libcurses -I/usr/src/usr.bin/tput/../tic -I/usr/src/usr.bin/tput -I. -Werror-implicit-function-declaration -MD -MP -c /usr/src/usr.bin/tput/../tic/tparm_type.c cc -g -O0 -I/usr/src/usr.bin/tput/../../lib/libcurses -I/usr/src/usr.bin/tput/../tic -I/usr/src/usr.bin/tput -I. -Werror-implicit-function-declaration -MD -MP -c tput.c cc -g -O0 -I/usr/src/usr.bin/tput/../../lib/libcurses -I/usr/src/usr.bin/tput/../tic -I/usr/src/usr.bin/tput -I. -Werror-implicit-function-declaration -MD -MP -c /usr/src/usr.bin/tput/../tic/transform.c cc -g -O0 -I/usr/src/usr.bin/tput/../../lib/libcurses -I/usr/src/usr.bin/tput/../tic -I/usr/src/usr.bin/tput -I. -Werror-implicit-function-declaration -MD -MP -c /usr/src/usr.bin/tput/../tic/tty_settings.c cc -o tput clear_cmd.o reset_cmd.o tparm_type.o tput.o transform.o tty_settings.o -lcurses ob$ doas ln tput clear
emacsからgdbすると、TERMが馬鹿端末としてターゲットが動作するんで、結果がエラーに なってしまう。裸のgdbを使うか、layout srcして少しはemacsの雰囲気で利用する事。 そして、特に意味もなく、qemu-kvmの環境で動作させた。TEFM=tmux-256color rows 34 が、Lubuntuの世界になってる。
Breakpoint 1, clear_cmd (legacy=false) at ../tic/clear_cmd.c:52 52 int retval = tputs(clear_screen, lines > 0 ? lines : 1, putch); (gdb) bt #0 clear_cmd (legacy=false) at ../tic/clear_cmd.c:52 #1 0x1443bc01 in tput_cmd (fd=2, settings=0xcf7d0b5c, argc=1, argv=0xcf7d1004, used=0xcf7d0b54) at tput.c:206 #2 0x1443b233 in main (argc=1, argv=0xcf7d1004) at tput.c:459 (gdb) l 47 } 48 49 int 50 clear_cmd(bool legacy) 51 { 52 int retval = tputs(clear_screen, lines > 0 ? lines : 1, putch); 53 if (!legacy) { 54 /* Clear the scrollback buffer if possible. */ 55 char *E3 = tigetstr("E3"); 56 if (E3) (gdb) s tputs (string=0x60b9a841 "\033[H\033[J", affcnt=34, outc=0x14438d30 <putch>) at /usr/src/lib/libcurses/tinfo/lib_tputs.c:454 454 SetSafeOutcWrapper(outc);
何やらエスケープシーケンス文字列が出てきたぞ。そして、少し丁寧に追跡。
440 #if NCURSES_SP_FUNCS 441 NCURSES_EXPORT(int) 442 _nc_outc_wrapper(SCREEN *sp, int c) 443 { 444 if (0 == sp) { 445 return fputc(c, stdout); 446 } else { >447 return sp->jump(c); 448 }
こんな所でループしてる。
(gdb) bt 3 #0 _nc_outc_wrapper (sp=0xcf7cebbc, c=91) at /usr/src/lib/libcurses/tinfo/lib_tputs.c:447 #1 0x0620b743 in tputs_sp (sp=0xcf7cebbc, string=0x7e850042 "[H\033[J", affcnt=34, outc=0x620b930 <_nc_outc_wrapper>) at /usr/src/lib/libcurses/tinfo/lib_tputs.c:372 #2 0x0620b9e7 in tputs (string=0x7e850041 "\033[H\033[J", affcnt=34, outc=0x1a175d30 <putch>) at /usr/src/lib/libcurses/tinfo/lib_tputs.c:455
で、どんな文字列が送出されるか、トレースしてみる。fd 1 == stdout
te$ ktrace -ti clear te$ kdump : 28404 clear GIO fd 1 wrote 10 bytes "\^[[H\^[[J\^[[3J"
前回のtermでやったのでもOK。但しクリア後のカーソル位置が異なるけど。
te$ ktrace -ti printf '\x1b[2J' te$ kdump : 26489 printf GIO fd 1 wrote 4 bytes "\^[[2J"
これを受信したカーネルは、どんな応答をするのかな? wscons/wsemul_vt100.c
あたりが基本になるのかな。
for OpenBSD
探ってみると、こんなのが出てくる。いかにも、っぽい。
vt100_handler *vt100_output[] = { wsemul_vt100_output_esc, wsemul_vt100_output_csi, wsemul_vt100_output_scs94, wsemul_vt100_output_scs94_percent, wsemul_vt100_output_scs96, wsemul_vt100_output_scs96_percent, wsemul_vt100_output_esc_hash, wsemul_vt100_output_esc_spc, wsemul_vt100_output_string, wsemul_vt100_output_string_esc, wsemul_vt100_output_dcs, wsemul_vt100_output_dcs_dollar, wsemul_vt100_output_esc_percent, };
が、どれにもヒットしない。com1をconsoleに見立てているから? だったらtty系を 追跡してみるか。
(gdb) bt 6 #0 ttyoutput (c=13, tp=0xd23f9400) at /usr/src/sys/kern/tty.c:606 #1 0xd0756bcf in ttwrite (tp=0xd23f9400, uio=0xf0bb1434, flag=1) at /usr/src/s\ ys/kern/tty.c:1835 #2 0xd06b586c in comwrite (dev=2048, uio=0xf0bb1434, flag=1) at /usr/src/sys/d\ ev/ic/com.c:629 #3 0xd04d554b in spec_write (v=0xf0bb1380) at /usr/src/sys/kern/spec_vnops.c:3\ 02 #4 0xd038cb79 in VOP_WRITE (vp=0xd226cd80, uio=0xf0bb1434, ioflag=1, cred=0xd2\ 395e10) at /usr/src/sys/kern/vfs_vops.c:245 #5 0xd0346446 in vn_write (fp=0xd22f1724, uio=0xf0bb1434, fflags=0) at /usr/sr\ c/sys/kern/vfs_vnops.c:408
printf '\x1b[2J' を使ってみると、
(gdb) p cp $1 = (u_char *) 0xf0b6f9cc "\033[2J<f\361\320P=}\317\001" (gdb)
確かに来てる。
/* * If ce is zero, then we're processing * a special character through ttyoutput. */ if (ce == 0) { tp->t_rocount = 0; => if (ttyoutput(*cp, tp) >= 0) { /* out of space */
んで、最後は、ここから抜けて行くんだけど、どうもすっきりしない。
done: if (obufcc) => explicit_bzero(obuf, obufcc); return (error);
実戦検証の前に、机上検討を十分に実施した方が良さそうだ。 tty/pty/termios とかが鍵かな。
term on vinix
暫く間を置いてしまったけれどvlangによるLinuxの実装であるvinixでは、どうなって いるか? dev/consoleなんて言うピッタリなデバイスが有ったんで目を皿のようにして眺めて みたんだけど、それらしいのは見当らず。検索範囲を広めたら、 kernel/c/flanterm/README.md に、それらしい記述を発見。
# Flanterm Flanterm is a fast and reasonably complete terminal emulator with support for multiple output backends. Included is a fast framebuffer backend.
更にソースを眺めたら、真面目なmanが紹介されてた。
console_codes(4)
これで解決って事にしましょうかね。
for FreeBSD
man screen あたりが関係しそうなマニュアルで、ソースは、 syscons/scterm-sc.c
static void scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c) { if (tcp->esc == 1) { /* seen ESC */ switch (c) { case '7': /* Save cursor position */ tcp->saved_xpos = scp->xpos; tcp->saved_ypos = scp->ypos; break; : case '[': /* Start ESC [ sequence */ tcp->esc = 2; tcp->last_param = -1; for (i = tcp->num_param; i < MAX_ESC_PAR; i++) tcp->param[i] = 1; tcp->num_param = 0; return;
大変な解析を行なっているぞ。このdirの中にはスクリーン・セーバーのモジュールも 置いてあった。見てると楽しい。
README
世界を席巻してるAIを下支えしてるGPU。 GPUと言えばNVIDIA。革ジャンの社長さんで有名。 何で革ジャンで登場する様になったかの説明は出てこなかったけど、同社の発展の 軌跡が熱く語られている。
こちらにハイライト の解説が掲載されてた。タイパやコスパ重視の方はどうぞ。
この会社、ブラック企業並に猛烈な働き方をするみたい。社員が逃避しない様に 株オプションと言う人参をチラつかせて、鼓舞してるそうだ。
社長さんは、随分長い事君臨してるけど、後継者の準備をちゃんとしてるのだろうか? この会社に期待してる金の亡者は、そんな事ばかり考えているようだ。