如何将CUDA tex1DFetch与CUDateTextureObject_t一起使用?
当我注意到纹理引用被弃用时,我正在使用纹理引用,我尝试更新我的测试函数以使用tex1Dfetch的“新”无绑定纹理对象,但无法产生相同的结果 我目前正在探索使用纹理内存来加速我的aho corasick实现;我能够让tex1D处理纹理引用,但是,我注意到它们已被弃用,并决定使用纹理对象 当我试图以任何方式使用结果时,我得到了一些非常奇怪的内核行为;我可以做结果[tidx]=tidx;没有任何问题,但结果[tidx]=temp+1;仅返回temp not temp*3的值或任何其他涉及temp的数值测试 我看不出这种行为的逻辑原因,文档示例看起来非常相似,我看不出哪里出了问题 我已经读过CUDA tex1Dfetch错误的行为和新的CUDA纹理对象-在2D情况下获取错误的数据,但两者似乎都与我遇到的问题无关 以防万一,这会产生影响;我正在使用CUDA版本10.0,V10.0.130和Nvidia GTX 980ti如何将CUDA tex1DFetch与CUDateTextureObject_t一起使用?,cuda,textures,Cuda,Textures,当我注意到纹理引用被弃用时,我正在使用纹理引用,我尝试更新我的测试函数以使用tex1Dfetch的“新”无绑定纹理对象,但无法产生相同的结果 我目前正在探索使用纹理内存来加速我的aho corasick实现;我能够让tex1D处理纹理引用,但是,我注意到它们已被弃用,并决定使用纹理对象 当我试图以任何方式使用结果时,我得到了一些非常奇怪的内核行为;我可以做结果[tidx]=tidx;没有任何问题,但结果[tidx]=temp+1;仅返回temp not temp*3的值或任何其他涉及temp的数
#include <iostream>
__global__ void test(cudaTextureObject_t tex ,int* results){
int tidx = threadIdx.y * blockDim.x + threadIdx.x;
unsigned temp = tex1Dfetch<unsigned>(tex, threadIdx.x);
results[tidx] = temp * 3;
}
int main(){
int *host_arr;
const int host_arr_size = 8;
// Create and populate host array
std::cout << "Host:" << std::endl;
cudaMallocHost(&host_arr, host_arr_size*sizeof(int));
for (int i = 0; i < host_arr_size; ++i){
host_arr[i] = i * 2;
std::cout << host_arr[i] << std::endl;
}
// Create resource description
struct cudaResourceDesc resDesc;
resDesc.resType = cudaResourceTypeLinear;
resDesc.res.linear.devPtr = &host_arr;
resDesc.res.linear.sizeInBytes = host_arr_size*sizeof(unsigned);
resDesc.res.linear.desc = cudaCreateChannelDesc<unsigned>();
// Create texture description
struct cudaTextureDesc texDesc;
texDesc.readMode = cudaReadModeElementType;
// Create texture
cudaTextureObject_t tex;
cudaCreateTextureObject(&tex, &resDesc, &texDesc, NULL);
// Allocate results array
int * result_arr;
cudaMalloc(&result_arr, host_arr_size*sizeof(unsigned));
// launch test kernel
test<<<1, host_arr_size>>>(tex, result_arr);
// fetch results
std::cout << "Device:" << std::endl;
cudaMemcpy(host_arr, result_arr, host_arr_size*sizeof(unsigned), cudaMemcpyDeviceToHost);
// print results
for (int i = 0; i < host_arr_size; ++i){
std::cout << host_arr[i] << std::endl;
}
// Tidy Up
cudaDestroyTextureObject(tex);
cudaFreeHost(host_arr);
cudaFree(result_arr);
}
实际结果:
Host:
0
2
4
6
8
10
12
14
Device:
0
2
4
6
8
10
12
14
有人知道到底出了什么问题吗?CUDA API函数调用返回错误代码。您想检查这些错误代码。特别是当某处明显出了问题 您可以使用相同的数组来存储初始数组数据以及从设备接收结果。内核启动失败,出现非法地址错误,因为您没有有效的纹理对象。您没有有效的纹理对象,因为创建纹理对象失败。内核启动后的第一个API调用是cudaMemcpy,用于返回结果。由于内核启动期间出错,将失败,返回最新的错误而不是执行复制。因此,host_arr缓冲区的内容保持不变,您只需再次显示原始输入数据即可 创建纹理对象失败的原因在“重点”中解释: 如果cudaResourceDesc::resType设置为cudaResourceTypeLinear,则必须将cudaResourceDesc::res::linear::devPtr设置为与cudaDeviceProp::textureAlignment对齐的有效设备指针。[……] 纹理对象无法引用主体内存。代码中的问题在于:
resDesc.res.linear.devPtr = &host_arr;
您需要在decive内存中分配一个缓冲区,例如,使用cudaMalloc,将数据复制到那里,并创建一个引用该设备缓冲区的纹理对象
此外,您的texDesc没有正确初始化。在您的情况下,仅将其初始化为零就足够了:
struct cudaTextureDesc texDesc = {};
CUDA API函数调用返回错误代码。您想检查这些错误代码。特别是当某处明显出了问题 您可以使用相同的数组来存储初始数组数据以及从设备接收结果。内核启动失败,出现非法地址错误,因为您没有有效的纹理对象。您没有有效的纹理对象,因为创建纹理对象失败。内核启动后的第一个API调用是cudaMemcpy,用于返回结果。由于内核启动期间出错,将失败,返回最新的错误而不是执行复制。因此,host_arr缓冲区的内容保持不变,您只需再次显示原始输入数据即可 创建纹理对象失败的原因在“重点”中解释: 如果cudaResourceDesc::resType设置为cudaResourceTypeLinear,则必须将cudaResourceDesc::res::linear::devPtr设置为与cudaDeviceProp::textureAlignment对齐的有效设备指针。[……] 纹理对象无法引用主体内存。代码中的问题在于:
resDesc.res.linear.devPtr = &host_arr;
您需要在decive内存中分配一个缓冲区,例如,使用cudaMalloc,将数据复制到那里,并创建一个引用该设备缓冲区的纹理对象
此外,您的texDesc没有正确初始化。在您的情况下,仅将其初始化为零就足够了:
struct cudaTextureDesc texDesc = {};
我不敢相信我错过了,谢谢你的提示!我在CUDA Pro提示中看到了memset初始化:开普勒纹理对象提高了性能和灵活性示例,因此认为这是必要的。我不敢相信我错过了,谢谢提示!我在CUDA Pro提示中看到了memset初始化:开普勒纹理对象提高了性能和灵活性示例,因此认为这是必需的。