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::NO_ERROR) { \
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;
}
父主题: Domain