2013-06-04 47 views
1

我試圖從蘋果的OpenCL編程指南建立的HelloWorld的OpenCL例如:的OpenCL的HelloWorld OSX鏈接錯誤

http://developer.apple.com/library/mac/documentation/Performance/Conceptual/OpenCL_MacProgGuide/OpenCL_MacProgGuide.pdf

通過的Xcode 4.6在iMac(2012年年底,OSX 10.8.3)和我的MacBook(2008年初,OSX 10.7.5),我得到什麼似乎是鏈接錯誤:(我試過的複製粘貼,但格式看起來可怕)

https://www.dropbox.com/s/iih87g0495qn4c6/Screen%20Shot%202013-06-04%20at%203.35.55%20PM.png

我跟着所有的說明OpenCL Mac編程指南,日期2012-07-23,但沒有雪茄。

// mykernel.cl 

kernel void square(global float* input, global float* output) { 
    size_t i = get_global_id(0); 
    output[i] = input[i] * input[i]; 
} 


// main.c 
// HelloWorld 

#include <stdio.h> 
#include <OpenCL/OpenCL.h> 
#include "mykernel.cl.h" 

static void print_device_info(cl_device_id device) { 
    char name[128]; 
    char vendor[128]; 

    clGetDeviceInfo(device, CL_DEVICE_NAME, 128, name, NULL); 
    clGetDeviceInfo(device, CL_DEVICE_VENDOR, 128, vendor, NULL); 
    fprintf(stdout, "%s : %s\n", vendor, name); 

} 

然而,年紀大了,時間越長的OpenCL的HelloWorld的蘋果版本,正常工作:

// 
// File:  hello.c 
// 
// Abstract: A simple "Hello World" compute example showing basic usage of OpenCL which 
//    calculates the mathematical square (X[i] = pow(X[i],2)) for a buffer of 
//    floating point values. 
//    
// 
// Version: <1.0> 
// 
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple") 
//    in consideration of your agreement to the following terms, and your use, 
//    installation, modification or redistribution of this Apple software 
//    constitutes acceptance of these terms. If you do not agree with these 
//    terms, please do not use, install, modify or redistribute this Apple 
//    software. 
// 
//    In consideration of your agreement to abide by the following terms, and 
//    subject to these terms, Apple grants you a personal, non - exclusive 
//    license, under Apple's copyrights in this original Apple software (the 
//    "Apple Software"), to use, reproduce, modify and redistribute the Apple 
//    Software, with or without modifications, in source and/or binary forms; 
//    provided that if you redistribute the Apple Software in its entirety and 
//    without modifications, you must retain this notice and the following text 
//    and disclaimers in all such redistributions of the Apple Software. Neither 
//    the name, trademarks, service marks or logos of Apple Inc. may be used to 
//    endorse or promote products derived from the Apple Software without specific 
//    prior written permission from Apple. Except as expressly stated in this 
//    notice, no other rights or licenses, express or implied, are granted by 
//    Apple herein, including but not limited to any patent rights that may be 
//    infringed by your derivative works or by other works in which the Apple 
//    Software may be incorporated. 
// 
//    The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO 
//    WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED 
//    WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A 
//    PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION 
//    ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 
// 
//    IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR 
//    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
//    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
//    INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION 
//    AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER 
//    UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR 
//    OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
// 
// Copyright (C) 2008 Apple Inc. All Rights Reserved. 
// 

//////////////////////////////////////////////////////////////////////////////// 

#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <OpenCL/opencl.h> 

//////////////////////////////////////////////////////////////////////////////// 

// Use a static data size for simplicity 
// 
#define DATA_SIZE (1024) 

//////////////////////////////////////////////////////////////////////////////// 

// Simple compute kernel which computes the square of an input array 
// 
const char *KernelSource = "\n" \ 
"__kernel void square(              \n" \ 
" __global float* input,            \n" \ 
" __global float* output,            \n" \ 
" const unsigned int count)           \n" \ 
"{                  \n" \ 
" int i = get_global_id(0);           \n" \ 
" if(i < count)              \n" \ 
"  output[i] = input[i] * input[i];        \n" \ 
"}                  \n" \ 
"\n"; 

//////////////////////////////////////////////////////////////////////////////// 

int main(int argc, char** argv) 
{ 
    int err;       // error code returned from api calls 

    float data[DATA_SIZE];    // original data set given to device 
    float results[DATA_SIZE];   // results returned from device 
    unsigned int correct;    // number of correct results returned 

    size_t global;      // global domain size for our calculation 
    size_t local;      // local domain size for our calculation 

    cl_device_id device_id;    // compute device id 
    cl_context context;     // compute context 
    cl_command_queue commands;   // compute command queue 
    cl_program program;     // compute program 
    cl_kernel kernel;     // compute kernel 

    cl_mem input;      // device memory used for the input array 
    cl_mem output;      // device memory used for the output array 

    // Fill our data set with random float values 
    // 
    int i = 0; 
    unsigned int count = DATA_SIZE; 
    for(i = 0; i < count; i++) 
     data[i] = rand()/(float)RAND_MAX; 

    // Connect to a compute device 
    // 
    int gpu = 1; 
    err = clGetDeviceIDs(NULL, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL); 
    if (err != CL_SUCCESS) 
    { 
     printf("Error: Failed to create a device group!\n"); 
     return EXIT_FAILURE; 
    } 

    // Create a compute context 
    // 
    context = clCreateContext(0, 1, &device_id, NULL, NULL, &err); 
    if (!context) 
    { 
     printf("Error: Failed to create a compute context!\n"); 
     return EXIT_FAILURE; 
    } 

    // Create a command commands 
    // 
    commands = clCreateCommandQueue(context, device_id, 0, &err); 
    if (!commands) 
    { 
     printf("Error: Failed to create a command commands!\n"); 
     return EXIT_FAILURE; 
    } 

    // Create the compute program from the source buffer 
    // 
    program = clCreateProgramWithSource(context, 1, (const char **) & KernelSource, NULL, &err); 
    if (!program) 
    { 
     printf("Error: Failed to create compute program!\n"); 
     return EXIT_FAILURE; 
    } 

    // Build the program executable 
    // 
    err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); 
    if (err != CL_SUCCESS) 
    { 
     size_t len; 
     char buffer[2048]; 

     printf("Error: Failed to build program executable!\n"); 
     clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len); 
     printf("%s\n", buffer); 
     exit(1); 
    } 

    // Create the compute kernel in the program we wish to run 
    // 
    kernel = clCreateKernel(program, "square", &err); 
    if (!kernel || err != CL_SUCCESS) 
    { 
     printf("Error: Failed to create compute kernel!\n"); 
     exit(1); 
    } 

    // Create the input and output arrays in device memory for our calculation 
    // 
    input = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float) * count, NULL, NULL); 
    output = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(float) * count, NULL, NULL); 
    if (!input || !output) 
    { 
     printf("Error: Failed to allocate device memory!\n"); 
     exit(1); 
    }  

    // Write our data set into the input array in device memory 
    // 
    err = clEnqueueWriteBuffer(commands, input, CL_TRUE, 0, sizeof(float) * count, data, 0, NULL, NULL); 
    if (err != CL_SUCCESS) 
    { 
     printf("Error: Failed to write to source array!\n"); 
     exit(1); 
    } 

    // Set the arguments to our compute kernel 
    // 
    err = 0; 
    err = clSetKernelArg(kernel, 0, sizeof(cl_mem), &input); 
    err |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &output); 
    err |= clSetKernelArg(kernel, 2, sizeof(unsigned int), &count); 
    if (err != CL_SUCCESS) 
    { 
     printf("Error: Failed to set kernel arguments! %d\n", err); 
     exit(1); 
    } 

    // Get the maximum work group size for executing the kernel on the device 
    // 
    err = clGetKernelWorkGroupInfo(kernel, device_id, CL_KERNEL_WORK_GROUP_SIZE, sizeof(local), &local, NULL); 
    if (err != CL_SUCCESS) 
    { 
     printf("Error: Failed to retrieve kernel work group info! %d\n", err); 
     exit(1); 
    } 

    // Execute the kernel over the entire range of our 1d input data set 
    // using the maximum number of work group items for this device 
    // 
    global = count; 
    err = clEnqueueNDRangeKernel(commands, kernel, 1, NULL, &global, &local, 0, NULL, NULL); 
    if (err) 
    { 
     printf("Error: Failed to execute kernel!\n"); 
     return EXIT_FAILURE; 
    } 

    // Wait for the command commands to get serviced before reading back results 
    // 
    clFinish(commands); 

    // Read back the results from the device to verify the output 
    // 
    err = clEnqueueReadBuffer(commands, output, CL_TRUE, 0, sizeof(float) * count, results, 0, NULL, NULL); 
    if (err != CL_SUCCESS) 
    { 
     printf("Error: Failed to read output array! %d\n", err); 
     exit(1); 
    } 

    // Validate our results 
    // 
    correct = 0; 
    for(i = 0; i < count; i++) 
    { 
     if(results[i] == data[i] * data[i]) 
      correct++; 
    } 

    // Print a brief summary detailing the results 
    // 
    printf("Computed '%d/%d' correct values!\n", correct, count); 

    // Shutdown and cleanup 
    // 
    clReleaseMemObject(input); 
    clReleaseMemObject(output); 
    clReleaseProgram(program); 
    clReleaseKernel(kernel); 
    clReleaseCommandQueue(commands); 
    clReleaseContext(context); 

    return 0; 
} 

回答

0

我沒有使用過的OpenCL,但鏈接錯誤是說,它不能找到一個主()函數在你的程序中。你的第一個代碼是完整的程序嗎?如果是這樣,你需要添加一個main()函數到調用print_device_info()函數的main.c文件中。