当前位置: 首页 > news >正文

CANN/sip批量复数矩阵求逆

CmatinvBatched

【免费下载链接】sip本项目是CANN提供的一款高效、可靠的高性能信号处理算子加速库,基于华为Ascend AI处理器,专门为信号处理领域而设计。项目地址: https://gitcode.com/cann/sip

产品支持情况

产品是否支持
Atlas 200I/500 A2 推理产品×
Atlas 推理系列产品×
Atlas 训练系列产品×
Atlas A3 训练系列产品/Atlas A3 推理系列产品
Atlas A2 训练系列产品/Atlas A2 推理系列产品
Ascend 950PR/Ascend 950DT×

功能说明

  • 接口功能:
    asdBlasMakeCmatinvBatchedPlan:初始化该句柄对应的算子配置
    asdBlasCmatinvBatched:对复数矩阵进行求逆。

  • 计算公式:
    计算批量复数矩阵的逆矩阵,每个复数矩阵需满足条件$A^{-1}A=I$,其中A为非奇异方阵,且A是一个n*n的输入方阵,I为单位矩阵。

    示例:
    输入“A”为:
    [2-2i ,1-i ,1-i, 1-i
    1-i, 2-2i, 1-i ,1-i
    1-i, 1-i ,2-2i ,1-i
    1-i ,1-i, 1-i, 2-2i]\

    [3-3i ,1-i, 1-i, 1-i
    1-i, 3-3i, 1-i ,1-i
    1-i, 1-i ,3-3i ,1-i
    1-i, 1-i, 1-i, 3-3i]
    输入“n”为: 4
    输入“batchSize”为:2
    调用“asdBlasCmatinvBatched”算子后,
    输出“Ainv”为:
    [0.4+0.4i, -0.1-0.1i,-0.1-0.1i ,-0.1-0.1i
    -0.1-0.1i ,0.4+0.4i ,-0.1-0.1i ,-0.1-0.1i
    -0.1-0.1i ,-0.1-0.1i,0.4+0.4i ,-0.1-0.1i
    -0.1-0.1i ,-0.1-0.1i,-0.1-0.1i,0.4+0.4i]

    [0.208+0.208i,-0.0417-0.0417i,-0.0417-0.0417i,-0.0417-0.0417i
    -0.0417-0.0417i,0.208+0.208i,-0.0417-0.0417i,-0.0417-0.0417i
    -0.0417-0.0417i,-0.0417-0.0417i,0.208+0.208i,-0.0417-0.0417i
    -0.0417-0.0417i,-0.0417-0.0417i,-0.0417-0.0417i,0.208+0.208i]

函数原型

AspbStatus asdBlasMakeCmatinvBatchedPlan( asdBlasHandle handle, const int64_t n, const int64_t batchSize)
AspbStatus asdBlasCmatinvBatched( asdBlasHandle handle, const int64_t n, aclTensor * A, const int64_t lda, aclTensor * Ainv, const int64_t lda_inv, aclTensor * info, int64_t batchSize)

asdBlasMakeCmatinvBatchedPlan

  • 参数说明:

    参数名输入/输出描述
    handle(asdBlasHandle)输入算子的句柄
    n(int64_t)输入单批次矩阵A的行数。
    batchSize(int64_t)输入复数矩阵求逆中的矩阵数量。
  • 返回值

    返回状态码,具体参见SiP返回码。

asdBlasCmatinvBatched

  • 参数说明:

    参数名输入/输出描述
    handle(asdBlasHandle)输入算子的句柄
    n(int64_t)输入单批次矩阵A的行数。
    A(aclTensor *)输入
    • 输入的矩阵,对应公式中的'A'。
    • 行主序。
    • 数据类型支持COMPLEX64。
    • 数据格式支持ND。
    • shape为[batchCount ,m, n]。
    lda( int64_t)输入A左右相邻元素间的内存地址偏移量(当前约束为n)。
    Ainv(aclTensor *)输出
    • 输出的逆矩阵。
    • 数据类型支持COMPLEX64。
    • 数据格式支持ND。
    • shape为[batch, n, n]。
    lda_inv(int64_t)输入输出的逆矩阵的左右相邻元素间的内存地址偏移量(当前约束为n)。
    info(aclTensor *)输入
    • 每个batch矩阵的求逆结果信息。
    • 数据类型支持int32_t。
    • 数据格式支持ND。
    • shape为[batch, 1]。
    batchSize(int64_t)输入复数矩阵求逆中的矩阵数量。
  • 返回值

    返回状态码,具体参见SiP返回码。

约束说明

  • lda、lda_inv、info参数在当前版本实际未启用。
  • 输入参数n小于等于256。
  • 输入参数batchSize小于等于3000。

调用示例

示例代码如下,该样例旨在提供快速上手、开发和调试算子的最小化实现,其核心目标是使用最精简的代码展示算子的核心功能,而非提供生产级的安全保障。不推荐用户直接将示例代码作为业务代码,若用户将示例代码应用在自身的真实业务场景中且发生了安全问题,则需用户自行承担。

#include <iostream> #include <vector> #include <complex> #include "asdsip.h" #include "acl/acl.h" #include "acl_meta.h" using namespace AsdSip; #define ASD_STATUS_CHECK(err) \ do { \ AsdSip::AspbStatus err_ = (err); \ if (err_ != AsdSip::ErrorType::ACL_SUCCESS) { \ std::cout << "Execute failed." << std::endl; \ exit(-1); \ } else { \ std::cout << "Execute successfully." << std::endl; \ } \ } while (0) void printTensor(const std::complex<float> *tensorData, int64_t batchSize, int64_t rows, int64_t cols) { for(int64_t b = 0; b < batchSize; b++) { for (int64_t i = 0; i < rows; i++) { for (int64_t j = 0; j < cols; j++) { std::cout << tensorData[b * rows * cols + i * cols + j] << " "; } std::cout << std::endl; } std::cout << std::endl; } } #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) int64_t GetShapeSize(const std::vector<int64_t> &shape) { int64_t shapeSize = 1; for (auto i : shape) { shapeSize *= i; } return shapeSize; } int Init(int32_t deviceId, aclrtStream *stream) { // 固定写法,acl初始化 auto ret = aclInit(nullptr); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret); ret = aclrtSetDevice(deviceId); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret); ret = aclrtCreateStream(stream); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret); return 0; } template <typename T> int CreateAclTensor(const std::vector<T> &hostData, const std::vector<int64_t> &shape, void **deviceAddr, aclDataType dataType, aclTensor **tensor) { auto size = GetShapeSize(shape) * sizeof(T); // 调用aclrtMalloc申请device侧内存 auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret); // 调用aclrtMemcpy将host侧数据复制到device侧内存上 ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret); // 计算连续tensor的strides std::vector<int64_t> strides(shape.size(), 1); for (int64_t i = shape.size() - 2; i >= 0; i--) { strides[i] = shape[i + 1] * strides[i + 1]; } // 调用aclCreateTensor接口创建aclTensor *tensor = aclCreateTensor(shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr); return 0; } int main(int argc, char **argv) { int deviceId = 0; aclrtStream stream; auto ret = Init(deviceId, &stream); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret); int64_t batchSize = 3; int64_t n = 4; int64_t tensorASize = batchSize * n * n; std::vector<std::complex<float>> tensorInAData; std::vector<std::complex<float>> tensorInAinvData; std::vector<int32_t> tensorInInfoData; tensorInAData.reserve(tensorASize); tensorInAinvData.reserve(tensorASize); tensorInInfoData.reserve(batchSize); for (int32_t batchIdx = 0; batchIdx < batchSize; batchIdx++) { for (int32_t i = 0; i < n; i++) { for (int32_t j = 0; j < n; j++) { if (i == j) { tensorInAData[n * n * batchIdx + n * i + j] = {2.0f + batchIdx, -2.0f - batchIdx}; } else { tensorInAData[n * n * batchIdx + n * i + j] = {1.0f, -1.0f}; } } } } for (int32_t batchIdx = 0; batchIdx < batchSize; batchIdx++) { for (int32_t i = 0; i < n; i++) { for (int32_t j = 0; j < n; j++) { tensorInAinvData[n * n * batchIdx + n * i + j] = {-1.0f, -1.0f}; } } } for (int32_t batchIdx = 0; batchIdx < batchSize; batchIdx++) { tensorInInfoData[batchIdx] = 0; } std::cout << "------- input TensorInA -------" << std::endl; printTensor(tensorInAData.data(), batchSize, n, n); std::cout << "------- input TensorInAinv -------" << std::endl; printTensor(tensorInAinvData.data(), batchSize, n, n); std::vector<int64_t> aShape = {batchSize, n, n}; std::vector<int64_t> ainvShape = {batchSize, n, n}; std::vector<int64_t> infoShape = {batchSize}; aclTensor *inputA = nullptr; aclTensor *inputAinv = nullptr; aclTensor *inputInfo = nullptr; void *inputADeviceAddr = nullptr; void *inputAinvDeviceAddr = nullptr; void *inputInfoDeviceAddr = nullptr; ret = CreateAclTensor(tensorInAData, aShape, &inputADeviceAddr, aclDataType::ACL_COMPLEX64, &inputA); CHECK_RET(ret == ::ACL_SUCCESS, return ret); ret = CreateAclTensor(tensorInAinvData, ainvShape, &inputAinvDeviceAddr, aclDataType::ACL_COMPLEX64, &inputAinv); CHECK_RET(ret == ::ACL_SUCCESS, return ret); ret = CreateAclTensor(tensorInInfoData, infoShape, &inputInfoDeviceAddr, aclDataType::ACL_INT32, &inputInfo); CHECK_RET(ret == ::ACL_SUCCESS, return ret); asdBlasHandle handle; asdBlasCreate(handle); size_t lwork = 0; void *buffer = nullptr; asdBlasMakeCmatinvBatchedPlan(handle, n, batchSize); asdBlasGetWorkspaceSize(handle, lwork); std::cout << "lwork = " << lwork << std::endl; if (lwork > 0) { ret = aclrtMalloc(&buffer, static_cast<int64_t>(lwork), ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret); } asdBlasSetWorkspace(handle, buffer); asdBlasSetStream(handle, stream); asdBlasSynchronize(handle); ASD_STATUS_CHECK(asdBlasCmatinvBatched(handle, n, inputA, n, inputAinv, n, inputInfo, batchSize)); asdBlasSynchronize(handle); asdBlasDestroy(handle); ret = aclrtMemcpy(tensorInAinvData.data(), tensorASize * sizeof(std::complex<float>), inputAinvDeviceAddr, tensorASize * sizeof(std::complex<float>), ACL_MEMCPY_DEVICE_TO_HOST); CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("copy Ainv from device to host failed. ERROR: %d\n", ret); return ret); std::cout << "------- output TensorInAinv -------" << std::endl; printTensor(tensorInAinvData.data(), batchSize, n, n); aclDestroyTensor(inputA); aclDestroyTensor(inputAinv); aclDestroyTensor(inputInfo); aclrtFree(inputADeviceAddr); aclrtFree(inputAinvDeviceAddr); aclrtFree(inputInfoDeviceAddr); aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); return 0; }

【免费下载链接】sip本项目是CANN提供的一款高效、可靠的高性能信号处理算子加速库,基于华为Ascend AI处理器,专门为信号处理领域而设计。项目地址: https://gitcode.com/cann/sip

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.cnnetsun.cn/news/2854249.html

相关文章:

  • deepseek 回答怎么导出?别再手动复制啦,AI 导出鸭帮你轻松完整导出对话内容
  • Oryx(SRS Stack)的AI功能深度解析:语音转文字、视频翻译、OCR识别
  • Android Material Stepper实战:构建复杂多步骤表单应用案例
  • AirIAM高级配置:10个最佳实践优化你的AWS IAM权限管理
  • 租用GPU云服务器进行深度学习(AutoDL,超保姆级,适重大更新)
  • Azure Automation Runbook 获取托管标识的访问令牌(Access Token)
  • 东航逆向实录:refer__1036、req/res、ssxmod_itna/itna2 一锅端
  • AI 死活记不住你的接口?我花 5 分钟配了个东西,从此一劳永逸
  • 2026验证码破解指南:5种方案实测,从Tesseract到YOLOv8,哪种才是你的最优解?
  • 113.体育分析实战:从YOLO检测到多目标跟踪的坑与经验
  • Highcharts v13 DataTable + TypedArray 性能压测白皮书
  • GEE教程:Google Earth Engine中导出影像过程中的Pyramiding Policy:MEAN、MODE、MIN、MAX与SAMPLE全解析
  • 实习日记--核心板第一周
  • 深入理解Kotlin中的noinline与crossinline修饰符:Android开发的必备进阶技巧
  • JVM——线程池实现原理
  • 洛谷题解P4314 [CPU监控]
  • Dubbo的实现原理
  • 公司要求全员学 AI:别只追工具,核心要掌握方法与工作流
  • 蓝桥杯嵌入式备赛避坑指南:从第八届电梯题看状态机设计与调试技巧
  • Windows 10上5分钟搞定EMQX MQTT服务器,叉车本地测试不求人
  • 告别手动复制粘贴!用Wireshark命令行+Python脚本,一键批量提取pcap原始16进制数据
  • 从设计稿到上线:手把手教你用el-table实现高还原度的复杂数据表格(含暗黑模式适配)
  • 保姆级教程:在Win11上搞定MySQL 8.0.28安装与配置(附常见错误排查清单)
  • FusionCompute 8.0 VRM主备部署:从规划IP到登录管理后台的完整配置清单与注意事项
  • 告别Softmax,拥抱Logistic:YOLOv3的多标签分类实战与损失函数调优指南
  • 终于有人整理出了,AI漫剧角色创作全流程:从设定、三视图、表情、动作到提示词
  • 2026成都苹果手机维修性价比推荐:不花冤枉钱的理性选择
  • DocuSign电子签API集成实战:批量发送信封与Webhook回调处理
  • 2026年鹤壁烟酒选购指南:口碑好店真实对比
  • 易连EDI—EasyLink:企业级全场景文件传输管理(MFT)解决方案