Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays OpenCL中结构数组的垃圾输出_Arrays_Struct_Opencl - Fatal编程技术网

Arrays OpenCL中结构数组的垃圾输出

Arrays OpenCL中结构数组的垃圾输出,arrays,struct,opencl,Arrays,Struct,Opencl,我完全是OpenCL的初学者,我正在努力使下面的内核正常工作。我正在向内核传递一个结构数组,并试图修改它的值。我的结构声明是: #define LIST_SIZE 10 #pragma pack(push, 1) typedef struct pairt { int a; int b; } pairt; #pragma pack(pop) 我创建用于传递此结构的缓冲区的主机代码为: pairt p[LIST_SIZE]; p_mem_obj = clCreateBuffer

我完全是OpenCL的初学者,我正在努力使下面的内核正常工作。我正在向内核传递一个结构数组,并试图修改它的值。我的结构声明是:

#define LIST_SIZE 10
#pragma pack(push, 1)

typedef struct pairt {
    int a;
    int b;
} pairt;

#pragma pack(pop)
我创建用于传递此结构的缓冲区的主机代码为:

pairt p[LIST_SIZE];
p_mem_obj = clCreateBuffer(context, CL_MEM_READ_WRITE, LIST_SIZE*sizeof(struct pairt), NULL, &ret);
ret = clEnqueueWriteBuffer(command_queue, p_mem_obj, CL_TRUE, 0, LIST_SIZE*sizeof(struct pairt), &p, 0, NULL, NULL);
我设置内核参数的代码是:

ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&p_mem_obj);
size_t global_item_size = LIST_SIZE;
size_t local_item_size = 2;
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, &events[0]);
ret = clWaitForEvents(1, &events[0]);
ret = clReleaseEvent(events[0]);
ret = clEnqueueReadBuffer(command_queue, p_mem_obj, CL_TRUE, 0, LIST_SIZE*sizeof(struct pairt), p, 0, NULL, &events[1]);
ret = clWaitForEvents(1, &events[1]);
我的核心是:

struct __attribute__ ((packed)) pairt {
    int a;
    int b;
};

__kernel void simple_diff( __global struct pairt* p)
{
    int i = get_global_id(0);
    __global struct pairt *tmp = &p[i];

    tmp->a = tmp->a * -1;
    tmp->b = tmp->b * -1;

}
我使用以下值初始化了数组:

1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
17 18
19 20
但是内核返回的值是:

-298660672 -32767
0 0
-4198172 0
-298660832 -32767
-4200052 0
-1 -2
-3 -4
-5 -6
-7 -8
-9 -10

我不知道为什么会发生这种情况?

我在4核CPU和AMD6950GPU上使用Vs2010和AMD APP SDK,使用32位和64位构建的两种设备,尝试了下面的代码。这是我的工作

尝试将结构从pragma pack 1更改为默认打包或使用int2向量

/*  
Copyright (C) Tim Child 2012
All rights reserved

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <memory.h>
#include <malloc.h>

#include "CL\cl.h"

#define LIST_SIZE 10
#pragma pack(push, 1)

typedef struct pairt 
{
    int a;
    int b;
} pairt;

#pragma pack(pop)

typedef struct pair32 
{
    int32_t a;
    int32_t b;
} pair32;

void  printAligment( char * msg, size_t a, size_t b)
{
    printf("%s\n", msg);
    printf( "\t%d\t%d\n", a, b );
}

/**
    OpenCLEnvironment  An OpenCl Environment structure
**/

typedef struct OpenCLEnvironment
{
    cl_platform_id *    platformId;
    cl_uint             platformCount;  
    cl_device_id *      deviceId;
    cl_uint      *      deviceCount;    
    cl_uint             deviceTotal;
    cl_context          context;
    cl_command_queue    queue;
    cl_uint             currentPlatform;
    cl_uint             currentDevice;

} OpenCLEnvironment;

typedef struct OpenCLKernel
{
        char *      name;
        cl_program  program;
        cl_kernel   kernel;
        char *      sourceCode;
        char *      compilerOptions;
        char *      compilerErrors;

}  OpenCLKernel;

/**
    NewOpenCLEnvironment  Create a new OpenCL Environment
    @param[in]  currentPlatform  Index of the platform Id to use
    @param[in]  currentDevice    Index of the Device Id to use

    @returns OpenCL Environment
**/
OpenCLEnvironment * NewOpenCLEnvironment(cl_uint     currentPlatform, cl_uint    currentDevice)
{
    OpenCLEnvironment * environment = NULL;
    cl_int      error = 0;
    cl_uint     i = 0;
    cl_uint     sum;
    cl_uint     offset = 0;
    static cl_context_properties properties[] = { CL_CONTEXT_PLATFORM, 0, 0};

    if ( ( environment = (OpenCLEnvironment *)malloc(sizeof (OpenCLEnvironment  ) ) ) != NULL)
    {
        memset( environment, 0, sizeof(OpenCLEnvironment) );

        if ( ( error = clGetPlatformIDs( 0, NULL,  &environment->platformCount) ) == CL_SUCCESS)
        {
            environment->deviceCount = (cl_uint*)malloc( sizeof( cl_uint) * environment->platformCount  ) ;
            environment->platformId =  (cl_platform_id *)malloc( sizeof( cl_platform_id) * environment->platformCount  ) ;
            if ( environment->platformId &&
                environment->platformCount > 0 &&
                ( error = clGetPlatformIDs( environment->platformCount, environment->platformId,  0) ) == CL_SUCCESS)
            {
                sum = 0;
                for( i = 0; i < environment->platformCount; i++)
                {
                     if ( ( error = clGetDeviceIDs( environment->platformId[i], CL_DEVICE_TYPE_ALL, 0, NULL, &sum ) ) == CL_SUCCESS )
                     {
                         environment->deviceCount[i] = sum;
                         environment->deviceTotal += sum;
                     }
                }

                environment->deviceId = (cl_device_id *) malloc( sizeof(cl_device_id) * environment->deviceTotal );
                offset = 0;
                for( i = 0; i < environment->platformCount  && environment->deviceId; i++)
                {
                    if (  ( error = clGetDeviceIDs( environment->platformId[i], CL_DEVICE_TYPE_ALL, environment->deviceCount[i], 
                                        &environment->deviceId[offset],  &sum ) ) == CL_SUCCESS )
                    {
                        offset += sum;
                    }
                }
            }
        }

        if ( currentPlatform <  environment->platformCount && currentDevice < environment->deviceTotal )
        {
            environment->currentPlatform = currentPlatform;
            environment->currentDevice = currentDevice;
            properties[ 1] = (cl_context_properties)environment->platformId[ environment->currentPlatform ];
            environment->context = clCreateContext( properties, 1, &environment->deviceId[ environment->currentDevice ],
                NULL, NULL, &error );

            if (error == CL_SUCCESS)
            {
                environment->queue = clCreateCommandQueue( environment->context,environment->deviceId[ environment->currentDevice ], 0, &error);
            }
        }
    }

     return environment;
}

/**
    NewOpenCLKernel  Create a new OpenCL Kernel from Source code
    @param[in] environment  OpenC;l Environment
    @param[in] name Kernel Name
    @param[in] sourceCode  Kernel source code
    @param[in] compilerOptions command line option used to compile the  kernel

    @returns  a New OpenCL Kernel structure
**/
OpenCLKernel * NewOpenCLKernel( OpenCLEnvironment *  environment, char * name, char * sourceCode, char * compilerOptions )
{
    OpenCLKernel *  kernel = NULL;
    size_t          size = 0;
    cl_int          error = CL_SUCCESS;
    cl_int          error2 = CL_SUCCESS;

    if (  ( kernel = ( OpenCLKernel * ) malloc(sizeof ( OpenCLKernel )  ) ) != NULL )
    {
        memset(kernel, 0, sizeof( OpenCLKernel ) );
        kernel->sourceCode = sourceCode;
        kernel->name = name;
        kernel->compilerOptions = compilerOptions;

        kernel->program = clCreateProgramWithSource( environment->context, 1, &kernel->sourceCode, NULL, &error );

        error = clBuildProgram( kernel->program, 1, &environment->deviceId[ environment->currentDevice], kernel->compilerOptions,
            NULL, NULL );

        if ( error == CL_BUILD_SUCCESS )
        {
             kernel->kernel = clCreateKernel( kernel->program, name, &error );
        }
        else if ( error != CL_SUCCESS)
        {
            error2 = clGetProgramBuildInfo( kernel->program, environment->deviceId[ environment->currentDevice], 
                CL_PROGRAM_BUILD_LOG, (size_t)NULL, NULL, &size );
            kernel->compilerErrors = (char*)malloc( size  +1);

            error2 = clGetProgramBuildInfo( kernel->program, environment->deviceId[ environment->currentDevice], 
                CL_PROGRAM_BUILD_LOG, size, kernel->compilerErrors , &size );

        }

    }

    return kernel;
}


void PrintPair(char * msg, pairt * p, int n)
{
    int i = 0;

    printf("%s\n", msg);
    for ( i = 0; i < n; i++)
    {
        printf ("\t%d\t%d\n", p[i].a, p[i].b );
    }
    printf( " \n" );
}

int main ( int argc, char  ** argv)
{
    cl_int      error = CL_SUCCESS;
    cl_mem      p_mem_obj;
    size_t      global_item_size = LIST_SIZE;
    size_t      local_item_size = 2;
    cl_event    events[2];

    static pairt    unaligned[] = { 
        1, 2,
        3, 4,
        5, 6,
        7, 8,
        9, 10,
        11, 12,
        13, 14,
        15, 16,
        17, 18,
        19, 20,};

    pair32  aligned[] = { 
        1, 2,
        3, 4,
        5, 6,
        7, 8,
        9, 10,
        11, 12,
        13, 14,
        15, 16,
        17, 18,
        19, 20,};

    cl_int2 vector[] = {

        1, 2,
        3, 4,
        5, 6,
        7, 8,
        9, 10,
        11, 12,
        13, 14,
        15, 16,
        17, 18,
        19, 20,};

    OpenCLEnvironment *  environment = NewOpenCLEnvironment(0, 1);



    static char * simple_diff = "struct __attribute__ ((packed)) pairt { \
    int a; \
    int b; \
}; \
 \
__kernel void simple_diff( __global struct pairt* p) \
{                                                    \
    int i = get_global_id(0); \
    __global struct pairt *tmp = &p[i]; \
    \
    tmp->a = tmp->a * -1; \
    tmp->b = tmp->b * -1; \
\
}";

    OpenCLKernel *  simpleDiff;  

    printAligment( "Pack 1 aligned", offsetof(pairt, a), offsetof(pairt, b) );
    printAligment( "Default aligned", offsetof(pair32, a), offsetof(pair32, b) );
    printAligment( "Vector aligned", offsetof(cl_int2, s[0]), offsetof(cl_int2, s[1]) );

    simpleDiff = NewOpenCLKernel(environment,  "simple_diff", simple_diff, "" );

    p_mem_obj = clCreateBuffer(environment->context, CL_MEM_READ_WRITE, LIST_SIZE*sizeof(struct pairt), NULL, &error);
    error = clEnqueueWriteBuffer(environment->queue, p_mem_obj, CL_TRUE, 0, LIST_SIZE*sizeof(struct pairt), &unaligned, 0, NULL, NULL);

    error = clSetKernelArg(simpleDiff->kernel, 0, sizeof(cl_mem), (void *)&p_mem_obj);

    error = clEnqueueNDRangeKernel( environment->queue, simpleDiff->kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, &events[0]);
    error = clWaitForEvents(1, &events[0]);
    error = clReleaseEvent(events[0]);
    error = clEnqueueReadBuffer(environment->queue, p_mem_obj, CL_TRUE, 0, LIST_SIZE*sizeof(struct pairt), unaligned, 0, NULL, &events[1]);
    error = clWaitForEvents(1, &events[1]);
    error = clReleaseEvent(events[1]);


     PrintPair( "Pack 1", unaligned, sizeof(unaligned)/sizeof(unaligned[0]) )
}
/*
版权所有(C)Tim Child 2012
版权所有
本软件按“原样”提供,无任何形式的明示或明示担保
默示,包括但不限于适销性保证,
适用于特定目的和非侵权。在任何情况下
作者或版权持有人应承担任何索赔、损害或其他责任
无论是在合同诉讼、侵权诉讼或其他诉讼中,由以下原因引起的责任:,
与本软件有关或与本软件的使用或其他交易有关
软件。
*/
#包括
#包括
#包括
#包括
#包括
#包括“CL\CL.h”
#定义列表大小为10
#pragma包(推送,1)
类型定义结构对
{
INTA;
int b;
}派特;
#布拉格语包(流行语)
typedef结构对32
{
int32_t a;
int32_t b;
}对32;
无效打印验证(字符*消息,大小a,大小b)
{
printf(“%s\n”,msg);
printf(“\t%d\t%d\n”,a,b);
}
/**
OpenClenEnvironment一种OpenCl环境结构
**/
typedef结构OpenClenEnvironment
{
cl_平台id*平台id;
cl_单元平台计数;
cl_设备id*设备id;
cl_uint*设备计数;
氯离子装置总数;
语境;
cl_命令_队列;
cl_-uint当前平台;
电流互感器;
}开放环境;
typedef结构OpenCLKernel
{
字符*名称;
CLU计划;
cl_核;
字符*源代码;
字符*编译器选项;
字符*编译器错误;
}OpenCLKernel;
/**
新建OpenClenEnvironment创建一个新的OpenCL环境
@param[in]要使用的平台Id的currentPlatform索引
@param[in]要使用的设备Id的currentDevice索引
@返回OpenCL环境
**/
OpenClenEnvironment*新OpenClenEnvironment(cl_uint currentPlatform,cl_uint currentDevice)
{
OpenClenEnvironment*environment=NULL;
cl_int error=0;
cl_uint i=0;
信用证金额;
cl_uint偏移=0;
静态cl_上下文_属性[]={cl_上下文_平台,0,0};
if((环境=(OpenClenEnvironment*)malloc(sizeof(OpenClenEnvironment))!=NULL)
{
memset(环境,0,sizeof(OpenCLEnvironment));
if((error=clGetPlatformIDs(0,NULL,&environment->platformCount))==CL\u SUCCESS)
{
环境->设备计数=(cl_单元*)malloc(sizeof(cl_单元)*环境->平台计数);
环境->平台id=(cl_平台id*)malloc(sizeof(cl_平台id)*环境->平台计数);
if(环境->平台化&&
环境->平台计数>0&&
(错误=CLGetPlatformId(环境->平台计数,环境->平台ID,0))==CL\U成功)
{
总和=0;
对于(i=0;iplatformCount;i++)
{
if((error=clgetDeviceID(环境->平台ID[i],CL\u设备类型\u ALL,0,NULL,&sum))==CL\u成功)
{
环境->设备计数[i]=总和;
环境->设备总数+=总和;
}
}
环境->设备id=(cl_设备id*)malloc(sizeof(cl_设备id)*环境->设备总数);
偏移量=0;
对于(i=0;iplatformCount&&environment->deviceId;i++)
{
如果((错误=CLGetDeviceID(环境->平台ID[i],CL\U设备类型\U全部,环境->设备计数[i],
&环境->设备ID[offset],&sum))==CL\u成功)
{
偏移量+=和;
}
}
}
}
if(currentPlatformplatformCount和currentDevicedeviceTotal)
{
环境->当前平台=当前平台;
环境->当前设备=当前设备;
属性[1]=(cl_上下文_属性)环境->平台[environment->currentPlatform];
环境->上下文=clCreateContext(属性,1,&environment->deviceId[environment->currentDevice],
NULL、NULL和error);
如果(错误==CL_成功)
{
环境->队列=clCreateCommandQueue(环境->上下文,环境->设备ID[environment->currentDevice],0,&错误);
}
}
}
回归环境;
}
/**
NewOpenCL内核从源代码创建一个新的OpenCL内核
@param[in]环境OpenC;环境
@param[in]名称内核名称
@param[in]源代码内核源代码
@用于编译内核的param[in]compilerOptions命令行选项
@返回一个新的OpenCL内核结构
**/
OpenCLKernel*新OpenCLKernel(OpenCLEnvironment*环境,char*名称,char*源代码,char*编译器选项)
{
OpenCLKernel*kernel=NULL;
大小\u t大小=0;
cl_int error=cl_SUCCESS;
cl_内部错误2=cl