[m-rev.] for review: new module mdprof_CSS_above_threshold

Jerome Tannier jerome.tannier at student.fundp.ac.be
Thu Oct 19 13:45:13 AEST 2006


Branches: main

deep_profiler/mpdrof_feedback.m:
    New module which writes to a file the list of call sites static
    whose matching call sites dynamic's average/median
    callseqs exceed the given threshold.

Mmakefile:
deep_profiler/Mmakefile:
    Build and install mdprof_feedback.m.

    Fix an existing bug. The install target should depend
    on mdprof_test and mdprof_dump.


Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/Mmakefile,v
retrieving revision 1.114
diff -u -r1.114 Mmakefile
--- Mmakefile	2 Oct 2006 06:30:34 -0000	1.114
+++ Mmakefile	18 Oct 2006 07:39:45 -0000
@@ -141,7 +141,8 @@
 ifeq ("$(ENABLE_DEEP_PROFILER)","yes")
 dep_deep_profiler: deep_profiler/$(deps_subdir)mdprof_cgi.dep \
 		deep_profiler/$(deps_subdir)mdprof_test.dep \
-		deep_profiler/$(deps_subdir)mdprof_dump.dep
+		deep_profiler/$(deps_subdir)mdprof_dump.dep \
+		deep_profiler/$(deps_subdir)mdprof_feedback.dep
 else
 dep_deep_profiler:
 endif
@@ -158,6 +159,10 @@
 		library/$(deps_subdir)$(STD_LIB_NAME).dep
 	+cd deep_profiler && $(SUBDIR_MMAKE) mdprof_dump.depend
 
+deep_profiler/$(deps_subdir)mdprof_feedback.dep: \
+		library/$(deps_subdir)$(STD_LIB_NAME).dep
+	+cd deep_profiler && $(SUBDIR_MMAKE) mdprof_feedback.depend
+
 # depend_library MUST be done before depend_compiler and
depend_profiler
 
 .PHONY: depend
Index: deep_profiler/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/Mmakefile,v
retrieving revision 1.18
diff -u -r1.18 Mmakefile
--- deep_profiler/Mmakefile	9 Oct 2006 07:13:37 -0000	1.18
+++ deep_profiler/Mmakefile	18 Oct 2006 07:39:45 -0000
@@ -20,7 +20,7 @@
 # can be found by `mmc --make'.
 include Mercury.options
 
-ALL_DEEP_MODULES=mdprof_cgi mdprof_test mdprof_dump
+ALL_DEEP_MODULES=mdprof_cgi mdprof_test mdprof_dump mdprof_feedback
 
 ifeq ("$(ENABLE_DEEP_PROFILER)","yes")
 	MAIN_TARGET=all
@@ -71,6 +71,8 @@
 mdprof_test:	$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
 mdprof_dump:	$(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
 mdprof_dump:	$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
+mdprof_feedback:	$(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
+mdprof_feedback:	$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
 # XXX Should also depend on $(BOEHM_GC_DIR)/libgc(_prof).$A, but only
 # if in .gc(.prof) grade.
 endif
@@ -78,6 +80,7 @@
 $(cs_subdir)mdprof_cgi_init.c:		$(UTIL_DIR)/mkinit
 $(cs_subdir)mdprof_test_init.c:		$(UTIL_DIR)/mkinit
 $(cs_subdir)mdprof_dump_init.c:		$(UTIL_DIR)/mkinit
+$(cs_subdir)mdprof_feedback_init.c: $(UTIL_DIR)/mkinit
 

#-----------------------------------------------------------------------------#
 
@@ -97,7 +100,7 @@
 .PHONY: tags
 tags:	.deep.tags
 
-DEEP_MS = $(mdprof_cgi.ms) $(mdprof_test.ms) $(mdprof_dump.ms)
+DEEP_MS = $(mdprof_cgi.ms) $(mdprof_test.ms) $(mdprof_dump.ms)
$(mdprof_feedback.ms)
 
 .deep.tags: $(MTAGS) $(DEEP_MS) $(LIBRARY_DIR)/*.m
 	$(MTAGS) $(DEEP_MS) $(LIBRARY_DIR)/*.m
@@ -113,7 +116,8 @@
 
 .PHONY: dates
 dates:
-	touch $(mdprof_cgi.dates) $(mdprof_test.dates) $(mdprof_dump.dates)
+	touch $(mdprof_cgi.dates) $(mdprof_test.dates) $(mdprof_dump.dates) \
+		$(mdprof_feedback.dates)
 

#-----------------------------------------------------------------------------#
 
@@ -121,9 +125,11 @@
 os: $(mdprof_cgi.os) $(os_subdir)mdprof_cgi_init.o
 os: $(mdprof_test.os) $(os_subdir)mdprof_test_init.o
 os: $(mdprof_dump.os) $(os_subdir)mdprof_dump_init.o
+os: $(mdprof_feedback.os) $(os_subdir)mdprof_feedback_init.o
 cs: $(mdprof_cgi.cs) $(cs_subdir)mdprof_cgi_init.c
 cs: $(mdprof_test.cs) $(cs_subdir)mdprof_test_init.c
 cs: $(mdprof_dump.cs) $(cs_subdir)mdprof_dump_init.c
+cs: $(mdprof_feedback.cs) $(cs_subdir)mdprof_feedback_init.c
 

#-----------------------------------------------------------------------------#
 
@@ -144,7 +150,7 @@
 # by different paths.
 
 .PHONY: install_cgi_progs
-install_cgi_progs: mdprof_cgi
+install_cgi_progs: mdprof_cgi mdprof_dump mdprof_test mdprof_feedback
 	# $(INSTALL_CGI_DIR) is likely to be writeable only by root or
 	# the www system administrator, which is why we don't consider a
 	# failure of this action to be an error. If the command fails,
@@ -174,6 +180,8 @@
 		$(INSTALL_MERC_BIN_DIR)/mdprof_test
 	cp `vpath_find mdprof_dump$(EXT_FOR_EXE)` \
 		$(INSTALL_MERC_BIN_DIR)/mdprof_dump
+	cp `vpath_find mdprof_feedback$(EXT_FOR_EXE)` \
+		$(INSTALL_MERC_BIN_DIR)/mdprof_feedback
 
 uninstall:
 	# We try to uninstall mdprof_cgi, but failure to do so is not an
Index: deep_profiler/mdprof_feedback.m
===================================================================
RCS file: deep_profiler/mdprof_feedback.m
diff -N deep_profiler/mdprof_feedback.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ deep_profiler/mdprof_feedback.m	19 Oct 2006 01:46:27 -0000
@@ -0,0 +1,322 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2001, 2004-2006 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: mdprof_feedback.m.
+% Author: tannier.
+%
+% This module contains the code for writing to a file the CSSs whose
CSD's 
+% average/median callseqs (own and desc) exceed the given threshold. 
+% 
+% The generated file will then be used by the compiler for implicit
parallelism.
+%
+%-----------------------------------------------------------------------------%
+
+:- module mdprof_feedback.
+:- interface.
+
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module conf.
+:- import_module measurements.
+:- import_module profile.
+:- import_module startup.
+
+:- import_module array.
+:- import_module bool.
+:- import_module char.
+:- import_module getopt.
+:- import_module int.
+:- import_module library.
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+:- import_module require.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+main(!IO) :-
+    io.progname_base("Profiling feedback program", ProgName, !IO),
+    io.command_line_arguments(Args0, !IO),
+    getopt.process_options(option_ops_multi(short, long, defaults),
+        Args0, Args, MaybeOptions),
+    (
+        MaybeOptions = ok(Options),
+        lookup_bool_option(Options, help, Help),
+        lookup_bool_option(Options, version, Version),
+        ( Version = yes ->
+            io.format("%s Version 1.0\n", [s(ProgName)], !IO)
+        ; Help = yes ->
+            write_help_message(ProgName, !IO)
+        ; 
+            ( Args = [Input, Output] ->
+                lookup_string_option(Options, distribution,
Distribution),
+                ( construct_distribution(Distribution,
DistributionType) ->
+                    lookup_int_option(Options, threshold, Threshold),
+                    lookup_bool_option(Options, verbose, Verbose),
+                    read_deep_file(Input, Verbose, MaybeProfile, !IO),
+                    (
+                        MaybeProfile = ok(Deep),
+                        compute_css_list_above_threshold(0, Deep,
Threshold, 
+                            DistributionType, [],
CSSListAboveThreshold),
+                        generate_file(CSSListAboveThreshold, Deep, 
+                            DistributionType, Threshold, Output, !IO)
+                    ;
+                        MaybeProfile = error(Error),
+                        io.stderr_stream(Stderr, !IO),
+                        io.set_exit_status(1, !IO),
+                        io.format(Stderr, "%s: error reading deep file:
%s\n",
+                            [s(ProgName), s(Error)], !IO)
+                    )   
+                ;
+                    io.set_exit_status(1, !IO),
+                    write_help_message(ProgName, !IO)
+                )
+            ;
+                io.set_exit_status(1, !IO),
+                write_help_message(ProgName, !IO)
+            )
+        )
+    ;
+        MaybeOptions = error(Msg),
+        io.stderr_stream(Stderr, !IO),
+        io.set_exit_status(1, !IO),
+        io.format(Stderr, "%s: error parsing options: %s\n",
+            [s(ProgName), s(Msg)], !IO)
+    ).
+
+:- pred write_help_message(string::in, io::di, io::uo) is det.
+
+write_help_message(ProgName) -->
+    io.format("Usage: %s [<options>] <input> <output>\n",
[s(ProgName)]),
+    io.format("<input> must name a deep profiling data file.\n", []),
+    io.format("<output> is the file generated by this program.\n", []),
+    io.format("You may specify one of the following options:\n", []),
+    io.format("--help      Generate this help message.\n", []),
+    io.format("--version   Report the program's version number.\n",
[]),
+    io.format("--verbose   Generate progress messages.\n", []),
+    io.format("--threshold <value>\n", []),
+    io.format("            Set the threshold to <value>.\n",[]),
+    io.format("--distrib average|median\n",[]),
+    io.format("            average : Write to <output> the call sites
\n",[]),
+    io.format("            static whose call sites dynamic's average
\n",[]),
+    io.format("            callseqs exceed the given threshold (default
\n",[]), 
+    io.format("            option).\n",[]),
+    io.format("            median : Write to <output> the call sites
\n",[]),
+    io.format("            static whose call sites dynamic's median
\n",[]),
+    io.format("            callseqs exceed the given threshold.\n",[]).
+
+%-----------------------------------------------------------------------------%
+
+    % Reads a deep data file.
+    % 
+:- pred read_deep_file(string::in, bool::in, maybe_error(deep)::out,
+    io::di, io::uo) is det.
+
+read_deep_file(Input, Verbose, MaybeProfile, !IO) :-
+    server_name(Machine, !IO),
+    (
+        Verbose = yes,
+        io.stdout_stream(Stdout, !IO),
+        MaybeOutput = yes(Stdout)
+    ;
+        Verbose = no,
+        MaybeOutput = no
+    ),
+    read_and_startup(Machine, [Input], no, MaybeOutput, [], [],
MaybeProfile, 
+        !IO).
+
+    % Determines those CSSs whose CSDs have an average/median callseq
count 
+    % above the given threshold.
+    % 
+:- pred compute_css_list_above_threshold(int::in, deep::in, int::in, 
+    distribution_type::in, list(call_site_static)::in, 
+    list(call_site_static)::out) is det.
+
+compute_css_list_above_threshold(Index, Deep, Threshold, Distribution,
+        !CSSAcc) :-
+    array.size(Deep ^ call_site_statics, Size),
+    ( Index = Size ->
+        true
+    ;
+        CallSiteCall = array.lookup(Deep ^ call_site_calls, Index),
+        CSDListList = map.values(CallSiteCall),
+        CSDList = list.condense(CSDListList),
+        list.length(CSDList, NumCSD),
+        ( NumCSD = 0 ->
+            % The CSS doesn't have any CSDs.
+            Callseqs = 0
+        ;
+            ( 
+                Distribution = average,
+                list.foldr(sum_callseqs_csd_ptr(Deep), CSDList,
+                    0, SumCallseqs),
+                % NOTE: we have checked that NumCSD is not zero above.
+                Callseqs = SumCallseqs // NumCSD
+            ;
+                Distribution = median,
+                list.sort(compare_csd_ptr(Deep), CSDList,
CSDListSorted),
+                IndexMedian = NumCSD // 2,
+                list.index0_det(CSDListSorted, IndexMedian, MedianPtr),
+                sum_callseqs_csd_ptr(Deep, MedianPtr, 0, Callseqs)
+            )
+        ),
+        ( Callseqs >= Threshold ->
+            CSS = array.lookup(Deep ^ call_site_statics, Index),
+            !:CSSAcc = [ CSS | !.CSSAcc ],
+            compute_css_list_above_threshold(Index + 1, Deep,
Threshold, 
+                Distribution, !CSSAcc)
+        ;
+            compute_css_list_above_threshold(Index + 1, Deep,
Threshold, 
+                Distribution, !CSSAcc)
+        ) 
+    ).
+
+    % Adds the callseqs (own and desc) of CSDPtr to the accumulator.
+    % 
+:- pred sum_callseqs_csd_ptr(deep::in, call_site_dynamic_ptr::in,
+    int::in, int::out) is det.
+
+sum_callseqs_csd_ptr(Deep, CSDPtr, !Sum) :-
+    lookup_call_site_dynamics(Deep ^ call_site_dynamics, CSDPtr, CSD),
+    lookup_csd_desc(Deep ^ csd_desc, CSDPtr, IPO),
+    !:Sum = !.Sum + callseqs(CSD ^ csd_own_prof) +
inherit_callseqs(IPO).
+
+    % Compares 2 CSDPtr on the basis of their callseqs (own and 
+    % desc).
+    % 
+:- pred compare_csd_ptr(deep::in, call_site_dynamic_ptr::in, 
+    call_site_dynamic_ptr::in, comparison_result::out) is det.
+
+compare_csd_ptr(Deep, CSDPtrA, CSDPtrB, Result) :-
+    sum_callseqs_csd_ptr(Deep, CSDPtrA, 0, SumA),
+    sum_callseqs_csd_ptr(Deep, CSDPtrB, 0, SumB),
+    compare(Result, SumA, SumB).
+
+    % Generates a profiling feedback file that contains the CSSs whose 
+    % CSD's average/median callseqs (own and desc) exceed the given
threshold. 
+    % 
+:- pred generate_file(list(call_site_static)::in, deep::in, 
+    distribution_type::in, int::in, string::in, io::di, io::uo) is det.
+    
+generate_file(CSSList, Deep, Distribution, Threshold, Output, !IO) :-
+    io.open_output(Output, Result, !IO),
+    (
+        Result = io.error(Err),
+        io.stderr_stream(Stderr, !IO),
+        io.write_string(Stderr, io.error_message(Err) ++ "\n", !IO)
+    ;
+        Result = ok(OutStrm),
+        io.write_string(OutStrm, "Profiling feedback file\n", !IO),
+        io.write_string(OutStrm, "Version = 1.0\n", !IO),
+        (
+            Distribution = average,
+            io.write_string(OutStrm, "Distribution = average\n", !IO)
+        ;
+            Distribution = median,
+            io.write_string(OutStrm, "Distribution = median\n", !IO)
+        ),
+        io.format(OutStrm, "Threshold = %i\n", [i(Threshold)], !IO),
+        write_css_list(CSSList, Deep, OutStrm, !IO),
+        io.close_output(OutStrm, !IO)
+    ).
+
+    % Writes to the output the list of CSSs     
+    % 
+:- pred write_css_list(list(call_site_static)::in, deep::in,
output_stream::in, 
+    io::di, io::uo) is det.
+   
+write_css_list([], _, _, !IO).
+write_css_list([ CSS | CSSList0 ], Deep, OutStrm, !IO) :-
+        
+    % Prints the caller
+    lookup_proc_statics(Deep ^ proc_statics, CSS ^ css_container,
Caller),
+    io.write_string(OutStrm, Caller ^ ps_raw_id ++ " ", !IO),
+        
+    % Prints the slot number of the call_site_static
+    io.write_int(OutStrm, CSS ^ css_slot_num, !IO),
+    io.write_string(OutStrm, " ", !IO),
+    
+    % Prints the callee
+    (
+        CSS ^ css_kind = normal_call_and_callee(Ps_ptr, _),
+        lookup_proc_statics(Deep ^ proc_statics, Ps_ptr, Callee),
+        io.format(OutStrm, "normal_call %s\n", [s(Callee ^
ps_raw_id)], !IO)
+    ;
+        CSS ^ css_kind = special_call_and_no_callee,
+        io.write_string(OutStrm, "special_call\n", !IO)
+    ;
+        CSS ^ css_kind = higher_order_call_and_no_callee,
+        io.write_string(OutStrm, "higher_order_call\n", !IO)
+    ;
+        CSS ^ css_kind = method_call_and_no_callee,
+        io.write_string(OutStrm, "method_call\n", !IO)
+    ;
+        CSS ^ css_kind = callback_and_no_callee,
+        io.write_string(OutStrm, "callback\n", !IO)
+    ),
+    write_css_list(CSSList0, Deep, OutStrm, !IO).
+
+%-----------------------------------------------------------------------------%
+
+:- type option
+    --->    threshold
+    ;       help
+    ;       verbose
+    ;       version
+    ;       distribution.
+
+:- type distribution_type
+    --->    average
+    ;       median.
+
+:- type option_table == option_table(option).
+
+:- pred short(char::in, option::out) is semidet.
+
+short('V',  verbose).
+short('t',  threshold).
+short('h',  help).
+short('v',  version).
+short('d',  distribution).
+
+
+:- pred long(string::in, option::out) is semidet.
+
+long("threshold",           threshold).
+long("help",                help).
+long("verbose",             verbose).
+long("version",             version).
+long("distrib",             distribution).
+long("distribution",        distribution).
+
+:- pred defaults(option::out, option_data::out) is multi.
+
+defaults(threshold,         int(100000)).
+defaults(help,              bool(no)).
+defaults(verbose,           bool(no)).
+defaults(version,           bool(no)).
+defaults(distribution,      string("average")).
+
+:- pred construct_distribution(string::in, distribution_type::out) is
semidet.
+
+construct_distribution("average",    average).
+construct_distribution("median",     median).
+
+%-----------------------------------------------------------------------------%
+:- end_module mdprof_feedback.
+%-----------------------------------------------------------------------------%


On Thu, 2006-10-19 at 11:48 +1000, Jerome Tannier wrote:
> For review.
> 
> The file has been renamed to mdprof_feedback.m. 
> 
> Jerome.
> 
> On Wed, 2006-10-18 at 18:09 +1000, Julien Fischer wrote:
> > On Wed, 18 Oct 2006, Ralph Becket wrote:
> > 
> > > [Forwarded by Ralph because Jerome is having e-mail trouble on this list.]
> > >
> > 
> > I think this should be fixed now.
> > 
> > > ----- Forwarded message from Jerome Tannier <jerome.tannier at student.fundp.ac.be> -----
> > >
> > > Branches: main
> > >
> > > deep_profiler/mdprof_CSS_above_threshold.m:
> > >        New module which writes to a file the list of call site statics
> > >        whose matching call site dynamics have an average/median
> > >        callseqs above a given threshold.
> > >
> > 
> > Jerome and I have discussed this diff in person and also modified various
> > Mmakefiles and so forth.  There should be a new diff posted tommorrow
> > some time.
> > 
> > Julien.
> > --------------------------------------------------------------------------
> > mercury-reviews mailing list
> > Post messages to:       mercury-reviews at csse.unimelb.edu.au
> > Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
> > Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
> > --------------------------------------------------------------------------

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list