Repository: PanZezhong1725/InfiniCore
Pull request #96: issur/87/feat:修改昇腾平台的handle
Author: login: bitzyz
Labels: name: 准备好了
name: 类型：重构
Created: 2025-03-10T01:50:28Z | Merged: 2025-03-17T03:22:15Z

修改昇腾平台的handle


Diff:
diff --git a/src/infiniop/devices/ascend/ascend_handle.cc b/src/infiniop/devices/ascend/ascend_handle.cc
index 1e36fc170..df1cf5513 100644
--- a/src/infiniop/devices/ascend/ascend_handle.cc
+++ b/src/infiniop/devices/ascend/ascend_handle.cc
@@ -1,15 +1,14 @@
-#include "common_ascend.h"
+#include "ascend_handle.h"
 
-infiniStatus_t createAscendHandle(infiniopAscendHandle_t *handle_ptr) {
-    int device_id = 0;
-    CHECK_ACL(aclrtGetDevice(&device_id));
+namespace device::ascend {
 
-    *handle_ptr = new InfiniopAscendHandle{INFINI_DEVICE_ASCEND, device_id};
+Handle::Handle(int device_id)
+    : InfiniopHandle{INFINI_DEVICE_ASCEND, device_id} {}
 
-    return INFINI_STATUS_SUCCESS;
-}
+infiniStatus_t Handle::create(InfiniopHandle **Handle_ptr, int device_id) {
+    *Handle_ptr = new Handle(device_id);
 
-infiniStatus_t destroyAscendHandle(infiniopAscendHandle_t handle_ptr) {
-    delete handle_ptr;
     return INFINI_STATUS_SUCCESS;
 }
+
+} // namespace device::ascend
diff --git a/src/infiniop/devices/ascend/ascend_handle.h b/src/infiniop/devices/ascend/ascend_handle.h
index f128c4e82..4cf41d599 100644
--- a/src/infiniop/devices/ascend/ascend_handle.h
+++ b/src/infiniop/devices/ascend/ascend_handle.h
@@ -2,13 +2,16 @@
 #define __INFINIOP_ASCEND_HANDLE_H__
 
 #include "../../handle.h"
-#include "infinicore.h"
 
-struct InfiniopAscendHandle;
-typedef struct InfiniopAscendHandle *infiniopAscendHandle_t;
+namespace device::ascend {
 
-infiniStatus_t createAscendHandle(infiniopAscendHandle_t *handle_ptr);
+class Handle : public InfiniopHandle {
 
-infiniStatus_t destroyAscendHandle(infiniopAscendHandle_t handle_ptr);
+    Handle(int device_id);
+
+public:
+    static infiniStatus_t create(InfiniopHandle **handle_ptr, int device_id);
+};
+} // namespace device::ascend
 
 #endif
diff --git a/src/infiniop/devices/ascend/common_ascend.cc b/src/infiniop/devices/ascend/common_ascend.cc
index 67fd18d24..736878288 100644
--- a/src/infiniop/devices/ascend/common_ascend.cc
+++ b/src/infiniop/devices/ascend/common_ascend.cc
@@ -1,19 +1,59 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   data);
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(aclDataType dtype, const std::vector<int64_t> &shape, const std::vector<int64_t> &strides, void *data) {
+    this->ndim = shape.size();
+    this->shape = shape;
+    this->strides = strides;
+    this->dataType = dtype;
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   data);
 }
 
-infiniStatus_t freeWorkspace(void *workspaceAddr) {
-    if (workspaceAddr != nullptr) {
-        CHECK_ACL(aclrtFree(workspaceAddr));
+aclnnTensorDescriptor::~aclnnTensorDescriptor() {
+    if (this->tensor) {
+        aclDestroyTensor(this->tensor);
+        this->tensor = nullptr;
     }
-    return INFINI_STATUS_SUCCESS;
 }
 
 aclDataType toAclDataType(infiniDtype_t dt) {
@@ -129,3 +169,55 @@ const char *formatToString(aclFormat format) {
         return "UNKNOWN";
     }
 }
+
+std::string aclnnTensorDescriptor::toString() {
+    std::ostringstream oss;
+
+    // 写入 ndim
+    oss << "ndim: " << this->ndim << "\n";
+
+    // 写入 shape
+    oss << "shape: [";
+    for (uint64_t i = 0; i < this->ndim; ++i) {
+        oss << this->shape[i];
+        if (i < this->ndim - 1) {
+            oss << ", ";
+        }
+    }
+    oss << "]\n";
+
+    // 写入 stride
+    oss << "stride: [";
+    for (uint64_t i = 0; i < this->ndim; ++i) {
+        oss << this->strides[i];
+        if (i < this->ndim - 1) {
+            oss << ", ";
+        }
+    }
+    oss << "]\n";
+
+    // 写入 offset
+    oss << "offset: " << this->offset << "\n";
+
+    // 写入 dataType
+    oss << "dataType: " << dataTypeToString(this->dataType) << "\n";
+
+    // 写入 format
+    oss << "format: " << formatToString(this->format) << "\n";
+
+    // 写入 storageShape
+    oss << "storageShape: [";
+    for (int64_t i = 0; i < this->storageNdim; ++i) {
+        oss << this->storageShape[i];
+        if (i < this->storageNdim - 1) {
+            oss << ", ";
+        }
+    }
+    oss << "]\n";
+
+    // 写入 storageNdim
+    oss << "storageNdim: " << this->storageNdim << "\n";
+
+    // 返回构建的字符串
+    return oss.str();
+}
diff --git a/src/infiniop/devices/ascend/common_ascend.h b/src/infiniop/devices/ascend/common_ascend.h
index af735562a..da11a0869 100644
--- a/src/infiniop/devices/ascend/common_ascend.h
+++ b/src/infiniop/devices/ascend/common_ascend.h
@@ -2,6 +2,7 @@
 #define __INFINIOP_COMMON_ASCEND_H__
 
 #include "../../../utils.h"
+#include "../../tensor.h"
 #include "ascend_handle.h"
 #include <acl/acl.h>
 #include <acl/acl_base.h>
@@ -11,6 +12,7 @@
 #include <functional>
 #include <inttypes.h>
 #include <numeric>
+#include <sstream>
 #include <vector>
 
 #ifdef __cplusplus
@@ -21,15 +23,34 @@ extern "C" {
 };
 #endif
 
-struct InfiniopAscendHandle {
-    infiniDevice_t device;
-    int device_id;
+struct aclnnTensorDescriptor {
+    uint64_t ndim;
+    std::vector<int64_t> shape;
+    std::vector<int64_t> strides;
+    int64_t offset = 0;
+    aclDataType dataType;
+    aclFormat format;
+    std::vector<int64_t> storageShape;
+    int64_t storageNdim = 1;
+    aclTensor *tensor;
+
+    // aclnnGemmGetWorkspaceSize only support 2D matrix multiply, so we need to convert 3D tensor to 2D tensor
+    aclnnTensorDescriptor(aclDataType dtype, const std::vector<int64_t> &shape, const std::vector<int64_t> &strides, void *data = nullptr);
+    aclnnTensorDescriptor(infiniopTensorDescriptor_t y_desc, void *data = nullptr);
+    ~aclnnTensorDescriptor();
+
+    std::string toString();
 };
+typedef aclnnTensorDescriptor *aclnnTensorDescriptor_t;
 
-const char *dataTypeToString(aclDataType dtype);
-const char *formatToString(aclFormat format);
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize);
-infiniStatus_t freeWorkspace(void *workspaceAddr);
 aclDataType toAclDataType(infiniDtype_t dt);
 
+#define GetRecentErrMsg()                                   \
+    {                                                       \
+        auto tmp_err_msg = aclGetRecentErrMsg();            \
+        if (tmp_err_msg != NULL) {                          \
+            printf(" ERROR Message : %s \n ", tmp_err_msg); \
+        }                                                   \
+    }
+
 #endif
diff --git a/src/infiniop/devices/ascend/tensor_aclnn.cc b/src/infiniop/devices/ascend/tensor_aclnn.cc
deleted file mode 100644
index 56762d9a0..000000000
--- a/src/infiniop/devices/ascend/tensor_aclnn.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "tensor_aclnn.h"
-#include "../../../utils.h"
-#include "../../tensor.h"
-#include <algorithm>
-
-infiniStatus_t aclnnTensorDescriptor::setDescriptor(aclDataType dtype, const std::vector<int64_t> &shape, const std::vector<int64_t> &strides) {
-    if (shape.size() != strides.size()) {
-        return INFINI_STATUS_BAD_TENSOR_STRIDES;
-    }
-    this->ndim = shape.size();
-    this->shape = std::vector<int64_t>(shape);
-    this->strides = std::vector<int64_t>(strides);
-    this->dataType = dtype;
-
-    // Set format
-    // TODO: Support other format
-    aclFormat format = aclFormat::ACL_FORMAT_ND;
-    this->format = format;
-
-    CHECK_STATUS(this->inferStorageShape());
-
-    return INFINI_STATUS_SUCCESS;
-}
-
-/// @brief Infer storage shape. For now this ruturns a 1D shape of the total tensor storage size.
-/// We don't see why higher dimensional storage shape is ever needed. To change if necesary.
-infiniStatus_t aclnnTensorDescriptor::inferStorageShape() {
-    auto index = std::max_element(this->strides.begin(), this->strides.end());
-    uint64_t max_stride_index = std::distance(this->strides.begin(), index);
-    this->storageNdim = 1;
-    this->storageShape = std::vector<int64_t>({this->shape[max_stride_index] * this->strides[max_stride_index]});
-
-    return INFINI_STATUS_SUCCESS;
-}
-
-/// @brief Set aclnnTensorDescriptor from infiniopTensorDescriptor
-/// @param y infiniopTensorDescriptor
-/// @return infiniopStatus_t
-infiniStatus_t aclnnTensorDescriptor::fromInfiniOpTensorDescriptor(infiniopTensorDescriptor_t y) {
-    uint64_t ndim = y->ndim();
-    // Cast shape type
-    auto shape = std::vector<int64_t>(ndim);
-    auto strides = std::vector<int64_t>(ndim);
-    for (uint64_t i = 0; i < ndim; ++i) {
-        shape[i] = static_cast<int64_t>(y->dim(i));
-        strides[i] = y->stride(i);
-    }
-    return setDescriptor(toAclDataType(y->dtype()), shape, strides);
-}
-
-/// @brief Wrapper of aclCreateTensor. Create aclTensor.
-/// See https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/80RC3alpha001/apiref/appdevgapi/aclcppdevg_03_0168.html
-/// @param desc Alias of aclnnTensorDescriptor*.
-/// @param data Data ptr on device global mem.
-/// @param tensor Pointer of pointer of aclTensor.
-/// @return
-infiniStatus_t aclnnTensorDescriptor::createTensor(void *data) {
-    if (this->t) {
-        return INFINI_STATUS_SUCCESS;
-    }
-    this->t = aclCreateTensor(this->shape.data(),
-                              this->ndim,
-                              this->dataType,
-                              this->strides.data(),
-                              this->offset,
-                              this->format,
-                              this->storageShape.data(),
-                              this->storageNdim,
-                              data);
-    return INFINI_STATUS_SUCCESS;
-}
-
-infiniStatus_t aclnnTensorDescriptor::destroyTensor() {
-    CHECK_ACL(aclDestroyTensor(this->t));
-    t = nullptr;
-
-    return INFINI_STATUS_SUCCESS;
-}
-
-aclnnTensorDescriptor::~aclnnTensorDescriptor() {
-    if (this->t) {
-        destroyTensor();
-    }
-}
-
-/// @brief TensorDescriptor's string info
-/// @param desc Alias of aclnnTensorDescriptor*.
-/// @return String of aclnnTensorDescriptor.
-char *aclnnTensorDescriptor::toString() {
-
-    // Assume bufferSize
-    size_t bufferSize = 1024 + this->ndim * 40 + this->storageNdim * 40;
-    char *buffer = (char *)malloc(bufferSize);
-    if (!buffer) {
-        return NULL;
-    }
-
-    // Write info into buffer
-    char *ptr = buffer;
-    ptr += sprintf(ptr, "ndim: %" PRId64 "\n", this->ndim);
-
-    ptr += sprintf(ptr, "shape: [");
-    for (uint64_t i = 0; i < this->ndim; ++i) {
-        ptr += sprintf(ptr, "%" PRId64, this->shape[i]);
-        if (i < this->ndim - 1) {
-            ptr += sprintf(ptr, ", ");
-        }
-    }
-    ptr += sprintf(ptr, "]\n");
-
-    ptr += sprintf(ptr, "stride: [");
-    for (uint64_t i = 0; i < this->ndim; ++i) {
-        ptr += sprintf(ptr, "%" PRId64, this->strides[i]);
-        if (i < this->ndim - 1) {
-            ptr += sprintf(ptr, ", ");
-        }
-    }
-    ptr += sprintf(ptr, "]\n");
-
-    ptr += sprintf(ptr, "offset: %" PRId64 "\n", this->offset);
-    ptr += sprintf(ptr, "dataType: %s\n", dataTypeToString(this->dataType));
-    ptr += sprintf(ptr, "format: %s\n", formatToString(this->format));
-
-    ptr += sprintf(ptr, "storageShape: [");
-    for (int64_t i = 0; i < this->storageNdim; ++i) {
-        ptr += sprintf(ptr, "%" PRId64, this->storageShape[i]);
-        if (i < this->storageNdim - 1) {
-            ptr += sprintf(ptr, ", ");
-        }
-    }
-    ptr += sprintf(ptr, "]\n");
-
-    ptr += sprintf(ptr, "storageNdim: %" PRId64 "\n", this->storageNdim);
-
-    return buffer;
-}
diff --git a/src/infiniop/devices/ascend/tensor_aclnn.h b/src/infiniop/devices/ascend/tensor_aclnn.h
deleted file mode 100644
index d84586be8..000000000
--- a/src/infiniop/devices/ascend/tensor_aclnn.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __ACLNN_TENSOR__
-#define __ACLNN_TENSOR__
-
-#include "../../operator.h"
-#include "common_ascend.h"
-#include <acl/acl.h>
-#include <acl/acl_base.h>
-#include <aclnn/acl_meta.h>
-#include <vector>
-
-// Aclnn tensor descriptor,
-// used to build aclTensor
-struct aclnnTensorDescriptor {
-    uint64_t ndim;
-    std::vector<int64_t> shape;
-    std::vector<int64_t> strides;
-    int64_t offset;
-    aclDataType dataType;
-    aclFormat format;
-    std::vector<int64_t> storageShape;
-    int64_t storageNdim;
-
-    aclTensor *t;
-
-    // Transfer from infiniOp DT to aclDataType
-    infiniStatus_t setDescriptor(aclDataType dtype, const std::vector<int64_t> &shape, const std::vector<int64_t> &strides);
-    infiniStatus_t inferStorageShape();
-    // Convert form InfiniOpTensorDescriptor
-    infiniStatus_t fromInfiniOpTensorDescriptor(infiniopTensorDescriptor_t y_desc);
-    infiniStatus_t createTensor(void *data = nullptr);
-    infiniStatus_t destroyTensor();
-    ~aclnnTensorDescriptor();
-
-    char *toString();
-};
-
-typedef aclnnTensorDescriptor *aclnnTensorDescriptor_t;
-
-#endif
diff --git a/src/infiniop/devices/handle.cc b/src/infiniop/devices/handle.cc
index b836ce24a..2359804d1 100644
--- a/src/infiniop/devices/handle.cc
+++ b/src/infiniop/devices/handle.cc
@@ -45,9 +45,7 @@ __C infiniStatus_t infiniopCreateHandle(infiniopHandle_t *handle_ptr) {
         CREATE(INFINI_DEVICE_CAMBRICON, bang::cambricon);
 #endif
 #ifdef ENABLE_ASCEND_API
-    case INFINI_DEVICE_ASCEND: {
-        return createAscendHandle((infiniopAscendHandle_t *)handle_ptr);
-    }
+        CREATE(INFINI_DEVICE_ASCEND, ascend);
 #endif
 #ifdef ENABLE_KUNLUN_API
     case INFINI_DEVICE_KUNLUN: {
@@ -83,9 +81,7 @@ __C infiniStatus_t infiniopDestroyHandle(infiniopHandle_t handle) {
         DELETE(INFINI_DEVICE_CAMBRICON, bang::cambricon);
 #endif
 #ifdef ENABLE_ASCEND_API
-    case INFINI_DEVICE_ASCEND: {
-        return destroyAscendHandle((infiniopAscendHandle_t)handle);
-    }
+        DELETE(INFINI_DEVICE_ASCEND, ascend);
 #endif
 #ifdef ENABLE_KUNLUN_API
     case INFINI_DEVICE_KUNLUN: {
diff --git a/src/infiniop/ops/matmul/ascend/matmul_ascend.cc b/src/infiniop/ops/matmul/ascend/matmul_ascend.cc
index 0d8a1d7bf..79158b548 100644
--- a/src/infiniop/ops/matmul/ascend/matmul_ascend.cc
+++ b/src/infiniop/ops/matmul/ascend/matmul_ascend.cc
@@ -1,8 +1,5 @@
 #include "matmul_ascend.h"
-#include "../../../devices/ascend/ascend_handle.h"
-#include "../../../devices/ascend/tensor_aclnn.h"
-#include <acl/acl_base.h>
-#include <aclnn/acl_meta.h>
+#include "../../../devices/ascend/common_ascend.h"
 #include <aclnnop/aclnn_matmul.h>
 #include <aclnnop/level2/aclnn_gemm.h>
 
@@ -34,7 +31,7 @@ infiniStatus_t Descriptor::create(
     infiniopTensorDescriptor_t c_desc,
     infiniopTensorDescriptor_t a_desc,
     infiniopTensorDescriptor_t b_desc) {
-    auto handle = reinterpret_cast<infiniopAscendHandle_t>(handle_);
+    auto handle = reinterpret_cast<device::ascend::Handle *>(handle_);
     auto dtype = c_desc->dtype();
 
     if (dtype != INFINI_DTYPE_F16 && dtype != INFINI_DTYPE_F32) {
@@ -47,35 +44,20 @@ infiniStatus_t Descriptor::create(
         return status;
     }
 
-    auto c = new aclnnTensorDescriptor(),
-         a = new aclnnTensorDescriptor(),
-         b = new aclnnTensorDescriptor();
-
-    // Treat A, B, C as 2D matrix, reuse aclnnTensorDescriptor for batched
-    // operation
-    CHECK_STATUS(c->setDescriptor(
-        toAclDataType(c_desc->dtype()),
-        {static_cast<int64_t>(info.c_matrix.rows),
-         static_cast<int64_t>(info.c_matrix.cols)},
-        {info.c_matrix.row_stride, info.c_matrix.col_stride}));
-    CHECK_STATUS(a->setDescriptor(
-        toAclDataType(a_desc->dtype()),
-        {static_cast<int64_t>(info.a_matrix.rows),
-         static_cast<int64_t>(info.a_matrix.cols)},
-        {info.a_matrix.row_stride, info.a_matrix.col_stride}));
-    CHECK_STATUS(b->setDescriptor(
-        toAclDataType(b_desc->dtype()),
-        {static_cast<int64_t>(info.b_matrix.rows),
-         static_cast<int64_t>(info.b_matrix.cols)},
-        {info.b_matrix.row_stride, info.b_matrix.col_stride}));
-
-    CHECK_STATUS(c->createTensor());
-    CHECK_STATUS(a->createTensor());
-    CHECK_STATUS(b->createTensor());
-
-    auto tc = c->t,
-         ta = a->t,
-         tb = b->t;
+    auto c = new aclnnTensorDescriptor(toAclDataType(c_desc->dtype()),
+                                       {static_cast<int64_t>(info.c_matrix.rows), static_cast<int64_t>(info.c_matrix.cols)},
+                                       {info.c_matrix.row_stride, info.c_matrix.col_stride});
+    auto a = new aclnnTensorDescriptor(toAclDataType(a_desc->dtype()),
+                                       {static_cast<int64_t>(info.a_matrix.rows), static_cast<int64_t>(info.a_matrix.cols)},
+                                       {info.a_matrix.row_stride, info.a_matrix.col_stride});
+    auto b = new aclnnTensorDescriptor(toAclDataType(b_desc->dtype()),
+                                       {static_cast<int64_t>(info.b_matrix.rows), static_cast<int64_t>(info.b_matrix.cols)},
+                                       {info.b_matrix.row_stride, info.b_matrix.col_stride});
+
+    auto tc = c->tensor,
+         ta = a->tensor,
+         tb = b->tensor;
+
     aclOpExecutor *executor;
     size_t workspace_size;
     // aclnnGemm support C = alpha * A @ B + beta * C
@@ -85,7 +67,6 @@ infiniStatus_t Descriptor::create(
 
     int8_t mt = 1;
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
-    aclSetAclOpExecutorRepeatable(executor);
 
     *desc_ptr = new Descriptor(
         dtype, info, workspace_size,
@@ -110,9 +91,9 @@ infiniStatus_t Descriptor::calculate(
     float alpha,
     void *stream) const {
 
-    auto tc = _opaque->c->t,
-         ta = _opaque->a->t,
-         tb = _opaque->b->t;
+    auto tc = _opaque->c->tensor,
+         ta = _opaque->a->tensor,
+         tb = _opaque->b->tensor;
 
     size_t workspace_size;
     CHECK_ACL(aclnnGemmGetWorkspaceSize(


Reviews:
user: login: PanZezhong1725
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-10T03:17:09Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-11T07:48:25Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-11T07:48:31Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-11T07:48:35Z
user: login: PanZezhong1725
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-11T09:14:42Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-11T09:24:37Z
user: login: PanZezhong1725
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-11T11:00:48Z
user: login: zhangyue207
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:09:12Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:16:36Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:18:36Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:18:51Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:19:38Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:19:46Z
user: login: zhangyue207
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:19:59Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:20:36Z
user: login: zhangyue207
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:20:47Z
user: login: zhangyue207
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:22:29Z
user: login: zhangyue207
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T09:23:32Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:18:18Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:18:24Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:18:30Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:18:36Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:18:42Z
user: login: bitzyz
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:18:49Z
user: login: zhangyue207
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:20:37Z
user: login: zhangyue207
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T10:20:59Z
user: login: zhangyue207
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-17T01:56:26Z
user: login: zhangyue207
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-17T01:57:33Z

Review comments:
diff_hunk: @@ -1,15 +1,12 @@
-#include "common_ascend.h"
+#include "ascend_handle.h"
 
-infiniStatus_t createAscendHandle(infiniopAscendHandle_t *handle_ptr) {
-    int device_id = 0;
-    CHECK_ACL(aclrtGetDevice(&device_id));
+namespace device::ascend {
 
-    *handle_ptr = new InfiniopAscendHandle{INFINI_DEVICE_ASCEND, device_id};
+Handle::Handle() : InfiniopHandle{INFINI_DEVICE_ASCEND, 0} {}
path: src/infiniop/devices/ascend/ascend_handle.cc
user: login: PanZezhong1725
body: 需要用infinirtGetDevice拿到当前设备号
created_at: 2025-03-10T03:05:25Z
author_association: COLLABORATOR
diff_hunk: @@ -21,11 +20,6 @@ extern "C" {
 };
 #endif
 
-struct InfiniopAscendHandle {
-    infiniDevice_t device;
-    int device_id;
-};
-
 const char *dataTypeToString(aclDataType dtype);
path: src/infiniop/devices/ascend/common_ascend.h
user: login: PanZezhong1725
body: 这几个接口只保留toAclDataType，其他删掉。
created_at: 2025-03-10T03:14:54Z
author_association: COLLABORATOR
diff_hunk: @@ -2,7 +2,6 @@
 #define __INFINIOP_COMMON_ASCEND_H__
 
 #include "../../../utils.h"
path: src/infiniop/devices/ascend/common_ascend.h
user: login: PanZezhong1725
body: acl Tensor的重构呢？对外只保留创建aclTensor的接口，接口通过common_ascend.h 透出去。
created_at: 2025-03-10T03:17:05Z
author_association: COLLABORATOR
diff_hunk: @@ -2,7 +2,6 @@
 #define __INFINIOP_COMMON_ASCEND_H__
 
 #include "../../../utils.h"
path: src/infiniop/devices/ascend/common_ascend.h
user: login: bitzyz
body: 修复
created_at: 2025-03-11T07:48:25Z
author_association: COLLABORATOR
diff_hunk: @@ -21,11 +20,6 @@ extern "C" {
 };
 #endif
 
-struct InfiniopAscendHandle {
-    infiniDevice_t device;
-    int device_id;
-};
-
 const char *dataTypeToString(aclDataType dtype);
path: src/infiniop/devices/ascend/common_ascend.h
user: login: bitzyz
body: 修复
created_at: 2025-03-11T07:48:31Z
author_association: COLLABORATOR
diff_hunk: @@ -1,15 +1,12 @@
-#include "common_ascend.h"
+#include "ascend_handle.h"
 
-infiniStatus_t createAscendHandle(infiniopAscendHandle_t *handle_ptr) {
-    int device_id = 0;
-    CHECK_ACL(aclrtGetDevice(&device_id));
+namespace device::ascend {
 
-    *handle_ptr = new InfiniopAscendHandle{INFINI_DEVICE_ASCEND, device_id};
+Handle::Handle() : InfiniopHandle{INFINI_DEVICE_ASCEND, 0} {}
path: src/infiniop/devices/ascend/ascend_handle.cc
user: login: bitzyz
body: 修复
created_at: 2025-03-11T07:48:35Z
author_association: COLLABORATOR
diff_hunk: @@ -129,3 +172,52 @@ const char *formatToString(aclFormat format) {
         return "UNKNOWN";
     }
 }
+
+char *aclnnTensorDescriptor::toString() {
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: PanZezhong1725
body: 请用std string， 可配合ostringstream
created_at: 2025-03-11T09:11:52Z
author_association: COLLABORATOR
diff_hunk: @@ -129,3 +172,52 @@ const char *formatToString(aclFormat format) {
         return "UNKNOWN";
     }
 }
+
+char *aclnnTensorDescriptor::toString() {
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: bitzyz
body: 已修改
created_at: 2025-03-11T09:24:37Z
author_association: COLLABORATOR
diff_hunk: @@ -21,15 +23,35 @@ extern "C" {
 };
 #endif
 
-struct InfiniopAscendHandle {
-    infiniDevice_t device;
-    int device_id;
+struct aclnnTensorDescriptor {
+    uint64_t ndim;
+    std::vector<int64_t> shape;
+    std::vector<int64_t> strides;
+    int64_t offset = 0;
+    aclDataType dataType;
+    aclFormat format;
+    std::vector<int64_t> storageShape;
+    int64_t storageNdim = 1;
+    void *data = nullptr;
+    aclTensor *tensor;
+
+    // aclnnGemmGetWorkspaceSize only support 2D matrix multiply, so we need to convert 3D tensor to 2D tensor
path: src/infiniop/devices/ascend/common_ascend.h
user: login: zhangyue207
body: 这个接口的存在目的并不只是为 gemm 服务的，其他算子也有需要set Descriptor 的情况，删掉注释就可以
created_at: 2025-03-12T08:45:31Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,62 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data_) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    if (!data_) {
+        this->data = data_;
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: zhangyue207
body: 这里 data_ 是空指针的情况一样可以传给 aclCreateTensor 接口，没必要做判断
created_at: 2025-03-12T08:48:24Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,62 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data_) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    if (!data_) {
+        this->data = data_;
+    }
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   this->data);
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: zhangyue207
body: 这里的 data 没有赋值，直接传入 aclCreateTensor 有风险，在最外面接口应该保留 一个 data_
created_at: 2025-03-12T08:50:47Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: zhangyue207
body: 这个会掉性能，只有debug 的时候才用
created_at: 2025-03-12T09:01:55Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: zhangyue207
body: 为什么要重复调用两次 aclnnGemmGetWorkspaceSize 这个接口
created_at: 2025-03-12T09:03:23Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
     aclSetAclOpExecutorRepeatable(executor);
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: zhangyue207
body: 这个可以删去，我看到 calculate 的时候调过了
created_at: 2025-03-12T09:05:01Z
author_association: COLLABORATOR
diff_hunk: @@ -21,15 +23,35 @@ extern "C" {
 };
 #endif
 
-struct InfiniopAscendHandle {
-    infiniDevice_t device;
-    int device_id;
+struct aclnnTensorDescriptor {
+    uint64_t ndim;
+    std::vector<int64_t> shape;
+    std::vector<int64_t> strides;
+    int64_t offset = 0;
+    aclDataType dataType;
+    aclFormat format;
+    std::vector<int64_t> storageShape;
+    int64_t storageNdim = 1;
+    void *data = nullptr;
+    aclTensor *tensor;
+
+    // aclnnGemmGetWorkspaceSize only support 2D matrix multiply, so we need to convert 3D tensor to 2D tensor
path: src/infiniop/devices/ascend/common_ascend.h
user: login: bitzyz
body: 后续还会有哪些算子会用到呢，我理解是其他算子大部分用的还是从infiniopTensorDescriptor_t做转换就可以了啊
created_at: 2025-03-12T09:16:36Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,62 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data_) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    if (!data_) {
+        this->data = data_;
+    }
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   this->data);
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: bitzyz
body: this->data在类声明里有做初始化nullptr
created_at: 2025-03-12T09:18:36Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: bitzyz
body: 这个当时忘了删了，我删一下
created_at: 2025-03-12T09:18:51Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: bitzyz
body: 这个不是因为昇腾的gemm在计算workspace的时候需要alpha和beta，但是create的时候没有alpha和beta吗
created_at: 2025-03-12T09:19:38Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
     aclSetAclOpExecutorRepeatable(executor);
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: bitzyz
body: 解释同上
created_at: 2025-03-12T09:19:46Z
author_association: COLLABORATOR
diff_hunk: @@ -21,15 +23,35 @@ extern "C" {
 };
 #endif
 
-struct InfiniopAscendHandle {
-    infiniDevice_t device;
-    int device_id;
+struct aclnnTensorDescriptor {
+    uint64_t ndim;
+    std::vector<int64_t> shape;
+    std::vector<int64_t> strides;
+    int64_t offset = 0;
+    aclDataType dataType;
+    aclFormat format;
+    std::vector<int64_t> storageShape;
+    int64_t storageNdim = 1;
+    void *data = nullptr;
+    aclTensor *tensor;
+
+    // aclnnGemmGetWorkspaceSize only support 2D matrix multiply, so we need to convert 3D tensor to 2D tensor
path: src/infiniop/devices/ascend/common_ascend.h
user: login: zhangyue207
body: 有些昇腾接口不能直接满足的时候，需要额外构建 aclTensor 就会用到
created_at: 2025-03-12T09:19:59Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,62 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data_) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    if (!data_) {
+        this->data = data_;
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: bitzyz
body: 这里我其实的想法是当它不为空的时候在aclnnTensorDescriptor这里存一份
created_at: 2025-03-12T09:20:36Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,62 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data_) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    if (!data_) {
+        this->data = data_;
+    }
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   this->data);
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: zhangyue207
body: 不行啊，那只能默认是 nullptr ，如果需要传入非nullptr 的时候怎么办
created_at: 2025-03-12T09:20:47Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: zhangyue207
body: 我说的重复是在 create 函数里连续调了两次，参数一样
created_at: 2025-03-12T09:22:29Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
     aclSetAclOpExecutorRepeatable(executor);
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: zhangyue207
body:  aclSetAclOpExecutorRepeatable 这个接口的意思是让 aclTensor 中的数据指针可以重新被赋值，所以调用一次就可以了

created_at: 2025-03-12T09:23:32Z
author_association: COLLABORATOR
diff_hunk: @@ -21,15 +23,35 @@ extern "C" {
 };
 #endif
 
-struct InfiniopAscendHandle {
-    infiniDevice_t device;
-    int device_id;
+struct aclnnTensorDescriptor {
+    uint64_t ndim;
+    std::vector<int64_t> shape;
+    std::vector<int64_t> strides;
+    int64_t offset = 0;
+    aclDataType dataType;
+    aclFormat format;
+    std::vector<int64_t> storageShape;
+    int64_t storageNdim = 1;
+    void *data = nullptr;
+    aclTensor *tensor;
+
+    // aclnnGemmGetWorkspaceSize only support 2D matrix multiply, so we need to convert 3D tensor to 2D tensor
path: src/infiniop/devices/ascend/common_ascend.h
user: login: bitzyz
body: 修复
created_at: 2025-03-12T10:18:17Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,62 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data_) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    if (!data_) {
+        this->data = data_;
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: bitzyz
body: 修复
created_at: 2025-03-12T10:18:24Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,62 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data_) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    if (!data_) {
+        this->data = data_;
+    }
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   this->data);
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: bitzyz
body: 修复
created_at: 2025-03-12T10:18:30Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: bitzyz
body: 修复
created_at: 2025-03-12T10:18:36Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: bitzyz
body: 修复
created_at: 2025-03-12T10:18:42Z
author_association: COLLABORATOR
diff_hunk: @@ -84,6 +66,13 @@ infiniStatus_t Descriptor::create(
     // use alpha = 0.5, beta = 0.5 temporarily
 
     int8_t mt = 1;
+    aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor);
+    auto msg = aclGetRecentErrMsg();
+    if (msg != nullptr) {
+        printf("aclnnGemmGetWorkspaceSize error: %s\n", msg);
+        return INFINI_STATUS_INTERNAL_ERROR;
+    }
+
     CHECK_ACL(aclnnGemmGetWorkspaceSize(ta, tb, tc, .5, .5, 0, 0, tc, mt, &workspace_size, &executor));
     aclSetAclOpExecutorRepeatable(executor);
path: src/infiniop/ops/matmul/ascend/matmul_ascend.cc
user: login: bitzyz
body: 修复
created_at: 2025-03-12T10:18:49Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,59 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   data);
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(aclDataType dtype, const std::vector<int64_t> &shape, const std::vector<int64_t> &strides, void *data) {
+    this->ndim = shape.size();
+    this->shape = shape;
+    this->strides = strides;
+    this->dataType = dtype;
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   data);
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: zhangyue207
body: self.data 也要赋值 这里的data，不一致可能会在下一次构建aclTensor的时候有问题
created_at: 2025-03-12T10:20:36Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,59 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   data);
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(aclDataType dtype, const std::vector<int64_t> &shape, const std::vector<int64_t> &strides, void *data) {
+    this->ndim = shape.size();
+    this->shape = shape;
+    this->strides = strides;
+    this->dataType = dtype;
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   data);
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: zhangyue207
body: 说错了，this->data
created_at: 2025-03-12T10:20:52Z
author_association: COLLABORATOR
diff_hunk: @@ -1,19 +1,59 @@
 #include "common_ascend.h"
 
-infiniStatus_t mallocWorkspace(void **workspaceAddr, size_t workspaceSize) {
-    *workspaceAddr = nullptr;
-    if (workspaceSize > 0) {
-        CHECK_ACL(aclrtMalloc(workspaceAddr, workspaceSize,
-                              ACL_MEM_MALLOC_HUGE_FIRST));
+std::vector<int64_t> inferStorageShape(std::vector<int64_t> shape, std::vector<int64_t> strides) {
+    auto index = std::max_element(strides.begin(), strides.end());
+    uint64_t max_stride_index = std::distance(strides.begin(), index);
+    auto storageShape = std::vector<int64_t>({shape[max_stride_index] * strides[max_stride_index]});
+
+    return storageShape;
+}
+
+aclnnTensorDescriptor::aclnnTensorDescriptor(infiniopTensorDescriptor_t desc, void *data) {
+    this->ndim = desc->ndim();
+    this->shape = std::vector<int64_t>(ndim);
+    this->strides = std::vector<int64_t>(ndim);
+    for (uint64_t i = 0; i < ndim; ++i) {
+        this->shape[i] = static_cast<int64_t>(desc->dim(i));
+        this->strides[i] = desc->stride(i);
     }
-    return INFINI_STATUS_SUCCESS;
+    this->storageShape = inferStorageShape(this->shape, this->strides);
+    this->dataType = toAclDataType(desc->dtype());
+    // TODO: support other formats
+    this->format = aclFormat::ACL_FORMAT_ND;
+    this->tensor = aclCreateTensor(this->shape.data(),
+                                   this->ndim,
+                                   this->dataType,
+                                   this->strides.data(),
+                                   this->offset,
+                                   this->format,
+                                   this->storageShape.data(),
+                                   this->storageNdim,
+                                   data);
path: src/infiniop/devices/ascend/common_ascend.cc
user: login: zhangyue207
body: 这里也是 this->data 没有被赋值
created_at: 2025-03-17T01:56:26Z
author_association: COLLABORATOR

PR comments:
user: login: bitzyz
created_at: 2025-03-10T01:55:03Z
body: ![image](https://github.com/user-attachments/assets/2d7ffa4e-7d68-4e6c-bb03-39064ce1888b)

author_association: COLLABORATOR
user: login: bitzyz
created_at: 2025-03-11T07:48:17Z
body: 1. 将tensor_aclnn文件中的aclnnTensorDescriptor挪到common_ascend文件中，并设定两种构造方式：

> 传入infiniopTensorDescriptor_t构建
> 传入shape和stride构建 （主要用于MatMul）

2. 添加debug相关内容，便于查看昇腾报错信息 
author_association: COLLABORATOR