1. 程式人生 > >高通平臺 msm8953一個可以執行的opencl的例子

高通平臺 msm8953一個可以執行的opencl的例子

在網上找了一些例子,測試了一下都是無法執行的。下面給出一個在msm8953測試通過的可以執行的openc的例項。當然這個例子也是在別人的基礎之上修改的,具體程式碼如下
1.Android.mk
程式碼路徑
:vendor/qcom/proprietary/mm-camera/mm-camera2/opencl/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE    := opencl
LOCAL_SRC_FILES := main.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/include/adreno/
#./vendor/qcom/proprietary/prebuilt_HY11/target/product/msm8953_64/obj/include/adreno/CL/cl.h
#./vendor/qcom/proprietary/prebuilt_HY11/target/product/msm8953_64/system/vendor/lib64/libOpenCL.so LOCAL_LDFLAGS += -lOpenCL include $(BUILD_EXECUTABLE)

2.cl_kernel2.cl
程式碼路徑
:vendor/qcom/proprietary/mm-camera/mm-camera2/opencl/cl_kernel2.cl

__kernel void cl_add(__global int *dst, __global int *src1, __global int
*src2) { int index = get_global_id(0); dst[index] = src1[index] + src2[index]; }

3.
程式碼路徑
:vendor/qcom/proprietary/mm-camera/mm-camera2/opencl/main.cpp

#include <stdio.h>
#include <stdlib.h>
#include "readyuv.h"
#include "CL/cl.h"
//#include "CL/cl_platform.h"
#include <iostream>
using namespace std; int main(void) { const int array_size = 1024; cl_uint numPlatforms = 0; cl_platform_id platform = nullptr; cl_context context = nullptr; cl_command_queue commandQueue = nullptr; cl_program program = nullptr; cl_mem input1MemObj = nullptr; cl_mem input2MemObj = nullptr; cl_mem outputMemObj = nullptr; cl_kernel kernel = nullptr; //step1. 查詢OpenCL平臺集合 /* * 這個函式一般被呼叫兩次: * 第一次呼叫這個函式是獲得可用平臺的數目, 然後為平臺物件分配記憶體空間 * 第二次呼叫用來獲取平臺物件 */ cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); if (status != CL_SUCCESS) { cout << "Error: Getting platforms!" << endl; return -1; } if (numPlatforms > 0) { cl_platform_id* platforms = (cl_platform_id*)malloc(numPlatforms* sizeof(cl_platform_id)); status = clGetPlatformIDs(numPlatforms, platforms, NULL); platform = platforms[0]; } else { puts("Your system does not have any OpenCL platform!"); return -1; } cl_uint numDevices = 0; cl_device_id *devices; cl_int errcode_ret ; //setp2.獲取一個平臺上的可用裝置清單 status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices); if (numDevices == 0) //no GPU available. { cout << "No GPU device available." << endl; cout << "Choose CPU as default device." << endl; status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &numDevices); devices = (cl_device_id*)malloc(numDevices * sizeof(cl_device_id)); status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, numDevices, devices, NULL); } else { devices = (cl_device_id*)malloc(numDevices * sizeof(cl_device_id)); status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL); cout << "The number of devices: " << numDevices << endl; } //step3.建立一個OpenCL上下文 /* *上下文是 OpenCL runtime 用來管理像命令佇列、記憶體佇列、程式物件和核心物件,並且在上下文中指定的一個或多個裝置上執行核心函式。 */ context = clCreateContext(NULL, 1, devices, NULL, NULL, &errcode_ret); if(errcode_ret == CL_SUCCESS) cout << "craet OpenCL runtime sucess." << endl; else return -1; //step4. 建立命令佇列 commandQueue = clCreateCommandQueue(context, devices[0], 0, &errcode_ret); if(errcode_ret == CL_SUCCESS) cout << "craet CommandQueue sucess." << endl; else return -1; char *kernelCodeBuffer = nullptr; char *Buffer = nullptr; const char *aSource = nullptr; size_t kernelLength = 0; size_t global_work_size[1] = { array_size }; // Read the kernel code to the buffer FILE *fp = fopen("cl_kernel2.cl", "rb"); if (fp == nullptr) { puts("The kernel file not found!"); goto RELEASE_RESOURCES; } fseek(fp, 0, SEEK_END); kernelLength = ftell(fp); cout << "kernelLength : " << kernelLength << endl; fseek(fp, 0, SEEK_SET); kernelCodeBuffer = (char*)malloc(kernelLength + 1); Buffer = (char*)malloc(kernelLength + 1); fread(kernelCodeBuffer, 1, kernelLength, fp); kernelCodeBuffer[kernelLength] = '\0'; fclose(fp); aSource = kernelCodeBuffer; strcpy(Buffer,aSource); cout << "kernelCodeBuffer : " << Buffer << endl; //step5. 建立程式物件 program = clCreateProgramWithSource(context, 1, &aSource, &kernelLength, NULL); //step6. 編譯程式物件 status = clBuildProgram(program, 1, devices, NULL, NULL, NULL); // Do initialization int i; int input1Buffer[array_size]; int input2Buffer[array_size]; int outputBuffer[array_size]; for (i = 0; i < array_size; i++) input1Buffer[i] = input2Buffer[i] = i + 1; memset(outputBuffer, 0, sizeof(outputBuffer)); // Create mmory object input1MemObj = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, array_size * sizeof(int), input1Buffer, nullptr); input2MemObj = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, array_size * sizeof(int), input2Buffer, nullptr); outputMemObj = clCreateBuffer(context, CL_MEM_WRITE_ONLY, array_size * sizeof(int), NULL, NULL); //step7.建立核心物件 kernel = clCreateKernel(program, "cl_add", NULL); //step8.設定核心引數,想要執行核心,就必須設定核心引數 status = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&outputMemObj); status = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&input1MemObj); status = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&input2MemObj); status = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL, global_work_size, NULL, 0, NULL, NULL); /* * clEnqueueNDRangeKernel( * * cl_command_queue queue, * * cl_kernel kernel, * * cl_uint work_dims, * //if you deal with image object, you should probably set work_dims equal 2 or 3. But for buffer objects, you can set whatever dimensionality you think best. * //For a buffer object containing a two-dimensional matrix, you might set work-dims equal 2. * * const size_t *global_work_offset, * //the global ID offset in each dimension * * const size_t *global_work_size, * //the number of work items in each dimension * const size_t *local_work_size, * //the number of work_items in a work_group,in each dimension * cl_uint num_events, * * const cl_event *wait_list, * * cl_event *event) */ /* * __kernel void cl_add(__global int *dst, __global int *src1, __global int *src2) * { * int index = get_global_id(0);//get_global_id獲取執行緒索引,其取值範圍是0 到 global_work_size - 1 * dst[index] = src1[index] + src2[index]; * } */ clFinish(commandQueue); //GPU中執行完成後需要Copy結果到記憶體 status = clEnqueueReadBuffer(commandQueue, outputMemObj, CL_TRUE, 0, global_work_size[0] * sizeof(int), outputBuffer, 0, NULL, NULL); printf("Veryfy the rsults... "); for (i = 0; i < array_size; i++) { if (outputBuffer[i] != (i + 1) * 2) { puts("Results not correct!"); break; } } if (i == array_size) puts("Correct!"); RELEASE_RESOURCES: status = clReleaseKernel(kernel);//*Release kernel. status = clReleaseProgram(program); //Release the program object. status = clReleaseMemObject(input1MemObj);//Release mem object. status = clReleaseMemObject(input2MemObj); status = clReleaseMemObject(outputMemObj); status = clReleaseCommandQueue(commandQueue);//Release Command queue. status = clReleaseContext(context);//Release context. free(devices); getchar(); return 0; } /* * clGetPlatformIDs---------------------------獲取平臺ID * * clGetDeviceIDs-----------------------------獲取裝置ID * * clCreateContext----------------------------建立上下文 * * clCreateCommandQueue-----------------------建立命令佇列 * * clCreateBuffer-----------------------------建立裝置記憶體 * * clCreateProgramWithSource------------------建立程式 * * clBuildProgram-----------------------------編譯程式 * * clGetProgramBuildInfo----------------------獲取編譯資訊 * * clCreateKernel-----------------------------建立核 * * clSetKernelArg-----------------------------設定核引數 * * clEnqueueNDRangeKernel---------------------執行核 * * clEnqueueReadBuffer------------------------讀取裝置記憶體 * * clReleaseMemObject-------------------------釋放記憶體物件 * * clReleaseKernel----------------------------釋放核 * * clReleaseCommandQueue----------------------釋放命令佇列 * * clReleaseContext---------------------------釋放上下文 */

執行編譯命令後驗證方法如下
一、把檔案推送到平臺端
1.adb root
2.adb remount
3.adb push out\target\product\msm8953_64\system\bin\opencl data
4.adb push vendor\qcom\proprietary\mm-camera\mm-camera2\opencl\cl_kernel2.cl data
二、執行命令
1 ) chmod 777 data/opencl
2 ) cd data/ (若不執行,會報錯誤如下The kernel file not found!)
3 ) ./opencl

執行完後可得成功log如下

The number of devices: 1
craet OpenCL runtime sucess.
craet CommandQueue sucess.
kernelLength : 162
kernelCodeBuffer : __kernel void cl_add(__global int *dst, __global int *src1, __global int *src2)
{
    int index = get_global_id(0);
    dst[index] = src1[index] + src2[index];
}

Veryfy the rsults... Correct!

相關推薦

平臺 msm8953一個可以執行opencl例子

在網上找了一些例子,測試了一下都是無法執行的。下面給出一個在msm8953測試通過的可以執行的openc的例項。當然這個例子也是在別人的基礎之上修改的,具體程式碼如下 1.Android.mk 程式碼路徑 :vendor/qcom/proprietary/mm

平臺msm8953 Linux DTS(Device Tree Source)裝置樹詳解之二(DTS裝置樹匹配過程)

本系列導航:有上一篇文章,我們瞭解了dts的背景知識和相關基礎,這次我們對應實際裝置進行一下相關分析。DTS裝置樹的匹配過程一個dts檔案確定一個專案,多個專案可以包含同一個dtsi檔案。找到該專案對應的dts檔案即找到了該裝置樹的根節點。kernel\arch\arm\bo

平臺新增或者移植一個完整的camera

OV8865 1、kernel部分: A、kernel_driver: 把驅動檔案ov8865_qtech_f8865ac.c 放到kernel/drivers/media/platform/msm/camera_v2/sensor/目錄下 B、kernel_dt

基於Android7.1 8953 平臺下零死角玩轉裝置樹DTS

【基於Android7.1 8953 高通平臺下零死角玩轉裝置樹DTS】 更新內容:  【創科之龍_安卓開發】第01課_為什麼引用linux裝置樹和對比優勢  【創科之龍_安卓開發】第02課_如何在Linux-3.x核心

平臺啟動log概述(PBL log、sbl1 log、kernel log)【轉】

本文轉自:https://blog.csdn.net/RadianceBlau/article/details/78416776?utm_source=blogxgwz9 高通平臺啟動log概述(PBL log、sbl1 log、kernel log)在嵌入式linux的除錯過程中log有著至關重要的地位,

平臺讀寫nv總結【轉】

本文轉載自:https://blog.csdn.net/suofeng12345/article/details/52713993 一,引言      1. 什麼是NV      &nbs

平臺 ramdump-parser 簡介

ramdump 是什麼?簡單來說就是把系統memory中的某一個時間點的的資料資訊通過一定手段取出來儲存起來的記憶體崩潰檔案,屬於ELF檔案格式。 當系統發生致命錯誤無法恢復的時候,主動觸發抓取ramdump把異常現場保留下來供離線分析定位問題是一種非常重要的高階除錯手段。 高

通過平臺簡單總結的許可權問題

 android 5.x開始,引入了非常嚴格的selinux許可權管理機制,我們經常會遇到因為selinux許可權問題造成的各種avc denied困擾。有時候我們在添加了一些驅動或應用的時候,發現不能用,但是程式本身查不出問題來,那就要抓log看一下了,很多時候就是因為沒有新增許可權,下

平臺電池曲線

跟電池相關的一些名詞: FCC Full-Charge Capacity 滿電荷電量 UC Remaining Capacity RC 剩餘電量 CC Coulumb Counter 電量計 UUC Unusable Capacity 不可用電量 PC Percentage

平臺SPI外設的片選訊號配置

spi master 和spi device有各自的dts配置: 這是spi master的配置示例,也就是spi控制器 這是一個spi device的配置示例,也就是spi外設(從裝置) 一個spi控制器上可以連線多個從裝置,在任何時刻只有一個從裝置可以通

平臺GPIO模擬PWM控制背光

    很多時候由於節省硬體資源,降低成本,會把PWM控制晶片去掉或者是改做它用,導致當我們想用PWM方式控制背光時只能使用帶有clk功能的GPIO口。本篇文件就來講解下如何使用GPIO模擬PWM功能進行背光的控制。本文以MSM8909為例。 一、選取GPIO口並進行配置

平臺 efs.mbn的製作與修改

1.修改需要修改的mbn相關檔案 如MDM9607/trunk/modem_proc/mcfg/mcfg_gen/genneric/China/CT下的 2.EFS相關程式碼修改 開啟相關巨集定義 #define FEATURE_EFS_NAND_FACTORY_STAR

[Android]平臺BootLoader啟動流程

一、什麼是BootLoader BootLoader程式碼是晶片復位後,進入作業系統之前執行的一段程式碼。主要用於完成由硬體啟動到作業系統啟動的過渡,從而為作業系統提供基本的執行環境。 BootLoder主要的啟動流程可以概括為:PBL階段、SBL階段、LK階段。之後會載入並啟動kern

平臺framework,hal,kernel開啟log【轉】

本文轉載自:https://blog.csdn.net/u010164190/article/details/78625636 1 1.Add framework log 2 #define LOG_NDEBUG 0 3 2.Add hal log 4 #define LOG_NDEBU

Android平臺下編譯時能生成(拷貝)預編譯的so到system的lib目錄

  參考hardware\qcom\display\libcopybit 通過編譯log可以知道編譯到這裡,生成的copybit.msm8937.so在out\target\product\msm8937_64\system\lib\hw下。libcopybit\Andr

平臺 UART log 開啟方法

1  配置kernel  DTS      例如:  kernel\arch\arm\boot\dts\qcom\msm8909-mtp.dtsi,  配置status屬性 okay.   同時檢查DTS 確認UART PIN  沒有配作他用      &blsp1

平臺bootloader裡面串列埠log輸出配置方法

1:在modem端將相應的gpio設定成相應功能。 2:在/lk/project/xxx.mk開啟uart輸出log功能。 3:在platform/msm_shared/uart.c中定義uart幾輸出log, #if PLATFORM_MSM7X30 static uns

[平臺小米4]的電源管理配置學習

1.溫控調頻 /system/etc/thermal-engine-8974.conf sampling 5000 [CPU0_MONITOR] algo_type monitor sensor cp

平臺中用devicetree註冊裝置及驅動匹配

1、在裝置樹檔案(.dts)中的相應節點下新增要註冊裝置的節點         &soc {                     ......                     plf_char_dev: mytest,plf_char_dev {

Android 平臺開機logo的修改

修改開機logo 修改開機logo有兩種方法,一種直接去改c語言程式碼,第二種替換圖片用python生成splash。第一種方法我沒試過,感覺挺麻煩的,還有解析度限制,超過多少解析度就不能用第一種方法。 修改的檔案路徑LINUX/android/boota