[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 }
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()
159 {
160 const unsigned char* bin;
161 cl_int err;
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 */
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 }
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 }
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()
234 {
235 cl_int err;
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");
264 }
266 /* Nothing past this point */