1 /*
2     Copyright (c) 2014-2016 Intel Corporation.  All Rights Reserved.
3 
4     Redistribution and use in source and binary forms, with or without
5     modification, are permitted provided that the following conditions
6     are met:
7 
8       * Redistributions of source code must retain the above copyright
9         notice, this list of conditions and the following disclaimer.
10       * Redistributions in binary form must reproduce the above copyright
11         notice, this list of conditions and the following disclaimer in the
12         documentation and/or other materials provided with the distribution.
13       * Neither the name of Intel Corporation nor the names of its
14         contributors may be used to endorse or promote products derived
15         from this software without specific prior written permission.
16 
17     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20     A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21     HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23     LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 
31 #include "offload_trace.h"
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stdint.h>
35 #include <sstream>
36 #include "liboffload_error_codes.h"
37 
38 extern const char *prefix;
39 
40 #if !HOST_LIBRARY
41 extern int mic_index;
42 #endif
43 
44 // The debug routines
45 
offload_stage(std::stringstream & ss,int offload_number,const char * tag,const char * text,bool print_tag)46 static const char * offload_stage(std::stringstream &ss,
47                                   int offload_number,
48                                   const char *tag,
49                                   const char *text,
50                                   bool print_tag)
51 {
52     ss << "[" << report_get_message_str(c_report_offload) << "]";
53 #if HOST_LIBRARY
54     ss << " [" << prefix << "]";
55     if (print_tag) {
56         ss << "  [" << report_get_message_str(c_report_tag);
57         ss << " " << offload_number << "]";
58     }
59     else {
60         ss << "         ";
61     }
62     ss << " [" << tag << "]";
63     ss << "           " << text;
64 #else
65     ss << " [" << prefix << " " << mic_index << "]";
66     if (print_tag) {
67         ss << " [" << report_get_message_str(c_report_tag);
68         ss << " " << offload_number << "]";
69     }
70     ss << " [" << tag << "]";
71     ss << "           " << text;
72 #endif
73     return 0;
74 }
75 
offload_message_2str(std::stringstream & ss,int offload_number,const char * tag,const char * text)76 static const char * offload_message_2str(std::stringstream &ss,
77                                   int offload_number,
78                                   const char *tag,
79                                   const char *text)
80 {
81     ss << "[" << report_get_message_str(c_report_offload) << "]";
82     ss << " [" << prefix << "]";
83     ss << "  [" << report_get_message_str(c_report_tag);
84     ss << " " << offload_number << "]";
85     ss << " [" << tag << "]";
86     ss << "          " << text;
87     return 0;
88 }
89 
offload_stage_print(int stage,int offload_number,...)90 void offload_stage_print(int stage, int offload_number, ...)
91 {
92     std::string buf;
93     std::stringstream ss;
94     char const *str1;
95     char const *str2;
96     va_list va_args;
97     va_start(va_args, offload_number);
98     va_arg(va_args, char*);
99 
100     switch (stage) {
101         case c_offload_start:
102             str1 = report_get_message_str(c_report_state);
103             str2 = report_get_message_str(c_report_start);
104             offload_stage(ss, offload_number, str1, str2, true);
105             break;
106         case c_offload_init:
107             str1 = report_get_message_str(c_report_state);
108             str2 = report_get_message_str(c_report_init);
109             offload_stage(ss, offload_number, str1, str2, false);
110             ss << " " << report_get_message_str(c_report_logical_card);
111             ss << " " << va_arg(va_args, int);
112             ss << " = " << report_get_message_str(c_report_physical_card);
113             ss << " " << va_arg(va_args, int);
114             break;
115         case c_offload_register:
116             str1 = report_get_message_str(c_report_state);
117             str2 = report_get_message_str(c_report_register);
118             offload_stage(ss, offload_number, str1, str2, true);
119             break;
120         case c_offload_init_func:
121             str1 = report_get_message_str(c_report_state);
122             str2 = report_get_message_str(c_report_init_func);
123             offload_stage(ss, offload_number, str1, str2, true);
124             ss << ": " << va_arg(va_args, char*);
125             break;
126         case c_offload_create_buf_host:
127             str1 = report_get_message_str(c_report_state);
128             str2 = report_get_message_str(c_report_create_buf_host);
129             offload_stage(ss, offload_number, str1, str2, true);
130             ss << ": base=0x" << std::hex << va_arg(va_args, uint64_t);
131             ss << " length=" << std::dec << va_arg(va_args, uint64_t);
132             break;
133         case c_offload_create_buf_mic:
134             str1 = report_get_message_str(c_report_state);
135             str2 = report_get_message_str(c_report_create_buf_mic);
136             offload_stage(ss, offload_number, str1, str2, true);
137             ss << ": size=" << va_arg(va_args, uint64_t);
138             ss << " offset=" << va_arg(va_args, int);
139             if (va_arg(va_args,int))
140                ss << " (2M page)";
141             break;
142         case c_offload_send_pointer_data:
143             str1 = report_get_message_str(c_report_state);
144             str2 = report_get_message_str(c_report_send_pointer_data);
145             offload_stage(ss, offload_number, str1, str2, true);
146             break;
147         case c_offload_sent_pointer_data:
148             str1 = report_get_message_str(c_report_state);
149             str2 = report_get_message_str(c_report_sent_pointer_data);
150             offload_stage(ss, offload_number, str1, str2, true);
151             ss << " " << va_arg(va_args, uint64_t);
152             break;
153         case c_offload_gather_copyin_data:
154             str1 = report_get_message_str(c_report_state);
155             str2 = report_get_message_str(c_report_gather_copyin_data);
156             offload_stage(ss, offload_number, str1, str2, true);
157             break;
158         case c_offload_copyin_data:
159             str1 = report_get_message_str(c_report_state);
160             str2 = report_get_message_str(c_report_copyin_data);
161             offload_stage(ss, offload_number, str1, str2, true);
162             ss << " " << va_arg(va_args, uint64_t) << " ";
163             break;
164         case c_offload_compute:
165             str1 = report_get_message_str(c_report_state);
166             str2 = report_get_message_str(c_report_compute);
167             offload_stage(ss, offload_number, str1, str2, true);
168             break;
169         case c_offload_receive_pointer_data:
170             str1 = report_get_message_str(c_report_state);
171             str2 = report_get_message_str(c_report_receive_pointer_data);
172             offload_stage(ss, offload_number, str1, str2, true);
173             break;
174         case c_offload_received_pointer_data:
175             str1 = report_get_message_str(c_report_state);
176             str2 = report_get_message_str(c_report_received_pointer_data);
177             offload_stage(ss, offload_number, str1, str2, true);
178             ss << " " << va_arg(va_args, uint64_t);
179             break;
180         case c_offload_start_target_func:
181             str1 = report_get_message_str(c_report_state);
182             str2 = report_get_message_str(c_report_start_target_func);
183             offload_stage(ss, offload_number, str1, str2, true);
184             ss << ": " << va_arg(va_args, char*);
185             break;
186         case c_offload_var:
187             str1 = report_get_message_str(c_report_var);
188             offload_stage(ss, offload_number, str1, "  ", true);
189             va_arg(va_args, int);
190             ss << va_arg(va_args, char*);
191             ss << " " << " " << va_arg(va_args, char*);
192             break;
193         case c_offload_scatter_copyin_data:
194             str1 = report_get_message_str(c_report_state);
195             str2 = report_get_message_str(c_report_scatter_copyin_data);
196             offload_stage(ss, offload_number, str1, str2, true);
197             break;
198         case c_offload_gather_copyout_data:
199             str1 = report_get_message_str(c_report_state);
200             str2 = report_get_message_str(c_report_gather_copyout_data);
201             offload_stage(ss, offload_number, str1, str2, true);
202             break;
203         case c_offload_scatter_copyout_data:
204             str1 = report_get_message_str(c_report_state);
205             str2 = report_get_message_str(c_report_scatter_copyout_data);
206             offload_stage(ss, offload_number, str1, str2, true);
207             break;
208         case c_offload_copyout_data:
209             str1 = report_get_message_str(c_report_state);
210             str2 = report_get_message_str(c_report_copyout_data);
211             offload_stage(ss, offload_number, str1, str2, true);
212             ss << "   " << va_arg(va_args, uint64_t);
213             break;
214         case c_offload_signal:
215             {
216                 uint64_t  *signal;
217                 str1 = report_get_message_str(c_report_state_signal);
218                 str2 = report_get_message_str(c_report_signal);
219                 offload_message_2str(ss, offload_number, str1, str2);
220                 signal = va_arg(va_args, uint64_t*);
221                 if (signal)
222                     ss << " 0x" << std::hex << *signal;
223                 else
224                     ss << " none";
225             }
226             break;
227         case c_offload_stream:
228             {
229                 int64_t  stream;
230                 str1 = report_get_message_str(c_report_state_stream);
231                 str2 = report_get_message_str(c_report_stream);
232                 offload_message_2str(ss, offload_number, str1, str2);
233                 stream = va_arg(va_args, int64_t);
234                 if (stream)
235                     ss << " 0x" << std::hex << stream;
236                 else
237                     ss << " none";
238             }
239             break;
240         case c_offload_wait:
241             {
242                 int count;
243                 OffloadWaitKind kind;
244                 uint64_t  **signal;
245                 kind = (enum OffloadWaitKind) va_arg(va_args, int);
246                 // kind ==  c_offload_wait_signal for signal;
247                 // other kinds are for stream
248                 if (kind == c_offload_wait_signal) {
249                     str1 = report_get_message_str(c_report_state_signal);
250                 }
251                 else {
252                     str1 = report_get_message_str(c_report_state_stream);
253                 }
254                 str2 = report_get_message_str(c_report_wait);
255                 offload_message_2str(ss, offload_number, str1, str2);
256                 count = va_arg(va_args, int);
257                 signal = va_arg(va_args, uint64_t**);
258                 if (count) {
259                     if (kind == c_offload_wait_signal) {
260                         while (count) {
261                             ss << " " << std::hex << signal[count-1];
262                             count--;
263                         }
264                     }
265                     else if (kind == c_offload_wait_stream) {
266                         ss << signal;
267                     }
268                     else {
269                         ss << " all";
270                     }
271                 }
272                 else
273                     ss << " none";
274             }
275             break;
276         case c_offload_unregister:
277             str1 = report_get_message_str(c_report_state);
278             str2 = report_get_message_str(c_report_unregister);
279             offload_stage(ss, offload_number, str1, str2, false);
280             break;
281         case c_offload_destroy:
282             str1 = report_get_message_str(c_report_state);
283             str2 = report_get_message_str(c_report_destroy);
284             offload_stage(ss, offload_number, str1, str2, true);
285             break;
286         case c_offload_myoinit:
287             str1 = report_get_message_str(c_report_state);
288             str2 = report_get_message_str(c_report_myoinit);
289             offload_stage(ss, offload_number, str1, str2, false);
290             break;
291         case c_offload_myoregister:
292             str1 = report_get_message_str(c_report_state);
293             str2 = report_get_message_str(c_report_myoregister);
294             offload_stage(ss, offload_number, str1, str2, false);
295             break;
296         case c_offload_myofini:
297             str1 = report_get_message_str(c_report_state);
298             str2 = report_get_message_str(c_report_myofini);
299             offload_stage(ss, offload_number, str1, str2, false);
300             break;
301         case c_offload_mic_myo_shared:
302             str1 = report_get_message_str(c_report_state);
303             str2 = report_get_message_str(c_report_mic_myo_shared);
304             offload_stage(ss, offload_number, str1, str2, false);
305             ss << " " << va_arg(va_args, char*);
306             break;
307         case c_offload_mic_myo_fptr:
308             str1 = report_get_message_str(c_report_state);
309             str2 = report_get_message_str(c_report_mic_myo_fptr);
310             offload_stage(ss, offload_number, str1, str2, false);
311             ss << " " << va_arg(va_args, char*);
312             break;
313         case c_offload_myosharedmalloc:
314             str1 = report_get_message_str(c_report_state);
315             str2 = report_get_message_str(c_report_myosharedmalloc);
316             offload_stage(ss, offload_number, str1, str2, false);
317             va_arg(va_args, char*);
318             ss << " " << va_arg(va_args, size_t);
319             break;
320         case c_offload_myosharedfree:
321             str1 = report_get_message_str(c_report_state);
322             str2 = report_get_message_str(c_report_myosharedfree);
323             offload_stage(ss, offload_number, str1, str2, false);
324             break;
325         case c_offload_myosharedalignedmalloc:
326             str1 = report_get_message_str(c_report_state);
327             str2 = report_get_message_str(c_report_myosharedalignedmalloc);
328             offload_stage(ss, offload_number, str1, str2, false);
329             va_arg(va_args, char*);
330             ss << " " << va_arg(va_args, size_t);
331             ss << " " << va_arg(va_args, size_t);
332             break;
333         case c_offload_myosharedalignedfree:
334             str1 = report_get_message_str(c_report_state);
335             str2 = report_get_message_str(c_report_myosharedalignedfree);
336             offload_stage(ss, offload_number, str1, str2, false);
337             ss << " " << va_arg(va_args, size_t);
338             break;
339         case c_offload_myoacquire:
340             str1 = report_get_message_str(c_report_state);
341             str2 = report_get_message_str(c_report_myoacquire);
342             offload_stage(ss, offload_number, str1, str2, false);
343             break;
344         case c_offload_myorelease:
345             str1 = report_get_message_str(c_report_state);
346             str2 = report_get_message_str(c_report_myorelease);
347             offload_stage(ss, offload_number, str1, str2, false);
348             break;
349         case c_offload_myosupportsfeature:
350             str1 = report_get_message_str(c_report_state);
351             str2 = report_get_message_str(c_report_myosupportsfeature);
352             offload_stage(ss, offload_number, str1, str2, false);
353             va_arg(va_args, int);
354             ss << " " << va_arg(va_args, int);
355             ss << " " << va_arg(va_args, int);
356             ss << " " << va_arg(va_args, int);
357             break;
358         case c_offload_myosharedarenacreate:
359             str1 = report_get_message_str(c_report_state);
360             str2 = report_get_message_str(c_report_myosharedarenacreate);
361             offload_stage(ss, offload_number, str1, str2, false);
362             va_arg(va_args, char*);
363             ss << " " << va_arg(va_args, int);
364             ss << " " << va_arg(va_args, int);
365             ss << " " << va_arg(va_args, unsigned int);
366             break;
367         case c_offload_myosharedalignedarenamalloc:
368             str1 = report_get_message_str(c_report_state);
369             str2 = report_get_message_str(c_report_myosharedalignedarenamalloc);
370             offload_stage(ss, offload_number, str1, str2, false);
371             va_arg(va_args, char*);
372             ss << " " << va_arg(va_args, int);
373             ss << " " << va_arg(va_args, size_t);
374             ss << " " << va_arg(va_args, size_t);
375             break;
376         case c_offload_myosharedalignedarenafree:
377             str1 = report_get_message_str(c_report_state);
378             str2 = report_get_message_str(c_report_myosharedalignedarenafree);
379             offload_stage(ss, offload_number, str1, str2, false);
380             va_arg(va_args, char*);
381             ss << " " << va_arg(va_args, int);
382             ss << " " << va_arg(va_args, size_t);
383             break;
384         case c_offload_myoarenaacquire:
385             str1 = report_get_message_str(c_report_state);
386             str2 = report_get_message_str(c_report_myoarenaacquire);
387             offload_stage(ss, offload_number, str1, str2, false);
388             va_arg(va_args, char*);
389             ss << " " << va_arg(va_args, int);
390             break;
391         case c_offload_myoarenarelease:
392             str1 = report_get_message_str(c_report_state);
393             str2 = report_get_message_str(c_report_myoarenarelease);
394             offload_stage(ss, offload_number, str1, str2, false);
395             va_arg(va_args, char*);
396             ss << " " << va_arg(va_args, int);
397             break;
398         default:
399             LIBOFFLOAD_ERROR(c_report_unknown_trace_node);
400             abort();
401     }
402     ss << "\n";
403     buf = ss.str();
404     fprintf(stdout, buf.data());
405     fflush(stdout);
406 
407     va_end(va_args);
408     return;
409 }
410