---
# System prepended metadata

title: hw4_111062501

---

# PP HW 4 Report 
111062501 曾雋恩 <br>
You can see this HackMD [here](https://hackmd.io/@dtseng89/ByBk9cYwp).

> - 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](https://github.com/NTHU-LSALAB/UCX-lsalab).

## 1. Overview
> In conjunction with the UCP architecture mentioned in the lecture, please read [ucp_hello_world.c](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c)
1. 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`
    
    <mark>Ans:</mark>
    - 在 UCP 中，我們會透過 `ucp_init` 來創建 `ucp_context`，`ucp_context` 的功用是存取 application 的 global context，是 UCP 操作之基礎，例如 [ucp_hello_world.c](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c) 裡面的 [`status = ucp_init(&ucp_params, config, &ucp_context);`](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c#L575)，若成功創建 `ucp_context` 則 status 會是 [`UCS_OK`](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c#L582C5-L582C54)。
    - `ucp_worker_create` 則是用來創立一個 `ucp_worker`，該物件算是執行 UCP 操作的主要實體，例如它需要負責處理傳輸過程的各種資源、處理 interrupts 等等。可以看到範例程式中的 [`status = ucp_worker_create(ucp_context, &worker_params, &ucp_worker);`](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c#L587) 就是基於前面創建的 `ucp_context`，根據一些 worker 的參數，配置一個 `ucp_worker`。
    - `ucp_ep_create` 是用來創建一個 `ucp_ep` (UCP endpoint)，例如範例中的 [`status = ucp_ep_create(ucp_worker, &ep_params, &server_ep);`](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c#L454C5-L454C64)，就是派遣前一步生出來的 `ucp_worker` 去處理該 endpoint 的通訊，然後新增的 endpoint 就存在 `server_ep` 位址處。
    
    
2. 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`
    
    <mark>Ans:</mark>
    - `ucp_context`：主要負責 UCP 的 global context 紀錄，也就是關乎全局的配置和傳輸過程的內存資源管理等等，在我來看有點像是一個地區的 "交通規則" 一般。
    - `ucp_worker`：這個部分可以參考 [ucp_worker.c](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/src/ucp/core/ucp_worker.c#L2311C14-L2311C31) 的程式，它的工作是處理傳輸的過程，還包含了[初始化 connection ](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/src/ucp/core/ucp_worker.c#L2459)、[分配 worker 資源](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/src/ucp/core/ucp_worker.c#L2462)、interrupt 的處理和事件處理完後的[終止](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/src/ucp/core/ucp_worker.c#L2545)等等。有點像是郵局分派任務給郵差，郵差要在遵守前面提到的交通規則下完成將 A 的信件送達 B 處的任務。
    - `ucp_ep`：它應該是用來記錄傳輸地址的，例如建立[客戶端點](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c#L454C5-L454C64)或[伺服器端點](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c#L251)，我想有點類似郵差要往返 A B 兩處需要確認該處的地址的感覺？
3. Based on the description in HW4, where do you think the following information is loaded/created?
    - `UCX_TLS`
    - TLS selected by UCX
    
    <mark>Ans:</mark>
    - `UCX_TLS`：該變數是用來指定傳輸層安全性 (TLS) 的參數，我想因為它是用來配置 UCX 如何在過程中處理安全傳輸的，應該算是一個全局的設定，要用 UCP Object 區分的話應算是 `ucp_context`。
    - TLS selected by UCX："選擇的 TLS 是哪一個" 也就是回傳 "選到的 TLS 的地址"，我想應該屬於 `ucp_ep` 的範疇。

## 2. Implementation

> Describe how you implemented the two special features of HW4.
1. Which files did you modify, and where did you choose to print Line 1 and Line 2?

    <mark>Ans:</mark>
    - 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);`](https://github.com/NTHU-LSALAB/UCX-lsalab/blob/ce5c5ee4b70a88ce7c15d2fe8acff2131a44aa4a/examples/ucp_hello_world.c#L578C8-L578C8)。
    
        不過這樣寫還有個問題，就是 `UCS_CONFIG_PRINT_CONFIG` 這個 flag 會 call 到 `parser.c` 的 [`ucs_config_parser_print_opts`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/parser.c#L1853) 函數中、包含 [`UCS_CONFIG_PRINT_CONFIG`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/parser.c#L1873) 的部分，因此我按照助教給的提示，增加了一個 `UCS_CONFIG_PRINT_TLS` 的 flag (需要到 [types.h](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/types.h#L94) 檔案中新增一行)，改寫成 [`ucp_config_print(config, stdout, ucs_string_buffer_cstr(&strb), UCS_CONFIG_PRINT_TLS);`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/ucp_worker.c#L1868C9-L1868C9)，讓 `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`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/parser.c#L2013) 函數，原因是我發現這個函數會印出一堆 configs，我們要的 `UCX_TLS` 就包含在其中一行，因此我的[實作](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/parser.c#L1894)就是參考它並在印出 `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);`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/ucp_worker.c#L1868C9-L1868C9) 的第三個參數就派上用場了，`&strb` 會記錄 transport protocols selected by UCX，即為我們第二行的輸出，只要在 `ucs_config_parser_print_opts` 裡面再寫 [`printf("%s\n", title);`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/eae0a87fe44613102e3073dfec8482474543835c/parser.c#L1909) 即可 (因為第三個參數的名稱是 `title`)。
    
    
    
    
2. How do the functions in these files call each other? Why is it designed this way?

    <mark>Ans:</mark> 如上面提到的，`ucp_worker.c` 中的 `ucp_config_print` 會去 call `parser.c` 中的 `ucs_config_parser_print_opts`，我想道理可能類似於 UCP Object 分工的機制，在 worker 中可能會記錄一些過程中用到的參數，然而在 worker 中無須理會使用者想印出的 configs 是哪些，只要選擇適當的 flag，請 `parser.c` 程式幫忙印出即可，同一時間 worker 可以繼續往下執行其他工作，達成平行化效果。
    


3. Observe when Line 1 and 2 are printed during the call of which UCP API?

    <mark>Ans:</mark> 根據[實驗結果](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/main/img/01.png)，在 `ucp_context` 時就有出現 "UCX_TLS=ud_verbs" 了，而具體的位址則是在 `ucp_worker.c:` 才出現。


4. Does it match your expectations for questions **1-3**? Why?

    <mark>Ans:</mark> 這個結果和我想的略有不同，主要是我以為 TLS 位址在 `ucp_ep` 確定，但看起來好像是在 `ucp_worker.c:` 就確定了，可能是 `ucp_worker.c` 需要負責決定取用的傳輸協議的緣故。

5. 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.

    <mark>Ans:</mark>
    
    - lanes：可能是指可用的傳輸通道。
    - tl_rsc：傳輸層資源，和資源配置有關。
    - tl_name：傳輸層的名稱。
    - tl_device：傳輸層裝置。
    - bitmap：應該和配置的選擇或篩選有關，例如我們前面提到的 `UCS_CONFIG_PRINT_TLS` flag 即為 bitmap 的一種應用。
    - iface：和網路介面有關的訊息。

## 3. Optimize System 
1. Below are the current configurations for OpenMPI and UCX in the system. Based on your learning, what methods can you use to optimize single-node performance by setting UCX environment variables?

- lanes

```
-------------------------------------------------------------------
/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:
```bash
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
```

<mark>Ans:</mark>  因為是在 single-node 上，所以最直覺能夠改進的方式我想就是用 shared memory 來進行單節點內的溝通，因此使用 `export UCX_TLS=sm` 指令來更改 `UCX_TLS`，果然速度和 bandwidth 都提升了一些，具體數據可以參考 [`osu_latency 數據`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/main/img/osu_latency.png) 和 [`osu_bw 數據`](https://github.com/davidtseng2000/Parallel_Programming_UCX/blob/main/img/osu_bw.png)。

另外我也有嘗試更改 `UCX_NET_DEVICES`、`UCX_MEMTYPE_CACHE`，但效果並沒有提升，這邊就沒有多做紀錄了。



### Advanced Challenge: Multi-Node Testing

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.

- For information on sbatch, refer to the documentation at [Slurm's sbatch page](https://slurm.schedmd.com/sbatch.html).
- To conduct multi-node testing, use the following command:
```
cd ~/UCX-lsalab/test/
sbatch run.batch
```


## 4. Experience & Conclusion
1. What have you learned from this homework?

    <mark>Ans:</mark>
    trace code 的過程其實不比自己打 code 輕鬆，要看出 UCX 的函數互相 call 來 call 去的關係其實也非易事，不過好險最後有做出來，也覺得能透過一些 UCX 的 API 一窺底層的溝通方式的選擇，其實還算滿有趣的！

    

2. Feedback (optional)

    <mark>Ans:</mark>
    這次作業是要 trace code 並修改，跟以往的作業滿不同的，之所以是 trace 我想是因為 UCX 的架構太大了，雖然有許多開源的社群可以討論和修改程式，但也因為 UCX 是許多單位和專家訂定出來的架構，要自己實作 UCX 之類的實在是不太可能，能夠看得懂我們需要的參數和重要的函數部分，就已經能夠從中學習到 UCX 的許多概念。我很敬佩 UCX 提出讓不同的加速能夠溝通的環境，在有著各式加速方法和許多異質計算的現代，能夠建構出這樣的環境非常不簡單，也著實重要！
