HcclCommSymWinRegister

Applicability

Product

Supported

Atlas 350 Accelerator Card

☓

Atlas A3 training product / Atlas A3 inference product

√

Atlas A2 training product / Atlas A2 inference product

☓

Atlas 200I/500 A2 inference product

☓

Atlas inference product

☓

Atlas training product

☓

Function

Registers the virtual memory as symmetric memory after allocating and mapping virtual and physical memory.

Symmetric memory is a memory management model that enables parallel processing units (such as ranks) to access each other's memory in a globally visible manner, without requiring explicit address exchange.

The following figure shows the basic implementation of symmetric memory, where each rank pre-reserves a virtual address space of identical size and layout.

Symmetric memory enables HCCL to operate directly on user-provided memory, completely bypassing intermediate buffers (such as the HCCL buffer) and eliminating memory copy overhead.

Prototype

1
HcclResult HcclCommSymWinRegister(HcclComm comm, void *addr, uint64_t size, CommSymWindow *winHandle, uint32_t flag)

Parameters

Parameter

Input/Output

Description

comm

Input

HCCL communicator. You are advised to use the largest-scale communicator within the SuperPoD, that is, the communicator that covers the maximum number of devices.

During communicator initialization, you can configure the symmetric memory size reserved per rank using the hcclSymWinMaxMemSizePerRank parameter in HcclCommConfig. If left unset, it defaults to 16 GB.

The total size of the reserved virtual symmetric memory in the current communicator is rankSize x HcclCommConfig.hcclSymWinMaxMemSizePerRank.

addr

Input

Address of reserved virtual memory.

The virtual memory needs to be reserved by calling the aclrtReserveMemAddress API.

size

Input

Size of the symmetric memory window, where 0 < size ≤ HcclCommConfig.hcclSymWinMaxMemSizePerRank. This value cannot exceed the size of the physical memory mapped to addr (that is, the device physical memory allocated by calling the aclrtMallocPhysical API).

Note: Symmetric memory registration is aligned with the physical memory size. Consequently, the actual window size registered is equal to the size of the physical memory mapped to addr.

winHandle

Output

Pointer that stores the symmetric memory window resource handle.

For details about the definition of the HcclCommSymWindow type, see HcclCommSymWindow.

flag

Input

Controls whether to enable symmetric memory. Currently, only 1 is allowed.

Returns

HcclResult: HCCL_SUCCESS on success, or else failure.

Constraints

Call Example

// Create and initialize the configuration items of the communicator.
HcclCommConfig config;
HcclCommConfigInit(&config);
// Modify the communicator configuration as required.
config.hcclSymWinMaxMemSizePerRank = 10; // Set per-rank size in GB (Default: 16). Total reserved virtual symmetric heap size = rankSize x hcclSymWinMaxMemSizePerRank.

// Obtain the communicator parameters.
uint32_t rankSize = 4;
uint32_t rankId = 0;
int32_t deviceId;
ACLCHECK(aclrtGetDevice(&deviceId));
HcclRootInfo rootInfo;
HCCLCHECK(HcclGetRootInfo(&rootInfo));

// Initialize the collective communicator.
HcclComm hcclComm;
HCCLCHECK(HcclCommInitRootInfoConfig(rankSize, &rootInfo, rankId, &config, &hcclComm));

// Create a task flow.
aclrtStream stream;
ACLCHECK(aclrtCreateStream(&stream));

// Configure the physical memory attributes.
aclrtPhysicalMemProp prop;
prop.handleType = ACL_MEM_HANDLE_TYPE_NONE;
prop.allocationType = ACL_MEM_ALLOCATION_TYPE_PINNED;
prop.memAttr = ACL_HBM_MEM_HUGE;
prop.location.id = deviceId;
prop.location.type = ACL_MEM_LOCATION_TYPE_DEVICE;
prop.reserve = 0;

// Obtain the alignment granularity, which is usually 2 MB.
size_t granularity;
ACLCHECK(aclrtMemGetAllocationGranularity(&prop, ACL_RT_MEM_ALLOC_GRANULARITY_RECOMMENDED, &granularity));

// Align the size based on the granularity.
size_t size = 2 * 1024 * 1024;
size_t allocSize = (size + granularity - 1) / granularity * granularity;

// Reserve virtual memory.
void *virPtr;
ACLCHECK(aclrtReserveMemAddress(&virPtr, allocSize, 0, nullptr, 1));

// Allocate physical memory.
aclrtDrvMemHandle memHandle;
ACLCHECK(aclrtMallocPhysical(&memHandle, allocSize, &prop, 0));

// Establish the mapping from physical memory to virtual memory.
ACLCHECK(aclrtMapMem(virPtr, allocSize, 0, memHandle, 0));

size_t sendBytes = 1024;
size_t recvBytes = rankSize * sendBytes;
HcclCommSymWindow symWin;
// Register symmetric memory.
HCCLCHECK(HcclCommSymWinRegister(hcclComm, virPtr, sendBytes + recvBytes, &symWin, 1));

// Use symmetric memory.
void *sendBuff = virPtr;
void *recvBuff = static_cast<char*>(sendBuff) + sendBytes;

// Call the collective communication operator.
HCCLCHECK(HcclAllGather(sendBuff, recvBuff, sendBytes, HCCL_DATA_TYPE_INT8, hcclComm, stream));

// Wait until the collective communication task in the task flow is complete.
ACLCHECK(aclrtSynchronizeStream(stream));

// Deregister symmetric memory.
HCCLCHECK(HcclCommSymWinDeregister(symWin));

// Free memory.
ACLCHECK(aclrtUnmapMem(virPtr));
ACLCHECK(aclrtFreePhysical(memHandle));
ACLCHECK(aclrtReleaseMemAddress(virPtr));

 // Destroy the task flow.
ACLCHECK(aclrtDestroyStream(stream));

// Destroy the communicator.
HCCLCHECK(HcclCommDestroy(hcclComm));