PASDK-258:Add LibArch release from Jianzhong
[processor-sdk/performance-audio-sr.git] / psdk_cust / libarch_k2g_1_0_1_0 / examples / arm+dsp / test_lib_arm.cpp
1 /******************************************************************************
2  * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com
3  *   All rights reserved.
4  *
5  *   Redistribution and use in source and binary forms, with or without
6  *   modification, are permitted provided that the following conditions are met:
7  *       * Redistributions of source code must retain the above copyright
8  *         notice, this list of conditions and the following disclaimer.
9  *       * Redistributions in binary form must reproduce the above copyright
10  *         notice, this list of conditions and the following disclaimer in the
11  *         documentation and/or other materials provided with the distribution.
12  *       * Neither the name of Texas Instruments Incorporated nor the
13  *         names of its contributors may be used to endorse or promote products
14  *         derived from this software without specific prior written permission.
15  *
16  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  *   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  *   THE POSSIBILITY OF SUCH DAMAGE.
27  *****************************************************************************/
29 ////////////////////////////////////////////////////////////////////////////////
30 //  This file shows an example of the ARM side code of an ARM+DSP library. 
31 //////////////////////////////////////////////////////////////////////////////// 
32 #include <cstdlib>
33 #include <cmath>
34 #include <cstring>
35 #include <iostream>
36 #include <fstream>
37 #include <iomanip>
38 #define __CL_ENABLE_EXCEPTIONS
39 #include <CL/cl.hpp>
40 using namespace std;
41 using namespace cl;
42 // Both cl and std namespace define size_t, so we must be explicit.
43 #define size_t ::size_t
44 #ifndef TEST_FAT_BINARY
45 #include "ocl_util.h"
46 #endif
47 #include <pthread.h>
50 // Include the DSP header file generated by "clocl --text" utility
51 #include "test_lib_ocl.dsp_h"
53 Context*             ocl_context = NULL;
54 std::vector<Device>* ocl_devices = NULL;
55 CommandQueue*        ocl_Q = NULL;
56 Program::Binaries*   ocl_binary = NULL;
57 Program*             ocl_program = NULL;
59 #define TEST_DEBUG_PRINT(...) {fprintf(stdout,"TEST DEBUG: ");fprintf(stdout,__VA_ARGS__);}
60 #define TEST_MSMC_MEM_SIZE (4608*1024UL)   //4.5M Bytes
61 #define TEST_DDR_MEM_SIZE  (10240*1024UL)  //10M Bytes
64 /*==============================================================================
65  * This is the library API to be called by the application on the ARM side. 
66  * This function will offload processing task to DSP for acceleration. 
67  *============================================================================*/
68 void lib_kernel_arm(double *in1_ptr, double *in2_ptr, double *out_ptr, int data_size)
69 {
70     TEST_DEBUG_PRINT("Allocating memory to run DSP processing kernel.\n");
72     // Allocate scratch memory for DSP acceleration
73     void *med_mem_ptr   = __malloc_msmc(TEST_MSMC_MEM_SIZE);
74     void *slow_mem_ptr  = __malloc_ddr(TEST_DDR_MEM_SIZE);
76     if(med_mem_ptr==NULL) {
77       med_mem_ptr   = __malloc_ddr(TEST_MSMC_MEM_SIZE);
78       TEST_DEBUG_PRINT("MSMC Memory is NOT available on the device. Reallocate memory from DDR.\n");
79     }
80  
81     if(med_mem_ptr==NULL || slow_mem_ptr==NULL) {
82         TEST_DEBUG_PRINT("Memory allocation error!\n");
83         exit(0);
84     }
85     else {
86         TEST_DEBUG_PRINT("Memory allocated.\n");
87         TEST_DEBUG_PRINT("Medium memory allocated at: 0x%08x.\n", (unsigned int)med_mem_ptr);
88         TEST_DEBUG_PRINT("Slow memory allocated at:   0x%08x.\n", (unsigned int)slow_mem_ptr);
89     }
91     // Prepare for OpenCL dispatching.
92     cl_int err;
94     // Create OpenCL Kernel from OpenCL Program. 
95     Kernel* ocl_kernel = new Kernel(*ocl_program, "lib_kernel_ocl", &err);
96     if(err != CL_SUCCESS){
97         TEST_DEBUG_PRINT("Kernel \"lib_kernel_ocl\" creation failed!\n");
98         exit(0);
99     }
100     TEST_DEBUG_PRINT("Kernel \"lib_kernel_ocl\" created!\n");
102     // Assign kernel arguments
103     Buffer mem_MSMC(*ocl_context, CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR, 
104                     TEST_MSMC_MEM_SIZE, med_mem_ptr);
105     ocl_kernel->setArg(0, mem_MSMC);
106     ocl_kernel->setArg(1, TEST_MSMC_MEM_SIZE);
108     Buffer mem_DDR(*ocl_context,  CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR, 
109                    TEST_DDR_MEM_SIZE, slow_mem_ptr);
110     ocl_kernel->setArg(2, mem_DDR);
111     ocl_kernel->setArg(3, TEST_DDR_MEM_SIZE);
113     Buffer buf_input1(*ocl_context,  CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR, 
114                       data_size*sizeof(double), in1_ptr);
115     ocl_kernel->setArg(4, buf_input1);
117     Buffer buf_input2(*ocl_context,  CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR, 
118                       data_size*sizeof(double), in2_ptr);
119     ocl_kernel->setArg(5, buf_input2);
121     Buffer buf_output(*ocl_context,  CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR, 
122                       data_size*sizeof(double), out_ptr);
123     ocl_kernel->setArg(6, buf_output);
125     ocl_kernel->setArg(7, data_size);
127     // Dispatch the kernel to DSP
128     TEST_DEBUG_PRINT("Enqueuing task and dispatching kernel \"lib_kernel_ocl\" to DSP.\n");
129     Event ocl_event;
130     err = ocl_Q->enqueueTask(*ocl_kernel, 0, &ocl_event);
131     if(err != CL_SUCCESS){
132         TEST_DEBUG_PRINT("Enqueuing task failed!\n");
133   exit(0);
134     }
136     // Wait fo the kernel to complete execution
137     ocl_event.wait();
139     delete(ocl_kernel);
140     ocl_kernel = NULL;
142     TEST_DEBUG_PRINT("Finished executing kernel \"lib_kernel_ocl\".\n");
144     delete(ocl_Q);
145     delete(ocl_program);
146     delete(ocl_binary);
147     delete(ocl_devices);
148     delete(ocl_context);
150     __free_msmc(med_mem_ptr);
151     __free_ddr(slow_mem_ptr); 
153 } /* lib_kernel_arm */
155 /*==============================================================================
156  * This function performs OpenCL initialization. 
157  *============================================================================*/
158 void lib_init_arm()
160     const unsigned char* bin;
161     cl_int err;
162     
163     // Create the OpenCL program using the DSP binary 
164 #ifdef TEST_FAT_BINARY
165     // DSP library object code converted to text in DSP header test_lib_ocl.dsp_h 
166     bin = (unsigned char *)test_lib_ocl_dsp_bin;        
167     const size_t bin_length = test_lib_ocl_dsp_bin_len;
168 #else
169     // DSP library object code archived in test_lib_ocl.out
170     const char binary[] = "./test_lib_ocl.out";
171     unsigned int bin_length;      
173     bin_length = ocl_read_binary(binary, (char*&)bin); 
174 #endif /* FAT_BINARY */
175     
176     // OpenCL initialization 
177     TEST_DEBUG_PRINT("Initializing OpenCL\n");
179     // Create an OpenCL context with the accelerator device
180     ocl_context = new Context(CL_DEVICE_TYPE_ACCELERATOR);
181     ocl_devices = new std::vector<Device> (ocl_context->getInfo<CL_CONTEXT_DEVICES>());
182     ocl_binary  = new Program::Binaries(1, std::make_pair(bin, bin_length));
183     ocl_program = new Program(*ocl_context, *ocl_devices, *ocl_binary);
184     ocl_program->build(*ocl_devices);
186     for (int d = 0; d < ocl_devices->size(); d++)
187     {
188          std::string str;
189          ocl_devices[0][d].getInfo(CL_DEVICE_NAME, &str);
190          cout << "    DEVICE: " << str << endl;
192          bool ti_dsp = (str.find("C66") != std::string::npos);
194          cl_uint bignum;
195          ocl_devices[0][d].getInfo(CL_DEVICE_MAX_CLOCK_FREQUENCY, &bignum);
196          cout << "      Frequency  : " << (double) bignum / 1e3 << " GHz"<< endl;
198          cl_ulong longnum;
199          ocl_devices[0][d].getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &longnum);
200          cout << "      Glb Mem    : " << setw(7) << longnum / 1024  << " KB" << endl;
202          if (ti_dsp)
203          {
204              ocl_devices[0][d].getInfo(CL_DEVICE_MSMC_MEM_SIZE_TI, &longnum);
205              cout << "      Msmc Mem   : " << setw(7) << longnum / 1024  << " KB" << endl;
206          }
208          ocl_devices[0][d].getInfo(CL_DEVICE_LOCAL_MEM_SIZE, &longnum);
209          cout << "      Loc Mem    : " << setw(7) << longnum / 1024  << " KB" << endl;
210     }
211  
212     // Create an OpenCL command queue
213     ocl_Q = new CommandQueue(*ocl_context, ocl_devices[0][0], CL_QUEUE_PROFILING_ENABLE, &err);
214     if(err != CL_SUCCESS){
215         TEST_DEBUG_PRINT("Command queue creation failed!\n");
216   exit(0);
217     }
219     if(ocl_Q==NULL){
220         TEST_DEBUG_PRINT("Command queue creation failed!\n");
221   exit(0);
222     }
223     
224 #ifndef TEST_FAT_BINARY
225     delete [] bin;
226 #endif /* FAT_BINARY */
228     TEST_DEBUG_PRINT("OpenCL initialized\n");
230     return;
231 } /* lib_init_arm */
233 void lib_find_l2_start()
235     cl_int err;
236  
237     // Create OpenCL Kernel from OpenCL Program to print L2 SRAM start address. 
238     Kernel* ocl_kernel = new Kernel(*ocl_program, "ocl_find_l2_start", &err);
239     if(err != CL_SUCCESS){
240         TEST_DEBUG_PRINT("OpencCL kernel \"ocl_find_l2_start\" creation failed!\n");
241   exit(0);
242     }
243     TEST_DEBUG_PRINT("OpenCL kernel \"ocl_find_l2_start\" created.\n");
245     // Assign kernel arguments
246     ocl_kernel->setArg(0, __local(1024));   // L2 start address will be passed to OCL kernel
248     // Dispatch the kernel to DSP
249     TEST_DEBUG_PRINT("Enqueuing task and dispatching kernel \"ocl_find_l2_start\" to DSP.\n");
250     Event ocl_event;
251     err = ocl_Q->enqueueTask(*ocl_kernel, 0, &ocl_event);
252     if(err != CL_SUCCESS){
253         TEST_DEBUG_PRINT("Enqueuing task failed!\n");
254   exit(0);
255     }
257     // Wait fo the kernel to complete execution
258     ocl_event.wait();
260     delete(ocl_kernel);
261     ocl_kernel = NULL;
263     TEST_DEBUG_PRINT("Finished kernel \"ocl_find_l2_start\".\n");
266 /* Nothing past this point */