Hello Arun,

Thanks for the patch.

I made made some changes to tthe examples. They both had problems
reading the 2 events. See the attached updated versions.

Also I have added some code to catch error especially on pfm_load_context.
This work well now. However, I am having problems catching the libpfm errors.

I would rather have the exception called libpfmError. I modified perfmon_int.i
for that but it did not work. How do you do that. I would also like to be able
to called pfmlib_strerror() to print the error message if necessary.

Do you know how to do that?

Thanks.


On Mon, Mar 24, 2008 at 7:02 PM, Arun Sharma <[EMAIL PROTECTED]> wrote:
> Hi Stephane,
>
>  I believe this updated patch handles exceptions better. I think I now
>  understand the distinction between libpfm errors and os errors you
>  were trying to make.
>
>  # python -c "import perfmon; perfmon.pfm_dispatch_events(None, None,
>  None, None)"
>  Traceback (most recent call last):
>   File "<string>", line 1, in ?
>  perfmon.ERROR: (-3, 'pfmlib not initialized')
>
>  # python -c "import perfmon; perfmon.pfm_start(1, None)"
>  Traceback (most recent call last):
>   File "<string>", line 1, in ?
>  OSError: [Errno 9] Bad file descriptor
>
>  This replaces all the other python related patches I've posted to the
>  list so far.
>
>   -Arun
>
>  PS: The strings os_err_t, pfm_err_t don't matter. We could rename them
>  to something else if you like.
>
> -------------------------------------------------------------------------
>  This SF.net email is sponsored by: Microsoft
>  Defy all challenges. Microsoft(R) Visual Studio 2008.
>  http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
>  perfmon2-devel mailing list
>  [email protected]
>  https://lists.sourceforge.net/lists/listinfo/perfmon2-devel
>
>
#!/usr/bin/env python
#
# Copyright (c) 2008 Google, Inc.
# Contributed by Arun Sharma <[EMAIL PROTECTED]>
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
# 
# Self monitoring example. Copied from self.c

import os
from optparse import OptionParser
import random
import errno
from perfmon import *

if __name__ == '__main__':
  parser = OptionParser()
  parser.add_option("-p", "--pid", help="Monitor this process id", action="store", dest="pid")
  parser.set_defaults(pid=os.getpid())
  (options, args) = parser.parse_args()

  # initialize library
  opts = pfmlib_options_t()
  opts.pfm_verbose = 1
  pfm_set_options(opts)
  pfm_initialize()

  # setup context
  ctx = pfarg_ctx_t()
  fd = pfm_create_context(ctx, None, None, 0)

  # select and dispatch events
  inp = pfmlib_input_param_t()
  pfm_get_cycle_event(inp.pfp_events[0])
  pfm_get_inst_retired_event(inp.pfp_events[1])

  # monitor at priv level 3 (user)
  inp.pfp_dfl_plm = PFM_PLM3|PFM_PLM2
  outp = pfmlib_output_param_t()

  # measuring two events
  cnt = 2
  inp.pfp_event_count = cnt

  # get assignment from libpfm
  try:
    pfm_dispatch_events(inp, None, outp, None)
  except libpfm.ERROR:
    print "dispatch failed"

  # pfp_pmc_count may be > cnt
  cnt = outp.pfp_pmc_count
  pmcs = pmc(outp.pfp_pmc_count)
  pmds = pmd(outp.pfp_pmd_count)

  # copy pmc configuration
  for i in xrange(outp.pfp_pmc_count):
    # This code is a bit icky.
    # pmcs[i].reg_num = x doesn't work
    # Consult with SWIG experts
    npmc = pfarg_pmc_t()
    npmc.reg_num = outp.pfp_pmcs[i].reg_num
    npmc.reg_value = outp.pfp_pmcs[i].reg_value

    pmcs[i] = npmc

  # copy pmd configuration
  for i in xrange(outp.pfp_pmd_count):
    npmd = pfarg_pmd_t()
    npmd.reg_num = outp.pfp_pmds[i].reg_num
    pmds[i] = npmd

  # program PMCs and PMDs
  pfm_write_pmcs(fd, pmcs, outp.pfp_pmc_count)
  pfm_write_pmds(fd, pmds, outp.pfp_pmd_count)

  # attach context to self
  load = pfarg_load_t()
  load.load_pid = int(options.pid)
  try:
    pfm_load_context(fd, load)
  except OSError, err:
    if err.errno == errno.EBUSY:
      print "There is a conflicting system-wide session"
    else:
      print "pfm_load_context failed:", os.strerror(err.errno)
    os.close(fd)
    os._exit(1)

  # Start measuring
  pfm_start(fd, None)

  # code to be measured
  #
  # note that this is not identical to what examples/self.c does
  # thus counts will be different in the end
  for i in range(1, 10000000):
    random.random()

  # stop monitoring
  pfm_stop(fd)

  # read counts
  pfm_read_pmds(fd, pmds, outp.pfp_pmd_count)

  # print the counts
  for i in xrange(outp.pfp_pmd_count):
    print """PMD%d\t%lu""" % (pmds[i].reg_num, pmds[i].reg_value)

  os.close(fd)
#!/usr/bin/env python
#
# Copyright (c) 2008 Google, Inc.
# Contributed by Arun Sharma <[EMAIL PROTECTED]>
# 
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
# 
# System wide monitoring example. Copied from syst.c
#
# Prints the CPI (cycles per instruction) on a given cpu
# Run as: taskset -c cpu ./sys.py -c cpu

import os
from optparse import OptionParser
import random
import time 
import errno
from perfmon import *

if __name__ == '__main__':
  parser = OptionParser()
  parser.add_option("-c", "--cpu", help="Monitor this cpu", action="store", dest="cpu")
  parser.set_defaults(cpu=0)
  (options, args) = parser.parse_args()

  # initialize library
  opts = pfmlib_options_t()
  opts.pfm_verbose = 1
  pfm_set_options(opts)
  pfm_initialize()

  # setup context as system-wide, i.e., cpu-wide
  ctx = pfarg_ctx_t()
  ctx.zero()
  ctx.ctx_flags = PFM_FL_SYSTEM_WIDE
  try:
    fd = pfm_create_context(ctx, None, None, 0)
  except OSError:
    print "cannot create context, exiting"
    os._exit(1)

  # select and dispatch events
  inp = pfmlib_input_param_t()
  pfm_get_cycle_event(inp.pfp_events[0])
  pfm_get_inst_retired_event(inp.pfp_events[1])

  # measure user + kernel
  inp.pfp_dfl_plm = PFM_PLM3 | PFM_PLM0
  inp.pfp_flags = PFMLIB_PFP_SYSTEMWIDE;
  outp = pfmlib_output_param_t()
  cnt = 2
  inp.pfp_event_count = cnt

  # get assignment from libpfm
  pfm_dispatch_events(inp, None, outp, None)

  # pfp_pm_count may be > cnt
  cnt = outp.pfp_pmc_count
  pmcs = pmc(outp.pfp_pmc_count)
  pmds = pmd(outp.pfp_pmd_count)

  # copy PMC configuration
  for i in xrange(outp.pfp_pmc_count):
    # This code is a bit icky.
    # pmcs[i].reg_num = x doesn't work
    # Consult with SWIG experts
    npmc = pfarg_pmc_t()
    npmc.reg_num = outp.pfp_pmcs[i].reg_num
    npmc.reg_value = outp.pfp_pmcs[i].reg_value

    pmcs[i] = npmc

  # copy the PMD configuration
  for i in xrange(outp.pfp_pmd_count):
    npmd = pfarg_pmd_t()
    npmd.reg_num = outp.pfp_pmds[i].reg_num
    pmds[i] = npmd

  # program PMCs and PMDs
  pfm_write_pmcs(fd, pmcs, outp.pfp_pmc_count)
  pfm_write_pmds(fd, pmds, outp.pfp_pmd_count)

  # attach to CPU
  # process must run on CPU being measured
  # perfmon does not change affinity. Given that
  # in Python there is no affinity call, the program
  # must be invoked via taskset -c XX if option --cpu
  # is set to X. pfm_load_context fails if not running
  # on the CPU to monitor
  #
  load = pfarg_load_t()
  load.zero()
  load.load_pid = int(options.cpu)

  try:
   pfm_load_context(fd, load)
  except OSError, err: 
    if err.errno == errno.EBUSY:
      print "There is a conflicting session"
    elif err.errno == errno.EINVAL:
      print """trying to monitor on CPU%s, but likely running on another, trying using taskset -c %s""" % (options.cpu, options.cpu)
    else:
      print "pfm_load_context failed:", os.strerror(err.errno)
    os.close(fd)
    os._exit(1)

  # Measuring loop
  print "Printing CPI"
  for i in range(1, 10):
    pfm_start(fd, None)
    time.sleep(1)
    pfm_stop(fd)
    pfm_read_pmds(fd, pmds, outp.pfp_pmd_count)
    # Print the counts
    #for i in xrange(cnt):
    #  print pmds[i].reg_value,
    print 1.0 * pmds[0].reg_value/pmds[1].reg_value

  os.close(fd)
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
perfmon2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel

Reply via email to