簡體   English   中英

如何在CUDA中將不同種類的紋理綁定到紋理參考?

[英]How to bind different kinds of textures to a texture reference in CUDA?

這段代碼適用於Cuda 4.2

extern "C" texture<int,1,cudaReadModeElementType> __tex0;
extern "C" __global__ void kernel(){
  float4 f = tex1Dfetch(*(texture<float4,1,cudaReadModeElementType>*)&__tex0,ii_z)
}

由於Cuda更改了語法,我無法從紋理中獲取不同類型的紋理,知道嗎?

PS 我已經在參考中找到了Cuda 紋理對象 ,但是要更改所有出現次數需要進行大量工作。 是否有較小的代碼更改更好的解決方案?

謝謝

如果有人想要原始代碼,請單擊此處

似乎最小的repro情況是:

texture<int,1,cudaReadModeElementType> __tex0;

__global__ void kernel0(float4 *out)
{
    int t__a = blockIdx.x*blockDim.x+threadIdx.x;
    int ii = (t__a*3);
    float4 rr = tex1Dfetch(*(texture<float4,1,cudaReadModeElementType>*)&__tex0,ii);
    out[t__a] = rr;
}

CUDA 7.5將無法編譯此內核,並顯示以下錯誤:

texture_repo.cu(7):錯誤:無法使用__device__/__global__函數中的紋理/表面變量"__tex0"地址

我相信這是正確的。 紋理引用是不透明的占位符類型,不具有POD類型的任何常規屬性,對於是否編寫代碼(例如您提供的鏈接示例),我將非常懷疑。

但是,確實CUDA 4.2會對此進行編譯並發出有效的PTX:

.entry _Z7kernel0P6float4(
        .param .u64 _Z7kernel0P6float4_param_0
)
{
        .reg .f32       %f<25>;
        .reg .s32       %r<8>;
        .reg .s64       %rl<5>;


        ld.param.u64    %rl1, [_Z7kernel0P6float4_param_0];
        cvta.to.global.u64      %rl2, %rl1;
        .loc 2 5 1
        mov.u32         %r2, %ntid.x;
        mov.u32         %r3, %ctaid.x;
        mov.u32         %r4, %tid.x;
        mad.lo.s32      %r5, %r2, %r3, %r4;
        .loc 2 6 1
        mul.lo.s32      %r1, %r5, 3;
        mov.u32         %r6, 0;
        // inline asm
        tex.1d.v4.f32.s32 {%f1, %f2, %f3, %f4}, [__tex0, {%r1}];
        // inline asm
        .loc 2 8 1
        mul.wide.s32    %rl3, %r5, 16;
        add.s64         %rl4, %rl2, %rl3;
        st.global.v4.f32        [%rl4], {%f1, %f2, %f3, %f4};
        .loc 2 9 2
        ret;
}

顯然,強制轉換除了抑制編譯器錯誤外沒有其他作用,並且在PTX級別上讀取是有效的,因為紋理引用讀取始終返回四寬矢量類型,即使多余的矢量元素為空且被忽略。 我認為在CUDA 4.2中進行編譯是一個編譯器錯誤,在這種情況下CUDA 7.5似乎是正確的。

也就是說,一個非常棘手的解決方法是:

texture<int,1,cudaReadModeElementType> __tex0;

__device__ float4 tex_load0(int idx)
{
    float4 temp;
    asm("tex.1d.v4.f32.s32 {%0, %1, %2, %3}, [__tex0, {%4}];" :
        "=f"(temp.x), "=f"(temp.y), "=f"(temp.z), "=f"(temp.w) : "r"(idx));
    return temp;
}

__global__ void kernel1(float4 *out)
{
    int t__a = blockIdx.x*blockDim.x+threadIdx.x;
    int ii = (t__a*3);
    float4 rr = tex_load0(ii); 
    out[t__a] = rr;
}

[免責聲明:已編譯,但從未經過測試。 不建議。 使用風險自負]。

例如,將CUDA 4.2編譯器內聯發出的相同PTX插入到設備函數中,並用對設備函數的調用替換紋理提取。 使用CUDA 7.5工具鏈,它發出:

//
// Generated by NVIDIA NVVM Compiler
//
// Compiler Build ID: CL-19856038
// Cuda compilation tools, release 7.5, V7.5.17
// Based on LLVM 3.4svn
//

.version 4.3
.target sm_30
.address_size 64

    // .globl   _Z9tex_load0i
.global .texref __tex0;

.visible .func  (.param .align 16 .b8 func_retval0[16]) _Z9tex_load0i(
    .param .b32 _Z9tex_load0i_param_0
)
{
    .reg .f32   %f<5>;
    .reg .b32   %r<2>;


    ld.param.u32    %r1, [_Z9tex_load0i_param_0];
    // inline asm
    tex.1d.v4.f32.s32 {%f1, %f2, %f3, %f4}, [__tex0, {%r1}];
    // inline asm
    st.param.f32    [func_retval0+0], %f1;
    st.param.f32    [func_retval0+4], %f2;
    st.param.f32    [func_retval0+8], %f3;
    st.param.f32    [func_retval0+12], %f4;
    ret;
}

    // .globl   _Z7kernel1P6float4
.visible .entry _Z7kernel1P6float4(
    .param .u64 _Z7kernel1P6float4_param_0
)
{
    .reg .f32   %f<5>;
    .reg .b32   %r<6>;
    .reg .b64   %rd<5>;


    ld.param.u64    %rd1, [_Z7kernel1P6float4_param_0];
    cvta.to.global.u64  %rd2, %rd1;
    mov.u32     %r2, %ctaid.x;
    mov.u32     %r3, %ntid.x;
    mov.u32     %r4, %tid.x;
    mad.lo.s32  %r5, %r3, %r2, %r4;
    mul.lo.s32  %r1, %r5, 3;
    mul.wide.s32    %rd3, %r5, 16;
    add.s64     %rd4, %rd2, %rd3;
    // inline asm
    tex.1d.v4.f32.s32 {%f1, %f2, %f3, %f4}, [__tex0, {%r1}];
    // inline asm
    st.global.v4.f32    [%rd4], {%f1, %f2, %f3, %f4};
    ret;
}

與發布的CUDA 4.2工具鏈相同的PTX。 之所以可行,是因為編譯器無法對嵌入式PTX應用幾乎相同級別的類型安全檢查。 但是,請認真考慮您是否真的想這樣做,因為(在我看來)這是不確定的行為。

還要注意,由於在PTX中處理紋理引用的方式,您不能將它們作為顯式參數傳遞,因此您將需要在代碼中為每個紋理定義一個讀取函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM