BaseLibraryCPP/GPUTool.cuh

452 lines
17 KiB
Plaintext

#ifndef GPUTOOL_H
#define GPUTOOL_H
#ifdef __CUDANVCC___
#include "BaseConstVariable.h"
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <cublas_v2.h>
#include <cuComplex.h>
#define __CUDADEBUG__
// 默认显存分布
enum LAMPGPUDATETYPE {
LAMP_LONG,
LAMP_FLOAT,
LAMP_COMPLEXFLOAT
};
extern "C" struct CUDASigmaParam {
float p1;
float p2;
float p3;
float p4;
float p5;
float p6;
};
extern "C" struct CUDAVector {
float x;
float y;
float z;
};
extern "C" struct CUDAVectorEllipsoidal {
float theta;
float phi;
float pho;
};
// GPU 内存函数
extern "C" void* mallocCUDAHost( long memsize); // 主机内存声明
extern "C" void FreeCUDAHost(void* ptr);
extern "C" void* mallocCUDADevice( long memsize); // GPU内存声明
extern "C" void FreeCUDADevice(void* ptr);
extern "C" void HostToDevice(void* hostptr, void* deviceptr, long memsize);//GPU 内存数据转移 设备 -> GPU
extern "C" void DeviceToHost(void* hostptr, void* deviceptr, long memsize);//GPU 内存数据转移 GPU -> 设备
// 仿真所需的常用函数
extern "C" void distanceAB(float* Ax, float* Ay, float* Az, float* Bx, float* By, float* Bz, float* R, long member);
extern "C" void BdistanceAs(float* Ax, float* Ay, float* Az, float Bx, float By, float Bz, float* R, long member);
extern "C" void make_VectorA_B(float sX, float sY, float sZ, float* tX, float* tY, float* tZ, float* RstX, float* RstY, float* RstZ, long member);
extern "C" void Norm_Vector(float* Vx, float* Vy, float* Vz, float* R, long member);
extern "C" void cosAngle_VA_AB(float* Ax, float* Ay, float* Az, float* Bx, float* By, float* Bz, float* anglecos, long len);
extern "C" void SatelliteAntDirectNormal(float* RstX, float* RstY, float* RstZ, float antXaxisX, float antXaxisY, float antXaxisZ, float antYaxisX, float antYaxisY, float antYaxisZ, float antZaxisX, float antZaxisY, float antZaxisZ, float antDirectX, float antDirectY, float antDirectZ, float* thetaAnt, float* phiAnt, long len);
extern "C" void AntPatternInterpGain(float* anttheta, float* antphi, float* gain, float* antpattern, float starttheta, float startphi, float dtheta, float dphi, int thetapoints, int phipoints,long len);
extern "C" void CUDA_RTPC_SiglePRF(
float antPx, float antPy, float antPZ,
float antXaxisX, float antXaxisY, float antXaxisZ,
float antYaxisX, float antYaxisY, float antYaxisZ,
float antZaxisX, float antZaxisY, float antZaxisZ,
float antDirectX, float antDirectY, float antDirectZ,
float* demx, float* demy, float* demz, long* demcls,
float* demslopex, float* demslopey, float* demslopez, float* demslopeangle,
float* Tantpattern, float Tstarttheta, float Tstartphi, float Tdtheta, float Tdphi, int Tthetapoints, int Tphipoints,
float* Rantpattern, float Rstarttheta, float Rstartphi, float Rdtheta, float Rdphi, int Rthetapoints, int Rphipoints,
float lamda, float fs, float nearrange, float Pt, int Freqnumbers,
CUDASigmaParam* sigma0Paramslist, int sigmaparamslistlen,
cuComplex* outecho, int* d_echoAmpFID,
int linecount, int colcount
);
extern "C" void CUDARTPCPRF(float antPx, long len);
extern "C" void CUDATestHelloWorld(float a, long len);
extern "C" void CUDATBPImage(
float* antPx,
float* antPy,
float* antPz,
float* imgx,
float* imgy,
float* imgz,
cuComplex* echoArr,
cuComplex* imgArr,
float freq, float fs, float Rnear, float Rfar,
long rowcount, long colcount,
long prfid, long freqcount
);
extern "C" void calculationEcho(float* sigma0, float* TransAnt, float* ReciveAnt,
float* localangle, float* R, float* slopeangle,
float nearRange, float Fs, float pt, float lamda, long FreqIDmax,
cuComplex* echoAmp, long* FreqID,
long len);
extern "C" void CUDAInterpSigma(
long* demcls, float* sigmaAmp, float* localanglearr, long len,
CUDASigmaParam* sigma0Paramslist, long sigmaparamslistlen);
#endif
#endif
/**
*
double* databuffer = new double[nXSize * nYSize * 2];
poBand->RasterIO(GF_Read, start_col, start_row, cols_count, rows_count, databuffer, cols_count,
rows_count, GDT_CFloat64, 0, 0);
GDALClose((GDALDatasetH)poDataset);
Eigen::MatrixXcd rasterData(nYSize, nXSize); // 使用Eigen的MatrixXcd
for(size_t i = 0; i < nYSize; i++) {
for(size_t j = 0; j < nXSize; j++) {
rasterData(i, j) = std::complex<double>(databuffer[i * nXSize * 2 + j * 2],
databuffer[i * nXSize * 2 + j * 2 + 1]);
}
}
delete[] databuffer;
gdalImage demxyz(demxyzPath);// 地面点坐标
gdalImage demlandcls(this->LandCoverPath);// 地表覆盖类型
gdalImage demsloperxyz(this->demsloperPath);// 地面坡向
omp_lock_t lock; // 定义锁
omp_init_lock(&lock); // 初始化锁
long start_ids = 1250;
for (start_ids = 1; start_ids < demxyz.height; start_ids = start_ids + line_invert) { // 8+ 17 + 0.3 MB
QDateTime current = QDateTime::currentDateTime();
long pluseStep = Memory1MB * 100 / 3 / PlusePoint;
if (pluseStep * num_thread * 3 > this->PluseCount) {
pluseStep = this->PluseCount / num_thread / 3;
}
pluseStep = pluseStep > 50 ? pluseStep : 50;
qDebug() << current.toString("yyyy-MM-dd HH:mm:ss.zzz") << " \tstart \t " << start_ids << " - " << start_ids + line_invert << "\t" << demxyz.height << "\t pluseCount:\t" << pluseStep;
// 文件读取
Eigen::MatrixXd dem_x = demxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 1); //
Eigen::MatrixXd dem_y = demxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 2); //
Eigen::MatrixXd dem_z = demxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 3); //
// 地表覆盖
std::shared_ptr<long> dem_landcls = readDataArr<long>(demlandcls, start_ids - 1, 0, line_invert + 1, demxyz.width, 1, GDALREADARRCOPYMETHOD::VARIABLEMETHOD); // 地表覆盖类型
long* dem_landcls_ptr = dem_landcls.get();
double localAngle = 30.0;
bool sigmaNoZeroFlag = true;
for (long ii = 0; ii < dem_x.rows(); ii++) {
for (long jj = 0; jj < dem_y.cols(); jj++) {
if (0 != this->SigmaDatabasePtr->getAmp(dem_landcls_ptr[dem_x.cols() * ii + jj], localAngle, polartype)) {
sigmaNoZeroFlag = false;
break;
}
}
if (!sigmaNoZeroFlag) {
break;
}
}
if (sigmaNoZeroFlag) {
continue;
}
//#ifdef DEBUGSHOWDIALOG
// dialog->load_double_MatrixX_data(dem_z, "dem_z");
//#endif
Eigen::MatrixXd demsloper_x = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 1); //
Eigen::MatrixXd demsloper_y = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 2); //
Eigen::MatrixXd demsloper_z = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 3); //
Eigen::MatrixXd sloperAngle = demsloperxyz.getData(start_ids - 1, 0, line_invert + 1, demxyz.width, 4); //
sloperAngle = sloperAngle.array() * T180_PI;
long dem_rows = dem_x.rows();
long dem_cols = dem_x.cols();
long freqidx = 0;//
#ifdef DEBUGSHOWDIALOG
ImageShowDialogClass* dialog = new ImageShowDialogClass(nullptr);
dialog->show();
Eigen::MatrixXd landaArr = Eigen::MatrixXd::Zero(dem_rows, dem_cols);
for (long i = 0; i < dem_rows; i++) {
for (long j = 0; j < dem_cols; j++) {
landaArr(i, j) = dem_landcls.get()[i * dem_cols + j];
}
}
dialog->load_double_MatrixX_data(landaArr, "landCover");
#endif
//qDebug() << " pluse bolck size :\t " << pluseStep << " all size:\t" << this->PluseCount;
long processNumber = 0;
#pragma omp parallel for
for (long startprfidx = 0; startprfidx < this->PluseCount; startprfidx = startprfidx + pluseStep) { // 17 + 0.3 MB
long prfcount_step = startprfidx + pluseStep < this->PluseCount ? pluseStep : this->PluseCount - startprfidx;
Eigen::MatrixXcd echoPluse = Eigen::MatrixXcd::Zero(prfcount_step, PlusePoint); // 当前脉冲的回波积分情况
// 内存预分配
Eigen::MatrixXd Rst_x = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd Rst_y = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd Rst_z = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd R = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd localangle = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd Vst_x = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd Vst_y = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd Vst_z = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd fde = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd fr = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd Rx = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd sigam = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd echoAmp = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols()).array() + Pt;
Eigen::MatrixXd Rphi = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd TimeRange = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd TransAnt = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd ReciveAnt = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd AntTheta = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
Eigen::MatrixXd AntPhi = Eigen::MatrixXd::Zero(dem_x.rows(), dem_x.cols());
double minR = 0, maxR = 0;
double minLocalAngle = 0, maxLocalAngle = 0;
Vector3D Rt = { 0,0,0 };
SatelliteOribtNode oRs = SatelliteOribtNode{ 0 };;
Vector3D p0 = {}, slopeVector = {}, sateAntDirect = {};
Vector3D Rs = {}, Vs = {}, Ast = {};
SatelliteAntDirect antdirectNode = {};
std::complex<double> echofreq;
std::complex<double> Imag1(0, 1);
double TAntPattern = 1; // 发射天线方向图
double RAntPanttern = 1;// 接收天线方向图
double maxechoAmp = 1;
double tempAmp = 1;
for (long prfidx = 0; prfidx < prfcount_step; prfidx++)
{
oRs = sateOirbtNodes[prfidx + startprfidx];
// 计算天线方向图
for (long jj = 1; jj < dem_cols - 1; jj++) {
for (long ii = 1; ii < dem_rows - 1; ii++) {
p0.x = dem_x(ii, jj);
p0.y = dem_y(ii, jj);
p0.z = dem_z(ii, jj);
this->TaskSetting->getSatelliteAntDirectNormal(oRs, p0, antdirectNode);
//antdirectNode.ThetaAnt = antdirectNode.ThetaAnt * r2d;
//antdirectNode.PhiAnt = antdirectNode.PhiAnt * r2d;
AntTheta(ii, jj) = antdirectNode.ThetaAnt * r2d;
AntPhi(ii, jj) = antdirectNode.PhiAnt * r2d;
}
}
// 计算发射天线方向图
for (long jj = 1; jj < dem_cols - 1; jj++) {
for (long ii = 1; ii < dem_rows - 1; ii++) {
TransformPattern->getGainLinear(AntTheta(ii, jj), AntPhi(ii, jj), TransAnt(ii, jj));
//TransAnt(ii, jj) = TAntPattern;
}
}
// 计算接收天线方向图
for (long jj = 1; jj < dem_cols - 1; jj++) {
for (long ii = 1; ii < dem_rows - 1; ii++) {
TransformPattern->getGainLinear(AntTheta(ii, jj), AntPhi(ii, jj), ReciveAnt(ii, jj));
//ReciveAnt(ii, jj) = RAntPanttern;
}
}
// 计算经过增益的能量
echoAmp = Pt * TransAnt.array() * ReciveAnt.array();
maxechoAmp = echoAmp.maxCoeff();
if (std::abs(maxechoAmp) < PRECISIONTOLERANCE) { // 这种情况下,不在合成孔径范围中
continue;
}
Rs.x = sateOirbtNodes[prfidx + startprfidx].Px; // 卫星位置
Rs.y = sateOirbtNodes[prfidx + startprfidx].Py;
Rs.z = sateOirbtNodes[prfidx + startprfidx].Pz;
Vs.x = sateOirbtNodes[prfidx + startprfidx].Vx; // 卫星速度
Vs.y = sateOirbtNodes[prfidx + startprfidx].Vy;
Vs.z = sateOirbtNodes[prfidx + startprfidx].Vz;
Ast.x = sateOirbtNodes[prfidx + startprfidx].AVx;// 卫星加速度
Ast.y = sateOirbtNodes[prfidx + startprfidx].AVy;
Ast.z = sateOirbtNodes[prfidx + startprfidx].AVz;
Rst_x = Rs.x - dem_x.array(); // Rst = Rs - Rt;
Rst_y = Rs.y - dem_y.array();
Rst_z = Rs.z - dem_z.array();
R = (Rst_x.array().pow(2) + Rst_y.array().pow(2) + Rst_z.array().pow(2)).array().sqrt(); // R
minR = R.minCoeff();
maxR = R.maxCoeff();
//qDebug() << "minR:\t" << minR << " maxR:\t" << maxR;
if (maxR<NearRange || minR>FarRange) {
continue;
}
else {}
// getCosAngle
// double c = dot(a, b) / (getlength(a) * getlength(b));
// return acos(c > 1 ? 1 : c < -1 ? -1 : c) * r2d;
// localangle = getCosAngle(Rst, slopeVector) * T180_PI; // 注意这个只能实时计算,因为非实时计算代价太大
localangle = (Rst_x.array() * demsloper_x.array() + Rst_y.array() * demsloper_y.array() + Rst_z.array() * demsloper_z.array()).array(); // dot(a, b)
localangle = localangle.array() / R.array();
localangle = localangle.array() / (demsloper_x.array().pow(2) + demsloper_y.array().pow(2) + demsloper_z.array().pow(2)).array().sqrt().array();
localangle = localangle.array().acos(); // 弧度值
minLocalAngle = localangle.minCoeff();
maxLocalAngle = localangle.maxCoeff();
if (maxLocalAngle<0 || minLocalAngle>PI / 2) {
continue;
}
else {}
//Vst_x = Vs.x + 1 * earthRoute * dem_y.array(); // Vst = Vs - Vt;
//Vst_y = Vs.y - 1 * earthRoute * dem_x.array();
//Vst_z = Vs.z - Eigen::MatrixXd::Zero(dem_x.rows(), dem_y.cols()).array();
//// 计算多普勒中心频率 Rst, Vst : ( - 2 / lamda) * dot(Rs - Rt, Vs - Vt) / R; // 星载合成孔径雷达原始回波数据模拟研究 3.18
//fde = (-2 / lamda) * (Rst_x.array() * Vst_x.array() + Rst_y.array() * Vst_y.array() + Rst_z.array() * Vst_z.array()).array() / (R.array());
//// 计算多普勒频率斜率 // 星载合成孔径雷达原始回波数据模拟研究 3.19
//// -(2/lamda)*( dot(Vs - Vt, Vs - Vt)/R + dot(Ast, Rs - Rt)/R - std::pow(dot(Vs - Vt, Rs - Rt),2 )/std::pow(R,3));
//fr = (-2 / lamda) *
// (Vst_x.array() * Vst_x.array() + Vst_y.array() * Vst_y.array() + Vst_z.array() * Vst_z.array()).array() / (R.array()) +
// (-2 / lamda) *
// (Ast.x * Rst_x.array() + Ast.y * Rst_y.array() + Ast.z * Rst_z.array()).array() / (R.array()) -
// (-2 / lamda) *
// (Vst_x.array() * Rst_x.array() + Vst_y.array() * Rst_y.array() + Vst_z.array() * Rst_z.array()).array().pow(2) / (R.array().pow(3));
// 计算回波
Rx = R;// -(lamda / 2) * (fde * TRx + 0.5 * fr * TRx * TRx); // 斜距历程值
// 逐点计算 this->SigmaDatabasePtr->getAmp(covercls, localangle, polartype); // 后向散射系数 HH
for (long ii = 0; ii < dem_x.rows(); ii++) {
for (long jj = 0; jj < dem_y.cols(); jj++) {
sigam(ii, jj) = this->SigmaDatabasePtr->getAmp(dem_landcls_ptr[dem_x.cols() * ii + jj], localangle(ii, jj) * r2d, polartype);
}
}
if (sigam.maxCoeff() > 0) {}
else {
continue;
}
// projArea = 1 / std::cos(sloperAngle) * std::sin(localangle); // 投影面积系数,单位投影面积 1m x 1m --注意这里是假设,后期再补充
// echoAmp = projArea*TAntPattern * RAntPanttern * sigam / (4 * PI * R * R);
echoAmp = echoAmp.array() * sigam.array() * (1 / sloperAngle.array().cos() * localangle.array().sin()); // 反射强度
echoAmp = echoAmp.array() / (4 * PI * R.array().pow(2)); // 距离衰减
Rphi = -4 * PI / lamda * Rx.array();// 距离徙动相位
// 积分
TimeRange = ((2 * R.array() / LIGHTSPEED - TimgNearRange).array() * Fs).array();
double localAnglepoint = -1;
long prf_freq_id = 0;
for (long jj = 1; jj < dem_cols - 1; jj++) {
for (long ii = 1; ii < dem_rows - 1; ii++) {
prf_freq_id = std::floor(TimeRange(ii, jj));
if (prf_freq_id < 0 || prf_freq_id >= PlusePoint || localangle(ii, jj) < 0 || localangle(ii, jj) > PI / 2 || echoAmp(ii, jj) == 0) {
continue;
}
echofreq = echoAmp(ii, jj) * std::exp(Rphi(ii, jj) * Imag1);
echoPluse(prfidx, prf_freq_id) = echoPluse(prfidx, prf_freq_id) + echofreq;
}
}
#ifdef DEBUGSHOWDIALOG
ImageShowDialogClass* localangledialog = new ImageShowDialogClass(dialog);
localangledialog->show();
localangledialog->load_double_MatrixX_data(localangle.array() * r2d, "localangle");
ImageShowDialogClass* sigamdialog = new ImageShowDialogClass(dialog);
sigamdialog->show();
sigamdialog->load_double_MatrixX_data(TimeRange, "TimeRange");
ImageShowDialogClass* ampdialog = new ImageShowDialogClass(dialog);
ampdialog->show();
ampdialog->load_double_MatrixX_data(echoAmp, "echoAmp");
Eigen::MatrixXd echoPluseamp = echoPluse.array().abs().cast<double>().array();
ImageShowDialogClass* echoampdialog = new ImageShowDialogClass(dialog);
echoampdialog->show();
echoampdialog->load_double_MatrixX_data(echoPluseamp, "echoPluseamp");
dialog->exec();
#endif
//qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") << " end " << prfidx;
}
//qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")<<" step "<< prfcount_step;
omp_set_lock(&lock); // 回波整体赋值处理
for (long prfidx = 0; prfidx < prfcount_step; prfidx++) {
for (long freqidx = 0; freqidx < PlusePoint; freqidx++)
{
//qDebug() << prfidx << " " << freqidx << " " << echoPluse(prfidx, freqidx).real() << " + " << echoPluse(prfidx, freqidx).imag() << " j";
echo.get()[(prfidx + startprfidx) * PlusePoint + freqidx] = echo.get()[(prfidx + startprfidx) * PlusePoint + freqidx] + echoPluse(prfidx, freqidx);
}
}
//this->EchoSimulationData->saveEchoArr(echo, 0, PluseCount);
omp_unset_lock(&lock); // 解锁
//qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") << " step 2" << prfcount_step;
}
omp_set_lock(&lock); // 保存文件
processNumber = processNumber + pluseStep;
this->EchoSimulationData->saveEchoArr(echo, 0, PluseCount);
omp_unset_lock(&lock); // 解锁
qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz") << " \t " << start_ids << "\t--\t " << start_ids + line_invert << "\t/\t" << demxyz.height;
}
omp_destroy_lock(&lock); // 销毁锁
*/