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

CANN/SiP三维FFT接口文档

FFT_3D【免费下载链接】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×功能说明接口功能asdFftMakePlan3D初始化三维FFT配置。asdFftExecC2C执行复数到复数的FFT变换。asdFftExecC2R执行复数到实数的FFT变换。asdFftExecR2C执行实数到复数的FFT变换。asdFftExecC2CSeparated执行复数到复数的FFT变换支持实部、虚部分开输入和输出。计算公式设有一个三维离散信号它的三维离散傅里叶变换定义为其中函数原型AspbStatus asdFftMakePlan3D( asdFftHandle handle, int64_t fftSizeX, int64_t fftSizeY, int64_t fftSizeZ, asdFftType fftType, asdFftDirection direction, int32_t batchSize)AspbStatus asdFftExecC2C( asdFftHandle handle, const aclTensor * input, const aclTensor * output)AspbStatus asdFftExecC2R( asdFftHandle handle, const aclTensor * input, const aclTensor * output)AspbStatus asdFftExecR2C( asdFftHandle handle, const aclTensor * input, const aclTensor * output)AspbStatus asdFftExecC2CSeparated( asdFftHandle handle, const aclTensor * inputReal, const aclTensor * inputImag, const aclTensor * outputReal, const aclTensor * outputImag)asdFftMakePlan3D参数说明参数名输入/输出描述handleasdFftHandle输入算子的句柄需要手动申请创建asdFftHandle对象。fftSizeXint64_t输入对应公式中的MFFT信号长度第一维。fftSizeYint64_t输入对应公式中的NFFT信号长度第二维。fftSizeZint64_t输入对应公式中的NFFT信号长度第三维。fftTypeasdFftType输入FFT变换类型ASCEND_FFT_C2C复数到复数的快速傅里叶变换。ASCEND_FFT_C2R复数到实数的快速傅里叶变换。ASCEND_FFT_R2C实数到复数的快速傅里叶变换。ASCEND_FFT_C2C_SEP复数到复数的分离式快速傅里叶变换。directionasdFftDirection输入选择FFT执行正向变换或反向变换ASCEND_FFT_FORWARD正向快速傅里叶变换。ASCEND_FFT_INVERSE逆向快速傅里叶变换。batchSizeint32_t输入FFT变换批处理操作中的数据批次数量。返回值返回状态码具体参见SiP返回码。asdFftExecC2C参数说明参数名输入/输出描述handleasdFftHandle输入算子的句柄需要手动申请创建asdFftHandle对象。inData aclTensor *输入对应公式中的x。数据类型支持COMPLEX64。数据格式支持ND。输入的shape为batchSizefftSizeXfftSizeYfftSizeZ。outDataaclTensor *输出对应公式中的y。数据类型支持COMPLEX64。数据格式支持ND。输入的shape为batchSizefftSizeXfftSizeYfftSizeZ。返回值返回状态码具体参见SiP返回码。asdFftExecC2R参数说明参数名输入/输出描述handleasdFftHandle输入算子的句柄需要手动申请创建asdFftHandle对象。inData aclTensor *输入对应公式中的x。数据类型支持COMPLEX64。数据格式支持ND。输入的shape为batchSizefftSizeXfftSizeYfftSizeZ/21。outDataaclTensor *输出对应公式中的y。数据类型支持FLOAT32。数据格式支持ND。输入的shape为batchSizefftSizeXfftSizeYfftSizeZ。返回值返回状态码具体参见SiP返回码。asdFftExecR2C参数说明参数名输入/输出描述handleasdFftHandle输入算子的句柄需要手动申请创建asdFftHandle对象。inData aclTensor *输入对应公式中的x。数据类型支持FLOAT32。数据格式支持ND。输入的shape为batchSizefftSizeXfftSizeYfftSizeZ。outDataaclTensor *输出对应公式中的y。数据类型支持COMPLEX64。数据格式支持ND。输入的shape为batchSizefftSizeXfftSizeYfftSizeZ/21。返回值返回状态码具体参见SiP返回码。asdFftExecC2CSeparated参数说明参数名输入/输出描述handleasdFftHandle输入算子的句柄需要手动申请创建asdFftHandle对象。inputReal aclTensor *输入公式中的x的实部。数据类型支持FLOAT32。数据格式支持ND。输入的shape为batchSizefftSize。inputImagaclTensor *输入公式中的x的虚部。数据类型支持FLOAT32。数据格式支持ND。输入的shape为batchSizefftSize。outputRealaclTensor *输出公式中的y的实部。数据类型支持FLOAT32。数据格式支持ND。输入的shape为batchSizefftSize。outputImagaclTensor *输出公式中的y的虚部。数据类型支持FLOAT32。数据格式支持ND。输入的shape为batchSizefftSize。返回值返回状态码具体参见SiP返回码。约束说明asdFftMakePlan3DfftSizeX、fftSizeY、fftSizeZ需保证不超过$2^{27}$且分解质因数后不包含超过199的质因子。batchSize在存储允许范围内应无额外约束。输入的元素个数理论支持[1$2^{30}$]。输入的元素不支持inf、-inf和nan如果输入中包含这些值, 那么结果为未定义。asdFftExecC2CSeparated 信号长度范围[2, 256]。调用示例示例代码如下该样例旨在提供快速上手、开发和调试算子的最小化实现其核心目标是使用最精简的代码展示算子的核心功能而非提供生产级的安全保障。不推荐用户直接将示例代码作为业务代码若用户将示例代码应用在自身的真实业务场景中且发生了安全问题则需用户自行承担。C2C_3D#include iostream #include vector #include asdsip.h #include acl/acl.h #include aclnn/acl_meta.h using namespace AsdSip; #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) #define ASD_STATUS_CHECK(err) \ do { \ AsdSip::AspbStatus err_ (err); \ if (err_ ! AsdSip::ErrorType::ACL_SUCCESS) { \ std::cout Execute failed. std::endl; \ exit(-1); \ } \ } while (0) int64_t GetShapeSize(const std::vectorint64_t shape) { int64_t shapeSize 1; for (auto i : shape) { shapeSize * i; } return shapeSize; } int Init(int32_t deviceId, aclrtStream *stream) { // 固定写法AscendCL初始化 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::vectorT hostData, const std::vectorint64_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::vectorint64_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() { int32_t 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); // 创造tensor的Host侧数据 int batch 1, Nfft1 256, Nfft2 64, Nfft3 64; const int64_t tensorInSize batch * Nfft1 * Nfft2 * Nfft3; std::vectorint64_t selfShape {batch, Nfft1, Nfft2, Nfft3}; std::vectorint64_t outShape {batch, Nfft1, Nfft2, Nfft3}; std::vectorstd::complexfloat inputHostData(tensorInSize, std::complexfloat(0, 0)); for (int i 0; i tensorInSize; i) { inputHostData[i] std::complexfloat(i, i 1); } std::vectorstd::complexfloat outHostData(tensorInSize, std::complexfloat(0, 0)); void *inputDeviceAddr nullptr; void *outDeviceAddr nullptr; aclTensor *input nullptr; aclTensor *out nullptr; ret CreateAclTensor(inputHostData, selfShape, inputDeviceAddr, aclDataType::ACL_COMPLEX64, input); CHECK_RET(ret ::ACL_SUCCESS, return ret); ret CreateAclTensor(outHostData, outShape, outDeviceAddr, aclDataType::ACL_COMPLEX64, out); CHECK_RET(ret ::ACL_SUCCESS, return ret); asdFftHandle handle; asdFftCreate(handle); asdFftMakePlan3D(handle, Nfft1, Nfft2, Nfft3, asdFftType::ASCEND_FFT_C2C, asdFftDirection::ASCEND_FFT_FORWARD, batch); size_t work_size; asdFftGetWorkspaceSize(handle, work_size); void *workspaceAddr nullptr; if (work_size 0) { ret aclrtMalloc(workspaceAddr, static_castint64_t(work_size), ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(allocate workspace failed. ERROR: %d\n, ret); return ret); } asdFftSetWorkspace(handle, (uint8_t *)workspaceAddr); asdFftSetStream(handle, stream); ASD_STATUS_CHECK(asdFftExecC2C(handle, input, out)); ret aclrtSynchronizeStream(stream); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(aclrtSynchronizeStream failed. ERROR: %d\n, ret); return ret); asdFftDestroy(handle); auto size GetShapeSize(outShape); std::vectorstd::complexfloat outData(size, 0); ret aclrtMemcpy(outData.data(), outData.size() * sizeof(outData[0]), outDeviceAddr, size * sizeof(outData[0]), ACL_MEMCPY_DEVICE_TO_HOST); // 打印输出tensor值中前16个 for (int64_t i 0; i std::min(static_castint64_t(16), tensorInSize); i) { std::cout static_caststd::complexfloat(outData[i]) \t; } std::cout \nend result std::endl; std::cout Execute successfully. std::endl; aclDestroyTensor(input); aclDestroyTensor(out); aclrtFree(inputDeviceAddr); aclrtFree(outDeviceAddr); if (work_size 0) { aclrtFree(workspaceAddr); } aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); return 0; }C2R_3D#include iostream #include vector #include asdsip.h #include acl/acl.h #include aclnn/acl_meta.h using namespace AsdSip; #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) #define ASD_STATUS_CHECK(err) \ do { \ AsdSip::AspbStatus err_ (err); \ if (err_ ! AsdSip::ErrorType::ACL_SUCCESS) { \ std::cout Execute failed. std::endl; \ exit(-1); \ } \ } while (0) int64_t GetShapeSize(const std::vectorint64_t shape) { int64_t shapeSize 1; for (auto i : shape) { shapeSize * i; } return shapeSize; } int Init(int32_t deviceId, aclrtStream *stream) { // 固定写法AscendCL初始化 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::vectorT hostData, const std::vectorint64_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::vectorint64_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() { int32_t 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); // 创造tensor的Host侧数据 int batch 2, Nfft1 2, Nfft2 128, Nfft3 128; const int64_t inSignal Nfft3 / 2 1; const int64_t outSignal Nfft3; const int64_t tensorInSize batch * Nfft1 * Nfft2 * inSignal; const int64_t tensorOutSize batch * Nfft1 * Nfft2 * outSignal; std::vectorint64_t selfShape {batch, Nfft1, Nfft2, inSignal}; std::vectorint64_t outShape {batch, Nfft1, Nfft2, outSignal}; std::vectorstd::complexfloat inputHostData(tensorInSize, std::complexfloat(0, 0)); for (int i 0; i tensorInSize; i) { inputHostData[i] std::complexfloat(i, i 1); } std::vectorfloat outHostData(tensorOutSize, 0); void *inputDeviceAddr nullptr; void *outDeviceAddr nullptr; aclTensor *input nullptr; aclTensor *out nullptr; ret CreateAclTensor(inputHostData, selfShape, inputDeviceAddr, aclDataType::ACL_COMPLEX64, input); CHECK_RET(ret ::ACL_SUCCESS, return ret); ret CreateAclTensor(outHostData, outShape, outDeviceAddr, aclDataType::ACL_FLOAT, out); CHECK_RET(ret ::ACL_SUCCESS, return ret); asdFftHandle handle; asdFftCreate(handle); asdFftMakePlan3D(handle, Nfft1, Nfft2, Nfft3, asdFftType::ASCEND_FFT_C2R, asdFftDirection::ASCEND_FFT_FORWARD, batch); size_t work_size; asdFftGetWorkspaceSize(handle, work_size); void *workspaceAddr nullptr; if (work_size 0) { ret aclrtMalloc(workspaceAddr, static_castint64_t(work_size), ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(allocate workspace failed. ERROR: %d\n, ret); return ret); } asdFftSetWorkspace(handle, (uint8_t *)workspaceAddr); asdFftSetStream(handle, stream); ASD_STATUS_CHECK(asdFftExecC2R(handle, input, out)); ret aclrtSynchronizeStream(stream); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(aclrtSynchronizeStream failed. ERROR: %d\n, ret); return ret); asdFftDestroy(handle); auto size GetShapeSize(outShape); std::vectorfloat outData(size, 0); ret aclrtMemcpy(outData.data(), outData.size() * sizeof(outData[0]), outDeviceAddr, size * sizeof(outData[0]), ACL_MEMCPY_DEVICE_TO_HOST); // 打印输出tensor值中前16个 for (int64_t i 0; i std::min(static_castint64_t(16), tensorOutSize); i) { std::cout static_castfloat(outData[i]) \t; } std::cout \nend result std::endl; std::cout Execute successfully. std::endl; aclDestroyTensor(input); aclDestroyTensor(out); aclrtFree(inputDeviceAddr); aclrtFree(outDeviceAddr); if (work_size 0) { aclrtFree(workspaceAddr); } aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); return 0; }R2C_2D#include iostream #include vector #include asdsip.h #include acl/acl.h #include aclnn/acl_meta.h using namespace AsdSip; #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) #define ASD_STATUS_CHECK(err) \ do { \ AsdSip::AspbStatus err_ (err); \ if (err_ ! AsdSip::ErrorType::ACL_SUCCESS) { \ std::cout Execute failed. std::endl; \ exit(-1); \ } \ } while (0) int64_t GetShapeSize(const std::vectorint64_t shape) { int64_t shapeSize 1; for (auto i : shape) { shapeSize * i; } return shapeSize; } int Init(int32_t deviceId, aclrtStream *stream) { // 固定写法AscendCL初始化 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::vectorT hostData, const std::vectorint64_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::vectorint64_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() { int32_t 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); // 创造tensor的Host侧数据 int batch 1, Nfft1 1, Nfft2 64, Nfft3 32; const int64_t tensorInSize batch * Nfft1 * Nfft2 * Nfft3; const int64_t tensorOutSize batch * Nfft1 * Nfft2 * (Nfft3 / 2 1); std::vectorint64_t selfShape {batch, Nfft1, Nfft2, Nfft3}; std::vectorint64_t outShape {batch, Nfft1, Nfft2, Nfft3 / 2 1}; std::vectorfloat inputHostData(tensorInSize, 0); for (int i 0; i tensorInSize; i) { inputHostData[i] i; } std::vectorstd::complexfloat outHostData(tensorInSize, std::complexfloat(0, 0)); void *inputDeviceAddr nullptr; void *outDeviceAddr nullptr; aclTensor *input nullptr; aclTensor *out nullptr; ret CreateAclTensor(inputHostData, selfShape, inputDeviceAddr, aclDataType::ACL_FLOAT, input); CHECK_RET(ret ::ACL_SUCCESS, return ret); ret CreateAclTensor(outHostData, outShape, outDeviceAddr, aclDataType::ACL_COMPLEX64, out); CHECK_RET(ret ::ACL_SUCCESS, return ret); asdFftHandle handle; asdFftCreate(handle); asdFftMakePlan3D(handle, Nfft1, Nfft2, Nfft3, asdFftType::ASCEND_FFT_R2C, asdFftDirection::ASCEND_FFT_FORWARD, batch); size_t work_size; asdFftGetWorkspaceSize(handle, work_size); void *workspaceAddr nullptr; if (work_size 0) { ret aclrtMalloc(workspaceAddr, static_castint64_t(work_size), ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(allocate workspace failed. ERROR: %d\n, ret); return ret); } asdFftSetWorkspace(handle, (uint8_t *)workspaceAddr); asdFftSetStream(handle, stream); ASD_STATUS_CHECK(asdFftExecR2C(handle, input, out)); ret aclrtSynchronizeStream(stream); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(aclrtSynchronizeStream failed. ERROR: %d\n, ret); return ret); asdFftDestroy(handle); auto size GetShapeSize(outShape); std::vectorstd::complexfloat outData(size, 0); ret aclrtMemcpy(outData.data(), outData.size() * sizeof(outData[0]), outDeviceAddr, size * sizeof(outData[0]), ACL_MEMCPY_DEVICE_TO_HOST); // 打印输出tensor值中前16个 for (int64_t i 0; i std::min(static_castint64_t(16), tensorOutSize); i) { std::cout static_caststd::complexfloat(outData[i]) \t; } std::cout \nend result std::endl; std::cout Execute successfully. std::endl; aclDestroyTensor(input); aclDestroyTensor(out); aclrtFree(inputDeviceAddr); aclrtFree(outDeviceAddr); if (work_size 0) { aclrtFree(workspaceAddr); } aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); return 0; }C2C_3D_SEP#include iostream #include fstream #include random #include vector #include asdsip.h #include acl/acl.h #include aclnn/acl_meta.h using namespace AsdSip; #define CHECK_RET(cond, return_expr) \ do { \ if (!(cond)) { \ return_expr; \ } \ } while (0) #define LOG_PRINT(message, ...) \ do { \ printf(message, ##__VA_ARGS__); \ } while (0) #define ASD_STATUS_CHECK(err) \ do { \ AsdSip::AspbStatus err_ (err); \ if (err_ ! AsdSip::ErrorType::ACL_SUCCESS) { \ std::cout Execute failed. std::endl; \ exit(-1); \ } \ } while (0) int64_t GetShapeSize(const std::vectorint64_t shape) { int64_t shapeSize 1; for (auto i : shape) { shapeSize * i; } return shapeSize; } int Init(int32_t deviceId, aclrtStream *stream) { // 固定写法AscendCL初始化 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::vectorT hostData, const std::vectorint64_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::vectorint64_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() { int32_t 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); // 创造tensor的Host侧数据 // int batch 2, Nfft1 256, Nfft2 256, Nfft3 256; // core dd int batch 2, Nfft1 4, Nfft2 4, Nfft3 4; // core dd // int batch 32, Nfft 256; // c2c dft // int batch 32, Nfft 8192; // c2c fftb // int batch 32, Nfft 15000; // c2c mixed // int batch 32, Nfft 32768; // c2c fftn // int batch 32, Nfft 199 * 199; // core any const int64_t tensorInSize batch * Nfft1 * Nfft2 * Nfft3; std::vectorint64_t selfShape {batch, Nfft1, Nfft2, Nfft3}; std::vectorint64_t outShape {batch, Nfft1, Nfft2, Nfft3}; std::vectorfloat inputRealHostData(tensorInSize, 0); std::vectorfloat inputImagHostData(tensorInSize, 0); std::vectorfloat outputRealHostData(tensorInSize, 0); std::vectorfloat outputImagHostData(tensorInSize, 0); std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distributionfloat dis(0.0f, 1.0f); for (int i 0; i tensorInSize; i) { inputRealHostData[i] dis(gen); inputImagHostData[i] dis(gen); } void *inputRealDeviceAddr nullptr; void *inputImagDeviceAddr nullptr; void *outputRealDeviceAddr nullptr; void *outputImagDeviceAddr nullptr; aclTensor *inputReal nullptr; aclTensor *inputImag nullptr; aclTensor *outputReal nullptr; aclTensor *outputImag nullptr; ret CreateAclTensor(inputRealHostData, selfShape, inputRealDeviceAddr, aclDataType::ACL_FLOAT, inputReal); CHECK_RET(ret ::ACL_SUCCESS, return ret); ret CreateAclTensor(inputImagHostData, selfShape, inputImagDeviceAddr, aclDataType::ACL_FLOAT, inputImag); CHECK_RET(ret ::ACL_SUCCESS, return ret); ret CreateAclTensor(outputRealHostData, outShape, outputRealDeviceAddr, aclDataType::ACL_FLOAT, outputReal); CHECK_RET(ret ::ACL_SUCCESS, return ret); ret CreateAclTensor(outputImagHostData, outShape, outputImagDeviceAddr, aclDataType::ACL_FLOAT, outputImag); CHECK_RET(ret ::ACL_SUCCESS, return ret); asdFftHandle handle; asdFftCreate(handle); asdFftMakePlan3D(handle, Nfft1, Nfft2, Nfft3, asdFftType::ASCEND_FFT_C2C_SEP, asdFftDirection::ASCEND_FFT_FORWARD, batch); size_t work_size; asdFftGetWorkspaceSize(handle, work_size); void *workspaceAddr nullptr; if (work_size 0) { ret aclrtMalloc(workspaceAddr, static_castint64_t(work_size), ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(allocate workspace failed. ERROR: %d\n, ret); return ret); } asdFftSetWorkspace(handle, (uint8_t *)workspaceAddr); asdFftSetStream(handle, stream); ASD_STATUS_CHECK(asdFftExecC2CSeparated(handle, inputReal, inputImag, outputReal, outputImag)); ret aclrtSynchronizeStream(stream); CHECK_RET(ret ::ACL_SUCCESS, LOG_PRINT(aclrtSynchronizeStream failed. ERROR: %d\n, ret); return ret); asdFftDestroy(handle); auto size GetShapeSize(outShape); std::vectorfloat outRealData(size, 0); std::vectorfloat outImagData(size, 0); std::vectorfloat workspaceData(size * 2, -1); ret aclrtMemcpy(outRealData.data(), outRealData.size() * sizeof(outRealData[0]), outputRealDeviceAddr, size * sizeof(outRealData[0]), ACL_MEMCPY_DEVICE_TO_HOST); ret aclrtMemcpy(outImagData.data(), outImagData.size() * sizeof(outImagData[0]), outputImagDeviceAddr, size * sizeof(outImagData[0]), ACL_MEMCPY_DEVICE_TO_HOST); ret aclrtMemcpy(workspaceData.data(), workspaceData.size() * sizeof(workspaceData[0]), workspaceAddr, workspaceData.size() * sizeof(workspaceData[0]), ACL_MEMCPY_DEVICE_TO_HOST); // 打印输出tensor值中前16个 std::cout real part: std::endl; for (int64_t i 0; i size; i) { std::cout static_castfloat(outRealData[i]) \t; } std::cout \nimag part: std::endl; for (int64_t i 0; i size; i) { std::cout static_castfloat(outImagData[i]) \t; } std::cout \nworkspace real part: std::endl; for (int64_t i 0; i size; i) { std::cout static_castfloat(workspaceData[i]) \t; } std::cout \nworkspace imag part: std::endl; for (int64_t i 0; i size; i) { std::cout static_castfloat(workspaceData[i size]) \t; } std::cout \nend result std::endl; std::cout Execute successfully. std::endl; aclDestroyTensor(inputReal); aclDestroyTensor(inputImag); aclDestroyTensor(outputReal); aclDestroyTensor(outputImag); aclrtFree(inputRealDeviceAddr); aclrtFree(inputImagDeviceAddr); aclrtFree(outputRealDeviceAddr); aclrtFree(outputImagDeviceAddr); if (work_size 0) { aclrtFree(workspaceAddr); } aclrtDestroyStream(stream); aclrtResetDevice(deviceId); aclFinalize(); return 0; }【免费下载链接】sip本项目是CANN提供的一款高效、可靠的高性能信号处理算子加速库基于华为Ascend AI处理器专门为信号处理领域而设计。项目地址: https://gitcode.com/cann/sip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关文章:

CANN/SiP三维FFT接口文档

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

ChatGPT-AutoExpert:构建领域专家提示词,实现AI深度专业协作

1. 项目概述:当ChatGPT学会“自我进化”如果你和我一样,深度依赖ChatGPT进行编程、写作或解决复杂问题,那你一定遇到过这样的困境:面对一个专业领域的问题,你需要反复向ChatGPT解释背景知识、行业术语和具体约束&#…...

移动端视频帧插值技术:ANVIL框架与NPU优化实践

1. 移动端视频帧插值的技术挑战与ANVIL框架概述视频帧插值(Video Frame Interpolation, VFI)作为提升视频流畅度的关键技术,在移动设备上实现实时处理面临三重技术壁垒:首先是计算复杂度与功耗限制,传统光流法需要执行…...

跟着 MDN 学 HTML day_30:(AbortController 实现可取消的异步请求)

在现代 Web 开发中,异步操作随处可见,尤其是网络请求。但有时候我们需要主动取消一个正在进行的请求,比如用户切换了页面、重复提交表单、或者文件下载被中断。传统的做法往往难以优雅地处理这些场景。AbortController 的出现,为我…...

PL/SQL:异常处理补充

PL/SQL异常处理补充:本文在基础异常处理语法基础上,重点补充了5个实用知识点:常见预定义异常(如NO_DATA_FOUND)及其应用场景;两种自定义异常实现方式(异常别名与RAISE_APPLICATION_ERROR&#x…...

离线优先的Markdown编辑器:inkdown如何实现极致专注写作

1. 项目概述:一个为创作者而生的轻量级写作工具如果你和我一样,经常需要在不同设备间切换写作,或者对市面上那些功能臃肿、界面花哨的写作软件感到厌倦,那么你可能会对inkdown产生兴趣。这不是一个功能大而全的“巨无霸”&#xf…...

ASIC功能验证:基于规范的方法与Specman实战

1. ASIC功能验证的现状与挑战在当今的芯片设计领域,功能验证已成为决定项目成败的关键环节。作为一名从业十余年的验证工程师,我亲眼见证了ASIC设计规模从几十万门级发展到如今的数亿门级,而验证复杂度却呈指数级增长。传统验证方法在面对这种…...

PMP管理大数据学习建议

本文提出用PMP五大过程组管理大数据开发学习,建议: 启动阶段明确学习边界,制定项目章程(如6周掌握PythonOracle核心);规划阶段细化WBS分解(Python语法→数据结构→Oracle SQL→PL/SQL&#xff0…...

别再刷后台了!我用凌风工具箱导出竞价表格,摸清所有对手底牌

做Temu一年多,我最怕的不是报不上活动,不是物流延迟,而是——竞价。每次打开商家后台的竞价管理页面,看着密密麻麻的商品列表和不断跳动的竞价倒计时,心里就开始发慌。哪个品该竞价、哪个该守住、哪个该放弃&#xff1…...

基于MCP协议的AI智能体实时金融数据工具箱Tickerr详解

1. 项目概述:一个为AI智能体打造的实时金融数据工具箱最近在折腾AI智能体(Agent)开发,特别是想让它们能处理一些实时性要求高的任务,比如监控股票价格、追踪新闻动态。我发现,要让一个智能体真正“理解”并…...

别再手动下架了!Temu查重复铺货那晚,我10分钟救了三个店

上周三晚上十一点多,我正准备关电脑睡觉,群里突然炸了。“卧槽,三个店全收到重复铺货警告!几十条链接被标记了!”我瞬间睡意全无。你们知道的,Temu现在对重复铺货是零容忍——一旦触发,直接下架…...

轻量级定时任务调度库timetask:配置即代码的Python实践指南

1. 项目概述与核心价值最近在折腾个人效率工具链,发现一个挺有意思的开源项目,叫haikerapples/timetask。乍一看名字,可能觉得就是个简单的定时任务工具,但深入把玩之后,我发现它的设计理念和实现方式,恰好…...

OpenCode集成Cursor Pro:通过代理架构实现AI编程工具的无缝桥接

1. 项目概述:打破限制,将 Cursor Pro 无缝接入 OpenCode 如果你和我一样,既是 Cursor Pro 的深度用户,又对 OpenCode 这个开源、可扩展的 AI 编程环境情有独钟,那你一定遇到过那个令人头疼的“二选一”困境。Cursor 的…...

RAGxplorer:可视化调试工具,提升检索增强生成系统可观测性

1. 项目概述:RAGxplorer,一个为RAG系统打造的“X光机”如果你正在构建或优化一个基于检索增强生成(RAG)的系统,那么你一定遇到过这样的困惑:为什么用户的问题没有得到预期的答案?是检索的文档不…...

Syncia:基于浏览器扩展的AI助手,实现网页上下文智能处理与本地模型集成

1. 项目概述:一个让AI能力随处可用的浏览器助手 如果你和我一样,每天大部分时间都泡在浏览器里,处理文档、阅读文章、查找资料,那你肯定也想过:要是能把ChatGPT的能力直接“嵌入”到每一个网页里,随时帮我…...

BricksLLM:开源LLM API网关,解决大模型应用成本管控与用量追踪难题

1. 项目概述:当大模型应用遇上“计费墙” 最近在折腾大模型应用的后端服务,一个绕不开的痛点就是成本核算。无论是内部团队使用,还是对外提供SaaS服务,只要接入了OpenAI、Anthropic这些按Token收费的第三方模型,账单管…...

如何用C语言解密网易云NCM音乐文件:实现跨平台音乐格式转换

如何用C语言解密网易云NCM音乐文件:实现跨平台音乐格式转换 【免费下载链接】ncmToMp3 网易云vip的ncm文件转mp3/flac - ncm file to mp3 or flac 项目地址: https://gitcode.com/gh_mirrors/nc/ncmToMp3 你是否曾经在网易云音乐下载了VIP歌曲,却…...

从循环处理、全局工作空间到高阶理论:AI架构的意识功能映射与工程启示

1. 项目概述:一场关于智能本质的跨界探索最近和几位做认知科学和哲学的朋友聊天,聊到了一个特别有意思的话题:我们整天在搞的AI,尤其是那些大语言模型,它们到底有没有可能产生“意识”?或者说,我…...

构建办公自动化CLI工具集:从Python库选型到实战应用

1. 项目概述:一个面向办公效率的CLI工具集如果你和我一样,每天大部分时间都泡在终端里,那么“officecli/officecli-skills”这个项目标题,一眼就能让你兴奋起来。它直指一个非常具体且高频的痛点:如何在命令行&#xf…...

AI编程助手代码审计工具whatdiditdo:从黑盒到白盒的智能复盘

1. 项目概述:当AI替你写代码后,如何快速复盘?如果你和我一样,已经深度依赖AI编程助手(比如Cursor、GitHub Copilot、Claude Code)来加速日常开发,那你一定遇到过这个场景:你给AI下了…...

透明计费与用量明细让个人开发者的项目预算更加清晰

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 透明计费与用量明细让个人开发者的项目预算更加清晰 对于独立开发者或小型团队而言,在集成大模型能力时,成…...

YAPI MCP PRO:基于MCP协议将YApi无缝集成AI代码编辑器的实践指南

1. 项目概述与核心价值如果你和我一样,每天都要在YApi里翻找接口文档、复制粘贴路径和参数,然后切回代码编辑器去写调用逻辑,那这个循环一定让你感到疲惫。更别提当后端同事更新了接口,你还在用旧参数调试的尴尬场景。YAPI MCP PR…...

ClawScript:专为量化交易与AI自动化设计的领域特定语言

1. 项目概述:ClawScript,一个为交易与自动化而生的领域特定语言如果你像我一样,在量化交易和自动化流程的构建上投入了大量时间,那你一定对那种在通用编程语言的灵活性与专用交易平台的便捷性之间反复横跳的体验深有感触。用Pytho…...

基于Tauri+React的AI编码代理实时监控工具设计与实践

1. 项目概述:一个为AI编码代理打造的实时监控桌面应用如果你和我一样,日常开发中重度依赖像Claude Code、OpenCode这类AI编码代理,那你肯定也遇到过这个痛点:当同时运行多个代理任务时,它们各自在独立的终端窗口里埋头…...

PotPlayer字幕翻译插件高级配置与性能优化深度解析

PotPlayer字幕翻译插件高级配置与性能优化深度解析 【免费下载链接】PotPlayer_Subtitle_Translate_Baidu PotPlayer 字幕在线翻译插件 - 百度平台 项目地址: https://gitcode.com/gh_mirrors/po/PotPlayer_Subtitle_Translate_Baidu PotPlayer字幕翻译插件是一款基于百…...

G-Helper华硕笔记本终极控制指南:5分钟掌握性能优化与电池保护技巧

G-Helper华硕笔记本终极控制指南:5分钟掌握性能优化与电池保护技巧 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook,…...

生成式AI艺术审美:从技术原理到人机协作的评判框架

1. 项目概述:当AI拿起画笔,我们如何评判它的“美”?最近几年,生成式AI的爆发,让“人工智能创作”从一个科幻概念变成了我们每天都能刷到的现实。从Midjourney绘制的赛博朋克城市,到Stable Diffusion生成的古…...

基于MCP协议实现AI助手本地读取Mac短信:原理、部署与应用场景

1. 项目概述:一个让AI助手“读懂”你Mac短信的桥梁如果你是一个重度依赖AI助手(比如Claude、Cursor等)进行编程、写作或日常信息处理的Mac用户,可能经常遇到一个痛点:当你想让AI帮你分析一段短信对话、查找某个联系人发…...

基于Claude AI的ASO自动化审计工具:从用户评论到文案优化的智能分析实践

1. 项目概述与核心价值最近在跟几个做ASO(应用商店优化)的朋友聊天,发现大家普遍有个痛点:面对海量的应用商店评论、榜单数据和竞品动态,人工分析不仅耗时耗力,还容易遗漏关键信息。我们经常需要从一堆看似…...

【最新 v2.7.1 版本】OpenClaw v2.7.1 一键安装包|Windows 稳定极速部署

OpenClaw 一键安装包|一键部署,告别复杂环境配置 ✨ 适配系统:Windows 10/11 64 位 当前版本:v2.7.1(虾壳云版) 核心优势:全程可视化操作,无需命令行、无需手动配置 Python/Node.…...