* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include <hccl/hccl_res_expt.h>
#include "log.h"
#include "utils.h"
#include "common.h"
#include "hccl_custom_p2p.h"
#include "load_kernel.h"
#include "launch_kernel.h"
using namespace ops_hccl_p2p;
HcclResult HcclSendCustom(
void* sendBuf, uint64_t count, HcclDataType dataType, uint32_t destRank, HcclComm comm, aclrtStream stream)
{
CHK_PTR_NULL(sendBuf);
CHK_PTR_NULL(comm);
CHK_PTR_NULL(stream);
OpParam param;
int ret = sprintf_s(param.tag, sizeof(param.tag), "%s", "hccl_custom_p2p");
if (ret <= 0) {
HCCL_ERROR("[HcclSendCustom] Failed to fill param.tag");
return HCCL_E_INTERNAL;
}
CHK_RET(HcclGetCommName(comm, param.commName));
param.inputPtr = sendBuf;
param.count = count;
param.dataType = dataType;
param.opType = HcclCMDType::HCCL_CMD_SEND;
uint32_t rank, rankSize;
CHK_RET(HcclGetRankId(comm, &rank));
CHK_RET(HcclGetRankSize(comm, &rankSize));
CHK_RET(GetDeviceType(¶m.devType));
CommEngine engine = CommEngine::COMM_ENGINE_AICPU;
void* ctx = nullptr;
uint64_t size = sizeof(AlgResourceCtx);
if (HcclEngineCtxGet(comm, param.tag, engine, &ctx, &size) == HCCL_SUCCESS) {
HCCL_INFO("[HcclSendCustom] Engine context already exists");
param.resCtx = static_cast<AlgResourceCtx*>(ctx);
} else {
HCCL_INFO("[HcclSendCustom] Creating engine context");
CHK_RET(HcclEngineCtxCreate(comm, param.tag, engine, size, &ctx));
param.resCtx = static_cast<AlgResourceCtx*>(ctx);
AlgResourceCtx resCtxHost;
CHK_RET(HcclThreadAcquireWithStream(comm, COMM_ENGINE_CPU_TS, stream, 1, ¶m.cpuThread));
CHK_RET(HcclThreadExportToCommEngine(
comm, 1, ¶m.cpuThread, COMM_ENGINE_AICPU_TS, &resCtxHost.cpuThreadOnAicpu));
CHK_RET(HcclThreadAcquire(comm, COMM_ENGINE_AICPU_TS, 1, 1, &resCtxHost.aicpuThread));
CHK_RET(HcclThreadExportToCommEngine(
comm, 1, &resCtxHost.aicpuThread, COMM_ENGINE_CPU_TS, ¶m.aicpuThreadOnCpu));
CHK_RET(AcquireChannel(comm, engine, param.devType, rank, destRank, &(resCtxHost.channelHandle)));
CHK_RET(HcclGetHcclBuffer(comm, &(resCtxHost.localBuffer.addr), &(resCtxHost.localBuffer.size)));
CHK_RET(HcclChannelGetHcclBuffer(
comm, resCtxHost.channelHandle, &(resCtxHost.remoteBuffer.addr), &(resCtxHost.remoteBuffer.size)));
ACLCHECK(aclrtMemcpy(param.resCtx, size, &resCtxHost, size, ACL_MEMCPY_HOST_TO_DEVICE));
}
CHK_RET(LaunchKernel(param, stream));
return HCCL_SUCCESS;
}