0

我有许多我想在我的应用程序中使用的向量。在方形网格中,这些是我可以从单元格中心开始的基数和对角线方向的向量。我的 OpenCL 内核会经常使用它们,所以我想在常量内存中定义它们。我在内核文件中编写了以下代码:

#define N_RADIAN  2 * M_PI_4_F
#define NE_RADIAN 1 * M_PI_4_F
#define E_RADIAN  0 * M_PI_4_F
#define SE_RADIAN 7 * M_PI_4_F
#define S_RADIAN  6 * M_PI_4_F
#define SW_RADIAN 5 * M_PI_4_F
#define W_RADIAN  4 * M_PI_4_F
#define NW_RADIAN 3 * M_PI_4_F

constant float2 E[8] = {
(float2)(cos( N_RADIAN), sin( N_RADIAN)),   // N
(float2)(cos(NE_RADIAN), sin(NE_RADIAN)),   // NE
(float2)(cos( E_RADIAN), sin( E_RADIAN)),   // E
(float2)(cos(SE_RADIAN), sin(SE_RADIAN)),   // SE
(float2)(cos( S_RADIAN), sin( S_RADIAN)),   // S
(float2)(cos(SW_RADIAN), sin(SW_RADIAN)),   // SW
(float2)(cos( W_RADIAN), sin( W_RADIAN)),   // W
(float2)(cos(NW_RADIAN), sin(NW_RADIAN))    // NW
};

这段代码拒绝为我编译。我收到的错误消息是 error: initializer element is not a compile-time constant。如果必须在设备上调用数学函数以使数组获取其值,我可以理解它。如果是这种情况,我可以制作一个计算这些值的内核,而不用大惊小怪。但是,这种方法对我来说会更方便。有什么方法可以让我在常量内存中声明这些值?您是否看到这种方法或代码有任何其他问题?

4

1 回答 1

3

我认为使用常量的唯一方法是使用这样的方法:

  constant float2 E[8] = {
  (0.0           , 1.0          ) ,   // N
  (CL_M_SQRT1_2  , CL_M_SQRT1_2 ) ,   // NE
  (1.0           , 0.0          ) ,   // E
  (CL_M_SQRT1_2  , -CL_M_SQRT1_2) ,   // SE
  (0.0           , -1.0         ) ,   // S
  (-CL_M_SQRT1_2 , -CL_M_SQRT1_2) ,   // SW
  (-1.0          , 0.0          ) ,   // W
  (-CL_M_SQRT1_2 , CL_M_SQRT1_2 )     // NW
  };

这个问题实际上可能是因祸得福。此替代代码生成精确到 32 位 IEEE 浮点数限制的值。由于 pi/4 和 M_PI_4_F 之间的差异,原始代码有点偏离。例如,原始代码生成 cosine (north) = -4.37114e-008 而不是预期的零值。

于 2013-09-30T02:56:34.147 回答