Unify environment variable management (#235)

* Add environment variable configuration infrastructure
  - Namespace rocshmem::envvar
  - Track all config env vars in per-category lists
  - Remove duplicates from list of allowed env var types
  - Reject negative inputs for unsigned integer types
  - Accept empty strings for std::string
  - Print error source location using C++20 std::source_location
  - Unit tests
* Port environment variables
  - ROCSHMEM_UNIQUEID_WITH_MPI
  - ROCSHMEM_RO_DISABLE_IPC
  - ROCSHMEM_BOOTSTRAP_TIMEOUT
  - ROCSHMEM_BOOTSTRAP_HOSTID
  - ROCSHMEM_BOOTSTRAP_SOCKET_IFNAME
  - ROCSHMEM_RO_PROGRESS_DELAY
  - ROCSHMEM_BOOTSTRAP_SOCKET_FAMILY
  - ROCSHMEM_MAX_NUM_CONTEXTS
    + Merge the independent per-backend copies into a single variable
      that is used by all three backends (IPC, RO, GDA).
    + Set default to 32 (for GDA); prior default for IPC and RO was 1024.
  - ROCSHMEM_MAX_NUM_HOST_CONTEXTS
  - ROCSHMEM_MAX_WF_BUFFERS
  - ROCSHMEM_SQ_SIZE
  - ROCSHMEM_RO_NET_CPU_QUEUE
    + Renamed from RO_NET_CPU_QUEUE
    + Change env var input type to bool, default to false
    + Invert code logic: setting RO_NET_CPU_QUEUE to anything
      would /disable/ a variable gpu_queue, which defaulted to true.
      Variable is now named config::ro::net_cpu_queue,
      with all prior checks for gpu_queue inverted.
  - ROCSHMEM_USE_IB_HCA
  - ROCSHMEM_HEAP_SIZE
    + Defaults to 1L << 30 i.e. 1 GiB,
      from default heap size in memory/heap_memory.hpp.
  - ROCSHMEM_MAX_NUM_TEAMS
    + Unlike other env vars, this can be referenced from devices.
    + Function currently narrows from size_t to int: uses need to be audited
      for safety and correctness in using size_t directly.
  - ROCSHMEM_GDA_ALTERNATE_QP_PORTS
* New env var ROCSHMEM_DEBUG
  - Debug levels:
    + NONE
    + VERSION
    + WARN
    + INFO
    + TRACE
  - Currently unused - will be added later
  - Mirrors RCCL debug control
* Remove rocshmem::rocshmem_env_config
* Change interface for GetClosestNicToGpu
  to accept const char** instead of char**:
  the pointed-to string does not need to be modified
  - Files were not audited for inclusion of util.hpp only for env vars
---------
Signed-off-by: Omri Mor <Omri.Mor@amd.com>
This commit is contained in:
Omri Mor
2025-10-06 10:05:57 -07:00
committed by GitHub
parent 0a4f8a83b9
commit a0fcbf8d35
29 changed files with 1070 additions and 277 deletions
+24 -35
View File
@@ -29,8 +29,9 @@
#include <cassert>
#include "backend_gda.hpp"
#include "mpi_instance.hpp"
#include "envvar.hpp"
#include "gda_team.hpp"
#include "mpi_instance.hpp"
#include "util.hpp"
#include "topology.hpp"
@@ -129,26 +130,14 @@ GDABackend::~GDABackend() {
}
void GDABackend::read_env() {
if (auto maximum_num_contexts_str = getenv("ROCSHMEM_MAX_NUM_CONTEXTS")) {
std::stringstream sstream(maximum_num_contexts_str);
sstream >> maximum_num_contexts_;
}
char* value{nullptr};
if ((value = getenv("ROCSHMEM_USE_IB_HCA"))) {
requested_dev = strdup(value);
if (!envvar::requested_dev.is_default()) {
requested_dev = envvar::requested_dev.get_value().c_str();
} else {
int gpu_dev = 0;
CHECK_HIP(hipGetDevice(&gpu_dev));
int nic_dev = rocshmem::GetClosestNicToGpu(gpu_dev, &requested_dev);
assert (nic_dev != -1);
}
if ((value = getenv("ROCSHMEM_SQ_SIZE"))) {
sq_size = atoi(value);
}
if ((value = getenv("ROCSHMEM_GDA_ALTERNATE_QP_PORTS"))) {
alternate_qp_ports_enabled = atoi(value);
}
}
void GDABackend::setup_ipc() {
@@ -178,9 +167,9 @@ void GDABackend::setup_ctxs() {
setup_host_ctx();
setup_default_ctx();
CHECK_HIP(hipMalloc(&ctx_array, sizeof(GDAContext) * maximum_num_contexts_));
CHECK_HIP(hipMalloc(&ctx_array, sizeof(GDAContext) * envvar::max_num_contexts));
// 0th context is default context
for (size_t i = 0; i < maximum_num_contexts_; i++) {
for (size_t i = 0; i < envvar::max_num_contexts; i++) {
new (&ctx_array[i]) GDAContext(this, i + 1);
ctx_free_list.get()->push_back(ctx_array + i);
}
@@ -188,7 +177,7 @@ void GDABackend::setup_ctxs() {
void GDABackend::cleanup_ctxs() {
ctx_free_list.~FreeListProxy();
for (size_t i = 0; i < maximum_num_contexts_; i++) {
for (size_t i = 0; i < envvar::max_num_contexts; i++) {
ctx_array[i].~GDAContext();
}
@@ -667,7 +656,7 @@ void GDABackend::exchange_qp_dest_info() {
dest_info[i].gid = gid;
}
for (int i = 0; i < maximum_num_contexts_ + 1; i++) {
for (size_t i = 0; i < envvar::max_num_contexts + 1; i++) {
if (backend_comm != MPI_COMM_NULL) {
mpilib_ftable_.Alltoall(MPI_IN_PLACE, sizeof(dest_info_t), MPI_CHAR, dest_info.data() + i * num_pes, sizeof(dest_info_t), MPI_CHAR, backend_comm);
} else {
@@ -718,7 +707,7 @@ void GDABackend::setup_gpu_qps() {
size_t qp_objs_count;
size_t qp_objs_mem_size;
qp_objs_count = (maximum_num_contexts_ + 1) * num_pes;
qp_objs_count = (envvar::max_num_contexts + 1) * num_pes;
qp_objs_mem_size = sizeof(QueuePair) * qp_objs_count;
CHECK_HIP(hipMalloc(&gpu_qps, qp_objs_mem_size));
@@ -726,7 +715,7 @@ void GDABackend::setup_gpu_qps() {
host_qps = (QueuePair*) malloc(qp_objs_mem_size);
CHECK_NNULL(host_qps, "malloc (host_qps)");
for (int i = 0; i < qp_objs_count; i++) {
for (size_t i = 0; i < qp_objs_count; i++) {
new (&host_qps[i]) QueuePair(pd_orig, gda_vendor);
CHECK_HIP(hipMemcpy(&gpu_qps[i], &host_qps[i], sizeof(QueuePair), hipMemcpyDefault));
@@ -741,9 +730,9 @@ void GDABackend::setup_gpu_qps() {
void GDABackend::cleanup_gpu_qps() {
size_t qp_objs_count;
qp_objs_count = (maximum_num_contexts_ + 1) * num_pes;
qp_objs_count = (envvar::max_num_contexts + 1) * num_pes;
for (int i = 0; i < qp_objs_count; i++) {
for (size_t i = 0; i < qp_objs_count; i++) {
host_qps[i].~QueuePair();
}
@@ -919,15 +908,15 @@ void GDABackend::modify_qps_rtr_to_rts() {
void GDABackend::create_queues() {
int ncqes;
int resize_length;
size_t resize_length;
if (gda_vendor == GDAVendor::IONIC) {
ncqes = sq_size << 1;
ncqes = envvar::sq_size << 1;
} else {
ncqes = sq_size;
ncqes = envvar::sq_size;
}
resize_length = (maximum_num_contexts_ + 1) * num_pes;
resize_length = (envvar::max_num_contexts + 1) * num_pes;
dest_info.resize(resize_length);
cqs.resize(resize_length);
@@ -938,25 +927,25 @@ void GDABackend::create_queues() {
if (gda_vendor == GDAVendor::BNXT) {
bnxt_create_cqs(ncqes);
bnxt_create_qps(sq_size);
bnxt_create_qps(envvar::sq_size);
} else {
create_cqs(ncqes);
create_qps(sq_size);
create_qps(envvar::sq_size);
}
alternate_qp_ports();
}
void GDABackend::alternate_qp_ports() {
int cur_qp_idx;
int new_qp_idx;
size_t cur_qp_idx;
size_t new_qp_idx;
/* We can't remap anything */
if (maximum_num_contexts_ == 1) {
if (envvar::max_num_contexts == 1) {
return;
}
if (alternate_qp_ports_enabled) {
if (envvar::gda::alternate_qp_ports) {
/* If we assume two PEs and a default context and two user context,
* initially QPs are in the following port order:
*
@@ -979,8 +968,8 @@ void GDABackend::alternate_qp_ports() {
*/
/* Re-Map each context */
for (int i = 1; i < (maximum_num_contexts_ + 1); i+=2) {
for (int p = 0; p < num_pes; p+=2) {
for (size_t i = 1; i < (envvar::max_num_contexts + 1); i += 2) {
for (size_t p = 0; p < num_pes; p += 2) {
cur_qp_idx = (i * num_pes) + p;
new_qp_idx = cur_qp_idx + 1;