昇腾社区首页
中文
注册

rsInterpolationBySinc

sincTab 预处理:
1、系数矩阵要和复数点乘,在NPU上会转换为系数矩阵和两组float32相乘,所以需要将系数转为下面格式
[系数1,       0]
[     0,  系数1]
此时虚数矩阵会被扩充成  ((quantNum + 1) * 2) * (interpNum * 2)
2、为了亲和NPU(32字节对齐),需要有四种格式矩阵,每行开头不补0,补2个0,补4个0及补6个0:
w0,0,w1,0,w2,0,w3,0,w4,0,w5,0,w6,0,w7,0,w8,0,w9,0,w10,0,w11,0,w12,0,w13,0,w14,0,w15,0,0,0,0,0,0,0,0
0,0,w0,0,w1,0,w2,0,w3,0,w4,0,w5,0,w6,0,w7,0,w8,0,w9,0,w10,0,w11,0,w12,0,w13,0,w14,0,w15,0,0,0,0,0,0
0,0,0,0,w0,0,w1,0,w2,0,w3,0,w4,0,w5,0,w6,0,w7,0,w8,0,w9,0,w10,0,w11,0,w12,0,w13,0,w14,0,w15,0,0,0,0
0,0,0,0,0,0,w0,0,w1,0,w2,0,w3,0,w4,0,w5,0,w6,0,w7,0,w8,0,w9,0,w10,0,w11,0,w12,0,w13,0,w14,0,w15,0,0

static void genTab(float *tab, int tabSize) {
    auto ret = memset_s(tab, tabSize * sizeof(float), 0, tabSize * sizeof(float));
    for(int i = 0; i < 4; i++) {
        int zeroOffset = i * 2;
        int blockOffset = i * (33 * 2) * (16 * 2 + 8);
        for(int j = 0; j < 33; j++) {
            int rowOffset_real = blockOffset + j * (16 * 2 + 8) * 2;
            int rowOffset_imag = rowOffset_real + (16 * 2 + 8);
            for(int k = 0; k < 16; k++) {
                tab[rowOffset_real + zeroOffset + k * 2] = DINTER_CORE_33x16[j * 16 + k];
                tab[rowOffset_imag + zeroOffset + k * 2 + 1] = DINTER_CORE_33x16[j * 16 + k]; 
            }
        }
    }
}

rsInterpolationBySinc

  • 安全声明:

    该样例旨在提供快速上手、开发和调试算子的最小化实现,其核心目标是使用最精简的代码展示算子的核心功能,而非提供生产级的安全保障。

    不推荐用户直接将样例作为业务代码,若用户将示例代码应用在自身的真实业务场景中且发生了安全问题,则需用户自行承担。

  • rsInterpolationBySinc算子调用示例:
    #include <iostream>
    #include <vector>
    #include <securec.h>
    #include "asdsip.h"
    #include "acl/acl.h"
    #include "acl_meta.h"
    
    using std::complex;
    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);                                                        \
            }                                                                    \
        } while (0)
    
    #define DINTER_CORE_SIZE 528
    
    static void genTab(float *tab, int tabSize)
    {
        static float DINTER_CORE_33x16[DINTER_CORE_SIZE];
        for (int i = 0; i < DINTER_CORE_SIZE; ++i) {
            DINTER_CORE_33x16[i] = ((rand() / (float)RAND_MAX) * 2.0f) - 1.0f;
        }
    
        for (int i = 0; i < 4; i++) {
            int zeroOffset = i * 2;
            int blockOffset = i * (33 * 2) * (16 * 2 + 8);
            for (int j = 0; j < 33; j++) {
                int rowOffset_real = blockOffset + j * (16 * 2 + 8) * 2;
                int rowOffset_imag = rowOffset_real + (16 * 2 + 8);
                for (int k = 0; k < 16; k++) {
                    tab[rowOffset_real + zeroOffset + k * 2] = DINTER_CORE_33x16[j * 16 + k];
                    tab[rowOffset_imag + zeroOffset + k * 2 + 1] = DINTER_CORE_33x16[j * 16 + k];
                }
            }
        }
    }
    
    #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);
    
        int batch = 1;
        int signalLength = 64;
        int interpLength = signalLength;
        const int64_t tabSize = (33 * 2) * (16 * 2 + 8) * 4;  // 2 :虚实系数,8:补零,4:不补0,补2,4,6个零
        const unsigned long inSize = batch * signalLength;
        const unsigned long posSize = batch * interpLength;
        const unsigned long tabIndexSize = batch * interpLength;
        const unsigned long outSize = batch * interpLength;
    
        float *tabDate = new float[tabSize]();
        genTab(tabDate, tabSize);
        std::vector<float> tab(tabDate, tabDate + tabSize);
        std::vector<complex<float>> inSignal;
        inSignal.reserve(inSize);
        for (long long ii = 0; ii < signalLength; ++ii) {
            inSignal[ii] = complex<float>(ii, ii);
        }
        std::vector<int32_t> intpPos;
        intpPos.reserve(posSize);
        for (long long ii = 0; ii < interpLength; ++ii) {
            intpPos[ii] = ii;
        }
        std::vector<int16_t> tabIndex;
        tabIndex.reserve(tabIndexSize);
        for (long long ii = 0; ii < interpLength; ++ii) {
            tabIndex[ii] = ii % 33;
        }
        std::vector<complex<float>> outSignal;
        outSignal.reserve(outSize);
        for (long long ii = 0; ii < interpLength; ++ii) {
            outSignal[ii] = complex<float>(0, 0);
        }
    
        aclTensor *tensorIn = nullptr;
        aclTensor *tensorTab = nullptr;
        aclTensor *tensorPos = nullptr;
        aclTensor *tensorTabIndex = nullptr;
        aclTensor *tensorOut = nullptr;
        void *tensorInDeviceAddr = nullptr;
        void *tensorTabDeviceAddr = nullptr;
        void *tensorPosDeviceAddr = nullptr;
        void *tensorTabIndexDeviceAddr = nullptr;
        void *tensorOutDeviceAddr = nullptr;
        ret = CreateAclTensor(inSignal, {batch, signalLength}, &tensorInDeviceAddr, aclDataType::ACL_COMPLEX64, &tensorIn);
        CHECK_RET(ret == ::ACL_SUCCESS, return ret);
        ret = CreateAclTensor(tab, {1, tabSize}, &tensorTabDeviceAddr, aclDataType::ACL_FLOAT, &tensorTab);
        CHECK_RET(ret == ::ACL_SUCCESS, return ret);
        ret = CreateAclTensor(intpPos, {batch, interpLength}, &tensorPosDeviceAddr, aclDataType::ACL_INT32, &tensorPos);
        CHECK_RET(ret == ::ACL_SUCCESS, return ret);
        ret = CreateAclTensor(
            tabIndex, {batch, interpLength}, &tensorTabIndexDeviceAddr, aclDataType::ACL_INT16, &tensorTabIndex);
        CHECK_RET(ret == ::ACL_SUCCESS, return ret);
        ret =
            CreateAclTensor(outSignal, {batch, interpLength}, &tensorOutDeviceAddr, aclDataType::ACL_COMPLEX64, &tensorOut);
        CHECK_RET(ret == ::ACL_SUCCESS, return ret);
    
        void *workspace = nullptr;
        size_t workspaceSize = 0;
        rsInterpolationBySincGetWorkspaceSize(workspaceSize);
        if (workspaceSize > 0) {
            ret = aclrtMalloc(&workspace, static_cast<int64_t>(workspaceSize), ACL_MEM_MALLOC_HUGE_FIRST);
            CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
        }
    
        ASD_STATUS_CHECK(rsInterpolationBySinc(
            tensorIn, tensorTab, tensorPos, tensorTabIndex, tensorOut, 16, 32, interpLength, stream, workspace));
    
        ret = aclrtSynchronizeStream(stream);
        CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
    
        ret = aclrtMemcpy(outSignal.data(),
            outSize * sizeof(std::complex<float>),
            tensorOutDeviceAddr,
            outSize * sizeof(std::complex<float>),
            ACL_MEMCPY_DEVICE_TO_HOST);
        CHECK_RET(ret == ::ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return ret);
    
        for (long long ii = 0; ii < interpLength; ++ii) {
            std::cout << outSignal[ii] << "\t";
        }
        std::cout << "\nend result" << std::endl;
        std::cout << "Execute successfully." << std::endl;
    
        delete[] tabDate;
        aclDestroyTensor(tensorIn);
        aclDestroyTensor(tensorPos);
        aclDestroyTensor(tensorTab);
        aclDestroyTensor(tensorTabIndex);
        aclDestroyTensor(tensorOut);
        aclrtFree(tensorInDeviceAddr);
        aclrtFree(tensorTabDeviceAddr);
        aclrtFree(tensorPosDeviceAddr);
        aclrtFree(tensorTabIndexDeviceAddr);
        aclrtFree(tensorOutDeviceAddr);
        if (workspaceSize > 0) {
            aclrtFree(workspace);
        }
        aclrtDestroyStream(stream);
        aclrtResetDevice(deviceId);
        aclFinalize();
        return 0;
    }