I want to ask how can I convert this texture:
texture<int, 2, cudaReadModeElementType> text1;
to
texture<int4, 2, cudaReadModeElementType> text2;
So my problem is with the indexes. For example, imagine that I acceesed to the col 10 row 5 in text1 like this
int col 10;
int row 5;
int tex2d(text1, col, row);
But if I did the same, obviously I'm not accessing to the same data:
int col 10;
int row 5;
int4 tex2d(text2, col, row);
So, I tried like dividing the col / 4 and row /4, but I don't succeed either. I think that I should use DIV and MOD, but I don't know how.
Does anyone know how to access correctly using 4 channels? Thank you very much!
The only indexing you need to modify between the two cases is the horizontal (x
) indexing. For the int4
case, the horizontal indexing can be divided by 4 (as compared to the int
case) but it will retrieve 4 values. Here is a full example:
$ cat t1918.cu
#include <helper_cuda.h>
#include <cstdio>
#define HEIGHT 7680
#ifndef USE_INT4
#define WIDTH 7245
typedef int it;
#else
#define WIDTH 1812
typedef int4 it;
#endif
cudaArray * Array_Device;
texture<it, 2,cudaReadModeElementType> Image;
__global__ void k(int x, int y)
{
int w;
#ifdef USE_INT4
w = WIDTH*4;
#else
w = WIDTH;
#endif
for (y = 0; y < HEIGHT; y++)
for (x = 0; x < w; x++){
int nx=x, no=0;
#ifdef USE_INT4
no = x&3; //modulo by 4
nx >>= 2; //division by 4
#endif
it val = tex2D(Image,nx,y);
int rval = reinterpret_cast<int *>(&val)[no];
if (rval != y*10000+x) {
printf("mismatch at %d, %d, was: %d, should be: %d\n", x,y, rval, y*10000+x);
return;
}
}
}
void p()
{
it *h = new it[WIDTH*HEIGHT];
// this dataset and test-case only works for textures up to width of 9999 for int or 2499 for int4
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++){
#ifndef USE_INT4
h[i*WIDTH+j] = i*10000+j;
#else
h[i*WIDTH+j] = {i*10000+j*4+0, i*10000+j*4+1, i*10000+j*4+2, i*10000+j*4+3};
#endif
}
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<it>();
checkCudaErrors(cudaMallocArray(&Array_Device, &channelDesc,WIDTH,HEIGHT ));
checkCudaErrors(cudaBindTextureToArray(Image,Array_Device));
checkCudaErrors(cudaMemcpy2DToArray( Array_Device,
0,
0,
h,
WIDTH*sizeof(it),
WIDTH*sizeof(it),
HEIGHT,
cudaMemcpyHostToDevice));
k<<<1,1>>>(0,0);
checkCudaErrors(cudaDeviceSynchronize());
}
int main(){
#ifdef USE_INT4
printf("int4\n");
#endif
p();
return 0;
}
$ nvcc -I/usr/local/cuda/samples/common/inc -o t1918 t1918.cu
t1918.cu(40): warning: function "tex2D(texture<T, 2, cudaReadModeElementType>, float, float) [with T=it]"
/usr/local/cuda/bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated
t1918.cu: In function ‘void p()’:
t1918.cu:63:49: warning: ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t) [with T = int; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’ is deprecated [-Wdeprecated-declarations]
checkCudaErrors(cudaBindTextureToArray(Image,Array_Device));
^
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1642:53: note: declared here
static __CUDA_DEPRECATED __inline__ __host__ cudaError_t cudaBindTextureToArray(
^~~~~~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h: In instantiation of ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t) [with T = int; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’:
t1918.cu:63:49: required from here
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1650:55: warning: ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t, const cudaChannelFormatDesc&) [with T = int; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’ is deprecated [-Wdeprecated-declarations]
return err == cudaSuccess ? cudaBindTextureToArray(tex, array, desc) : err;
~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1603:53: note: declared here
static __CUDA_DEPRECATED __inline__ __host__ cudaError_t cudaBindTextureToArray(
^~~~~~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h: In instantiation of ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t, const cudaChannelFormatDesc&) [with T = int; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’:
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1650:55: required from ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t) [with T = int; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’
t1918.cu:63:49: required from here
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1609:32: warning: ‘cudaError_t cudaBindTextureToArray(const textureReference*, cudaArray_const_t, const cudaChannelFormatDesc*)’ is deprecated [-Wdeprecated-declarations]
return ::cudaBindTextureToArray(&tex, array, &desc);
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime_api.h:8662:46: note: declared here
extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindTextureToArray(const struct textureReference *texref, cudaArray_const_t array, const struct cudaChannelFormatDesc *desc);
^~~~~~~~~~~~~~~~~~~~~~
$ cuda-memcheck ./t1918
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors
$ nvcc -I/usr/local/cuda/samples/common/inc -o t1918 t1918.cu -DUSE_INT4
t1918.cu(40): warning: function "tex2D(texture<T, 2, cudaReadModeElementType>, float, float) [with T=it]"
/usr/local/cuda/bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated
t1918.cu: In function ‘void p()’:
t1918.cu:63:49: warning: ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t) [with T = int4; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’ is deprecated [-Wdeprecated-declarations]
checkCudaErrors(cudaBindTextureToArray(Image,Array_Device));
^
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1642:53: note: declared here
static __CUDA_DEPRECATED __inline__ __host__ cudaError_t cudaBindTextureToArray(
^~~~~~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h: In instantiation of ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t) [with T = int4; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’:
t1918.cu:63:49: required from here
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1650:55: warning: ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t, const cudaChannelFormatDesc&) [with T = int4; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’ is deprecated [-Wdeprecated-declarations]
return err == cudaSuccess ? cudaBindTextureToArray(tex, array, desc) : err;
~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1603:53: note: declared here
static __CUDA_DEPRECATED __inline__ __host__ cudaError_t cudaBindTextureToArray(
^~~~~~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h: In instantiation of ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t, const cudaChannelFormatDesc&) [with T = int4; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’:
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1650:55: required from ‘cudaError_t cudaBindTextureToArray(const texture<T, dim, readMode>&, cudaArray_const_t) [with T = int4; int dim = 2; cudaTextureReadMode readMode = (cudaTextureReadMode)0; cudaError_t = cudaError; cudaArray_const_t = const cudaArray*]’
t1918.cu:63:49: required from here
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime.h:1609:32: warning: ‘cudaError_t cudaBindTextureToArray(const textureReference*, cudaArray_const_t, const cudaChannelFormatDesc*)’ is deprecated [-Wdeprecated-declarations]
return ::cudaBindTextureToArray(&tex, array, &desc);
~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime_api.h:8662:46: note: declared here
extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaBindTextureToArray(const struct textureReference *texref, cudaArray_const_t array, const struct cudaChannelFormatDesc *desc);
^~~~~~~~~~~~~~~~~~~~~~
$ cuda-memcheck ./t1918
========= CUDA-MEMCHECK
int4
========= ERROR SUMMARY: 0 errors
$
The data stored in the texture in the int
case looks like this:
0 1 2 3 4 5 6 7 ...
1000 1001 1002 1003 1004 1005 1006 1007...
2000 2001 2002 2003 2004 2005 2006 2007...
3000 3001 3002 3003 3004 3005 3006 3007...
...
In the int4
case it looks like this:
{ 0, 1, 2, 3} { 4, 5, 6, 7} ...
{1000,1001,1002,1003} {1004,1005,1006,1007} ...
{2000,2001,2002,2003} {2004,2005,2006,2007} ...
{3000,3001,3002,3003} {3004,3005,3006,3007} ...
...
The kernel demonstrates how to retrieve the same value for a given (x,y)
coordinate given to the kernel, in either case.
Note that textures are deprecated and for new work you should switch to texture objects.