HPCToolkit
common.c
Go to the documentation of this file.
1 // -*-Mode: C++;-*- // technically C99
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 #include <stdlib.h>
48 #include <string.h>
49 
50 #include "sample_source_obj.h"
51 #include "common.h"
52 
53 #include <messages/messages.h>
54 #include <hpcrun/thread_data.h>
55 
56 void
57 CMETHOD_FN(add_event, const char *ev)
58 {
59  char *evl = self->evl.evl_spec;
60 
61  TMSG(SS_COMMON,"add event %s to evl |%s|", ev, evl);
62  strcat(evl, ev);
63  strcat(evl," ");
64  TMSG(SS_COMMON,"evl after event added = |%s|",evl);
65 }
66 
67 void
68 CMETHOD_FN(store_event, int event_id, long thresh)
69 {
70  TMSG(SAMPLE_SOURCE,"%s: store event %d thresh = %ld", self->name, event_id, thresh);
71 
72  METHOD_CALL(self, store_event_and_info, event_id, thresh, 0, NULL);
73 }
74 
75 /***
76  * store events and its info, then returns the current event index
77  * returns -1 if fails
78  */
79 int
80 CMETHOD_FN(store_event_and_info, int event_id, long thresh,
81  int metric_id, void *info)
82 {
83  TMSG(SAMPLE_SOURCE,"%s: store event and info %d thresh = %ld", self->name, event_id, thresh);
84 
85  evlist_t *_p = &(self->evl);
86  int num_events = _p->nevents;
87 
88  int* ev = &(_p->nevents);
89  if (*ev >= MAX_EVENTS) {
90  EMSG("Too many events entered for sample source. Event code %d ignored", event_id);
91  return -1;
92  }
93  _ev_t* current_event = &(_p->events[*ev]);
94 
95  current_event->event = event_id;
96  current_event->thresh = thresh;
97  current_event->metric_id = metric_id;
98  current_event->event_info = info;
99 
100  (*ev)++;
101 
102  TMSG(SAMPLE_SOURCE,"%s now has %d events", self->name, *ev);
103 
104  return num_events;
105 }
106 
107 void
108 CMETHOD_FN(store_metric_id, int event_idx, int metric_id)
109 {
110 
111  TMSG(SAMPLE_SOURCE, "%s event[%d] = metric_id %d", self->name, event_idx, metric_id);
112  evlist_t *_p = &(self->evl);
113  int n_events = _p->nevents;
114 
115  if (event_idx >= n_events) {
116  EMSG("Trying to store metric_id(=%d) for an invalid event index(=%d)."
117  "Only %d events recorded for sample source %s", metric_id, event_idx, n_events, self->name);
118  return;
119  }
120  _ev_t* current_event = &(_p->events[event_idx]);
121 
122  current_event->metric_id = metric_id;
123 }
124 
125 
126 char*
127 CMETHOD_FN(get_event_str)
128 {
129  return (self->evl).evl_spec;
130 }
131 
132 bool
133 CMETHOD_FN(started)
134 {
135  return (TD_GET(ss_state)[self->sel_idx] == START);
136 }
137 
138 // **********************************************************
139 // Interface (NON method) functions
140 // **********************************************************
141 
142 int
144 {
145  TMSG(SAMPLE_SOURCE, "%s fetching metric_id for event %d", ss->name, event_idx);
146  evlist_t *_p = &(ss->evl);
147  int n_events = _p->nevents;
148 
149  if (event_idx >= n_events) {
150  EMSG("Trying to fetch metric id an invalid event index."
151  "Only %d events recorded for sample source %s. Returning 0", event_idx, n_events, ss->name);
152  return 0;
153  }
154  _ev_t* current_event = &(_p->events[event_idx]);
155 
156  TMSG(SAMPLE_SOURCE, "Fetched metric id = %d", current_event->metric_id);
157  return current_event->metric_id;
158 }
159 
160 // **********************************************************
161 // Sample Source Failure Messages (ssfail)
162 // **********************************************************
163 
164 static char *prefix = "HPCToolkit fatal error";
165 static char *warning = "HPCToolkit warning";
166 static char *hpcrun_L =
167  "If running a dynamically-linked program with hpcrun, use 'hpcrun -L <program>' for a list of available events.\n\n"
168  "If running a statically-linked program built with hpclink, set HPCRUN_EVENT_LIST=LIST in your environment and\n"
169  "run your program to see a list of available events.\n\n"
170  "Note: Either of the aforementioned methods will exit after listing available events. Arguments to your program\n"
171  "will be ignored. Thus, an execution to list events can be run on a single core and it will execute for only a few\n"
172  "seconds.";
173 static int papi_error = 0;
174 
175 
176 // Special case to treat failure in PAPI init as a soft error.
177 // If PAPI_library_init() fails, delay printing an error message until
178 // after trying all other sample sources.
179 //
180 // This is useful on ranger where PAPI is not compiled into the kernel
181 // on the login nodes, but we can still run with WALLCLOCK there.
182 //
183 void
185 {
186  papi_error = error;
187 }
188 
189 static void
191 {
193  STDERR_MSG("%s: PAPI_library_init() failed as unavailable.\n"
194  "Probably, the kernel is missing a module for accessing the hardware\n"
195  "performance counters (perf_events, perfmon or perfctr).\n",
196  warning);
197  }
199  STDERR_MSG("%s: PAPI_library_init() failed with version mismatch.\n"
200  "Probably, HPCToolkit is out of sync with PAPI, or else PAPI is\n"
201  "out of sync with the kernel.\n",
202  warning);
203  }
204 }
205 
206 // The none and unknown event failures happen before we set up the log
207 // file, so we can only write to stderr.
208 void
210 {
211  STDERR_MSG("%s: no sampling source specified.\n"
212  "Set HPCRUN_EVENT_LIST to a comma-separated list of EVENT@PERIOD pairs\n"
213  "and rerun your program. If you truly want to run with no events, then\n"
214  "set HPCRUN_EVENT_LIST=NONE.\n%s",
215  prefix, hpcrun_L);
216  exit(1);
217 }
218 
219 void
221 {
223 
224  STDERR_MSG("%s: event %s is unknown or unsupported.\n%s",
225  prefix, event, hpcrun_L);
226  exit(1);
227 }
228 
229 void
230 hpcrun_ssfail_unsupported(char *source, char *event)
231 {
232  EEMSG("%s: %s event %s is not supported on this platform.\n%s",
233  prefix, source, event, hpcrun_L);
234  exit(1);
235 }
236 
237 void
238 hpcrun_ssfail_derived(char *source, char *event)
239 {
240  EEMSG("%s: %s event %s is a derived event and thus cannot be profiled.\n%s",
241  prefix, source, event, hpcrun_L);
242  exit(1);
243 }
244 
245 void
247 {
248  EEMSG("%s: All %s events are derived. To use proxy sampling,\n"
249  "at least one event must support hardware overflow (eg, PAPI_TOT_CYC).\n",
250  prefix, source);
251  exit(1);
252 }
253 
254 void
255 hpcrun_ssfail_conflict(char *source, char *event)
256 {
257  EEMSG("%s: %s event %s cannot be profiled in this sequence.\n"
258  "Either it conflicts with another event, or it exceeds the number of\n"
259  "hardware counters.\n%s",
260  prefix, source, event, hpcrun_L);
261  exit(1);
262 }
263 
264 void
265 hpcrun_ssfail_start(char *source)
266 {
267  EEMSG("%s: sample source %s failed to start.\n"
268  "Check the event list and the HPCToolkit installation and try again.\n%s",
269  prefix, source, hpcrun_L);
270  exit(1);
271 }
272 
#define STDERR_MSG(...)
Definition: messages.h:89
void * event_info
Definition: evlist.h:62
void hpcrun_ssfail_derived(char *source, char *event)
Definition: common.c:238
void hpcrun_save_papi_error(int error)
Definition: common.c:184
void hpcrun_ssfail_all_derived(char *source)
Definition: common.c:246
void hpcrun_ssfail_unknown(char *event)
Definition: common.c:220
_ev_t events[MAX_EVENTS]
Definition: evlist.h:69
static char * prefix
Definition: common.c:164
static char * warning
Definition: common.c:165
exit
Definition: names.cpp:1
#define EMSG
Definition: messages.h:70
void hpcrun_ssfail_unsupported(char *source, char *event)
Definition: common.c:230
int metric_id
Definition: evlist.h:56
void CMETHOD_FN(add_event, const char *ev)
Definition: common.c:57
void hpcrun_ssfail_none(void)
Definition: common.c:209
static int papi_error
Definition: common.c:173
void hpcrun_ssfail_start(char *source)
Definition: common.c:265
long thresh
Definition: evlist.h:55
#define TD_GET(field)
Definition: thread_data.h:256
#define TMSG(f,...)
Definition: messages.h:93
int hpcrun_event2metric(sample_source_t *ss, int event_idx)
Definition: common.c:143
#define METHOD_CALL(obj, meth,...)
Definition: simple_oo.h:87
#define EEMSG(...)
Definition: messages.h:90
#define NULL
Definition: ElfHelper.cpp:85
static char * hpcrun_L
Definition: common.c:166
static int n_events
Definition: generic.c:129
int event
Definition: evlist.h:54
static void hpcrun_display_papi_error(void)
Definition: common.c:190
#define HPCRUN_PAPI_ERROR_VERSION
Definition: common.h:53
Definition: evlist.h:53
int nevents
Definition: evlist.h:68
#define MAX_EVENTS
Definition: evlist.h:51
#define HPCRUN_PAPI_ERROR_UNAVAIL
Definition: common.h:52
void hpcrun_ssfail_conflict(char *source, char *event)
Definition: common.c:255