Skip to content

Commit 6a7f05b

Browse files
committed
PMCTrack v0.5
1 parent d2d00d6 commit 6a7f05b

27 files changed

+1281
-930
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ To illustrate how the TBS mode works let us consider the following example comma
331331
...
332332

333333

334-
This command provides the user with the number of instructions retired, last-level cache (LLC) misses and core energy consumption (in mJ) every second. The beginning of the command output shows the event-to-counter mapping for the various hardware events and virtual counters. The "Event counts" section in the output displays a table with the raw counts for the various events; each sample (one per second) is represented by a different row. Note that the sampling period is specified in seconds via the -T option; fractions of a second can be also specified (e.g, 0.3 for 300ms). If the user includes the -A switch in the command line, `pmctrack` will display the aggregate event count for the application's entire execution instead. At the end of the line, we specify the command to run the associated application we wish to monitor (e.g: ./mcf06).
334+
This command provides the user with the number of instructions retired, last-level cache (LLC) misses and core energy consumption (in uJ) every second. The beginning of the command output shows the event-to-counter mapping for the various hardware events and virtual counters. The "Event counts" section in the output displays a table with the raw counts for the various events; each sample (one per second) is represented by a different row. Note that the sampling period is specified in seconds via the -T option; fractions of a second can be also specified (e.g, 0.3 for 300ms). If the user includes the -A switch in the command line, `pmctrack` will display the aggregate event count for the application's entire execution instead. At the end of the line, we specify the command to run the associated application we wish to monitor (e.g: ./mcf06).
335335

336336
In case a specific processor model does not integrate enough PMCs to monitor a given set of events at once, the user can turn to PMCTrack's event-multiplexing feature. This boils down to specifying several event sets by including multiple instances of the -c switch in the command line. In this case, the various events sets will be collected in a round-robin fashion and a new `expid` field in the output will indicate the event set a particular sample belongs to. In a similar vein, time-based sampling also supports multithreaded applications. In this case, samples from each thread in the application will be identified by a different value in the pid column.
337337

etc/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.4
1+
0.5

shrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ if [ "$PMCTRACK_ROOT" == "" ]; then
66
export PMCTRACK_ROOT
77
export PATH=$PMCTRACK_ROOT/bin:$PATH
88
export PYTHONPATH=$PMCTRACK_ROOT/bin:$PYTHONPATH
9+
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PMCTRACK_ROOT/src/lib/libpmctrack
910
fi
1011

1112

src/cmdtools/pmctrack/pmctrack.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ void monitoring_counters_syswide(struct options* opts,int optind,char** argv)
535535
pmctrack_exit(1);
536536

537537
/* Configure counters if there is something to configure */
538-
if (opts->strcfg[0] && pmct_config_counters((const char**)opts->strcfg,1))
538+
if (opts->strcfg[0] && pmct_config_counters((const char**)opts->strcfg,PMCT_CONFIG_SYSWIDE))
539539
pmctrack_exit(1);
540540

541541
/* Set up sampling period
@@ -544,7 +544,7 @@ void monitoring_counters_syswide(struct options* opts,int optind,char** argv)
544544
if (pmct_config_timeout(opts->msecs,(!(opts->strcfg)[0] && npmcs!=0)))
545545
pmctrack_exit(1);
546546

547-
if (opts->virtcfg && pmct_config_virtual_counters(opts->virtcfg,1))
547+
if (opts->virtcfg && pmct_config_virtual_counters(opts->virtcfg,PMCT_CONFIG_SYSWIDE))
548548
pmctrack_exit(1);
549549

550550
#ifndef USE_VFORK
@@ -908,7 +908,7 @@ static void process_pmc_counts(struct options* opts, int nr_experiments,unsigned
908908

909909
/* Make sure not to exceed the maximum number of samples requested */
910910
if (opts->max_samples!=-1 && (cont+nr_samples>opts->max_samples))
911-
nr_samples=opts->max_samples-(cont-1);
911+
nr_samples=opts->max_samples-(cont-1);
912912

913913
for (i=0; i<nr_samples; i++) {
914914
pmc_sample_t* cur=&samples[i];

src/gui/backend/pmc_connect.py

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
#
44
# pmc_connect.py
5-
# Component for connecting to remote machines using SSH or local machine.
5+
# Component for connecting to remote machines using SSH, ADB-server or local
6+
# machine.
67
#
78
##############################################################################
89
#
@@ -31,44 +32,47 @@
3132
class PMCConnect(object):
3233
def __init__(self, info_machine):
3334
self.info_machine = info_machine
34-
if info_machine.is_remote:
35-
self.ssh_array = info_machine.GetSSHCommand().split()
35+
self.conn_array = None
36+
if info_machine.type_machine == "ssh":
37+
self.conn_array = info_machine.GetSSHCommand().split()
38+
if info_machine.type_machine == "adb":
39+
self.conn_array = info_machine.GetADBCommand().split()
3640

3741
def CheckFileExists(self, file):
3842
if file != "" and file != "\n" and file.find("#") == -1:
39-
if self.info_machine.is_remote:
40-
command = self.ssh_array[:]
43+
if self.info_machine.type_machine == "local":
44+
ok = os.path.exists(file)
45+
else:
46+
command = self.conn_array[:]
4147
command.append("ls " + file)
4248
pipe = Popen(command, stdout=PIPE, stderr=PIPE)
4349
stdout, stderr = pipe.communicate()
44-
ok = (stderr == "")
45-
else:
46-
ok = os.path.exists(file)
50+
ok = (stdout.find(file) >= 0 and stdout.find("No such") < 0)
4751
else:
4852
ok = False
4953
return ok
5054

51-
def CheckPkgInstalled(self, pkg, remote):
55+
def CheckPkgInstalled(self, pkg, check_in_remote):
5256
command = None
53-
if remote: command = self.ssh_array[:]
54-
else: command = []
55-
command.append(pkg)
56-
try:
57-
pipe = Popen(command, stdout=PIPE, stderr=PIPE)
58-
stdout, stderr = pipe.communicate()
59-
installed = (stderr == "")
60-
except:
61-
installed = False
62-
return installed
57+
if check_in_remote:
58+
command = self.conn_array[:]
59+
command.append("which " + pkg)
60+
else:
61+
command = ["which", pkg]
62+
pipe = Popen(command, stdout=PIPE, stderr=PIPE)
63+
stdout, stderr = pipe.communicate()
64+
return (stdout.find(pkg) >= 0)
6365

6466
def CheckConnectivity(self):
65-
command = self.ssh_array[:]
66-
command.append("whoami")
67+
command = self.conn_array[:]
68+
command.append("echo hello")
6769
pipe = Popen(command, stdout=PIPE, stderr=PIPE)
6870
stdout, stderr = pipe.communicate()
6971
msg_error = ""
70-
if (stdout.find(self.info_machine.remote_user) != 0):
71-
if stderr.find("publickey,password") >= 0:
72+
if (stdout.find("hello") < 0):
73+
if stderr.find("Cannot start server") >= 0:
74+
msg_error = _("No connection with ADB server.")
75+
elif stderr.find("publickey,password") >= 0:
7276
msg_error = _("The SSH key provided is invalid.")
7377
elif stderr.find("ermis") >= 0:
7478
msg_error = _("The username or password are incorrect.")
@@ -81,13 +85,13 @@ def CheckConnectivity(self):
8185
return msg_error
8286

8387
def ReadFile(self, file):
84-
if self.info_machine.is_remote:
85-
command = self.ssh_array[:]
86-
command.append("cat " + file)
87-
pipe = Popen(command, stdout=PIPE, stderr=PIPE)
88-
result = pipe.stdout.read()
89-
else:
88+
if self.info_machine.type_machine == "local":
9089
descrip = open(file, 'rU')
9190
result = descrip.read()
9291
descrip.close()
92+
else:
93+
command = self.conn_array[:]
94+
command.append("cat " + file)
95+
pipe = Popen(command, stdout=PIPE, stderr=PIPE)
96+
result = pipe.stdout.read()
9397
return result

src/gui/backend/pmc_extract.py

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,43 +96,67 @@ def ResumeMonitoring(self):
9696
else:
9797
self.__send_signal_to_application("SIGCONT")
9898
self.state[self.app_running] = 'R'
99-
100-
def KillMonitoring(self):
101-
os.kill(self.pipe.pid, signal.SIGKILL)
99+
100+
def KillMonitoringRequest(self):
102101
self.state[self.app_running] = 'K'
102+
103+
104+
def __kill_monitoring(self):
105+
if self.user_config.machine.type_machine == "local":
106+
os.kill(self.pipe.pid, signal.SIGINT)
107+
else:
108+
comando = None
109+
if self.user_config.machine.type_machine == "ssh":
110+
comando = self.user_config.machine.GetSSHCommand().split()
111+
else:
112+
comando = self.user_config.machine.GetADBCommand().split()
113+
comando.append("kill -s SIGINT `pidof pmctrack`")
114+
Popen(comando)
103115

104116
def __send_signal_to_application(self, str_signal):
105117
if self.pid[self.app_running] != None and self.state[self.app_running] in ['R', 'S']:
106-
if not self.user_config.machine.is_remote:
118+
if self.user_config.machine.type_machine == "local":
107119
Popen(("kill -s " + str_signal + " " + self.pid[self.app_running]).split())
108120
else:
109-
comando = self.user_config.machine.GetSSHCommand().split()
121+
comando = None
122+
if self.user_config.machine.type_machine == "ssh":
123+
comando = self.user_config.machine.GetSSHCommand().split()
124+
else:
125+
comando = self.user_config.machine.GetADBCommand().split()
110126
comando.append("kill -s " + str_signal + " " + self.pid[self.app_running])
111127
Popen(comando)
112128

113129
def __pause_resume_syswide(self, arg):
114-
if not self.user_config.machine.is_remote:
115-
Popen(("echo -n syswide " + arg + " > /proc/pmc/enable").split())
116-
else:
130+
if self.user_config.machine.type_machine == "local":
131+
Popen(("echo -n syswide " + arg + " > /proc/pmc/enable").split())
132+
else:
133+
comando = None
134+
if self.user_config.machine.type_machine == "ssh":
117135
comando = self.user_config.machine.GetSSHCommand().split()
118-
comando.append("echo -n syswide " + arg + " > /proc/pmc/enable")
119-
Popen(comando)
136+
else:
137+
comando = self.user_config.machine.GetADBCommand().split()
138+
comando.append("echo -n syswide " + arg + " > /proc/pmc/enable")
139+
Popen(comando)
120140

121141
def __create_pipe(self, app):
122-
if not self.user_config.machine.is_remote:
142+
if self.user_config.machine.type_machine == "local":
123143
self.pipe = Popen(self.__get_command(app).split(), stdout=PIPE, stderr=PIPE)
124144
else:
125-
comando = self.user_config.machine.GetSSHCommand().split()
126-
comando.append("-t")
145+
comando = None
146+
if self.user_config.machine.type_machine == "ssh":
147+
comando = self.user_config.machine.GetSSHCommand().split()
148+
comando.append("-t")
149+
else:
150+
comando = self.user_config.machine.GetADBCommand().split()
127151
comando.append(self.__get_command(app) + " 2>&1")
128152
#comando.append(self.__get_command(app) + " 2> /dev/null")
129153
self.pipe = Popen(comando, stdout=PIPE, stderr=PIPE)
130154

131155
def __create_log_file_descriptors(self, app, line_head):
132-
if self.user_config.machine.is_remote:
133-
machine = self.user_config.machine.remote_address
134-
else:
156+
if self.user_config.machine.type_machine == "local":
135157
machine = _("local")
158+
else:
159+
machine = self.user_config.machine.remote_address
136160

137161
out_header = _("Generated by PMCTrack-GUI on {0}").format(time.strftime("%c")) + "\n\n"
138162
out_header += _("Command launched on '{0}':").format(machine) + "\n"
@@ -159,7 +183,7 @@ def __extract_information(self):
159183
self.__create_pipe(app)
160184
self.pos.clear()
161185
line_head = self.pipe.stdout.readline()
162-
if line_head.find("PID found") >= 0:
186+
while line_head.find("PID found") >= 0:
163187
line_head = self.pipe.stdout.readline()
164188
# This if checks if exists pmctrack command header
165189
if(line_head.find("nsample") >= 0 and line_head.find(self.pack) >= 0 and line_head.find("event") >= 0):
@@ -219,6 +243,10 @@ def __extract_information(self):
219243
for metric in self.user_config.experiments[ind_exp].metrics:
220244
self.out_metrics.write("-".rjust(13) + " ")
221245
self.out_metrics.write("\n")
246+
247+
if self.state[app] == 'K':
248+
self.__kill_monitoring()
249+
break
222250

223251
self.app_running = None
224252
if self.out_counters != None:
@@ -256,7 +284,7 @@ def __get_experiments_command(self, num_experiment):
256284

257285
# Returns pmctrack command of a particular app specified from user settings
258286
def __get_command(self, app):
259-
str_command = "pmctrack -L -r"
287+
str_command = self.user_config.pmctrack_path + " -L -r"
260288
str_command += " -T " + "{0:.2f}".format(float(self.user_config.time) / 1000)
261289
if self.user_config.system_wide:
262290
str_command += " -S"

src/gui/backend/user_config.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ def __init__(self):
6161

6262
class MachineConfig(object):
6363

64-
def __init__(self, is_remote, remote_address=None, remote_port=22, remote_user=None, remote_password=None, path_key=None):
65-
self.is_remote = is_remote
64+
def __init__(self, type_machine, remote_address=None, remote_port=22, remote_user=None, remote_password=None, path_key=None):
65+
self.type_machine = type_machine # "local", "ssh" or "adb"
6666
self.remote_address = remote_address
6767
self.remote_port = remote_port
6868
self.remote_user = remote_user
@@ -82,6 +82,10 @@ def GetSSHCommand(self):
8282
ssh_command += " -l " + self.remote_user
8383
ssh_command += " " + self.remote_address
8484
return ssh_command
85+
86+
def GetADBCommand(self):
87+
return "adb -H " + self.remote_address + " -P " + self.remote_port + " shell"
88+
8589

8690
class GraphStyleConfig(object):
8791

@@ -102,6 +106,7 @@ def __init__(self):
102106
self.machine = None # Information about monitoring machine
103107
self.applications = []
104108
self.cpu = None # CPU number where to run benchmark, or CPU mask
109+
self.pmctrack_path = None # Path to pmctrack command
105110
self.time = 0 # Time between samples (in miliseconds)
106111
self.buffer_size = 0 # Samples buffer size (in bytes)
107112
self.pid_app_running = None # Application's PID (if app to monitor is running)
@@ -113,7 +118,7 @@ def __init__(self):
113118

114119
def GetCopy(self):
115120
copy = UserConfig()
116-
copy.machine = MachineConfig(self.machine.is_remote, self.machine.remote_address, self.machine.remote_port, self.machine.remote_user, self.machine.remote_password, self.machine.path_key)
121+
copy.machine = MachineConfig(self.machine.type_machine, self.machine.remote_address, self.machine.remote_port, self.machine.remote_user, self.machine.remote_password, self.machine.path_key)
117122
num_exp = 0
118123

119124
for experiment in self.experiments:
@@ -135,6 +140,7 @@ def GetCopy(self):
135140
for application in self.applications:
136141
copy.applications.append(application)
137142
copy.cpu = self.cpu
143+
copy.pmctrack_path = self.pmctrack_path
138144
copy.time = self.time
139145
copy.buffer_size = self.buffer_size
140146
copy.pid_app_running = self.pid_app_running

0 commit comments

Comments
 (0)