tex2D使用学习

1. 背景:

        项目中使用到了纹理进行插值的加速,因此记录一些自己在学习tex2D的一些过程

2. 代码:

        

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <assert.h>
#include <stdio.h>
#include <iostream>
#include <cuda_fp16.h>
#include <vector>

void Data2Half(half* pDst, const int16_t* pSrc, const int Ndots);
static __global__ void Tex2DTest(cudaTextureObject_t p_rf_data, float* pfRes1, float* pfRes2);


static __global__ void data2half(half* pDst, const int16_t* pSrc, const int Ndots)
{
    const int tid = blockIdx.x * blockDim.x + threadIdx.x;
    if (tid >= Ndots)
        return;

    pDst[tid] = __short2half_rn(pSrc[tid]);
}

cudaTextureObject_t m_tex   = 0;
cudaArray* m_pRFData        = nullptr;
int16_t* m_i16RFDataBuffer  = nullptr; // 设备端的RF数据
half* m_pHalfRFDataCache    = nullptr; // 转换为半浮点型的RF数据缓存,用于将SHORT类型转换为FLOAT类型

int main()
{
    const int nRx     = 2;
    const int Nsample = 2;
    const int IQ      = 1;
    cudaError_t error;

    cudaChannelFormatDesc channelDesc = cudaCreateChannelDescHalf();
    error                             = cudaMallocArray(&m_pRFData, &channelDesc, nRx * IQ, Nsample, cudaArrayTextureGather);
    assert(m_pRFData);

    cudaResourceDesc texRes;
    memset(&texRes, 0, sizeof(cudaResourceDesc));
    texRes.resType         = cudaResourceTypeArray;
    texRes.res.array.array = m_pRFData;

    cudaTextureDesc texDescr;
    memset(&texDescr, 0, sizeof(cudaTextureDesc));
    texDescr.normalizedCoords = false;
    texDescr.filterMode       = cudaFilterModeLinear;  // 这里很重要
    texDescr.addressMode[0]   = cudaAddressModeBorder;
    texDescr.addressMode[1]   = cudaAddressModeBorder;


    error = cudaCreateTextureObject(&m_tex, &texRes, &texDescr, NULL);

    //int16_t pi16Src[nRx * Nsample * IQ] = {1, 11, 2, 22,
    //                                    3, 33, 4, 44, 
    //                                    5, 55, 6, 66, 
    //                                    7, 77, 8, 88};

    //int16_t pi16Src[nRx * Nsample * IQ] = { 1, 11, 2, 22,
    //                                        3, 33, 4, 44};


    int16_t pi16Src[nRx * Nsample * IQ] = { 1,2,
                                           3,4 };

    error = cudaMalloc(&m_i16RFDataBuffer, sizeof(int16_t) * nRx * IQ * Nsample);
    error = cudaMemcpy(m_i16RFDataBuffer, pi16Src, sizeof(int16_t) * nRx * IQ * Nsample, cudaMemcpyHostToDevice);

    error = cudaMalloc(&m_pHalfRFDataCache, sizeof(half) * nRx * IQ * Nsample);
    Data2Half(m_pHalfRFDataCache, m_i16RFDataBuffer, nRx * IQ * Nsample);

    error = cudaMemcpy2DToArray(m_pRFData, 0, 0, m_pHalfRFDataCache, sizeof(half) * nRx * IQ, sizeof(half) * nRx * IQ, Nsample, cudaMemcpyDeviceToDevice);

    float* pf_res1 = nullptr;
    float* pf_res2 = nullptr;

    error = cudaMalloc(&pf_res1, nRx * Nsample * sizeof(float)); cudaMemset(pf_res1, 0, nRx * Nsample * sizeof(float));
    error = cudaMalloc(&pf_res2, nRx * Nsample * sizeof(float)); cudaMemset(pf_res2, 0, nRx * Nsample * sizeof(float));
    
    error = cudaGetLastError();

    dim3 block_dim = dim3(1, 1);
    dim3 grid_dim  = dim3(1, 1);
    Tex2DTest << <grid_dim, block_dim >> > (m_tex, pf_res1, pf_res2);

    cudaDeviceSynchronize();

    std::vector<float> vf_res_1(nRx * Nsample, 0);
    std::vector<float> vf_res_2(nRx * Nsample, 0);

    cudaMemcpy(vf_res_1.data(), pf_res1, sizeof(float) * vf_res_1.size(), cudaMemcpyDeviceToHost);
    cudaMemcpy(vf_res_2.data(), pf_res2, sizeof(float) * vf_res_2.size(), cudaMemcpyDeviceToHost);

    return 0;
}

void Data2Half(half* pDst, const int16_t* pSrc, const int Ndots)
{
    dim3 block = dim3(512, 1);
    dim3 grid = dim3((Ndots - 1) / block.x + 1, 1);
    data2half << < grid, block >> > (pDst, pSrc, Ndots);
}

static __global__ void Tex2DTest(cudaTextureObject_t p_rf_data, float *pfRes1, float *pfRes2)
{

    for (size_t y = 0; y < 2; ++y)
    {
        for (size_t x = 0; x < 2; ++x) 
        {
            float value = tex2D<float>(p_rf_data, x,     y);
            //pfRes1[y * 4 + y] = 

            printf("x: %f\n", value);
        }
    }
}

3. 输出分析:

可以看到执行结果是

为什么呢?

原因是因为tex2D插值导致的,上面测试数据是

1  2

3   4

那在进行插值的时候会变成

0  0   0   0

0   1   2  0

0   3   4  0

每个点的输出都是当前前和左上角3个点进行平均计算出来的

比如第一个输出计算为:(1 + 0 + 0 + 0)/4 = 0.25

最后一个输出的计算为:(1 + 2 + 3 + 4) / 4 = 2.5

4. 问题

        上面只是单独数据实数点的计算,如果我的数据集合是复数怎么办?

        比如一组2 * 2大小的数据对

        (1, 2, 3, 4;

           5,   6, 7, 8)

        数据实际表示含义是

         (1 + j * 2,   3 + j * 4;

            5 + j * 6,   7 + j * 8)

        这种情况下怎么做到正确插值呢,比如第一个实数点的输出结果应该是

         (1 + 0 + 0 + 0)/ 4

           最后一个实数点的输出应该是:

            (1 + 3 + 5 + 7) / 4

           同理,最后一个虚数点的输出应该是:
           (2 + 4 + 6 + 8)/ 4

5. 解决

         

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <assert.h>
#include <stdio.h>
#include <iostream>
#include <cuda_fp16.h>
#include <vector>

void Data2Half(half* pDst, const int16_t* pSrc, const int Ndots);
static __global__ void Tex2DTest(cudaTextureObject_t p_rf_data, float* pfRes1, float* pfRes2);


static __global__ void data2half(half* pDst, const int16_t* pSrc, const int Ndots)
{
    const int tid = blockIdx.x * blockDim.x + threadIdx.x;
    if (tid >= Ndots)
        return;

    pDst[tid] = __short2half_rn(pSrc[tid]);
}

cudaTextureObject_t m_tex = 0;
cudaArray* m_pRFData = nullptr;
int16_t* m_i16RFDataBuffer = nullptr; // 设备端的RF数据
half* m_pHalfRFDataCache = nullptr; // 转换为半浮点型的RF数据缓存,用于将SHORT类型转换为FLOAT类型

using namespace std;

int main()
{
    const int nRx = 2;
    const int Nsample = 2;
    const int IQ = 2;
    cudaError_t error;

    cudaChannelFormatDesc channelDesc = cudaCreateChannelDescHalf2();
    error = cudaMallocArray(&m_pRFData, &channelDesc, nRx, Nsample, cudaArrayTextureGather);
    assert(m_pRFData);

    cudaResourceDesc texRes;
    memset(&texRes, 0, sizeof(cudaResourceDesc));
    texRes.resType = cudaResourceTypeArray;
    texRes.res.array.array = m_pRFData;

    cudaTextureDesc texDescr;
    memset(&texDescr, 0, sizeof(cudaTextureDesc));
    texDescr.normalizedCoords = false;
    texDescr.filterMode = cudaFilterModeLinear;  // 这里很重要
    texDescr.addressMode[0] = cudaAddressModeBorder;
    texDescr.addressMode[1] = cudaAddressModeBorder;


    error = cudaCreateTextureObject(&m_tex, &texRes, &texDescr, NULL);

    //int16_t pi16Src[nRx * Nsample * IQ] = {1, 11, 2, 22,
    //                                    3, 33, 4, 44, 
    //                                    5, 55, 6, 66, 
    //                                    7, 77, 8, 88};

    //int16_t pi16Src[nRx * Nsample * IQ] = { 1, 11, 2, 22,
    //                                        3, 33, 4, 44};


    int16_t pi16Src[nRx * Nsample * IQ] = { 1, 2, 3, 4,
                                            5, 6, 7, 8 };

    error = cudaMalloc(&m_i16RFDataBuffer, sizeof(int16_t) * nRx * IQ * Nsample);
    error = cudaMemcpy(m_i16RFDataBuffer, pi16Src, sizeof(int16_t) * nRx * IQ * Nsample, cudaMemcpyHostToDevice);

    error = cudaMalloc(&m_pHalfRFDataCache, sizeof(half) * nRx * IQ * Nsample);
    Data2Half(m_pHalfRFDataCache, m_i16RFDataBuffer, nRx * IQ * Nsample);

    error = cudaMemcpy2DToArray(m_pRFData, 0, 0, m_pHalfRFDataCache, sizeof(half2) * nRx, sizeof(half2) * nRx, Nsample, cudaMemcpyDeviceToDevice);

    float* pf_res1 = nullptr;
    float* pf_res2 = nullptr;

    error = cudaMalloc(&pf_res1, nRx * Nsample * sizeof(float)); cudaMemset(pf_res1, 0, nRx * Nsample * sizeof(float));
    error = cudaMalloc(&pf_res2, nRx * Nsample * sizeof(float)); cudaMemset(pf_res2, 0, nRx * Nsample * sizeof(float));

    error = cudaGetLastError();

    dim3 block_dim = dim3(1, 1);
    dim3 grid_dim  = dim3(1, 1);
    Tex2DTest << <grid_dim, block_dim >> > (m_tex, pf_res1, pf_res2);

    cudaDeviceSynchronize();

    std::vector<float> vf_res_1(nRx * Nsample, 0);
    std::vector<float> vf_res_2(nRx * Nsample, 0);

    cudaMemcpy(vf_res_1.data(), pf_res1, sizeof(float) * vf_res_1.size(), cudaMemcpyDeviceToHost);
    cudaMemcpy(vf_res_2.data(), pf_res2, sizeof(float) * vf_res_2.size(), cudaMemcpyDeviceToHost);

    return 0;
}

void Data2Half(half* pDst, const int16_t* pSrc, const int Ndots)
{
    dim3 block = dim3(512, 1);
    dim3 grid = dim3((Ndots - 1) / block.x + 1, 1);
    data2half << < grid, block >> > (pDst, pSrc, Ndots);
}

static __global__ void Tex2DTest(cudaTextureObject_t p_rf_data, float* pfRes1, float* pfRes2)
{

    for (size_t y = 0; y < 2; ++y)
    {
        for (size_t x = 0; x < 2; ++x)
        {
            float2 value = tex2D<float2>(p_rf_data, x, y);
            //pfRes1[y * 4 + y] = 

            printf("x: %f, y: %f", value.x, value.y);
            // printf("x: %f, y: %f\n", value.x, value.y);
        }
        printf("\n");
    }
}

其实关键是在tex2D的构造

然后按照half2的方式进行排布就好了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/205536.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【23真题】复录比高达2.24,但题目很棒!

今天分享的是23年广东工业837的信号与系统试题及解析。注意官方不公示真题&#xff0c;所以这套试卷为回忆版本。 本套试卷难度分析&#xff1a;22年广东工业837考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;平均分107.93&#xff…

腾讯云手动下发指令到设备-用于设备调试

打开腾讯云API Explorer&#xff0c;Publish Msg https://console.cloud.tencent.com/api/explorer?Productiotcloud&Version2021-04-08&ActionPublishMessagehttps://console.cloud.tencent.com/api/explorer?Productiotcloud&Version2021-04-08&ActionPub…

RocketMQ源码剖析之createUniqID方法

目录 版本信息&#xff1a; 写在前面&#xff1a; 源码剖析&#xff1a; 总计&#xff1a; 版本信息&#xff1a; RocketMQ-5.1.3 源码地址&#xff1a;https://github.com/apache/rocketmq 写在前面&#xff1a; 首先&#xff0c;笔者先吐槽一下RocketMQ的官方&#xff0…

【DDD】领域驱动设计总结——如何构造领域模型

文章目录 一 分离领域二 领域对象分类2.1 实体(ENTITY)2.2 值对象(VALUE OBJECT)2.3 服务(SERVICE)2.4 模块&#xff08;&#xff2d;ODULE&#xff09; 三 管理领域对象的生命周期3.1 聚合&#xff08;AGGREGATE&#xff09;3.2 工厂&#xff08;FACTORY&#xff09;3.3 存储库…

UE5富文本框学习(用途:A(名字)用刀(图片)击杀B(名字))

UE5-UMG教程-通用控件&#xff1a;多格式文本块&#xff08;RichTextBlock&#xff09;_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Pu4y1k7Z2/?p54&spm_id_frompageDriver 结果示例&#xff1a; 1.添加富文本框 2.添加文字样式库 点添加&#xff0c;更改每行行…

PostGIS学习教程八:空间关系

PostGIS学习教程八&#xff1a;空间关系 到目前为止&#xff0c;我们只使用了测量&#xff08;ST_Area、ST_Length&#xff09;、序列化&#xff08;ST_GeomFromText&#xff09;或者反序列化&#xff08;ST_AsGML&#xff09;几何图形&#xff08;geometry&#xff09;的空间…

【OJ比赛日历】快周末了,不来一场比赛吗? #12.02-12.08 #15场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-12-02&#xff08;周六&#xff09; #4场比赛2023-12-03…

五种多目标优化算法(MSSA、MOAHA、MOPSO、NSGA3、NSGA2)求解微电网多目标优化调度(MATLAB)

一、多目标优化算法简介 &#xff08;1&#xff09;多目标鳟海鞘算法MSSA 多目标优化算法&#xff1a;多目标鳟海鞘算法&#xff08;Multi-objective Salp Swarm Algorithm &#xff0c;MSSA&#xff09;-CSDN博客 参考文献&#xff1a; S. Mirjalili, A.H. Gandomi, S.Z. M…

C语言--每日选择题--Day31

第一题 1. 下面程序 i 的值为&#xff08;&#xff09; int main() {int i 10;int j 0;if (j 0)i; elsei--; return 0; } A&#xff1a;11 B&#xff1a;9 答案及解析 B if语句中的条件判断为赋值语句的时候&#xff0c;因为赋值语句的返回值是右操作数&#xff1b; …

系统设计面试指南之分布式任务调度

1 简介 任务是需要资源(CPU 时间、内存、存储、网络带宽等)在指定时间内完成的一段计算工作。 通过智能地将资源分配给任务以满足任务级和系统级目标的系统称为任务调度程序。 任务调度程序&#xff1a; 及时决定和分配资源给任务的过程称为任务调度。 当我们在 Facebook 发…

13-Vue基础之自定义指令与插槽的使用

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…

【驱动】串口驱动分析(二)-tty core

前言 tty这个名称源于电传打字节的简称&#xff0c;在linux表示各种终端&#xff0c;终端通常都跟硬件相对应。比如对应于输入设备键盘鼠标&#xff0c;输出设备显示器的控制终端和串口终端。也有对应于不存在设备的pty驱动。在如此众多的终端模型之中&#xff0c;linux是怎么…

jmeter做接口自动化测试,你可能只是个新手!

jmeter 这个工具既可以做接口的功能测试&#xff0c;也可以做自动化测试&#xff0c;还可以做性能测试&#xff0c;其主要用途就是用于性能测试。但是&#xff0c;有些公司和个人&#xff0c;就想用 jmeter 来做接口自动化测试。 你有没有想过呢&#xff1f; 下面我就给大家讲…

WPF应用开发之附件管理

在我们之前的开发框架中&#xff0c;往往都是为了方便&#xff0c;对附件的管理都会进行一些简单的封装&#xff0c;目的是为了方便快速的使用&#xff0c;并达到统一界面的效果&#xff0c;本篇随笔介绍我们基于SqlSugar开发框架的WPF应用端&#xff0c;对于附件展示和控件的一…

软考:2024年软考高级:软件工程

软考&#xff1a;2024年软考高级: 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &#xff08;1…

性能测试线上监控

如果你的产品出现了一个线上问题&#xff0c;你会是怎么样的反应&#xff1f; 也许会跟下面这张图一样。 哇&#xff01;有一个线上bug&#xff0c;好慌呀&#xff01;&#xff01; 咦&#xff0c;问题似乎自动解决了&#xff1f;渐渐冷静。 不对&#xff01;&#xff01;&a…

数据结构:图文详解顺序表的各种操作(新增元素,查找元素,删除元素,给指定位置元素赋值)

目录 一.顺序表的概念 二.顺序表的实现 新增元素 默认尾部新增 指定位置添加元素 查找元素 查找是否存在 查找元素对应的位置 查找指定位置对应的元素 删除元素 获取顺序表长度 清空顺序表 一.顺序表的概念 在线性数据结构中&#xff0c;我们一般分为俩类&#xf…

2023.11.29 -hmzx电商平台建设项目 -核销主题阶段总结

目录 1.准备源数据 2.准备数仓工具进行源数据同步到ods层,本项目使用Datax 3.使用Datax完成数据同步前建表时的方案选择 3.1同步方式区别: 3.2存储格式和压缩区别: 4.在hive中创建表,共31个表 5.数仓概念 和 数仓建模方案 5.1数仓的基本概念 5.2 数仓建模方案 关系建模…

接口02-Java

接口02 一、接口与继承类1、引入2、总结&#xff08;1&#xff09;接口和继承解决的问题不同。&#xff08;2&#xff09;接口比继承更加灵活。&#xff08;3&#xff09;接口在一定程度上实现代码解耦。 二、接口的多态性1、多态参数① 回顾&#xff1a;继承中的多态② 接口的…

银河麒麟v10——植物大战僵尸原版——2023教程

1、原版安装包如下&#xff1a; 阿里云盘分享https://www.alipan.com/s/Qn5DpDKs2YT 2、麒麟信息&#xff1a; 3、安装命令&#xff1a; 注意&#xff1a;最后一步&#xff0c;需要先解压tar包&#xff0c;再切到PlantsVsZombies.exe所在目录下&#xff0c;再执行启动命令&a…