双打纹理对象

时间:2016-02-01 17:58:11

标签: cuda

我想使用带双打的纹理对象(不是引用)。使用浮点数时,下面的代码有效,但double不是受支持的数据类型。

我可以使用2d纹理解决这个问题,如果是这样,我该如何设置这样的纹理?

纹理参考有一个类似的问题,但纹理对象没有。 Support for double type in texture memory in CUDA

__global__ void my_print(cudaTextureObject_t texObject)
{
    printf("%f\n",tex1Dfetch<double>(texObject,0));

    return;
}

int main()
{

    double i = 0.35;
    int numel = 50;

    double* d_data;
    cudaMalloc(&d_data,numel*sizeof(double));
    cudaMemcpy((void*)d_data,&i,1*sizeof(double), cudaMemcpyHostToDevice);


    cudaTextureDesc td;
    memset(&td, 0, sizeof(td));

    td.normalizedCoords = 0;
    td.addressMode[0] = cudaAddressModeClamp;
    td.readMode = cudaReadModeElementType;


    struct cudaResourceDesc resDesc;
    memset(&resDesc, 0, sizeof(resDesc));
    resDesc.resType = cudaResourceTypeLinear;
    resDesc.res.linear.devPtr = d_data;
    resDesc.res.linear.sizeInBytes = numel*sizeof(double);
    resDesc.res.linear.desc.f = cudaChannelFormatKindFloat;
    resDesc.res.linear.desc.x = 32;

    cudaTextureObject_t texObject = 0;
    gpuErrchk(cudaCreateTextureObject(&texObject, &resDesc, &td, NULL));

    my_print<<<1,1>>>(texObject);

    gpuErrchk(cudaDeviceSynchronize());
    return 0;
}

1 个答案:

答案 0 :(得分:5)

这个想法与纹理参考完全相同。您可以通过将数据绑定到支持的64位类型并将生成的读取转换为double来访问双精度。如果您修改代码如下:

#include <vector>
#include <cstdio>

static __inline__ __device__ double fetch_double(uint2 p){
    return __hiloint2double(p.y, p.x);
}

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess) 
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}
__global__ void my_print(cudaTextureObject_t texObject)
{
    uint2 rval = tex1Dfetch<uint2>(texObject, 0);
    double dval = fetch_double(rval);
    printf("%f\n", dval);
}

int main()
{

    double i = 0.35;
    int numel = 50;

    std::vector<double> h_data(numel, i);
    double* d_data;
    cudaMalloc(&d_data,numel*sizeof(double));
    cudaMemcpy((void*)d_data, &h_data[0], numel*sizeof(double), cudaMemcpyHostToDevice);


    cudaTextureDesc td;
    memset(&td, 0, sizeof(td));
    td.normalizedCoords = 0;
    td.addressMode[0] = cudaAddressModeClamp;
    td.readMode = cudaReadModeElementType;


    struct cudaResourceDesc resDesc;
    memset(&resDesc, 0, sizeof(resDesc));
    resDesc.resType = cudaResourceTypeLinear;
    resDesc.res.linear.devPtr = d_data;
    resDesc.res.linear.sizeInBytes = numel*sizeof(double);
    resDesc.res.linear.desc.f = cudaChannelFormatKindUnsigned;
    resDesc.res.linear.desc.x = 32;
    resDesc.res.linear.desc.y = 32;

    cudaTextureObject_t texObject;
    gpuErrchk(cudaCreateTextureObject(&texObject, &resDesc, &td, NULL));

    my_print<<<1,1>>>(texObject);

    gpuErrchk(cudaDeviceSynchronize());
    return 0;
}

即。将通道描述修改为64位,从纹理对象读取uint2,然后将其转换为double,它应该可以正常工作。