LLNL/Caliper

Caliper Python Interface

jrmadsen opened this issue · 0 comments

So not really an "issue" but... I just realized I have effectively provided a Caliper interface to Python through timemory.

Assuming, you've built timemory's python bindings:

Caliper Module

mkdir caliper
touch caliper/__init__.py

caliper/__init__.py

from __future__ import absolute_import
import timemory

__all__ = ['attribute']


class attribute(timemory.util.auto_tuple):
    """
    Creates caliper attribute through either:
        - decorator       :: wraps entire function
        - context-manager :: wraps block of code
    """

    def __init__(self, key="", mode="defer", add_args=False):
        """
        Args:
            key (str)       :: a custom tag if desired
            mode (str)      :: how to construct the signature of the attribute
            add_args (bool) :: encode argument values into signature

        Note on "mode":
            mode == "full"  :: create a signature based on: __func__, key, __FILE__, __LINE__
            mode == "basic" :: create a signature based on: __func__ and key
            mode == "blank" :: create a signature based on: key
            mode == "defer" :: if decorator, use "basic"
                                if context-manager, use "blank"
        """
        super(attribute, self).__init__([timemory.component.caliper],
                                        key=key, add_args=add_args, mode=mode)

Test Script

#!/usr/bin/env python

import sys
import caliper


def fib(n):
    return n if n < 2 else (fib(n-1) + fib(n-2))

#
#   Create attribute with decorator
#
@caliper.attribute(add_args=True)
def run_fib(n):
    return fib(n)


if __name__ == "__main__":

    nfib = int(sys.argv[1]) if len(sys.argv) > 1 else 34

    #
    #   Create attribute with context manager
    #
    with caliper.attribute("{}({})".format(sys.argv[0], nfib)):
        # first attribute will include these two calculation
        ans = fib(nfib)
        # creates second attribute via decorator
        ans += run_fib(nfib + 1)

    print("\t{} answer = {}\n".format(sys.argv[0], ans))

Execution

$ CALI_CONFIG_PROFILE=runtime-report python cali_example.py
== CALIPER: default: Registered aggregation service
== CALIPER: default: Registered event trigger service
== CALIPER: default: Registered report service
== CALIPER: default: Registered timestamp service
== CALIPER: Creating channel default
== CALIPER: Initialized
#--------------------- tim::manager initialized [0] ---------------------#

	cali_example.py answer = 14930352

== CALIPER: Finishing ...
== CALIPER: default: Flushing Caliper data
== CALIPER: default: Aggregate: flushed 3 snapshots.
Path                  Inclusive time Exclusive time Time %    
cali_example.py(34)         4.399537       1.804767 41.013405 
  run_fib(35)               2.594770       2.594770 58.966256 
== CALIPER: Finished


#---------------------- tim::manager destroyed [0] ----------------------#

Side note: currently you will need to checkout the GOTCHA branch but I am about to merge this branch soon once I resolve stupid Windows issues