FFmpeg
cuda_runtime.h
Go to the documentation of this file.
1 /*
2  * Minimum CUDA compatibility definitions header
3  *
4  * Copyright (c) 2019 Rodger Combs
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #ifndef COMPAT_CUDA_CUDA_RUNTIME_H
24 #define COMPAT_CUDA_CUDA_RUNTIME_H
25 
26 // Common macros
27 #define __global__ __attribute__((global))
28 #define __device__ __attribute__((device))
29 #define __device_builtin__ __attribute__((device_builtin))
30 #define __align__(N) __attribute__((aligned(N)))
31 #define __inline__ __inline__ __attribute__((always_inline))
32 
33 #define max(a, b) ((a) > (b) ? (a) : (b))
34 #define min(a, b) ((a) < (b) ? (a) : (b))
35 #define abs(x) ((x) < 0 ? -(x) : (x))
36 
37 #define atomicAdd(a, b) (__atomic_fetch_add(a, b, __ATOMIC_SEQ_CST))
38 
39 // Basic typedefs
40 typedef __device_builtin__ unsigned long long cudaTextureObject_t;
41 
43 {
44  unsigned char x, y;
46 
48 {
49  unsigned short x, y;
51 
53 {
54  float x, y;
56 
57 typedef struct __device_builtin__ __align__(8) int2
58 {
59  int x, y;
60 } int2;
61 
62 typedef struct __device_builtin__ uint3
63 {
64  unsigned int x, y, z;
65 } uint3;
66 
67 typedef struct uint3 dim3;
68 
69 typedef struct __device_builtin__ __align__(4) uchar4
70 {
71  unsigned char x, y, z, w;
73 
74 typedef struct __device_builtin__ __align__(8) ushort4
75 {
76  unsigned char x, y, z, w;
78 
79 typedef struct __device_builtin__ __align__(16) int4
80 {
81  int x, y, z, w;
82 } int4;
83 
84 typedef struct __device_builtin__ __align__(16) float4
85 {
86  float x, y, z, w;
88 
89 // Accessors for special registers
90 #define GETCOMP(reg, comp) \
91  asm("mov.u32 %0, %%" #reg "." #comp ";" : "=r"(tmp)); \
92  ret.comp = tmp;
93 
94 #define GET(name, reg) static inline __device__ uint3 name() {\
95  uint3 ret; \
96  unsigned tmp; \
97  GETCOMP(reg, x) \
98  GETCOMP(reg, y) \
99  GETCOMP(reg, z) \
100  return ret; \
101 }
102 
103 GET(getBlockIdx, ctaid)
104 GET(getBlockDim, ntid)
105 GET(getThreadIdx, tid)
106 
107 // Instead of externs for these registers, we turn access to them into calls into trivial ASM
108 #define blockIdx (getBlockIdx())
109 #define blockDim (getBlockDim())
110 #define threadIdx (getThreadIdx())
111 
112 // Basic initializers (simple macros rather than inline functions)
113 #define make_int2(a, b) ((int2){.x = a, .y = b})
114 #define make_uchar2(a, b) ((uchar2){.x = a, .y = b})
115 #define make_ushort2(a, b) ((ushort2){.x = a, .y = b})
116 #define make_float2(a, b) ((float2){.x = a, .y = b})
117 #define make_int4(a, b, c, d) ((int4){.x = a, .y = b, .z = c, .w = d})
118 #define make_uchar4(a, b, c, d) ((uchar4){.x = a, .y = b, .z = c, .w = d})
119 #define make_ushort4(a, b, c, d) ((ushort4){.x = a, .y = b, .z = c, .w = d})
120 #define make_float4(a, b, c, d) ((float4){.x = a, .y = b, .z = c, .w = d})
121 
122 // Conversions from the tex instruction's 4-register output to various types
123 #define TEX2D(type, ret) static inline __device__ void conv(type* out, unsigned a, unsigned b, unsigned c, unsigned d) {*out = (ret);}
124 
125 TEX2D(unsigned char, a & 0xFF)
126 TEX2D(unsigned short, a & 0xFFFF)
127 TEX2D(float, a)
128 TEX2D(uchar2, make_uchar2(a & 0xFF, b & 0xFF))
129 TEX2D(ushort2, make_ushort2(a & 0xFFFF, b & 0xFFFF))
131 TEX2D(uchar4, make_uchar4(a & 0xFF, b & 0xFF, c & 0xFF, d & 0xFF))
132 TEX2D(ushort4, make_ushort4(a & 0xFFFF, b & 0xFFFF, c & 0xFFFF, d & 0xFFFF))
133 TEX2D(float4, make_float4(a, b, c, d))
134 
135 // Template calling tex instruction and converting the output to the selected type
136 template<typename T>
137 inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
138 {
139  T ret;
140  unsigned ret1, ret2, ret3, ret4;
141  asm("tex.2d.v4.u32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
142  "=r"(ret1), "=r"(ret2), "=r"(ret3), "=r"(ret4) :
143  "l"(texObject), "f"(x), "f"(y));
144  conv(&ret, ret1, ret2, ret3, ret4);
145  return ret;
146 }
147 
148 template<>
149 inline __device__ float4 tex2D<float4>(cudaTextureObject_t texObject, float x, float y)
150 {
151  float4 ret;
152  asm("tex.2d.v4.f32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
153  "=r"(ret.x), "=r"(ret.y), "=r"(ret.z), "=r"(ret.w) :
154  "l"(texObject), "f"(x), "f"(y));
155  return ret;
156 }
157 
158 template<>
159 inline __device__ float tex2D<float>(cudaTextureObject_t texObject, float x, float y)
160 {
161  return tex2D<float4>(texObject, x, y).x;
162 }
163 
164 template<>
165 inline __device__ float2 tex2D<float2>(cudaTextureObject_t texObject, float x, float y)
166 {
167  float4 ret = tex2D<float4>(texObject, x, y);
168  return make_float2(ret.x, ret.y);
169 }
170 
171 // Math helper functions
172 static inline __device__ float floorf(float a) { return __builtin_floorf(a); }
173 static inline __device__ float floor(float a) { return __builtin_floorf(a); }
174 static inline __device__ double floor(double a) { return __builtin_floor(a); }
175 static inline __device__ float ceilf(float a) { return __builtin_ceilf(a); }
176 static inline __device__ float ceil(float a) { return __builtin_ceilf(a); }
177 static inline __device__ double ceil(double a) { return __builtin_ceil(a); }
178 static inline __device__ float truncf(float a) { return __builtin_truncf(a); }
179 static inline __device__ float trunc(float a) { return __builtin_truncf(a); }
180 static inline __device__ double trunc(double a) { return __builtin_trunc(a); }
181 static inline __device__ float fabsf(float a) { return __builtin_fabsf(a); }
182 static inline __device__ float fabs(float a) { return __builtin_fabsf(a); }
183 static inline __device__ double fabs(double a) { return __builtin_fabs(a); }
184 
185 static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); }
186 static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); }
187 
188 #endif /* COMPAT_CUDA_CUDA_RUNTIME_H */
static __device__ float __cosf(float a)
Definition: cuda_runtime.h:186
static __device__ float floorf(float a)
Definition: cuda_runtime.h:172
static int conv(int samples, float **pcm, char *buf, int channels)
Definition: libvorbisdec.c:131
static __device__ float trunc(float a)
Definition: cuda_runtime.h:179
ushort2
Definition: cuda_runtime.h:50
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
static __device__ float ceilf(float a)
Definition: cuda_runtime.h:175
uchar2
Definition: cuda_runtime.h:45
static __device__ float ceil(float a)
Definition: cuda_runtime.h:176
#define GET(name, reg)
Definition: cuda_runtime.h:94
static __device__ float floor(float a)
Definition: cuda_runtime.h:173
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
__device__ float2 tex2D< float2 >(cudaTextureObject_t texObject, float x, float y)
Definition: cuda_runtime.h:165
#define __align__(N)
Definition: cuda_runtime.h:30
#define TEX2D(type, ret)
Definition: cuda_runtime.h:123
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
#define make_ushort2(a, b)
Definition: cuda_runtime.h:115
static __device__ float __sinf(float a)
Definition: cuda_runtime.h:185
int2
Definition: cuda_runtime.h:60
unsigned int z
Definition: cuda_runtime.h:64
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
ushort4
Definition: cuda_runtime.h:77
__device_builtin__ unsigned long long cudaTextureObject_t
Definition: cuda_runtime.h:40
#define make_uchar4(a, b, c, d)
Definition: cuda_runtime.h:118
#define __device__
Definition: cuda_runtime.h:28
#define b
Definition: input.c:41
#define T(x)
Definition: vp56_arith.h:29
uint8_t w
Definition: llviddspenc.c:38
uchar4
Definition: cuda_runtime.h:72
#define __device_builtin__
Definition: cuda_runtime.h:29
#define make_uchar2(a, b)
Definition: cuda_runtime.h:114
#define make_float4(a, b, c, d)
Definition: cuda_runtime.h:120
static __device__ float truncf(float a)
Definition: cuda_runtime.h:178
float2
Definition: cuda_runtime.h:55
#define make_ushort4(a, b, c, d)
Definition: cuda_runtime.h:119
float4
Definition: cuda_runtime.h:87
#define make_float2(a, b)
Definition: cuda_runtime.h:116
__device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
Definition: cuda_runtime.h:137
int4
Definition: cuda_runtime.h:82
__device__ float tex2D< float >(cudaTextureObject_t texObject, float x, float y)
Definition: cuda_runtime.h:159
__device__ float4 tex2D< float4 >(cudaTextureObject_t texObject, float x, float y)
Definition: cuda_runtime.h:149