Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ option(WITH_ILUVATAR "Enable ILUVATAR GPU support" OFF)
option(WITH_METAX "Enable MetaX GPU support" OFF)
option(WITH_MOORE "Enable Moore GPU support" OFF)
option(WITH_CAMBRICON "Enable Cambricon MLU support" OFF)
option(WITH_ASCEND "Enable Ascend NPU support" OFF)
option(WITH_HYGON "Enable Hygon DCU support" OFF)

set(WITH_CPU ON CACHE INTERNAL "CPU backend is always enabled")
Expand All @@ -23,6 +24,7 @@ option(WITH_OMPI "Enable OpenMPI backend" OFF)
option(WITH_MPICH "Enable MPICH backend" OFF)
option(WITH_NCCL "Enable NCCL backend" OFF)
option(WITH_MCCL "Enable MCCL backend" OFF)
option(WITH_HCCL "Enable HCCL backend" OFF)

# =========================================================
# --- MISC. BUILD OPTIONS ---
Expand Down Expand Up @@ -178,6 +180,35 @@ if(AUTO_DETECT_DEVICES)
message(STATUS "Cambricon environment not detected.")
endif()

# Ascend
set(ASCEND_FOUND FALSE)

if(DEFINED ENV{ASCEND_HOME_PATH} OR DEFINED ENV{ASCEND_TOOLKIT_HOME} OR DEFINED ENV{ASCEND_HOME})
set(ASCEND_FOUND TRUE)
elseif(EXISTS "/dev/davinci0" OR EXISTS "/dev/davinci_manager")
set(ASCEND_FOUND TRUE)
else()
find_program(ASCEND_SMI_PATH npu-smi)
if(ASCEND_SMI_PATH)
execute_process(
COMMAND ${ASCEND_SMI_PATH} info
RESULT_VARIABLE ASCEND_SMI_RESULT
OUTPUT_QUIET
ERROR_QUIET
)
if(ASCEND_SMI_RESULT EQUAL 0)
set(ASCEND_FOUND TRUE)
endif()
endif()
endif()

if(ASCEND_FOUND)
set(WITH_ASCEND ON)
message(STATUS "Ascend environment detected.")
else()
message(STATUS "Ascend environment not detected.")
endif()

# Hygon DCU
if(NOT WITH_HYGON)
set(HYGON_FOUND FALSE)
Expand Down Expand Up @@ -307,10 +338,30 @@ if(AUTO_DETECT_BACKENDS)
else()
message(STATUS "No suitable device environment, skipping MCCL detection.")
endif()

# Detect HCCL dependencies.
if(WITH_ASCEND)
set(_HCCL_HINTS
"${ASCEND_HOME}"
"$ENV{ASCEND_HOME_PATH}"
"$ENV{ASCEND_TOOLKIT_HOME}"
"$ENV{ASCEND_HOME}"
/usr/local/Ascend/ascend-toolkit/latest
)
find_path(AUTO_HCCL_INC NAMES hccl/hccl.h HINTS ${_HCCL_HINTS} PATH_SUFFIXES include QUIET)
find_library(AUTO_HCCL_LIB NAMES hccl HINTS ${_HCCL_HINTS} PATH_SUFFIXES lib64 aarch64-linux/lib64 QUIET)

if(AUTO_HCCL_INC AND AUTO_HCCL_LIB)
set(WITH_HCCL ON)
message(STATUS "Auto-detected HCCL backend.")
else()
message(STATUS "HCCL library/headers not found in Ascend paths.")
endif()
endif()
endif()

# Fallback: If no backends are enabled or auto-detected, fall back to OpenMPI as the default bootstrap profile.
if(NOT WITH_OMPI AND NOT WITH_MPICH AND NOT WITH_NCCL AND NOT WITH_MCCL)
if(NOT WITH_OMPI AND NOT WITH_MPICH AND NOT WITH_NCCL AND NOT WITH_MCCL AND NOT WITH_HCCL)
set(WITH_OMPI ON)
message(STATUS "No backend specified or detected. Defaulting to `WITH_OMPI=ON`")
endif()
Expand Down Expand Up @@ -420,6 +471,26 @@ if(WITH_CAMBRICON)
find_library(CAMBRICON_PAPI_LIB NAMES cnpapi HINTS "${NEUWARE_HOME}/lib64" REQUIRED)
endif()

if(WITH_ASCEND)
set(_ASCEND_HINTS)
if(ASCEND_HOME)
list(APPEND _ASCEND_HINTS "${ASCEND_HOME}")
endif()
foreach(_ascend_env ASCEND_HOME_PATH ASCEND_TOOLKIT_HOME ASCEND_HOME)
if(DEFINED ENV{${_ascend_env}} AND NOT "$ENV{${_ascend_env}}" STREQUAL "")
list(APPEND _ASCEND_HINTS "$ENV{${_ascend_env}}")
endif()
endforeach()
list(APPEND _ASCEND_HINTS
/usr/local/Ascend/ascend-toolkit/latest
)

find_path(ASCEND_INC NAMES acl/acl.h HINTS ${_ASCEND_HINTS} PATH_SUFFIXES include REQUIRED)
find_library(ASCENDCL_LIB NAMES ascendcl HINTS ${_ASCEND_HINTS} PATH_SUFFIXES lib64 aarch64-linux/lib64 REQUIRED)

include_directories(${ASCEND_INC})
endif()

if(WITH_HYGON)
set(HYGON_DTK_ROOT "")
foreach(_hygon_env DTKROOT DTK_ROOT ROCM_PATH)
Expand Down Expand Up @@ -504,6 +575,17 @@ if(WITH_MCCL)
include_directories(${MCCL_INC})
endif()

if(WITH_HCCL)
if(NOT WITH_ASCEND)
message(FATAL_ERROR "HCCL backend requires Ascend device support. Please enable `WITH_ASCEND`.")
endif()

find_library(HCCL_LIB NAMES hccl HINTS ${_ASCEND_HINTS} PATH_SUFFIXES lib64 aarch64-linux/lib64 REQUIRED)
find_path(HCCL_INC NAMES hccl/hccl.h HINTS ${_ASCEND_HINTS} PATH_SUFFIXES include REQUIRED)

include_directories(${HCCL_INC})
endif()

# Python is required for code generation.
find_package(Python3 REQUIRED)

Expand Down
3 changes: 3 additions & 0 deletions scripts/gen_bridge.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@
"mpich": ["backends/mpi/ompi/impl"],
"nccl": ["backends/ccl/nccl/impl"],
"mccl": ["backends/ccl/mccl/impl"],
"hccl": ["backends/ccl/hccl/impl"],
}

BACKEND_COMMON_HEADERS = {
"nccl": ["backends/ccl/nccl/type_map.h"],
"mccl": ["backends/ccl/mccl/type_map.h"],
"hccl": ["backends/ccl/hccl/type_map.h"],
}

CCL_PROVIDER_BACKENDS = {
"nccl": "backends/ccl/nccl",
"mccl": "backends/ccl/mccl",
"hccl": "backends/ccl/hccl",
}

# =================================================================
Expand Down
24 changes: 24 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,20 @@ if(WITH_CAMBRICON)
)
endif()

# Ascend
if(WITH_ASCEND)
list(APPEND DEVICE_LIST "ascend")

file(GLOB_RECURSE ASCEND_SRCS
"devices/ascend/*.cc"
"devices/ascend/*.cpp"
)

target_sources(infiniccl PRIVATE ${ASCEND_SRCS})
target_include_directories(infiniccl PRIVATE ${ASCEND_INC})
target_link_libraries(infiniccl PRIVATE ${ASCENDCL_LIB})
endif()

# Hygon
if(WITH_HYGON)
list(APPEND DEVICE_LIST "hygon")
Expand Down Expand Up @@ -279,6 +293,16 @@ if(WITH_MCCL)
target_link_libraries(infiniccl PRIVATE ${MCCL_LIB})
endif()

# HCCL
if(WITH_HCCL)
list(APPEND BACKEND_LIST "hccl")
file(GLOB_RECURSE HCCL_SRCS "backends/ccl/hccl/*.cc" "backends/ccl/hccl/*.cpp")

target_sources(infiniccl PRIVATE ${HCCL_SRCS})
target_include_directories(infiniccl PRIVATE ${HCCL_INC})
target_link_libraries(infiniccl PRIVATE ${HCCL_LIB})
endif()

# =========================================================
# --- File Generation ---
# =========================================================
Expand Down
5 changes: 5 additions & 0 deletions src/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ struct BackendPriority<BackendType::kMccl> {
static constexpr int value = 10;
};

template <>
struct BackendPriority<BackendType::kHccl> {
static constexpr int value = 10;
};

} // namespace infini::ccl

#endif // INFINI_CCL_BACKEND_H_
4 changes: 4 additions & 0 deletions src/backend_device_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ template <>
struct IsSupportedCombination<BackendType::kMccl, Device::Type::kMoore>
: std::true_type {};

template <>
struct IsSupportedCombination<BackendType::kHccl, Device::Type::kAscend>
: std::true_type {};

}; // namespace infini::ccl

#endif // INFINI_CCL_BACKEND_DEVICE_MAP_H_
90 changes: 90 additions & 0 deletions src/backends/ccl/hccl/api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#ifndef INFINI_CCL_BACKENDS_CCL_HCCL_API_H_
#define INFINI_CCL_BACKENDS_CCL_HCCL_API_H_

#include <hccl/hccl.h>

#include <cstddef>
#include <cstdint>

#include "backends/ccl/common/api.h"
#include "logging.h"
#include "return_status_impl.h"
#include "runtime.h"

namespace infini::ccl {

template <Device::Type device>
struct HcclApi {
static constexpr BackendType kBackendType = BackendType::kHccl;
static constexpr Device::Type kDeviceType = device;

using Comm = HcclComm;
using Result = HcclResult;
using DataType = HcclDataType;
using RedOp = HcclReduceOp;
using Stream = typename Runtime<device>::Stream;

struct ThreadLocalStream {
Stream stream{};
Result status = HCCL_SUCCESS;

ThreadLocalStream() {
if (Runtime<device>::StreamCreate(&stream) != 0) {
status = HCCL_E_RUNTIME;
}
}

~ThreadLocalStream() {
if (stream != nullptr) {
Runtime<device>::StreamDestroy(stream);
}
}
};

static ReturnStatus Check(Result result) {
if (result != HCCL_SUCCESS) {
const char* message = HcclGetErrorString(result);
LOG(message ? message : "Unknown HCCL error");
return ReturnStatus::kSystemError;
}
return ReturnStatus::kSuccess;
}

static Result CommInitAll(Comm* comms, int n_dev, const int* dev_list,
const int*) {
return HcclCommInitAll(
static_cast<uint32_t>(n_dev),
reinterpret_cast<int32_t*>(const_cast<int*>(dev_list)), comms);
}

static Result CommDestroy(Comm comm) { return HcclCommDestroy(comm); }

static Result ResolveStream(Stream requested, Stream* resolved) {
if (requested != nullptr) {
*resolved = requested;
return HCCL_SUCCESS;
}

thread_local ThreadLocalStream default_stream;
if (default_stream.status != HCCL_SUCCESS) {
return default_stream.status;
}
*resolved = default_stream.stream;
return HCCL_SUCCESS;
}

static Result AllReduce(const void* send_buff, void* recv_buff, size_t count,
DataType data_type, RedOp op, Comm comm,
Stream stream) {
auto status = ResolveStream(stream, &stream);
if (status != HCCL_SUCCESS) {
return status;
}
return HcclAllReduce(const_cast<void*>(send_buff), recv_buff, count,
data_type, op, comm, stream);
}
};

} // namespace infini::ccl

#endif // INFINI_CCL_BACKENDS_CCL_HCCL_API_H_
15 changes: 15 additions & 0 deletions src/backends/ccl/hccl/ascend/api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef INFINI_CCL_BACKENDS_CCL_HCCL_ASCEND_API_H_
#define INFINI_CCL_BACKENDS_CCL_HCCL_ASCEND_API_H_

#include "backends/ccl/hccl/api.h"
#include "devices/ascend/runtime_.h"

namespace infini::ccl {

template <>
struct CclApi<BackendType::kHccl, Device::Type::kAscend>
: HcclApi<Device::Type::kAscend> {};

} // namespace infini::ccl

#endif // INFINI_CCL_BACKENDS_CCL_HCCL_ASCEND_API_H_
17 changes: 17 additions & 0 deletions src/backends/ccl/hccl/impl/all_reduce.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef INFINI_CCL_BACKENDS_CCL_HCCL_IMPL_ALL_REDUCE_H_
#define INFINI_CCL_BACKENDS_CCL_HCCL_IMPL_ALL_REDUCE_H_

#include "backends/ccl/common/impl/all_reduce.h"

namespace infini::ccl {

template <Device::Type device>
class AllReduceImpl<BackendType::kHccl, device>
: public CclAllReduceImpl<BackendType::kHccl, device> {};

template <>
struct BackendEnabled<AllReduce, BackendType::kHccl> : std::true_type {};

} // namespace infini::ccl

#endif // INFINI_CCL_BACKENDS_CCL_HCCL_IMPL_ALL_REDUCE_H_
17 changes: 17 additions & 0 deletions src/backends/ccl/hccl/impl/comm_destroy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef INFINI_CCL_BACKENDS_CCL_HCCL_IMPL_COMM_DESTROY_H_
#define INFINI_CCL_BACKENDS_CCL_HCCL_IMPL_COMM_DESTROY_H_

#include "backends/ccl/common/impl/comm_destroy.h"

namespace infini::ccl {

template <Device::Type device>
class CommDestroyImpl<BackendType::kHccl, device>
: public CclCommDestroyImpl<BackendType::kHccl, device> {};

template <>
struct BackendEnabled<CommDestroy, BackendType::kHccl> : std::true_type {};

} // namespace infini::ccl

#endif // INFINI_CCL_BACKENDS_CCL_HCCL_IMPL_COMM_DESTROY_H_
Loading
Loading