CUDA 3D阵列中的2D分层纹理(浮点vs int)

CUDA 3D阵列中的2D分层纹理(浮点vs int),cuda,Cuda,我得到了下面的程序,它几乎是SDK示例“简单分层纹理” //包括,系统 #包括 #包括 #包括 #包括 //包括,内核 #包括 //包括,项目 #包括 #包括//CUDA SDK示例共有的共享帮助程序 #定义出口2 静态字符*sSDKname=“simpleLayeredTexture”; //包括,内核 //声明分层二维浮动纹理的纹理参考 //注意:现在不推荐使用纹理参考模板中的“dim”字段。 //相反,请使用纹理类型宏,如CuDateTextureType1d等。 typedef int类

我得到了下面的程序,它几乎是SDK示例“简单分层纹理”

//包括,系统
#包括
#包括
#包括
#包括
//包括,内核
#包括
//包括,项目
#包括
#包括//CUDA SDK示例共有的共享帮助程序
#定义出口2
静态字符*sSDKname=“simpleLayeredTexture”;
//包括,内核
//声明分层二维浮动纹理的纹理参考
//注意:现在不推荐使用纹理参考模板中的“dim”字段。
//相反,请使用纹理类型宏,如CuDateTextureType1d等。
typedef int类型;
纹理纹理;
////////////////////////////////////////////////////////////////////////////////
//! 使用纹理查找变换分层2D纹理的层
//! @全局内存中的param g_odata输出数据
////////////////////////////////////////////////////////////////////////////////
__全局无效
transformKernel(类型*g_odata,整数宽度,整数高度,整数层)
{
//计算此线程的数据点
无符号整数x=blockIdx.x*blockDim.x+threadIdx.x;
无符号整数y=blockIdx.y*blockDim.y+threadIdx.y;
//0.5f偏移和分割是访问原始数据点所必需的
//在纹理中(这样双线性插值将不会被激活)。
//有关详细信息,请参见CUDA编程指南,附录D
浮动u=(x+0.5f)/(浮动)宽度;
浮动v=(y+0.5f)/(浮动)高度;
//从纹理中读取,执行预期的转换并写入全局内存
类型样本=tex2DLayered(tex,u,v,layered);
g_odata[层*宽度*高度+y*宽度+x]=样本;
printf(“样本%d\n”,样本);
}
////////////////////////////////////////////////////////////////////////////////
//主程序
////////////////////////////////////////////////////////////////////////////////
int
主(内部argc,字符**argv)
{
printf(“[%s]-开始…\n”,sSDKname);
//使用命令行指定的CUDA设备,否则使用Gflops/s最高的设备
int-devID=findCudaDevice(argc,(const-char**)argv);
bool-bResult=true;
//获取此GPU上的短信数
cudaDeviceProp设备PROPS;
检查CUDAERRORS(cudaGetDeviceProperties(&deviceProps,devID));
printf(“CUDA设备[%s]有%d个多处理器”,deviceProps.name,deviceProps.multiProcessorCount);
printf(“SM%d.%d\n”,deviceProps.major,deviceProps.minor);
如果(设备主减速器<2)
{
printf(“%s要求SM>=2.0以支持纹理数组。将放弃测试…\n”,sSDKname);
cudaDeviceReset();
退出(退出成功);
}
//为分层纹理生成输入数据
无符号整数宽度=16,高度=16,层数=5;
无符号整数大小=宽度*高度*层数*大小(类型);
类型*h_数据=(类型*)malloc(大小);
对于(无符号整数层=0;层(d_数据,宽度,高度,0);//预热(用于更好的计时)
//检查内核执行是否产生错误
getLastCudaError(“预热内核执行失败”);
检查CUDAErrors(cudaDeviceSynchronize());
StopWatchInterface*计时器=NULL;
sdkCreateTimer(&timer);
sdkStartTimer(&timer);
//执行内核
对于(无符号整数层=0;层(d_数据、宽度、高度、层);
//检查内核执行是否产生错误
getLastCudaError(“内核执行失败”);
检查CUDAErrors(cudaDeviceSynchronize());
sdkStopTimer(&timer);
printf(“处理时间:%.3f毫秒\n”,sdkGetTimerValue(&timer));
printf(%.2f Mtexlookups/sec\n),(宽度*高度*层数/(sdkGetTimerValue(&timer)/1000.0f)/1e6);
sdkDeleteTimer(&timer);
//为主机端的结果分配mem
类型*h_odata=(类型*)malloc(大小);
//将结果从设备复制到主机
检查CUDAERRORS(cudaMemcpy(h_odata,d_数据,大小,cudaMemcpyDeviceToHost));
printf(“将内核输出与预期数据进行比较\n”);
#定义最小ε误差5e-3f
// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

// includes, kernels
#include <cuda_runtime.h>

// includes, project
#include <helper_cuda.h>
#include <helper_functions.h>  // helper for shared that are common to CUDA SDK samples

#define EXIT_WAIVED 2

static char *sSDKname = "simpleLayeredTexture";

// includes, kernels
// declare texture reference for layered 2D float texture
// Note: The "dim" field in the texture reference template is now deprecated.
// Instead, please use a texture type macro such as cudaTextureType1D, etc.

typedef int TYPE;

texture<TYPE, cudaTextureType2DLayered> tex;

////////////////////////////////////////////////////////////////////////////////
//! Transform a layer of a layered 2D texture using texture lookups
//! @param g_odata  output data in global memory
////////////////////////////////////////////////////////////////////////////////
__global__ void
transformKernel(TYPE *g_odata, int width, int height, int layer)
{
    // calculate this thread's data point
    unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;

    // 0.5f offset and division are necessary to access the original data points
    // in the texture (such that bilinear interpolation will not be activated).
    // For details, see also CUDA Programming Guide, Appendix D
    float u = (x+0.5f) / (float) width;
    float v = (y+0.5f) / (float) height;

    // read from texture, do expected transformation and write to global memory
    TYPE sample = tex2DLayered(tex, u, v, layer);
    g_odata[layer*width*height + y*width + x] = sample;

    printf("Sample %d\n", sample);
}


////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int
main(int argc, char **argv)
{
    printf("[%s] - Starting...\n", sSDKname);

    // use command-line specified CUDA device, otherwise use device with highest Gflops/s
    int devID = findCudaDevice(argc, (const char **)argv);

    bool bResult = true;

    // get number of SMs on this GPU
    cudaDeviceProp deviceProps;

    checkCudaErrors(cudaGetDeviceProperties(&deviceProps, devID));
    printf("CUDA device [%s] has %d Multi-Processors ", deviceProps.name, deviceProps.multiProcessorCount);
    printf("SM %d.%d\n", deviceProps.major, deviceProps.minor);

    if (deviceProps.major < 2)
    {
        printf("%s requires SM >= 2.0 to support Texture Arrays.  Test will be waived... \n", sSDKname);
        cudaDeviceReset();
        exit(EXIT_SUCCESS);
    }

    // generate input data for layered texture
    unsigned int width=16, height=16, num_layers = 5;
    unsigned int size = width * height * num_layers * sizeof(TYPE);
    TYPE *h_data = (TYPE *) malloc(size);

    for (unsigned int layer = 0; layer < num_layers; layer++)
        for (int i = 0; i < (int)(width * height); i++)
        {
            h_data[layer*width*height + i] = 15;//(float)i;
        }

    // this is the expected transformation of the input data (the expected output)
    TYPE *h_data_ref = (TYPE *) malloc(size);

    for (unsigned int layer = 0; layer < num_layers; layer++)
        for (int i = 0; i < (int)(width * height); i++)
        {
            h_data_ref[layer*width*height + i] = h_data[layer*width*height + i];
        }

    // allocate device memory for result
    TYPE *d_data = NULL;
    checkCudaErrors(cudaMalloc((void **) &d_data, size));

    // allocate array and copy image data
    cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<TYPE>();
    cudaArray *cu_3darray;
    checkCudaErrors(cudaMalloc3DArray(&cu_3darray, &channelDesc, make_cudaExtent(width, height, num_layers), cudaArrayLayered));
    cudaMemcpy3DParms myparms = {0};
    myparms.srcPos = make_cudaPos(0,0,0);
    myparms.dstPos = make_cudaPos(0,0,0);
    myparms.srcPtr = make_cudaPitchedPtr(h_data, width * sizeof(TYPE), width, height);
    myparms.dstArray = cu_3darray;
    myparms.extent = make_cudaExtent(width, height, num_layers);
    myparms.kind = cudaMemcpyHostToDevice;
    checkCudaErrors(cudaMemcpy3D(&myparms));

    // set texture parameters
    tex.addressMode[0] = cudaAddressModeWrap;
    tex.addressMode[1] = cudaAddressModeWrap;
//    tex.filterMode = cudaFilterModeLinear;
    tex.filterMode = cudaFilterModePoint;
    tex.normalized = true;  // access with normalized texture coordinates

    // Bind the array to the texture
    checkCudaErrors(cudaBindTextureToArray(tex, cu_3darray, channelDesc));

    dim3 dimBlock(8, 8, 1);
    dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);

    printf("Covering 2D data array of %d x %d: Grid size is %d x %d, each block has 8 x 8 threads\n",
           width, height, dimGrid.x, dimGrid.y);

    transformKernel<<< dimGrid, dimBlock >>>(d_data, width, height, 0);  // warmup (for better timing)

    // check if kernel execution generated an error
    getLastCudaError("warmup Kernel execution failed");

    checkCudaErrors(cudaDeviceSynchronize());

    StopWatchInterface *timer = NULL;
    sdkCreateTimer(&timer);
    sdkStartTimer(&timer);

    // execute the kernel
    for (unsigned int layer = 0; layer < num_layers; layer++)
        transformKernel<<< dimGrid, dimBlock, 0 >>>(d_data, width, height, layer);

    // check if kernel execution generated an error
    getLastCudaError("Kernel execution failed");

    checkCudaErrors(cudaDeviceSynchronize());
    sdkStopTimer(&timer);
    printf("Processing time: %.3f msec\n", sdkGetTimerValue(&timer));
    printf("%.2f Mtexlookups/sec\n", (width *height *num_layers / (sdkGetTimerValue(&timer) / 1000.0f) / 1e6));
    sdkDeleteTimer(&timer);

    // allocate mem for the result on host side
    TYPE *h_odata = (TYPE *) malloc(size);
    // copy result from device to host
    checkCudaErrors(cudaMemcpy(h_odata, d_data, size, cudaMemcpyDeviceToHost));

    printf("Comparing kernel output to expected data\n");

#define MIN_EPSILON_ERROR 5e-3f
    bResult = compareData(h_odata, h_data_ref, width*height*num_layers, MIN_EPSILON_ERROR, 0.0f);

    printf("Host sample: %d == %d\n", h_data_ref[0], h_odata[0]);

    // cleanup memory
    free(h_data);
    free(h_data_ref);
    free(h_odata);

    checkCudaErrors(cudaFree(d_data));
    checkCudaErrors(cudaFreeArray(cu_3darray));

    cudaDeviceReset();

    if (bResult)
        printf("Success!");
    else
        printf("Failure!");

    exit(bResult ? EXIT_SUCCESS : EXIT_FAILURE);
}
typedef int TYPE;
typedef float TYPE;
printf("Sample %d\n", sample);
               ^^
$ cat t1519.cu
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

// includes, kernels
#include <cuda_runtime.h>

// includes, project
#include <helper_cuda.h>
#include <helper_functions.h>  // helper for shared that are common to CUDA SDK samples

#define EXIT_WAIVED 2

static char *sSDKname = "simpleLayeredTexture";

// includes, kernels
// declare texture reference for layered 2D float texture
// Note: The "dim" field in the texture reference template is now deprecated.
// Instead, please use a texture type macro such as cudaTextureType1D, etc.

typedef float TYPE;

texture<TYPE, cudaTextureType2DLayered> tex;

////////////////////////////////////////////////////////////////////////////////
//! Transform a layer of a layered 2D texture using texture lookups
//! @param g_odata  output data in global memory
////////////////////////////////////////////////////////////////////////////////
__global__ void
transformKernel(TYPE *g_odata, int width, int height, int layer)
{
    // calculate this thread's data point
    unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
    unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;

    // 0.5f offset and division are necessary to access the original data points
    // in the texture (such that bilinear interpolation will not be activated).
    // For details, see also CUDA Programming Guide, Appendix D
    float u = (x+0.5f) / (float) width;
    float v = (y+0.5f) / (float) height;

    // read from texture, do expected transformation and write to global memory
    TYPE sample = tex2DLayered(tex, u, v, layer);
    g_odata[layer*width*height + y*width + x] = sample;

    printf("Sample %f\n", sample);
}


////////////////////////////////////////////////////////////////////////////////
// Program main
////////////////////////////////////////////////////////////////////////////////
int
main(int argc, char **argv)
{
    printf("[%s] - Starting...\n", sSDKname);

    // use command-line specified CUDA device, otherwise use device with highest Gflops/s
    int devID = findCudaDevice(argc, (const char **)argv);

    bool bResult = true;

    // get number of SMs on this GPU
    cudaDeviceProp deviceProps;

    checkCudaErrors(cudaGetDeviceProperties(&deviceProps, devID));
    printf("CUDA device [%s] has %d Multi-Processors ", deviceProps.name, deviceProps.multiProcessorCount);
    printf("SM %d.%d\n", deviceProps.major, deviceProps.minor);

    if (deviceProps.major < 2)
    {
        printf("%s requires SM >= 2.0 to support Texture Arrays.  Test will be waived... \n", sSDKname);
        cudaDeviceReset();
        exit(EXIT_SUCCESS);
    }

    // generate input data for layered texture
    unsigned int width=16, height=16, num_layers = 5;
    unsigned int size = width * height * num_layers * sizeof(TYPE);
    TYPE *h_data = (TYPE *) malloc(size);

    for (unsigned int layer = 0; layer < num_layers; layer++)
        for (int i = 0; i < (int)(width * height); i++)
        {
            h_data[layer*width*height + i] = 15;//(float)i;
        }

    // this is the expected transformation of the input data (the expected output)
    TYPE *h_data_ref = (TYPE *) malloc(size);

    for (unsigned int layer = 0; layer < num_layers; layer++)
        for (int i = 0; i < (int)(width * height); i++)
        {
            h_data_ref[layer*width*height + i] = h_data[layer*width*height + i];
        }

    // allocate device memory for result
    TYPE *d_data = NULL;
    checkCudaErrors(cudaMalloc((void **) &d_data, size));

    // allocate array and copy image data
    cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<TYPE>();
    cudaArray *cu_3darray;
    checkCudaErrors(cudaMalloc3DArray(&cu_3darray, &channelDesc, make_cudaExtent(width, height, num_layers), cudaArrayLayered));
    cudaMemcpy3DParms myparms = {0};
    myparms.srcPos = make_cudaPos(0,0,0);
    myparms.dstPos = make_cudaPos(0,0,0);
    myparms.srcPtr = make_cudaPitchedPtr(h_data, width * sizeof(TYPE), width, height);
    myparms.dstArray = cu_3darray;
    myparms.extent = make_cudaExtent(width, height, num_layers);
    myparms.kind = cudaMemcpyHostToDevice;
    checkCudaErrors(cudaMemcpy3D(&myparms));

    // set texture parameters
    tex.addressMode[0] = cudaAddressModeWrap;
    tex.addressMode[1] = cudaAddressModeWrap;
//    tex.filterMode = cudaFilterModeLinear;
    tex.filterMode = cudaFilterModePoint;
    tex.normalized = true;  // access with normalized texture coordinates

    // Bind the array to the texture
    checkCudaErrors(cudaBindTextureToArray(tex, cu_3darray, channelDesc));

    dim3 dimBlock(8, 8, 1);
    dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);

    printf("Covering 2D data array of %d x %d: Grid size is %d x %d, each block has 8 x 8 threads\n",
           width, height, dimGrid.x, dimGrid.y);

    transformKernel<<< dimGrid, dimBlock >>>(d_data, width, height, 0);  // warmup (for better timing)

    // check if kernel execution generated an error
    getLastCudaError("warmup Kernel execution failed");

    checkCudaErrors(cudaDeviceSynchronize());

    StopWatchInterface *timer = NULL;
    sdkCreateTimer(&timer);
    sdkStartTimer(&timer);

    // execute the kernel
    for (unsigned int layer = 0; layer < num_layers; layer++)
        transformKernel<<< dimGrid, dimBlock, 0 >>>(d_data, width, height, layer);

    // check if kernel execution generated an error
    getLastCudaError("Kernel execution failed");

    checkCudaErrors(cudaDeviceSynchronize());
    sdkStopTimer(&timer);
    printf("Processing time: %.3f msec\n", sdkGetTimerValue(&timer));
    printf("%.2f Mtexlookups/sec\n", (width *height *num_layers / (sdkGetTimerValue(&timer) / 1000.0f) / 1e6));
    sdkDeleteTimer(&timer);

    // allocate mem for the result on host side
    TYPE *h_odata = (TYPE *) malloc(size);
    // copy result from device to host
    checkCudaErrors(cudaMemcpy(h_odata, d_data, size, cudaMemcpyDeviceToHost));

    printf("Comparing kernel output to expected data\n");

#define MIN_EPSILON_ERROR 5e-3f
    bResult = compareData(h_odata, h_data_ref, width*height*num_layers, MIN_EPSILON_ERROR, 0.0f);

    printf("Host sample: %d == %d\n", h_data_ref[0], h_odata[0]);

    // cleanup memory
    free(h_data);
    free(h_data_ref);
    free(h_odata);

    checkCudaErrors(cudaFree(d_data));
    checkCudaErrors(cudaFreeArray(cu_3darray));

    cudaDeviceReset();

    if (bResult)
        printf("Success!");
    else
        printf("Failure!");

    exit(bResult ? EXIT_SUCCESS : EXIT_FAILURE);
}
$ nvcc -I/usr/local/cuda/samples/common/inc t1519.cu -o t1519
t1519.cu(15): warning: conversion from a string literal to "char *" is deprecated

t1519.cu(15): warning: conversion from a string literal to "char *" is deprecated

[user2@dc10 misc]$ cuda-memcheck ./t1519
========= CUDA-MEMCHECK
[simpleLayeredTexture] - Starting...
GPU Device 0: "Tesla V100-PCIE-32GB" with compute capability 7.0

CUDA device [Tesla V100-PCIE-32GB] has 80 Multi-Processors SM 7.0
Covering 2D data array of 16 x 16: Grid size is 2 x 2, each block has 8 x 8 threads
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
Sample 15.000000
...
Sample 15.000000
Sample 15.000000
Sample 15.000000
Processing time: 13.991 msec
0.09 Mtexlookups/sec
Comparing kernel output to expected data
Host sample: 8964432 == 1
Success!========= ERROR SUMMARY: 0 errors
$
printf("Host sample: %d == %d\n", h_data_ref[0], h_odata[0]);