111062501 曾雋恩
You can see this HackMD here.
- Please include both brief and detailed answers.
- The report should be based on the UCX code.
- Describe the code using the 'permalink' from GitHub repository.
In conjunction with the UCP architecture mentioned in the lecture, please read ucp_hello_world.c
Identify how UCP Objects (ucp_context
, ucp_worker
, ucp_ep
) interact through the API, including at least the following functions:
ucp_init
ucp_worker_create
ucp_ep_create
Ans:
ucp_init
來創建 ucp_context
,ucp_context
的功用是存取 application 的 global context,是 UCP 操作之基礎,例如 ucp_hello_world.c 裡面的 status = ucp_init(&ucp_params, config, &ucp_context);
,若成功創建 ucp_context
則 status 會是 UCS_OK
。ucp_worker_create
則是用來創立一個 ucp_worker
,該物件算是執行 UCP 操作的主要實體,例如它需要負責處理傳輸過程的各種資源、處理 interrupts 等等。可以看到範例程式中的 status = ucp_worker_create(ucp_context, &worker_params, &ucp_worker);
就是基於前面創建的 ucp_context
,根據一些 worker 的參數,配置一個 ucp_worker
。ucp_ep_create
是用來創建一個 ucp_ep
(UCP endpoint),例如範例中的 status = ucp_ep_create(ucp_worker, &ep_params, &server_ep);
,就是派遣前一步生出來的 ucp_worker
去處理該 endpoint 的通訊,然後新增的 endpoint 就存在 server_ep
位址處。What is the specific significance of the division of UCP Objects in the program? What important information do they carry?
ucp_context
ucp_worker
ucp_ep
Ans:
ucp_context
:主要負責 UCP 的 global context 紀錄,也就是關乎全局的配置和傳輸過程的內存資源管理等等,在我來看有點像是一個地區的 "交通規則" 一般。ucp_worker
:這個部分可以參考 ucp_worker.c 的程式,它的工作是處理傳輸的過程,還包含了初始化 connection 、分配 worker 資源、interrupt 的處理和事件處理完後的終止等等。有點像是郵局分派任務給郵差,郵差要在遵守前面提到的交通規則下完成將 A 的信件送達 B 處的任務。ucp_ep
:它應該是用來記錄傳輸地址的,例如建立客戶端點或伺服器端點,我想有點類似郵差要往返 A B 兩處需要確認該處的地址的感覺?Based on the description in HW4, where do you think the following information is loaded/created?
UCX_TLS
Ans:
UCX_TLS
:該變數是用來指定傳輸層安全性 (TLS) 的參數,我想因為它是用來配置 UCX 如何在過程中處理安全傳輸的,應該算是一個全局的設定,要用 UCP Object 區分的話應算是 ucp_context
。ucp_ep
的範疇。Describe how you implemented the two special features of HW4.
Which files did you modify, and where did you choose to print Line 1 and Line 2?
Ans:
ucp_worker.c:一開始看助教的 spec 提示說可以使用 ucp_config_print
印出 UCX_TLS
,不過在找來找去都沒有看到 ucp_config_print
,結果在 ucp_hello_world.c
才找到,就參考了它的寫法寫出了 ucp_config_print(config, stdout, NULL, UCS_CONFIG_PRINT_CONFIG);
。
不過這樣寫還有個問題,就是 UCS_CONFIG_PRINT_CONFIG
這個 flag 會 call 到 parser.c
的 ucs_config_parser_print_opts
函數中、包含 UCS_CONFIG_PRINT_CONFIG
的部分,因此我按照助教給的提示,增加了一個 UCS_CONFIG_PRINT_TLS
的 flag (需要到 types.h 檔案中新增一行),改寫成 ucp_config_print(config, stdout, ucs_string_buffer_cstr(&strb), UCS_CONFIG_PRINT_TLS);
,讓 ucp_worker.c
可以成功 call 到 ucs_config_parser_print_opts
函數裡我新增的部分。
parser.c:上面提到 ucp_worker.c
會 call parser.c
裡面的 ucs_config_parser_print_opts
函數,而在該函數中,首先為了印出第一行的 UCX_TLS
結果,我參考了同樣在 parser.c
中的 ucs_config_parser_print_env_vars
函數,原因是我發現這個函數會印出一堆 configs,我們要的 UCX_TLS
就包含在其中一行,因此我的實作就是參考它並在印出 envstr
前,看看 envstr
是否包含 "UCX_TLS" 這個字串,若有則印出。
至於為了印出第二行的 0x56544467c8f0 self cfg#0 tag(ud_verbs/ibp3s0:1)
,我們剛才從 ucp_worker.c
傳遞 ucp_config_print(config, stdout, ucs_string_buffer_cstr(&strb), UCS_CONFIG_PRINT_TLS);
的第三個參數就派上用場了,&strb
會記錄 transport protocols selected by UCX,即為我們第二行的輸出,只要在 ucs_config_parser_print_opts
裡面再寫 printf("%s\n", title);
即可 (因為第三個參數的名稱是 title
)。
How do the functions in these files call each other? Why is it designed this way?
Ans: 如上面提到的,ucp_worker.c
中的 ucp_config_print
會去 call parser.c
中的 ucs_config_parser_print_opts
,我想道理可能類似於 UCP Object 分工的機制,在 worker 中可能會記錄一些過程中用到的參數,然而在 worker 中無須理會使用者想印出的 configs 是哪些,只要選擇適當的 flag,請 parser.c
程式幫忙印出即可,同一時間 worker 可以繼續往下執行其他工作,達成平行化效果。
Observe when Line 1 and 2 are printed during the call of which UCP API?
Ans: 根據實驗結果,在 ucp_context
時就有出現 "UCX_TLS=ud_verbs" 了,而具體的位址則是在 ucp_worker.c:
才出現。
Does it match your expectations for questions 1-3? Why?
Ans: 這個結果和我想的略有不同,主要是我以為 TLS 位址在 ucp_ep
確定,但看起來好像是在 ucp_worker.c:
就確定了,可能是 ucp_worker.c
需要負責決定取用的傳輸協議的緣故。
In implementing the features, we see variables like lanes, tl_rsc, tl_name, tl_device, bitmap, iface, etc., used to store different Layer's protocol information. Please explain what information each of them stores.
Ans:
UCS_CONFIG_PRINT_TLS
flag 即為 bitmap 的一種應用。-------------------------------------------------------------------
/opt/modulefiles/openmpi/4.1.5:
module-whatis {Sets up environment for OpenMPI located in /opt/openmpi}
conflict mpi
module load ucx
setenv OPENMPI_HOME /opt/openmpi
prepend-path PATH /opt/openmpi/bin
prepend-path LD_LIBRARY_PATH /opt/openmpi/lib
prepend-path CPATH /opt/openmpi/include
setenv UCX_TLS ud_verbs
setenv UCX_NET_DEVICES ibp3s0:1
-------------------------------------------------------------------
Please use the following commands to test different data sizes for latency and bandwidth, to verify your ideas:
module load openmpi/4.1.5
mpiucx -n 2 $HOME/UCX-lsalab/test/mpi/osu/pt2pt/standard/osu_latency
mpiucx -n 2 $HOME/UCX-lsalab/test/mpi/osu/pt2pt/standard/osu_bw
Ans: 因為是在 single-node 上,所以最直覺能夠改進的方式我想就是用 shared memory 來進行單節點內的溝通,因此使用 export UCX_TLS=sm
指令來更改 UCX_TLS
,果然速度和 bandwidth 都提升了一些,具體數據可以參考 osu_latency 數據
和 osu_bw 數據
。
另外我也有嘗試更改 UCX_NET_DEVICES
、UCX_MEMTYPE_CACHE
,但效果並沒有提升,這邊就沒有多做紀錄了。
This challenge involves testing the performance across multiple nodes. You can accomplish this by utilizing the sbatch script provided below. The task includes creating tables and providing explanations based on your findings. Notably, Writing a comprehensive report on this exercise can earn you up to 5 additional points.
cd ~/UCX-lsalab/test/
sbatch run.batch
What have you learned from this homework?
Ans:
trace code 的過程其實不比自己打 code 輕鬆,要看出 UCX 的函數互相 call 來 call 去的關係其實也非易事,不過好險最後有做出來,也覺得能透過一些 UCX 的 API 一窺底層的溝通方式的選擇,其實還算滿有趣的!
Feedback (optional)
Ans:
這次作業是要 trace code 並修改,跟以往的作業滿不同的,之所以是 trace 我想是因為 UCX 的架構太大了,雖然有許多開源的社群可以討論和修改程式,但也因為 UCX 是許多單位和專家訂定出來的架構,要自己實作 UCX 之類的實在是不太可能,能夠看得懂我們需要的參數和重要的函數部分,就已經能夠從中學習到 UCX 的許多概念。我很敬佩 UCX 提出讓不同的加速能夠溝通的環境,在有著各式加速方法和許多異質計算的現代,能夠建構出這樣的環境非常不簡單,也著實重要!