LCOV - code coverage report
Current view: top level - legacy/ascend950/unified_platform/resource/connection/aicpu - rdma_vendor_1825_ops.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 64.5 % 183 118
Test Date: 2026-08-18 17:47:01 Functions: 81.2 % 16 13

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #ifndef RDMA_VENDOR_1825_OPS_H
      12              : #define RDMA_VENDOR_1825_OPS_H
      13              : 
      14              : #include "rma_conn_lite.h"
      15              : #include "rdma_vendor_base_ops.h"
      16              : 
      17              : namespace Hccl {
      18              : 
      19              : // 先默认所有WQE都只占一个WQEBB
      20              : #define WQEBB_SHIFT 6
      21              : 
      22              : #define ROCE_WQE_OWNERBIT_SHIFT 7
      23              : #define ROCE_WQE_CTRL_VALUE 0x40
      24              : #define ROCE_SQ_VA_VALUE 0x20
      25              : #define ROCE_SQ_SIGNAL_SHIFT 7
      26              : #define ROCE_WQE_CQE_SIGNAL_SHIFT 7
      27              : #define ROCE_WQE_CMP_TASK_LEN1 1u /* wqe cl is set to 1 */
      28              : #define ROCE_WQE_CMP_TASK_LEN_SHIFT 28
      29              : #define ROCE_TASK_SEG_ALIGN 8
      30              : #define ROCE_WQE_FAST_DMA_SHIFT 10
      31              : #define ROCE_WQE_SSN_MASK 0x3
      32              : #define ROCE_WQE_SSN_SHIFT 12
      33              : #define ROCE_WQE_DATA_SEG_SHIFT 4
      34              : #define ROCE_WQE_TASK_SEG_LAST_EXT_LEN 4
      35              : #define ROCE_WQE_TASK_REDUCE_OP_OFFSET 4
      36              : #define WQE_SECTION_ALIGN_SHIFT 3
      37              : 
      38              : #define ROCE_WQE_NEXT_SGE_INVALID (1u << 31)
      39              : 
      40              : using Roce3CtrlSeg = struct {
      41              :     // Control Segment
      42              :     uint8_t owner_sl; /* ownerbit:ctrl_section_length:csl:dif_sl = 1:2:2:3; */
      43              :     uint8_t df_tsl;   /* cr:df:va:tal = 1:1:1:5; */
      44              :     uint16_t wf_bdsl; /* cf:wf:wqe_msn:fde:fast:drvsl:bdsl = 1:1:2:1:1:2:8; */
      45              :     uint32_t cl_pi;   /* cl:signature:mask_pi = 4:8:20; */
      46              :     uint64_t db;      /* used by direct wqe*/
      47              : };
      48              : 
      49              : union Roce3TaskSeg {
      50              :     struct {
      51              :         uint32_t xrcSrqn : 18;
      52              :         uint32_t ext : 1;
      53              :         uint32_t dif : 1;
      54              :         uint32_t rsvd0 : 3;
      55              :         uint32_t so : 1;
      56              :         uint32_t opType : 5;
      57              :         uint32_t signal : 1;
      58              :         uint32_t fence : 1;
      59              :         uint32_t se : 1; /* solited event flag; */
      60              :     } dw0;
      61              :     uint32_t value;
      62              : };
      63              : 
      64              : using Roce3TaskWqeSeg = struct {
      65              :     // Task Wqe Segment
      66              :     union Roce3TaskSeg tskSeg;
      67              :     uint32_t dataLen;
      68              :     uint32_t immData;
      69              :     union {
      70              :         struct {
      71              :             uint32_t lastExtLen : 8;
      72              :             uint32_t cmdLen : 8;
      73              :             uint32_t pi : 16;
      74              :         } bs;
      75              : 
      76              :         uint32_t feth; /* cflush feth header */
      77              :         uint32_t value;
      78              :     } dw3;
      79              :     uint64_t va;   /* to indicate remote buf address; */
      80              :     uint32_t rkey; /* to indicate remote mr buf; */
      81              :     uint32_t ulp;  /* ulp预留字段 */
      82              : };
      83              : 
      84              : static constexpr uint32_t DTYPE_INVALID = 0xFFu;
      85              : 
      86              : static const uint32_t Roce3ReduceDataTypeMap[] = {
      87              :     /* [DINT8]   = */ 0x0,           // INT8
      88              :     /* [DINT16]  = */ 0x1,           // INT16
      89              :     /* [DINT32]  = */ 0x2,           // INT32
      90              :     /* [DFP16]   = */ 0x6,           // FP16_NORMAL
      91              :     /* [DFP32]   = */ 0x7,           // FP32
      92              :     /* [DINT64]  = */ DTYPE_INVALID, // 硬件不支持
      93              :     /* [DUINT32] = */ DTYPE_INVALID, // 硬件不支持
      94              : };
      95              : 
      96              : static const uint32_t Roce3ReduceOpTypeMap[] = {
      97              :     /* [SUM]    = */ 0xA,           // ADD
      98              :     /* [PROD]   = */ DTYPE_INVALID, // 求积, 硬件不支持
      99              :     /* [MAX]    = */ 0x8,           // MAX
     100              :     /* [MIN]    = */ 0x9,           // MIN
     101              :     /* [EQUAL]  = */ 0xB,           // EQUAL
     102              : };
     103              : 
     104              : using Roce3WqeDataSeg = struct {
     105              :     uint64_t bufAddr; /* buffer address that wqe sge indicate; */
     106              :     uint32_t rLen;    /* buffer length that wqe sge indicate; */
     107              :     uint32_t leKey;   /* buffer lkey that wqe sge indicate; */
     108              : };
     109              : 
     110              : using Roce3WqeEntry = struct {
     111              :     Roce3CtrlSeg ctrl;
     112              :     Roce3TaskWqeSeg task;
     113              :     Roce3WqeDataSeg data;
     114              : };
     115              : 
     116              : // Cqe related
     117              : constexpr uint32_t ROCE_CQE_OPCODE_SHIFT = 27;
     118              : constexpr uint32_t ROCE_CQE_OPCODE_MASK = 0x1f;
     119              : constexpr uint32_t ROCE_CQ_UPDATE_CI_MASK = 0xffffff; /* cq arm db ci mask; */
     120              : constexpr uint32_t ROCE_CQE_MAX_GEN_NUM = 1024;
     121              : constexpr uint32_t ROCE_CQE_OWNERBIT_SHIFT = 31;
     122              : constexpr uint32_t ROCE_CQE_QPN_MASK = 0xfffff;
     123              : 
     124              : enum class RoceCqeType : uint32_t {
     125              :     ERROR = 0x1e,  /* indicate the cqe is an error cqe */
     126              :     RESIZE = 0x16, /* indicate the cqe is an resize type cqe */
     127              :     INVALID = 0x1f
     128              : };
     129              : 
     130              : struct Roce3CqeEntry {
     131              :     uint32_t owner_id_qpn; /* ownerbit: cqe_size:dif_en:wq_id:error_code:qpn = 1:2:1:4:4:20; */
     132              :     uint32_t op_sr_wqebb;  /* opcode:s_r:inline_r:merge:fake:rsvd:linkwqe_used:wqebb_index = 5:1:1:1:1:2:1:20; */
     133              :     uint32_t byte_cnt;     /* reflect the data size we reveive; */
     134              :     uint32_t imm_data;     /* the immediate data we receive */
     135              : 
     136              :     union {
     137              :         struct {
     138              :             uint8_t smac_h[2];    /* smac value; */
     139              :             uint16_t vlan_id_pri; /* vlan_id:vlan_priority:reserved:smac = 12:1:3:16; */
     140              :         } mac_vlanid;
     141              :     } dw4;
     142              :     union {
     143              :         uint8_t smac_l[4]; /* smac value */
     144              :         uint32_t wqe_num;  /* merged wqe num */
     145              :     };
     146              :     uint32_t vlan_queue_index; /* vlan:force_loopback:reserved:RQPN = 2:1:5:24; */
     147              :     uint8_t syndrome;          /* record syndrome code; */
     148              :     uint8_t reserved2;
     149              :     uint16_t wqe_counter; /* the wqe index, valid for sq; */
     150              : };
     151              : 
     152              : // Doorbell related
     153              : constexpr uint32_t ROCE_SQ_DOORBELL_TYPE = 21;
     154              : constexpr uint32_t ROCE_INIT_SQ_DB_SGIT_IDX = 1;
     155              : 
     156              : using Roce3DbEntry = struct {
     157              :     union {
     158              :         struct {
     159              :             uint32_t qpn : 20;     /* indicate the sq qpn; */
     160              :             uint32_t cntxSize : 2; /* indicate the qpc size; */
     161              :             uint32_t r : 1;        /* reserved bit; */
     162              :             uint32_t c : 1;
     163              :             uint32_t cos : 3;
     164              :             uint32_t type : 5;
     165              : 
     166              :             uint32_t pi : 8;
     167              :             uint32_t resv : 8;
     168              :             uint32_t xrcvld : 1;
     169              :             uint32_t vxlan : 1;
     170              :             uint32_t mtuShift : 3;
     171              :             uint32_t sgidIndex : 7;
     172              :             uint32_t subType : 4;
     173              :         } bs;
     174              :         uint64_t db_value;
     175              :     } dw0;
     176              : };
     177              : 
     178              : enum class ROCE3_OPCODE : uint32_t { ROCE_OPCODE_RDMA_WRITE = 4U, ROCE_OPCODE_RDMA_READ = 8U };
     179              : 
     180              : // post_send helper
     181              : struct Roce3PostSendParams {
     182              :     const SqeConfigLite& cfg;
     183              :     const RmaBufSliceLite& loc;
     184              :     const RmtRmaBufSliceLite& rmt;
     185              :     const uint32_t opCode;
     186              : 
     187              :     Roce3PostSendParams(const Roce3PostSendParams&) = delete;
     188              :     Roce3PostSendParams& operator=(const Roce3PostSendParams&) = delete;
     189              : };
     190              : 
     191              : class Rdma1825Ops : public RdmaBaseOps {
     192              : public:
     193           39 :     Rdma1825Ops(RdmaSqContextLite* sqContext, RdmaCqContextLite* cqContext) : RdmaBaseOps(sqContext, cqContext) {}
     194              : 
     195           78 :     ~Rdma1825Ops() override {}
     196              : 
     197            7 :     HcclResult BuildDoorbell(u64& dbAddr, u64& dbValue) override
     198              :     {
     199              :         Roce3DbEntry dbEntry;
     200            7 :         dbEntry.dw0.db_value = 0;
     201            7 :         dbEntry.dw0.bs.r = 0;
     202            7 :         dbEntry.dw0.bs.c = 0;
     203            7 :         dbEntry.dw0.bs.cntxSize = 1;
     204            7 :         dbEntry.dw0.bs.qpn = sqContext_->qpn;
     205            7 :         dbEntry.dw0.bs.subType = 0;
     206            7 :         dbEntry.dw0.bs.resv = 0;
     207            7 :         dbEntry.dw0.bs.pi = ((sqHead_ >> 8) & 0xff);
     208            7 :         dbEntry.dw0.bs.sgidIndex = ROCE_INIT_SQ_DB_SGIT_IDX;
     209            7 :         dbEntry.dw0.bs.type = ROCE_SQ_DOORBELL_TYPE;
     210              : 
     211            7 :         dbEntry.dw0.bs.mtuShift = static_cast<uint32_t>(
     212            7 :             (sqContext_->dbVendorSpecified >> UB_DB_VENDOR_MTUSHIFT_SHIFT) & UB_DB_VENDOR_FIELD_MASK);
     213            7 :         dbEntry.dw0.bs.cos = static_cast<uint32_t>(
     214            7 :             (sqContext_->dbVendorSpecified >> UB_DB_VENDOR_COS_SHIFT) & UB_DB_VENDOR_FIELD_MASK);
     215              : 
     216            7 :         dbAddr = sqContext_->dbHwVa;
     217            7 :         dbValue = dbEntry.dw0.db_value;
     218              : 
     219           21 :         HCCL_INFO(
     220              :             "[Rdma1825Ops::%s] SQ DB ready, qpn[%u], sqHead[%u], mtuShift[%u], cos[%u], "
     221              :             "dbAddr[0x%llx], dbValue[0x%llx]",
     222              :             __func__, sqContext_->qpn, sqHead_, dbEntry.dw0.bs.mtuShift, dbEntry.dw0.bs.cos, dbAddr, dbValue);
     223            7 :         return HCCL_SUCCESS;
     224              :     }
     225              : 
     226            3 :     HcclResult BuildCqDoorbell(u64& dbAddr, u64& dbValue) override
     227              :     {
     228            3 :         if (cqDbFlush_) {
     229            2 :             dbAddr = cqContext_->dbSwVa;
     230              : 
     231            2 :             const uint32_t dbValue32 = Htonl32(cqTail_ & ROCE_CQ_UPDATE_CI_MASK);
     232            2 :             dbValue = dbValue32;
     233              : 
     234              :             // Ring Cq Soft DB
     235            2 :             auto ret = memcpy_sp(reinterpret_cast<void*>(dbAddr), sizeof(uint32_t), &dbValue32, sizeof(uint32_t));
     236            2 :             if (UNLIKELY(ret != 0)) {
     237            0 :                 THROW<InternalException>(
     238            0 :                     StringFormat("[Rdma1825Ops::%s] write soft Cq DB failed, ret = %d", __func__, ret));
     239              :             }
     240            6 :             HCCL_INFO(
     241              :                 "[Rdma1825Ops::%s] CQ DB updated, cqTail[%u], dbAddr[0x%llx], dbValue[0x%llx]", __func__, cqTail_,
     242              :                 dbAddr, dbValue);
     243              :         } else {
     244            1 :             dbAddr = 0;
     245            1 :             dbValue = 0;
     246              :         }
     247              : 
     248            3 :         cqDbFlush_ = false;
     249              : 
     250            3 :         return HCCL_SUCCESS;
     251              :     }
     252              : 
     253              : protected:
     254              :     HcclResult
     255            3 :     BuildReadWqe(const RmaBufSliceLite& loc, const RmtRmaBufSliceLite& rmt, const SqeConfigLite& cfg) override
     256              :     {
     257            3 :         Roce3WqeEntry wqe{};
     258            3 :         Roce3PostSendParams params{cfg, loc, rmt, static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_READ)};
     259              : 
     260            3 :         CHK_RET(FillCtrlSeg(&wqe, params));
     261            3 :         CHK_RET(FillTaskSeg(&wqe, params));
     262            3 :         CHK_RET(FillDataSeg(&wqe, params));
     263              : 
     264            3 :         CHK_RET(CommitWqe(&wqe, sizeof(Roce3WqeEntry)));
     265            9 :         HCCL_INFO(
     266              :             "[Rdma1825Ops::%s] WQE committed, qpn[%u], sqHead[%u], loc[0x%llx], rmt[0x%llx], size[%u]", __func__,
     267              :             sqContext_->qpn, sqHead_, loc.GetAddr(), rmt.GetAddr(), loc.GetSize());
     268            3 :         return HCCL_SUCCESS;
     269              :     }
     270              : 
     271              :     HcclResult
     272            6 :     BuildWriteWqe(const RmaBufSliceLite& loc, const RmtRmaBufSliceLite& rmt, const SqeConfigLite& cfg) override
     273              :     {
     274            6 :         Roce3WqeEntry wqe{};
     275            6 :         Roce3PostSendParams params{cfg, loc, rmt, static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_WRITE)};
     276              : 
     277            6 :         CHK_RET(FillCtrlSeg(&wqe, params));
     278            6 :         CHK_RET(FillTaskSeg(&wqe, params));
     279            6 :         CHK_RET(FillDataSeg(&wqe, params));
     280              : 
     281            6 :         CHK_RET(CommitWqe(&wqe, sizeof(Roce3WqeEntry)));
     282           18 :         HCCL_INFO(
     283              :             "[Rdma1825Ops::%s] WQE committed, qpn[%u], sqHead[%u], loc[0x%llx], rmt[0x%llx], size[%u]", __func__,
     284              :             sqContext_->qpn, sqHead_, loc.GetAddr(), rmt.GetAddr(), loc.GetSize());
     285            6 :         return HCCL_SUCCESS;
     286              :     }
     287              : 
     288            2 :     HcclResult BuildWriteReduceWqe(
     289              :         const RmaBufSliceLite& loc, const RmtRmaBufSliceLite& rmt, const SqeConfigLite& cfg, DataType dataType,
     290              :         ReduceOp reduceOp) override
     291              :     {
     292            2 :         Roce3WqeEntry wqe{};
     293            2 :         Roce3PostSendParams params{cfg, loc, rmt, static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_WRITE)};
     294              : 
     295            2 :         CHK_RET(FillCtrlSeg(&wqe, params));
     296            2 :         CHK_RET(FillTaskSeg(&wqe, params));
     297            2 :         CHK_RET(FillReduceTaskSeg(&wqe, params, dataType, reduceOp));
     298            2 :         CHK_RET(FillDataSeg(&wqe, params));
     299              : 
     300            2 :         CHK_RET(CommitWqe(&wqe, sizeof(Roce3WqeEntry)));
     301            6 :         HCCL_INFO(
     302              :             "[Rdma1825Ops::%s] WQE committed, qpn[%u], sqHead[%u], loc[0x%llx], rmt[0x%llx], size[%u], "
     303              :             "dataType[%u], reduceOp[%u]",
     304              :             __func__, sqContext_->qpn, sqHead_, loc.GetAddr(), rmt.GetAddr(), loc.GetSize(),
     305              :             static_cast<uint32_t>(dataType), static_cast<uint32_t>(reduceOp));
     306            2 :         return HCCL_SUCCESS;
     307              :     }
     308              : 
     309            0 :     HcclResult WriteInvalidWqebb(uint32_t nextIdx) override
     310              :     {
     311            0 :         const uint32_t sqDepth = sqContext_->depth;
     312            0 :         const uint32_t sqMask = sqDepth - 1U;
     313            0 :         uint8_t ownerSl = ((nextIdx & sqDepth) == 0) ? 0xff : 0x7f;
     314              : 
     315            0 :         auto* dst
     316            0 :             = reinterpret_cast<void*>(sqContext_->sqVa + static_cast<uint64_t>(nextIdx & sqMask) * sqContext_->wqeSize);
     317              : 
     318            0 :         auto ret = memcpy_sp(dst, sizeof(ownerSl), &ownerSl, sizeof(ownerSl));
     319            0 :         if (UNLIKELY(ret != 0)) {
     320            0 :             THROW<InternalException>(
     321            0 :                 StringFormat("[Rdma1825Ops::%s] write invalid wqebb failed, ret = %d", __func__, ret));
     322              :         }
     323            0 :         return HCCL_SUCCESS;
     324              :     }
     325              : 
     326            3 :     int32_t PollCqImpl(int32_t numEntries, std::vector<int32_t>& errList) override
     327              :     {
     328            3 :         int32_t pollNum = 0;
     329            3 :         CqPollStatus ret = CqPollStatus::ERROR;
     330              : 
     331            4 :         while (pollNum < numEntries) {
     332            3 :             ret = PollOne(errList);
     333            3 :             if (ret != CqPollStatus::SUCCESS) {
     334            2 :                 if (ret != CqPollStatus::EMPTY && ret != CqPollStatus::ERROR) {
     335            0 :                     HCCL_ERROR(
     336              :                         "[Rdma1825Ops::%s][Poll cq] Poll CQ error, ret: %d", __func__, static_cast<int32_t>(ret));
     337              :                 }
     338            2 :                 break;
     339              :             }
     340              : 
     341              :             // Update Cq CI
     342            1 :             cqTail_ += 1;
     343              : 
     344            1 :             ++pollNum;
     345              :         }
     346              : 
     347            3 :         if ((pollNum != 0) || (ret == CqPollStatus::ERROR)) {
     348              :             // Need to flush Cq DB
     349            2 :             cqDbFlush_ = true;
     350              :         }
     351              : 
     352            3 :         return (ret == CqPollStatus::ERROR) ? static_cast<int32_t>(ret) : pollNum;
     353              :     }
     354              : 
     355              : private:
     356           11 :     HcclResult FillCtrlSeg(Roce3WqeEntry* wqe, const Roce3PostSendParams& params) const
     357              :     {
     358              :         // 赋值本wqe的owner
     359           11 :         uint8_t owner = (sqHead_ & (sqContext_->depth)) == 0 ? 0 : 1;
     360           11 :         wqe->ctrl.owner_sl = (owner << ROCE_WQE_OWNERBIT_SHIFT) | ROCE_WQE_CTRL_VALUE;
     361              : 
     362              :         // 不产生cqe + task字段的长度
     363           11 :         wqe->ctrl.df_tsl = ((params.cfg.cqeEn == true) ? (1U << ROCE_SQ_SIGNAL_SHIFT) : 0) | ROCE_SQ_VA_VALUE;
     364           11 :         wqe->ctrl.df_tsl |= sizeof(Roce3TaskWqeSeg) / ROCE_TASK_SEG_ALIGN;
     365              : 
     366              :         // fast_dma + SSN + sge长度
     367           11 :         wqe->ctrl.wf_bdsl = Htons16(static_cast<uint16_t>(0 << ROCE_WQE_FAST_DMA_SHIFT));
     368           11 :         wqe->ctrl.wf_bdsl |= Htons16((sqHead_ & ROCE_WQE_SSN_MASK) << ROCE_WQE_SSN_SHIFT);
     369           11 :         wqe->ctrl.wf_bdsl |= Htons16(
     370              :             static_cast<uint16_t>(static_cast<uint32_t>(1) << (ROCE_WQE_DATA_SEG_SHIFT - WQE_SECTION_ALIGN_SHIFT)));
     371              : 
     372              :         // cl
     373           11 :         wqe->ctrl.cl_pi = Htonl32(ROCE_WQE_CMP_TASK_LEN1 << ROCE_WQE_CMP_TASK_LEN_SHIFT);
     374              : 
     375           11 :         return HCCL_SUCCESS;
     376              :     }
     377              : 
     378           11 :     HcclResult FillTaskSeg(Roce3WqeEntry* wqe, const Roce3PostSendParams& params) const
     379              :     {
     380              :         // ----- Task Seg -----
     381           11 :         wqe->task.tskSeg.value = 0;
     382           11 :         wqe->task.tskSeg.dw0.signal = !!((wqe->ctrl.df_tsl & (1U << ROCE_WQE_CQE_SIGNAL_SHIFT)) > 0);
     383           11 :         wqe->task.tskSeg.dw0.fence = params.cfg.fence;
     384           11 :         wqe->task.tskSeg.dw0.opType = params.opCode;
     385           11 :         wqe->task.tskSeg.dw0.se = 0;
     386           11 :         wqe->task.tskSeg.value = Htonl32(wqe->task.tskSeg.value);
     387              : 
     388           11 :         wqe->task.dataLen = Htonl32(params.loc.GetSize());
     389           11 :         wqe->task.immData = 0;
     390              :         wqe->task.dw3.value
     391           11 :             = (params.opCode == static_cast<uint32_t>(ROCE3_OPCODE::ROCE_OPCODE_RDMA_READ) ?
     392            3 :                    Htonl32(ROCE_WQE_TASK_SEG_LAST_EXT_LEN) :
     393              :                    0);
     394           11 :         wqe->task.va = Htonll64(params.rmt.GetAddr());
     395           11 :         wqe->task.rkey = Htonl32(params.rmt.GetRkey());
     396           11 :         wqe->task.ulp = Htonl32(params.loc.GetLkey() & 0xffff);
     397              : 
     398           11 :         return HCCL_SUCCESS;
     399              :     }
     400              : 
     401              :     HcclResult
     402            2 :     FillReduceTaskSeg(Roce3WqeEntry* wqe, const Roce3PostSendParams& params, DataType dataType, ReduceOp reduceOp) const
     403              :     {
     404              :         // Hcomm Type -> Roce3 Type
     405            2 :         uint32_t dataTypeIdx = static_cast<uint32_t>(dataType);
     406            2 :         if (dataTypeIdx >= sizeof(Roce3ReduceDataTypeMap) / sizeof(uint32_t)) {
     407            0 :             HCCL_ERROR("[Rdma1825Ops::%s] invalid DataType %u", __func__, dataTypeIdx);
     408            0 :             return HCCL_E_PARA;
     409              :         }
     410            2 :         uint32_t reduceDataType = Roce3ReduceDataTypeMap[dataTypeIdx];
     411            2 :         if (reduceDataType == DTYPE_INVALID) {
     412            0 :             HCCL_ERROR("[Rdma1825Ops::%s] DataType %u not support by inline reduce", __func__, dataTypeIdx);
     413            0 :             return HCCL_E_NOT_SUPPORT;
     414              :         }
     415              : 
     416            2 :         uint32_t reduceOpIdx = static_cast<uint32_t>(reduceOp);
     417            2 :         if (reduceOpIdx >= sizeof(Roce3ReduceOpTypeMap) / sizeof(uint32_t)) {
     418            0 :             HCCL_ERROR("[Rdma1825Ops::%s] invalid ReduceOpType %u", __func__, reduceOpIdx);
     419            0 :             return HCCL_E_PARA;
     420              :         }
     421            2 :         uint32_t reduceOpType = Roce3ReduceOpTypeMap[reduceOpIdx];
     422            2 :         if (reduceOpType == DTYPE_INVALID) {
     423            0 :             HCCL_ERROR("[Rdma1825Ops::%s] ReduceOpType %u not support by inline reduce", __func__, reduceOpIdx);
     424            0 :             return HCCL_E_NOT_SUPPORT;
     425              :         }
     426              : 
     427              :         // Reduce data
     428            2 :         uint32_t mptIndex = params.loc.GetLkey() & 0xffff;
     429            2 :         uint32_t reduceOpInfo = ((reduceOpType << ROCE_WQE_TASK_REDUCE_OP_OFFSET) | reduceDataType);
     430              : 
     431              :         // ----- Task Reduce Seg -----
     432            2 :         wqe->task.ulp = Htonl32(mptIndex | reduceOpInfo);
     433              : 
     434            2 :         return HCCL_SUCCESS;
     435              :     }
     436              : 
     437           11 :     HcclResult FillDataSeg(Roce3WqeEntry* wqe, const Roce3PostSendParams& params) const
     438              :     {
     439              :         // ----- Data Seg -----
     440           11 :         wqe->data.bufAddr = Htonll64(static_cast<uint64_t>(params.loc.GetAddr()));
     441           11 :         wqe->data.leKey = Htonl32(
     442           11 :             (params.loc.GetLkey() & (~ROCE_WQE_NEXT_SGE_INVALID)) | ROCE_WQE_NEXT_SGE_INVALID); // 当前sge就是最后一个
     443           11 :         wqe->data.rLen = Htonl32(params.loc.GetSize());
     444              : 
     445           11 :         return HCCL_SUCCESS;
     446              :     }
     447              : 
     448            0 :     CqPollStatus PollOne(std::vector<int32_t>& errList)
     449              :     {
     450            0 :         bool need_poll = true;
     451            0 :         while (need_poll) {
     452            0 :             Roce3CqeEntry* rcqe = nullptr;
     453            0 :             rcqe = Roce3GetOneCqe(cqHead_);
     454            0 :             if (rcqe == nullptr) {
     455            0 :                 return CqPollStatus::EMPTY;
     456              :             }
     457              : 
     458            0 :             ++cqHead_;
     459              : 
     460            0 :             uint32_t syndrome = static_cast<uint32_t>(rcqe->syndrome);
     461            0 :             uint32_t ownerIdQpn = static_cast<uint32_t>(rcqe->owner_id_qpn);
     462            0 :             auto cqeType
     463            0 :                 = static_cast<RoceCqeType>((rcqe->op_sr_wqebb >> ROCE_CQE_OPCODE_SHIFT) & ROCE_CQE_OPCODE_MASK);
     464              :             // 存在错误
     465            0 :             if (cqeType == RoceCqeType::ERROR) {
     466            0 :                 const uint32_t cqeErrCode = (ownerIdQpn >> 20U) & 0xfU;
     467              : 
     468            0 :                 HCCL_ERROR(
     469              :                     "[Rdma1825Ops::%s][Poll cq] CQE error, qpn[%u], syndrome[%u], cqeErrCode[%u], "
     470              :                     "wqeCounter[%u]",
     471              :                     __func__, ownerIdQpn & ROCE_CQE_QPN_MASK, syndrome, cqeErrCode,
     472              :                     static_cast<uint32_t>(rcqe->wqe_counter));
     473              : 
     474              :                 // 后续优化为具体ErrorCode
     475            0 :                 int32_t ERROR_CODE = 1;
     476            0 :                 errList.push_back(ERROR_CODE);
     477            0 :                 return CqPollStatus::ERROR;
     478              :             }
     479              : 
     480            0 :             HCCL_INFO(
     481              :                 "[Rdma1825Ops::%s][Poll cq] CQE completed, cqHead[%u], qpn[%u], syndrome[%u], "
     482              :                 "wqeCounter[%u]",
     483              :                 __func__, cqHead_, ownerIdQpn & ROCE_CQE_QPN_MASK, syndrome, static_cast<uint32_t>(rcqe->wqe_counter));
     484            0 :             need_poll = false;
     485              :         }
     486              : 
     487            0 :         return CqPollStatus::SUCCESS;
     488              :     }
     489              : 
     490            0 :     Roce3CqeEntry* Roce3GetOneCqe(uint32_t consIndex)
     491              :     {
     492            0 :         uint32_t cqeSize = 64;
     493            0 :         uint32_t cqDepthReal = cqContext_->cqDepth + ROCE_CQE_MAX_GEN_NUM; // Must be power of 2
     494            0 :         uint32_t cqeMask = cqDepthReal - 1;
     495            0 :         uint32_t cqeSlot = consIndex & cqeMask;
     496              : 
     497              :         // Calculate Cqe Addr
     498            0 :         auto cqeAddr = reinterpret_cast<Roce3CqeEntry*>(
     499            0 :             reinterpret_cast<uint8_t*>(cqContext_->cqVa) + static_cast<size_t>(cqeSlot * cqeSize));
     500              : 
     501              :         // Memcpy Cqe
     502            0 :         auto ret = memcpy_sp(&cqeReadback_, sizeof(cqeReadback_), cqeAddr, sizeof(cqeReadback_));
     503            0 :         if (UNLIKELY(ret != 0)) {
     504            0 :             THROW<InternalException>(StringFormat("[Rdma1825Ops::%s] memcpy_sp cqe failed, ret = %d", __func__, ret));
     505              :         }
     506              : 
     507              :         // Cqe Details Parse
     508            0 :         uint32_t opSrWqebb = cqeReadback_.op_sr_wqebb;
     509            0 :         uint32_t ownerIdQpn = cqeReadback_.owner_id_qpn;
     510            0 :         auto cqeType = static_cast<RoceCqeType>((opSrWqebb >> ROCE_CQE_OPCODE_SHIFT) & ROCE_CQE_OPCODE_MASK);
     511            0 :         if (cqeType == RoceCqeType::INVALID) {
     512            0 :             HCCL_INFO("[Rdma1825Ops::%s][Poll cq] CQE invalid, consIndex[%u], slot[%u]", __func__, consIndex, cqeSlot);
     513            0 :             return nullptr;
     514              :         }
     515              : 
     516              :         // Judge Owner bit
     517            0 :         uint32_t calHwOwner = static_cast<uint32_t>((consIndex & cqDepthReal) == 0);
     518            0 :         uint32_t curCqeOwner = !((ownerIdQpn & (1U << ROCE_CQE_OWNERBIT_SHIFT)) == 0);
     519            0 :         if ((calHwOwner ^ curCqeOwner) == 0) {
     520            0 :             HCCL_INFO(
     521              :                 "[Rdma1825Ops::%s][Poll cq] CQE owner not ready, consIndex[%u], slot[%u], "
     522              :                 "calHwOwner[%u], curCqeOwner[%u]",
     523              :                 __func__, consIndex, cqeSlot, calHwOwner, curCqeOwner);
     524            0 :             return nullptr;
     525              :         }
     526              : 
     527            0 :         return &cqeReadback_;
     528              :     }
     529              : 
     530              :     Roce3CqeEntry cqeReadback_{};
     531              : };
     532              : 
     533              : } // namespace Hccl
     534              : #endif // RDMA_VENDOR_1825_OPS_H
        

Generated by: LCOV version 2.0-1