[m-rev.] for post-commit review: break up mdprog_feedback
Zoltan Somogyi
zs at csse.unimelb.edu.au
Mon Sep 26 15:36:50 AEST 2011
The concept has been discussed and approved, and the details are trivial.
The only thing I am seeking feedback on are the texts of the two help
messages.
Zoltan.
Replace mdprof_feedback, which currently does two jobs, with
mdprof_create_feedback and mdprof_report_feedback, which do one job each.
deep_profiler/mdprof_feedback.m:
Remove this module.
deep_profiler/mdprof_create_feedback.m:
deep_profiler/mdprof_report_feedback.m:
Add these two modules. mdprof_create_feedback.m contains most of the
code originally in mdprof_feedback.m, while mdprof_report_feedback.m
contains only the code needed for printing out reports.m
deep_profiler/autopar_reports.m:
Move here some code that would otherwise hav to duplicated in
mdprof_create_feedback.m and mdprof_report_feedback.m.
Keep private the previously exported predicates that are not needed
outside this module after the above move.
deep_profiler/Mmakefile:
Replace references to the deleted module with references to the new
modules.
doc/user_guide.texi:
Update the only reference to mdprof_feedback in this directory.
cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing deep_profiler
Index: deep_profiler/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/Mmakefile,v
retrieving revision 1.40
diff -u -b -r1.40 Mmakefile
--- deep_profiler/Mmakefile 27 Jan 2011 02:53:46 -0000 1.40
+++ deep_profiler/Mmakefile 26 Sep 2011 04:50:06 -0000
@@ -38,7 +38,8 @@
mdprof_cgi \
mdprof_test \
mdprof_dump \
- mdprof_feedback \
+ mdprof_create_feedback \
+ mdprof_report_feedback \
mdprof_procrep
# Always compile the deep profiler, even if it is not enabled.
@@ -135,8 +136,10 @@
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
+mdprof_create_feedback: $(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
+mdprof_create_feedback: $(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
+mdprof_report_feedback: $(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
+mdprof_report_feedback: $(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
mdprof_procrep: $(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
mdprof_procrep: $(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
# XXX Should also depend on $(BOEHM_GC_DIR)/libgc(_prof).$A, but only
@@ -146,7 +149,8 @@
$(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
+$(cs_subdir)mdprof_create_feedback_init.c: $(UTIL_DIR)/mkinit
+$(cs_subdir)mdprof_report_feedback_init.c: $(UTIL_DIR)/mkinit
$(cs_subdir)mdprof_procrep_init.c: $(UTIL_DIR)/mkinit
#-----------------------------------------------------------------------------#
@@ -171,7 +175,8 @@
$(mdprof_cgi.ms) \
$(mdprof_test.ms) \
$(mdprof_dump.ms) \
- $(mdprof_feedback.ms) \
+ $(mdprof_create_feedback.ms) \
+ $(mdprof_report_feedback.ms) \
$(mdprof_procrep.ms)
.deep_tags: $(MTAGS) $(DEEP_MS) \
@@ -191,8 +196,12 @@
.PHONY: dates
dates:
- touch $(mdprof_cgi.dates) $(mdprof_test.dates) $(mdprof_dump.dates) \
- $(mdprof_feedback.dates) $(mdprof_procrep.dates)
+ touch $(mdprof_cgi.dates) \
+ $(mdprof_test.dates) \
+ $(mdprof_dump.dates) \
+ $(mdprof_create_feedback.dates) \
+ $(mdprof_report_feedback.dates) \
+ $(mdprof_procrep.dates)
#-----------------------------------------------------------------------------#
@@ -200,12 +209,14 @@
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
+os: $(mdprof_create_feedback.os) $(os_subdir)mdprof_create_feedback_init.o
+os: $(mdprof_report_feedback.os) $(os_subdir)mdprof_report_feedback_init.o
os: $(mdprof_procrep.os) $(os_subdir)mdprof_procrep_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
+cs: $(mdprof_create_feedback.cs) $(cs_subdir)mdprof_create_feedback_init.c
+cs: $(mdprof_report_feedback.cs) $(cs_subdir)mdprof_report_feedback_init.c
cs: $(mdprof_procrep.cs) $(cs_subdir)mdprof_procrep_init.c
#-----------------------------------------------------------------------------#
@@ -228,7 +239,8 @@
# by different paths.
.PHONY: install_cgi_progs
-install_cgi_progs: mdprof_cgi mdprof_dump mdprof_test mdprof_feedback
+install_cgi_progs: mdprof_cgi mdprof_dump mdprof_test \
+ mdprof_create_feedback mdprof_report_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,
@@ -262,8 +274,10 @@
$(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
+ cp `vpath_find mdprof_create_feedback$(EXT_FOR_EXE)` \
+ $(INSTALL_MERC_BIN_DIR)/mdprof_create_feedback
+ cp `vpath_find mdprof_report_feedback$(EXT_FOR_EXE)` \
+ $(INSTALL_MERC_BIN_DIR)/mdprof_report_feedback
uninstall:
# We try to uninstall mdprof_cgi, but failure to do so is not an
Index: deep_profiler/autopar_reports.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_reports.m,v
retrieving revision 1.2
diff -u -b -r1.2 autopar_reports.m
--- deep_profiler/autopar_reports.m 16 Apr 2011 03:13:04 -0000 1.2
+++ deep_profiler/autopar_reports.m 26 Sep 2011 05:25:33 -0000
@@ -21,17 +21,11 @@
:- import_module mdbcomp.feedback.automatic_parallelism.
:- import_module mdbcomp.program_representation.
-:- import_module assoc_list.
:- import_module cord.
-:- import_module pair.
-
-:- pred create_feedback_autopar_report(candidate_par_conjunctions_params::in,
- assoc_list(string_proc_label, candidate_par_conjunctions_proc)::in,
- string::out) is det.
+:- import_module io.
-:- pred create_candidate_parallel_conj_proc_report(
- pair(string_proc_label, candidate_par_conjunctions_proc)::in,
- cord(string)::out) is det.
+:- pred print_feedback_report(string::in, feedback_info::in, io::di, io::uo)
+ is det.
:- pred create_candidate_parallel_conj_report(var_table::in,
candidate_par_conjunction(pard_goal)::in, cord(string)::out) is det.
@@ -51,6 +45,7 @@
:- import_module int.
:- import_module list.
:- import_module maybe.
+:- import_module pair.
:- import_module require.
:- import_module set.
:- import_module std_util.
@@ -58,6 +53,32 @@
%----------------------------------------------------------------------------%
+print_feedback_report(ProgName, Feedback, !IO) :-
+ get_all_feedback_data(Feedback, AllFeedback),
+ list.map(create_feedback_report, AllFeedback, Reports),
+ ReportStr = string.append_list(Reports),
+ io.format("Feedback report for %s:\n\n%s", [s(ProgName), s(ReportStr)],
+ !IO).
+
+:- pred create_feedback_report(feedback_data::in, string::out) is det.
+
+create_feedback_report(FeedbackData, Report) :-
+ (
+ FeedbackData = feedback_data_calls_above_threshold_sorted(_, _, _),
+ Report =
+ " feedback_data_calls_above_threshold_sorted is not supported\n"
+ ;
+ FeedbackData = feedback_data_candidate_parallel_conjunctions(
+ Parameters, Conjs),
+ create_feedback_autopar_report(Parameters, Conjs, Report)
+ ).
+
+%----------------------------------------------------------------------------%
+
+:- pred create_feedback_autopar_report(candidate_par_conjunctions_params::in,
+ assoc_list(string_proc_label, candidate_par_conjunctions_proc)::in,
+ string::out) is det.
+
create_feedback_autopar_report(Parameters, ProcConjs, Report) :-
NumProcConjs = length(ProcConjs),
foldl(count_conjunctions_in_procs, ProcConjs, 0, NumConjs),
@@ -124,18 +145,26 @@
:- pred count_conjunctions_in_procs(
pair(T, candidate_par_conjunctions_proc)::in, int::in, int::out) is det.
-count_conjunctions_in_procs(_ -
- candidate_par_conjunctions_proc(_VarTable, _Pushes, Conjs), !NumConjs) :-
+count_conjunctions_in_procs(_ - Cands, !NumConjs) :-
+ Cands = candidate_par_conjunctions_proc(_VarTable, _Pushes, Conjs),
!:NumConjs = !.NumConjs + length(Conjs).
:- pred best_par_algorithm_string(best_par_algorithm::in, string::out) is det.
-best_par_algorithm_string(bpa_greedy, "greedy").
-best_par_algorithm_string(bpa_complete_branches(N),
- format("complete-branches(%d)", [i(N)])).
-best_par_algorithm_string(bpa_complete_size(N),
- format("complete-size(%d)", [i(N)])).
-best_par_algorithm_string(bpa_complete, "complete").
+best_par_algorithm_string(Alg, Str) :-
+ (
+ Alg = bpa_greedy,
+ Str = "greedy"
+ ;
+ Alg = bpa_complete_branches(N),
+ Str = string.format("complete-branches(%d)", [i(N)])
+ ;
+ Alg = bpa_complete_size(N),
+ Str = string.format("complete-size(%d)", [i(N)])
+ ;
+ Alg = bpa_complete,
+ Str = "complete"
+ ).
create_candidate_parallel_conj_proc_report(Proc - CandidateParConjunctionProc,
Report) :-
@@ -145,9 +174,7 @@
list.map(create_push_goal_report, PushGoals, PushGoalReports),
list.map(create_candidate_parallel_conj_report(VarTable),
CandidateParConjunctions, CandidateParConjunctionReports),
- Header = string.format(
- " %s\n",
- [s(ProcString)]),
+ Header = string.format(" %s\n", [s(ProcString)]),
Report = cord.singleton(Header) ++
cord_list_to_cord(PushGoalReports) ++
cord.singleton("\n") ++
@@ -166,6 +193,10 @@
TailPushGoalStrs = list.map(FormatPushedGoals, PushedGoalPathStrs),
Report = cord.from_list([HeadPushGoalStr | TailPushGoalStrs]).
+:- pred create_candidate_parallel_conj_proc_report(
+ pair(string_proc_label, candidate_par_conjunctions_proc)::in,
+ cord(string)::out) is det.
+
create_candidate_parallel_conj_report(VarTable, CandidateParConjunction,
Report) :-
CandidateParConjunction = candidate_par_conjunction(GoalPathString,
@@ -188,9 +219,7 @@
TimeSaving = parallel_exec_metrics_get_time_saving(ParExecMetrics),
TotalDeadTime = FirstConjDeadTime + FutureDeadTime,
- string.format(
- " Path: %s\n",
- [s(GoalPathString)], Header1Str),
+ string.format(" Path: %s\n", [s(GoalPathString)], Header1Str),
Header1 = cord.singleton(Header1Str),
(
Index: deep_profiler/mdprof_create_feedback.m
===================================================================
RCS file: deep_profiler/mdprof_create_feedback.m
diff -N deep_profiler/mdprof_create_feedback.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ deep_profiler/mdprof_create_feedback.m 26 Sep 2011 05:21:39 -0000
@@ -0,0 +1,722 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2006-2011 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_create_feedback.m.
+% Author: tannier, pbone.
+%
+% This module contains code for generating feedback files that tell the
+% compiler things such as which conjunctions can be profitably parallelised.
+%
+%-----------------------------------------------------------------------------%
+
+:- module mdprof_create_feedback.
+:- interface.
+
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module conf.
+:- import_module mdbcomp.
+:- import_module mdbcomp.feedback.
+:- import_module mdbcomp.feedback.automatic_parallelism.
+:- import_module mdprof_fb.
+:- import_module mdprof_fb.automatic_parallelism.
+:- import_module mdprof_fb.automatic_parallelism.autopar_search_callgraph.
+:- import_module mdprof_fb.automatic_parallelism.autopar_reports.
+:- import_module message.
+:- import_module profile.
+:- import_module startup.
+
+:- import_module bool.
+:- import_module char.
+:- import_module cord.
+:- import_module float.
+:- import_module getopt.
+:- import_module int.
+:- import_module library.
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+:- import_module parsing_utils.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+%
+% This section contains the main predicate as well as code to read the deep
+% profiling data and display usage and version messages to the user.
+%
+
+main(!IO) :-
+ io.progname_base("mdprof_create_feedback", ProgName, !IO),
+ io.command_line_arguments(Args0, !IO),
+ getopt.process_options(option_ops_multi(short, long, defaults),
+ Args0, Args, MaybeOptions),
+ io.stderr_stream(Stderr, !IO),
+ (
+ MaybeOptions = ok(Options0),
+ post_process_options(ProgName, Options0, Options, !IO),
+ lookup_bool_option(Options, help, Help),
+ lookup_bool_option(Options, version, Version),
+ ( Version = yes ->
+ write_version_message(ProgName, !IO)
+ ; Help = yes ->
+ write_help_message(ProgName, !IO)
+ ;
+ (
+ Args = [InputFileName, OutputFileName],
+ get_feedback_requests(ProgName, Options, FoundError,
+ RequestedFeedbackInfo, !IO),
+ (
+ FoundError = have_not_found_error,
+ generate_requested_feedback(ProgName, Options,
+ InputFileName, OutputFileName, RequestedFeedbackInfo,
+ !IO)
+ ;
+ FoundError = found_error
+ % The error message have already been printed.
+ )
+ ;
+ ( Args = []
+ ; Args = [_]
+ ; Args = [_, _, _ | _]
+ ),
+ write_help_message(ProgName, !IO),
+ io.set_exit_status(1, !IO)
+ )
+ )
+ ;
+ MaybeOptions = error(Msg),
+ io.format(Stderr, "%s: error parsing options: %s\n",
+ [s(ProgName), s(Msg)], !IO),
+ write_help_message(ProgName, !IO),
+ io.set_exit_status(1, !IO)
+ ).
+
+:- pred generate_requested_feedback(string::in, option_table(option)::in,
+ string::in, string::in, requested_feedback_info::in, io::di, io::uo)
+ is det.
+
+generate_requested_feedback(ProgName, Options, InputFileName, OutputFileName,
+ RequestedFeedbackInfo, !IO) :-
+ io.stderr_stream(Stderr, !IO),
+ RequestedFeedbackInfo = requested_feedback_info(MaybeParallelize),
+ (
+ MaybeParallelize = yes(_),
+ lookup_bool_option(Options, debug_read_profile, DebugReadProfile),
+ lookup_bool_option(Options, report, Report),
+ read_deep_file(InputFileName, DebugReadProfile, MaybeDeep, !IO),
+ (
+ MaybeDeep = ok(Deep),
+ ProfileProgName = Deep ^ profile_stats ^ prs_program_name,
+ feedback.read_or_create(OutputFileName, ProfileProgName,
+ FeedbackReadResult, !IO),
+ (
+ FeedbackReadResult = ok(Feedback0),
+ process_deep_to_feedback(RequestedFeedbackInfo,
+ Deep, Messages, Feedback0, Feedback),
+ (
+ Report = yes,
+ print_feedback_report(ProfileProgName, Feedback, !IO)
+ ;
+ Report = no
+ ),
+ write_feedback_file(OutputFileName, ProfileProgName,
+ Feedback, WriteResult, !IO),
+ (
+ WriteResult = ok
+ ;
+ ( WriteResult = open_error(Error)
+ ; WriteResult = write_error(Error)
+ ),
+ io.error_message(Error, ErrorMessage),
+ io.format(Stderr, "%s: %s: %s\n",
+ [s(ProgName), s(OutputFileName), s(ErrorMessage)],
+ !IO),
+ io.set_exit_status(1, !IO)
+ ),
+ lookup_int_option(Options, verbosity, VerbosityLevel),
+ set_verbosity_level(VerbosityLevel, !IO),
+ write_out_messages(Stderr, Messages, !IO)
+ ;
+ FeedbackReadResult = error(FeedbackReadError),
+ feedback.read_error_message_string(OutputFileName,
+ FeedbackReadError, Message),
+ io.write_string(Stderr, Message, !IO),
+ io.set_exit_status(1, !IO)
+ )
+ ;
+ MaybeDeep = error(Error),
+ io.set_exit_status(1, !IO),
+ io.format(Stderr, "%s: error reading %s: %s\n",
+ [s(ProgName), s(InputFileName), s(Error)], !IO)
+ )
+ ;
+ MaybeParallelize = no,
+ io.format(Stderr, "%s: options do not request any form of feedback\n",
+ [s(ProgName)], !IO)
+ ).
+
+:- func help_message(string) = string.
+
+help_message(ProgName) = HelpMessage :-
+ FormatStr =
+"Usage: %s [<options>] <profdatafile> <feedbackfile>
+ This command generates feedback information from profiling data.
+
+ The first argument must name a deep profiling data file such as Deep.data.
+ The second argument should be the name of the file into which this command
+ should put the feedback information it generates.
+
+ You may specify the following general options:
+
+ -h --help Generate this help message.
+ -V --version Report the program's version number.
+ -v --verbosity <0-4>
+ Generate messages. The higher the argument, the more
+ verbose the program becomes. 2 is recommended and the
+ default.
+ --debug-read-profile
+ Generate debugging messages when reading the deep profile
+ and creating the deep structure.
+ --no-report Suppress the report about the feedback information in the
+ file that is usually displayed after any processing has
+ been done.
+
+ The following options select sets of feedback information useful
+ for particular compiler optimizations:
+
+ --implicit-parallelism
+ Generate information that the compiler can use for automatic
+ parallelization.
+ --desired-parallelism <value>
+ The amount of desired parallelism for implicit parallelism,
+ which must be a floating point number above 1.0.
+ Note: This option is currently ignored.
+ --implicit-parallelism-intermodule-var-use
+ Assume that the compiler will be able to push signals and waits
+ for futures across module boundaries.
+ --ipar-sparking-cost <value>
+ The cost of creating a spark, measured in the deep profiler's
+ call sequence counts.
+ --ipar-sparking-delay <value>
+ The time taken from the time a spark is created until the spark
+ is executed by another processor, assuming that there is a free
+ processor.
+ --ipar-barrier-cost <value>
+ The cost of executing the barrier code at the end of each
+ parallel conjunct.
+ --ipar-future-signal-cost <value>
+ The cost of the signal() call for the producer of a shared
+ variable, measured in the profiler's call sequence counts.
+ --ipar-future-wait-cost <value>
+ The cost of the wait() call for the consumer of a shared
+ variable, measured in the profiler's call sequence counts.
+ --ipar-context-wakeup-delay <value>
+ The time taken for a context to resume execution after being
+ placed on the run queue. This is used to estimate the impact
+ of blocking of a context's execution, it is measured in the
+ profiler's call sequence counts.
+ --ipar-clique-cost-threshold <value>
+ The cost threshold for cliques to be considered for implicit
+ parallelism, measured on the profiler's call sequence counts.
+ --ipar-call-site-cost-threshold <value>
+ The cost of a call site to be considered for parallelism
+ against another call site.
+ --no-ipar-dep-conjs
+ Disable parallelisation of dependent conjunctions.
+ --ipar-speedup-alg <alg>
+ Choose the algorithm that is used to estimate the speedup for
+ dependent calculations. The available algorithms are:
+ overlap: Compute the overlap between dependent
+ conjunctions.
+ num_vars: Use the number of shared variables as a proxy for
+ the amount of overlap available.
+ naive: Ignore dependencies.
+ The default is overlap.
+ --ipar-speedup-threshold <value>
+ The threshold that a speedup ratio must meet before the
+ feedback tool will accept a parallelization. It must be
+ a floating point number, which must be at least 1.0.
+ If it is e.g. 1.02, then the feedback tool will ignore
+ parallelizations that promise less than a 2%% local speedup.
+ --ipar-best-par-alg <alg>
+ Select which algorithm to use to find the best way to
+ parallelise a conjunction. The available algorithms are:
+ greedy: A greedy algorithm with a linear time complexity.
+ complete: A complete algorithm with a branch and bound
+ search. This can be slow for problems larger than 50
+ conjuncts, since it has an exponential complexity.
+ complete-size(N): As above exept that it takes a single
+ parameter, N. If a conjunction has more than N
+ conjuncts, then the greedy algorithm will be used.
+ complete-branches(N): The same as the complete algorithm,
+ except that it allows at most N branches to be created
+ during the search. Once N branches have been created,
+ a greedy search is used on each open branch.
+ The default is complete-branches(1000).
+
+ The following options select specific types of feedback information
+ and parameterise them:
+
+ --candidate-parallel-conjunctions
+ Produce a list of candidate parallel conjunctions for implicit
+ parallelism. This option uses the implicit parallelism
+ settings above.
+
+",
+ HelpMessage = string.format(FormatStr, [s(ProgName)]).
+
+:- pred write_help_message(string::in, io::di, io::uo) is det.
+
+write_help_message(ProgName, !IO) :-
+ io.write_string(help_message(ProgName), !IO).
+
+:- pred write_version_message(string::in, io::di, io::uo) is det.
+
+write_version_message(ProgName, !IO) :-
+ library.version(Version),
+ io.format("%s: Mercury deep profiler\n%s\n",
+ [s(ProgName), s(Version)], !IO).
+
+ % Read a deep profiling data file.
+ %
+:- pred read_deep_file(string::in, bool::in, maybe_error(deep)::out,
+ io::di, io::uo) is det.
+
+read_deep_file(Input, Debug, MaybeDeep, !IO) :-
+ server_name_port(Machine, !IO),
+ script_name(ScriptName, !IO),
+ (
+ Debug = yes,
+ io.stdout_stream(Stdout, !IO),
+ MaybeOutput = yes(Stdout)
+ ;
+ Debug = no,
+ MaybeOutput = no
+ ),
+ read_and_startup_default_deep_options(Machine, ScriptName, Input, no,
+ MaybeOutput, [], MaybeDeep, !IO).
+
+%----------------------------------------------------------------------------%
+%
+% This section describes and processes command line options. Individual
+% feedback information can be requested by the user, as well as options named
+% after optimizations that may imply one or more feedback inforemation types,
+% which that optimization uses.
+%
+
+ % Command line options.
+ %
+:- type option
+ ---> help
+ ; version
+ ; verbosity
+ ; debug_read_profile
+ ; report
+
+ % A list of candidate parallel conjunctions is produced for the new
+ % implicit parallelism implementation.
+ ; candidate_parallel_conjunctions
+
+ % Provide suitable feedback information for implicit parallelism
+ ; implicit_parallelism
+ ; desired_parallelism
+ ; ipar_intermodule_var_use
+ ; ipar_sparking_cost
+ ; ipar_sparking_delay
+ ; ipar_barrier_cost
+ ; ipar_future_signal_cost
+ ; ipar_future_wait_cost
+ ; ipar_context_wakeup_delay
+ ; ipar_clique_cost_threshold
+ ; ipar_call_site_cost_threshold
+ ; ipar_speedup_threshold
+ ; ipar_dep_conjs
+ ; ipar_speedup_alg
+ ; ipar_best_par_alg.
+
+% TODO: Introduce an option to disable parallelisation of dependent
+% conjunctions, or switch to the simple calculations for independent
+% conjunctions.
+
+:- pred short(char::in, option::out) is semidet.
+
+short('h', help).
+short('v', verbosity).
+short('V', version).
+
+:- pred long(string::in, option::out) is semidet.
+
+long("help",
+ help).
+long("verbosity",
+ verbosity).
+long("version",
+ version).
+long("debug-read-profile",
+ debug_read_profile).
+long("report",
+ report).
+long("candidate-parallel-conjunctions",
+ candidate_parallel_conjunctions).
+long("implicit-parallelism",
+ implicit_parallelism).
+long("desired-parallelism",
+ desired_parallelism).
+long("implicit-parallelism-intermodule-var-use",
+ ipar_intermodule_var_use).
+long("ipar-intermodule-var-use",
+ ipar_intermodule_var_use).
+long("implicit-parallelism-sparking-cost",
+ ipar_sparking_cost).
+long("ipar-sparking-cost",
+ ipar_sparking_cost).
+long("implicit-parallelism-sparking-delay",
+ ipar_sparking_delay).
+long("ipar-sparking-delay",
+ ipar_sparking_delay).
+long("implicit-parallelism-future-signal-cost",
+ ipar_future_signal_cost).
+long("ipar-future-signal-cost",
+ ipar_future_signal_cost).
+long("implicit-parallelism-barrier-cost",
+ ipar_barrier_cost).
+long("ipar-barrier-cost",
+ ipar_barrier_cost).
+long("implicit-parallelism-future-wait-cost",
+ ipar_future_wait_cost).
+long("ipar-future-wait-cost",
+ ipar_future_wait_cost).
+long("implicit-parallelism-context-wakeup-delay",
+ ipar_context_wakeup_delay).
+long("ipar-context-wakeup-delay",
+ ipar_context_wakeup_delay).
+long("implicit-parallelism-clique-cost-threshold",
+ ipar_clique_cost_threshold).
+long("ipar-clique-cost-threshold",
+ ipar_clique_cost_threshold).
+long("implicit-parallelism-call-site-cost-threshold",
+ ipar_call_site_cost_threshold).
+long("ipar-call-site-cost-threshold",
+ ipar_call_site_cost_threshold).
+long("implicit-parallelism-dependant-conjunctions",
+ ipar_dep_conjs).
+long("ipar-dep-conjs",
+ ipar_dep_conjs).
+long("implicit-parallelism-dependant-conjunctions-algorithm",
+ ipar_speedup_alg).
+long("ipar-speedup-alg",
+ ipar_speedup_alg).
+long("implicit-parallelism-speedup-threshold",
+ ipar_speedup_threshold).
+long("ipar-speedup-threshold",
+ ipar_speedup_threshold).
+long("implicit-parallelism-best-parallelisation-algorithm",
+ ipar_best_par_alg).
+long("ipar-best-par-alg",
+ ipar_best_par_alg).
+
+:- pred defaults(option::out, option_data::out) is multi.
+
+defaults(help, bool(no)).
+defaults(verbosity, int(2)).
+defaults(version, bool(no)).
+defaults(debug_read_profile, bool(no)).
+defaults(report, bool(yes)).
+
+defaults(candidate_parallel_conjunctions, bool(no)).
+
+defaults(implicit_parallelism, bool(no)).
+defaults(desired_parallelism, string("8.0")).
+% XXX: These values have been chosen arbitrarily; we should set them
+% based on measurements.
+defaults(ipar_intermodule_var_use, bool(no)).
+defaults(ipar_sparking_cost, int(100)).
+defaults(ipar_sparking_delay, int(1000)).
+defaults(ipar_barrier_cost, int(100)).
+defaults(ipar_future_signal_cost, int(100)).
+defaults(ipar_future_wait_cost, int(200)).
+defaults(ipar_context_wakeup_delay, int(1000)).
+defaults(ipar_clique_cost_threshold, int(2000)).
+defaults(ipar_call_site_cost_threshold, int(2000)).
+defaults(ipar_dep_conjs, bool(yes)).
+defaults(ipar_speedup_threshold, string("1.01")).
+defaults(ipar_speedup_alg, string("overlap")).
+defaults(ipar_best_par_alg, string("complete-branches(1000)")).
+
+:- pred construct_measure(string::in, stat_measure::out) is semidet.
+
+construct_measure("mean", stat_mean).
+construct_measure("median", stat_median).
+
+:- pred post_process_options(string::in,
+ option_table(option)::in, option_table(option)::out,
+ io::di, io::uo) is det.
+
+post_process_options(ProgName, !Options, !IO) :-
+ lookup_int_option(!.Options, verbosity, VerbosityLevel),
+ io.stderr_stream(Stderr, !IO),
+ ( VerbosityLevel < 0 ->
+ io.format(Stderr,
+ "%s: warning: verbosity level should not be negative.\n",
+ [s(ProgName)], !IO),
+ set_option(verbosity, int(0), !Options)
+ ; VerbosityLevel > 4 ->
+ io.format(Stderr,
+ "%s: warning: verbosity level should not exceed 4.\n",
+ [s(ProgName)], !IO),
+ set_option(verbosity, int(4), !Options)
+ ;
+ true
+ ),
+ lookup_bool_option(!.Options, implicit_parallelism, ImplicitParallelism),
+ (
+ ImplicitParallelism = yes,
+ set_option(candidate_parallel_conjunctions, bool(yes), !Options)
+ ;
+ ImplicitParallelism = no
+ ).
+
+ % This type defines the set of feedback_types that are to be calculated and
+ % put into the feedback info file. They should correspond with the values
+ % of feedback_type.
+ %
+:- type requested_feedback_info
+ ---> requested_feedback_info(
+ rfi_parallel :: maybe(candidate_par_conjunctions_params)
+ ).
+
+:- type maybe_found_error
+ ---> have_not_found_error
+ ; found_error.
+
+ % Check all the command line options, and return a representation
+ % of the user's request.
+ %
+:- pred get_feedback_requests(string::in, option_table(option)::in,
+ maybe_found_error::out, requested_feedback_info::out,
+ io::di, io::uo) is det.
+
+get_feedback_requests(ProgName, Options, !:Error, Requested, !IO) :-
+ io.stderr_stream(Stderr, !IO),
+ !:Error = have_not_found_error,
+ % For each feedback type, determine if it is requested, and fill in the
+ % field in the RequestedFeedbackInfo structure.
+ lookup_bool_option(Options, candidate_parallel_conjunctions,
+ CandidateParallelConjunctions),
+ (
+ CandidateParallelConjunctions = yes,
+ lookup_string_option(Options, desired_parallelism,
+ DesiredParallelismStr),
+ ( string.to_float(DesiredParallelismStr, DesiredParallelismPrime) ->
+ DesiredParallelism = DesiredParallelismPrime,
+ ( DesiredParallelism > 1.0 ->
+ true
+ ;
+ io.format(Stderr,
+ "%s: error: desired parallelism level should be > 1.\n",
+ [s(ProgName)], !IO),
+ !:Error = found_error
+ )
+ ;
+ io.format(Stderr,
+ "%s: error: desired parallelism level should be a number.\n",
+ [s(ProgName)], !IO),
+ !:Error = found_error,
+ DesiredParallelism = 1.0 % dummy value
+ ),
+ lookup_string_option(Options, ipar_speedup_threshold,
+ SpeedupThresholdStr),
+ ( string.to_float(SpeedupThresholdStr, SpeedupThresholdPrime) ->
+ SpeedupThreshold = SpeedupThresholdPrime,
+ ( SpeedupThreshold >= 1.0 ->
+ true
+ ;
+ io.format(Stderr,
+ "%s: error: speedup threshold should be >= 1.\n",
+ [s(ProgName)], !IO),
+ !:Error = found_error
+ )
+ ;
+ io.format(Stderr,
+ "%s: error: speedup threshold should be a number.\n",
+ [s(ProgName)], !IO),
+ !:Error = found_error,
+ SpeedupThreshold = 1.0 % dummy value
+ ),
+ lookup_bool_option(Options, ipar_intermodule_var_use,
+ IntermoduleVarUse),
+ lookup_int_option(Options, ipar_sparking_cost, SparkingCost),
+ lookup_int_option(Options, ipar_sparking_delay, SparkingDelay),
+ lookup_int_option(Options, ipar_barrier_cost, BarrierCost),
+ lookup_int_option(Options, ipar_future_signal_cost, FutureSignalCost),
+ lookup_int_option(Options, ipar_future_wait_cost, FutureWaitCost),
+ lookup_int_option(Options, ipar_context_wakeup_delay,
+ ContextWakeupDelay),
+ lookup_int_option(Options, ipar_clique_cost_threshold,
+ CPCCliqueThreshold),
+ lookup_int_option(Options, ipar_call_site_cost_threshold,
+ CPCCallSiteThreshold),
+ lookup_bool_option(Options, ipar_dep_conjs, AllowDepConjs),
+ lookup_string_option(Options, ipar_speedup_alg, SpeedupAlgString),
+ (
+ parse_parallelise_dep_conjs_string(AllowDepConjs,
+ SpeedupAlgString, SpeedupAlgPrime)
+ ->
+ SpeedupAlg = SpeedupAlgPrime
+ ;
+ io.format(Stderr,
+ "%s: error: %s is not a speedup estimate algorithm.\n",
+ [s(ProgName), s(SpeedupAlgString)], !IO),
+ !:Error = found_error,
+ SpeedupAlg = do_not_parallelise_dep_conjs % dummy value
+ ),
+ lookup_string_option(Options, ipar_best_par_alg, BestParAlgStr),
+ parse_best_par_algorithm(BestParAlgStr, MaybeBestParAlg),
+ (
+ MaybeBestParAlg = ok(BestParAlg)
+ ;
+ MaybeBestParAlg = error(MaybeMessage, _Line, _Col),
+ (
+ MaybeMessage = yes(Message),
+ io.format(Stderr,
+ "%s: error: %s is not a best parallelisation " ++
+ "algorithm: %s.\n",
+ [s(ProgName), s(BestParAlgStr), s(Message)], !IO)
+ ;
+ MaybeMessage = no,
+ io.format(Stderr,
+ "%s: error: %s is not a best parallelisation algorithm.\n",
+ [s(ProgName), s(BestParAlgStr)], !IO)
+ ),
+ !:Error = found_error,
+ BestParAlg = bpa_greedy % dummy value
+ ),
+ AutoParOpts =
+ candidate_par_conjunctions_params(DesiredParallelism,
+ IntermoduleVarUse,
+ SparkingCost,
+ SparkingDelay,
+ BarrierCost,
+ FutureSignalCost,
+ FutureWaitCost,
+ ContextWakeupDelay,
+ CPCCliqueThreshold,
+ CPCCallSiteThreshold,
+ SpeedupThreshold,
+ SpeedupAlg,
+ BestParAlg),
+ MaybeAutoParOpts = yes(AutoParOpts)
+ ;
+ CandidateParallelConjunctions = no,
+ MaybeAutoParOpts = no
+ ),
+ Requested = requested_feedback_info(MaybeAutoParOpts).
+
+:- pred parse_best_par_algorithm(string::in,
+ parse_result(best_par_algorithm)::out) is det.
+
+parse_best_par_algorithm(String, Result) :-
+ promise_equivalent_solutions [Result] (
+ parse(String, best_par_algorithm_parser, Result)
+ ).
+
+:- pred best_par_algorithm_parser(src::in, best_par_algorithm::out,
+ ps::in, ps::out) is semidet.
+
+best_par_algorithm_parser(Src, Algorithm, !PS) :-
+ whitespace(Src, _, !PS),
+ (
+ keyword(idchars, "greedy", Src, _, !PS)
+ ->
+ Algorithm = bpa_greedy
+ ;
+ keyword(idchars, "complete-branches", Src, _, !PS),
+ brackets("(", ")", int_literal, Src, N, !PS),
+ N >= 0
+ ->
+ Algorithm = bpa_complete_branches(N)
+ ;
+ keyword(idchars, "complete-size", Src, _, !PS),
+ brackets("(", ")", int_literal, Src, N, !PS),
+ N >= 0
+ ->
+ Algorithm = bpa_complete_size(N)
+ ;
+ keyword(idchars, "complete", Src, _, !PS),
+ Algorithm = bpa_complete
+ ),
+ eof(Src, _, !PS).
+
+:- func idchars = string.
+
+idchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".
+
+:- pred parse_parallelise_dep_conjs_string(bool::in, string::in,
+ parallelise_dep_conjs::out) is semidet.
+
+parse_parallelise_dep_conjs_string(no, _, do_not_parallelise_dep_conjs).
+parse_parallelise_dep_conjs_string(yes, "naive",
+ parallelise_dep_conjs(estimate_speedup_naively)).
+parse_parallelise_dep_conjs_string(yes, "num_vars",
+ parallelise_dep_conjs(estimate_speedup_by_num_vars)).
+parse_parallelise_dep_conjs_string(yes, "overlap",
+ parallelise_dep_conjs(estimate_speedup_by_overlap)).
+
+ % Adjust command line options when one option implies other options.
+ %
+:- pred option_implies(option::in, option::in, bool::in,
+ option_table(option)::in, option_table(option)::out) is det.
+
+option_implies(Option, ImpliedOption, ImpliedValue, !Options) :-
+ ( lookup_bool_option(!.Options, Option, yes) ->
+ set_option(ImpliedOption, bool(ImpliedValue), !Options)
+ ;
+ true
+ ).
+
+ % Set the value of an option in the option table.
+ %
+:- pred set_option(option::in, option_data::in,
+ option_table(option)::in, option_table(option)::out) is det.
+
+set_option(Option, Value, !Options) :-
+ map.set(Option, Value, !Options).
+
+%----------------------------------------------------------------------------%
+
+ % process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages,
+ % !Feedback)
+ %
+ % Process a deep profiling structure and update the feedback information
+ % according to the RequestedFeedbackInfo parameter.
+ %
+:- pred process_deep_to_feedback(requested_feedback_info::in, deep::in,
+ cord(message)::out, feedback_info::in, feedback_info::out) is det.
+
+process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages, !Feedback) :-
+ RequestedFeedbackInfo = requested_feedback_info(MaybeAutoParOpts),
+ (
+ MaybeAutoParOpts = yes(AutoParOpts),
+ candidate_parallel_conjunctions(AutoParOpts, Deep, Messages, !Feedback)
+ ;
+ MaybeAutoParOpts = no,
+ Messages = cord.empty
+ ).
+
+%-----------------------------------------------------------------------------%
+:- end_module mdprof_create_feedback.
+%-----------------------------------------------------------------------------%
Index: deep_profiler/mdprof_feedback.m
===================================================================
RCS file: deep_profiler/mdprof_feedback.m
diff -N deep_profiler/mdprof_feedback.m
--- deep_profiler/mdprof_feedback.m 11 Jul 2011 19:47:25 -0000 1.41
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,770 +0,0 @@
-%-----------------------------------------------------------------------------%
-% vim: ft=mercury ts=4 sw=4 et
-%-----------------------------------------------------------------------------%
-% Copyright (C) 2006-2011 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, pbone.
-%
-% This module contains code for generating feedback files that tell the
-% compiler things such as which conjunctions can be profitably parallelised.
-%
-%-----------------------------------------------------------------------------%
-
-:- module mdprof_feedback.
-:- interface.
-
-:- import_module io.
-
-%-----------------------------------------------------------------------------%
-
-:- pred main(io::di, io::uo) is det.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-:- import_module conf.
-:- import_module mdbcomp.
-:- import_module mdbcomp.feedback.
-:- import_module mdbcomp.feedback.automatic_parallelism.
-:- import_module mdprof_fb.
-:- import_module mdprof_fb.automatic_parallelism.
-:- import_module mdprof_fb.automatic_parallelism.autopar_search_callgraph.
-:- import_module mdprof_fb.automatic_parallelism.autopar_reports.
-:- import_module message.
-:- import_module profile.
-:- import_module startup.
-
-:- import_module bool.
-:- import_module char.
-:- import_module cord.
-:- import_module float.
-:- import_module getopt.
-:- import_module int.
-:- import_module library.
-:- import_module list.
-:- import_module map.
-:- import_module maybe.
-:- import_module parsing_utils.
-:- import_module require.
-:- import_module string.
-
-%-----------------------------------------------------------------------------%
-%
-% This section contains the main predicate as well as code to read the deep
-% profiling data and display usage and version messages to the user.
-%
-
-main(!IO) :-
- io.progname_base("mdprof_feedback", ProgName, !IO),
- io.command_line_arguments(Args0, !IO),
- getopt.process_options(option_ops_multi(short, long, defaults),
- Args0, Args, MaybeOptions),
- io.stderr_stream(Stderr, !IO),
- (
- MaybeOptions = ok(Options0),
- post_process_options(ProgName, Options0, Options, !IO),
- lookup_bool_option(Options, help, Help),
- lookup_bool_option(Options, version, Version),
- (
- Version = yes
- ->
- write_version_message(ProgName, !IO)
- ;
- Help = yes
- ->
- write_help_message(ProgName, !IO)
- ;
- (
- Args = [OutputFileName],
- feedback.read_feedback_file(OutputFileName, FeedbackReadResult,
- !IO),
- (
- FeedbackReadResult = ok(Feedback),
- ProfileProgName = get_feedback_program_name(Feedback),
- print_feedback_report(ProfileProgName, Feedback, !IO)
- ;
- FeedbackReadResult = error(FeedbackReadError),
- feedback.read_error_message_string(OutputFileName,
- FeedbackReadError, Message),
- io.format(Stderr, "%s: %s\n",
- [s(ProgName), s(Message)], !IO),
- io.set_exit_status(1, !IO)
- )
- ;
- Args = [InputFileName, OutputFileName],
- get_feedback_requests(ProgName, Options, FoundError,
- RequestedFeedbackInfo, !IO),
- (
- FoundError = have_not_found_error,
- generate_requested_feedback(ProgName, Options,
- InputFileName, OutputFileName, RequestedFeedbackInfo,
- !IO)
- ;
- FoundError = found_error
- % The error message have already been printed.
- )
- ;
- ( Args = []
- ; Args = [_, _, _ | _]
- ),
- write_help_message(ProgName, !IO),
- io.set_exit_status(1, !IO)
- )
- )
- ;
- MaybeOptions = error(Msg),
- io.format(Stderr, "%s: error parsing options: %s\n",
- [s(ProgName), s(Msg)], !IO),
- write_help_message(ProgName, !IO),
- io.set_exit_status(1, !IO)
- ).
-
-:- pred generate_requested_feedback(string::in, option_table(option)::in,
- string::in, string::in, requested_feedback_info::in, io::di, io::uo) is det.
-
-generate_requested_feedback(ProgName, Options, InputFileName, OutputFileName,
- RequestedFeedbackInfo, !IO) :-
- io.stderr_stream(Stderr, !IO),
- RequestedFeedbackInfo = requested_feedback_info(MaybeParallelize),
- (
- MaybeParallelize = yes(_),
- lookup_bool_option(Options, debug_read_profile, DebugReadProfile),
- lookup_bool_option(Options, report, Report),
- read_deep_file(InputFileName, DebugReadProfile, MaybeDeep, !IO),
- (
- MaybeDeep = ok(Deep),
- ProfileProgName = Deep ^ profile_stats ^ prs_program_name,
- feedback.read_or_create(OutputFileName, ProfileProgName,
- FeedbackReadResult, !IO),
- (
- FeedbackReadResult = ok(Feedback0),
- process_deep_to_feedback(RequestedFeedbackInfo,
- Deep, Messages, Feedback0, Feedback),
- (
- Report = yes,
- print_feedback_report(ProfileProgName, Feedback, !IO)
- ;
- Report = no
- ),
- write_feedback_file(OutputFileName, ProfileProgName,
- Feedback, WriteResult, !IO),
- (
- WriteResult = ok
- ;
- ( WriteResult = open_error(Error)
- ; WriteResult = write_error(Error)
- ),
- io.error_message(Error, ErrorMessage),
- io.format(Stderr, "%s: %s: %s\n",
- [s(ProgName), s(OutputFileName), s(ErrorMessage)],
- !IO),
- io.set_exit_status(1, !IO)
- ),
- lookup_int_option(Options, verbosity, VerbosityLevel),
- set_verbosity_level(VerbosityLevel, !IO),
- write_out_messages(Stderr, Messages, !IO)
- ;
- FeedbackReadResult = error(FeedbackReadError),
- feedback.read_error_message_string(OutputFileName,
- FeedbackReadError, Message),
- io.write_string(Stderr, Message, !IO),
- io.set_exit_status(1, !IO)
- )
- ;
- MaybeDeep = error(Error),
- io.set_exit_status(1, !IO),
- io.format(Stderr, "%s: error reading %s: %s\n",
- [s(ProgName), s(InputFileName), s(Error)], !IO)
- )
- ;
- MaybeParallelize = no,
- io.format(Stderr, "%s: options do not request any form of feedback\n",
- [s(ProgName)], !IO)
- ).
-
-:- pred print_feedback_report(string::in, feedback_info::in, io::di, io::uo)
- is det.
-
-print_feedback_report(ProgName, Feedback, !IO) :-
- get_all_feedback_data(Feedback, AllFeedback),
- map(create_feedback_report, AllFeedback, Reports),
- ReportStr = string.append_list(Reports),
- io.format("Feedback report for %s:\n\n%s", [s(ProgName), s(ReportStr)],
- !IO).
-
-:- pred create_feedback_report(feedback_data::in, string::out) is det.
-
-create_feedback_report(feedback_data_calls_above_threshold_sorted(_, _, _),
- Report) :-
- Report = " feedback_data_calls_above_threshold_sorted is not supported\n".
-create_feedback_report(feedback_data_candidate_parallel_conjunctions(
- Parameters, Conjs), Report) :-
- create_feedback_autopar_report(Parameters, Conjs, Report).
-
-:- func help_message(string) = string.
-
-help_message(ProgName) = format(
-"Usage: %s [<options>] <input> <output>
- %s <output>
- %s --help
- %s --version
-
- The first form of this command generates feedback information from
- profiling data. The second form prints a report of the feedback data and
- does not modify it. The third and forth forms print this help message and
- version information respectively.
-
- <input> must name a deep profiling data file.
- <output> is the name of the file to be generated by this program.
-
- You may specify the following general options:
-
- -h --help Generate this help message.
- -V --version Report the program's version number.
- -v --verbosity <0-4>
- Generate messages. The higher the argument, the more
- verbose the program becomes. 2 is recommended and the
- default.
- --debug-read-profile
- Generate debugging messages when reading the deep profile
- and creating the deep structure.
- --no-report Suppress the report about the feedback information in the
- file that is usually displayed after any processing has
- been done.
-
- The following options select sets of feedback information useful
- for particular compiler optimizations:
-
- --implicit-parallelism
- Generate information that the compiler can use for automatic
- parallelization.
- --desired-parallelism <value>
- The amount of desired parallelism for implicit parallelism,
- which must be a floating point number above 1.0.
- Note: This option is currently ignored.
- --implicit-parallelism-intermodule-var-use
- Assume that the compiler will be able to push signals and waits
- for futures across module boundaries.
- --ipar-sparking-cost <value>
- The cost of creating a spark, measured in the deep profiler's
- call sequence counts.
- --ipar-sparking-delay <value>
- The time taken from the time a spark is created until the spark
- is executed by another processor, assuming that there is a free
- processor.
- --ipar-barrier-cost <value>
- The cost of executing the barrier code at the end of each
- parallel conjunct.
- --ipar-future-signal-cost <value>
- The cost of the signal() call for the producer of a shared
- variable, measured in the profiler's call sequence counts.
- --ipar-future-wait-cost <value>
- The cost of the wait() call for the consumer of a shared
- variable, measured in the profiler's call sequence counts.
- --ipar-context-wakeup-delay <value>
- The time taken for a context to resume execution after being
- placed on the run queue. This is used to estimate the impact
- of blocking of a context's execution, it is measured in the
- profiler's call sequence counts.
- --ipar-clique-cost-threshold <value>
- The cost threshold for cliques to be considered for implicit
- parallelism, measured on the profiler's call sequence counts.
- --ipar-call-site-cost-threshold <value>
- The cost of a call site to be considered for parallelism
- against another call site.
- --no-ipar-dep-conjs
- Disable parallelisation of dependent conjunctions.
- --ipar-speedup-alg <alg>
- Choose the algorithm that is used to estimate the speedup for
- dependent calculations. The available algorithms are:
- overlap: Compute the overlap between dependent
- conjunctions.
- num_vars: Use the number of shared variables as a proxy for
- the amount of overlap available.
- naive: Ignore dependencies.
- The default is overlap.
- --ipar-speedup-threshold <value>
- The threshold that a speedup ratio must meet before the
- feedback tool will accept a parallelization. It must be
- a floating point number, which must be at least 1.0.
- If it is e.g. 1.02, then the feedback tool will ignore
- parallelizations that promise less than a 2%% local speedup.
- --ipar-best-par-alg <alg>
- Select which algorithm to use to find the best way to
- parallelise a conjunction. The available algorithms are:
- greedy: A greedy algorithm with a linear time complexity.
- complete: A complete algorithm with a branch and bound
- search. This can be slow for problems larger than 50
- conjuncts, since it has an exponential complexity.
- complete-size(N): As above exept that it takes a single
- parameter, N. If a conjunction has more than N
- conjuncts, then the greedy algorithm will be used.
- complete-branches(N): The same as the complete algorithm,
- except that it allows at most N branches to be created
- during the search. Once N branches have been created,
- a greedy search is used on each open branch.
- The default is complete-branches(1000).
-
- The following options select specific types of feedback information
- and parameterise them:
-
- --candidate-parallel-conjunctions
- Produce a list of candidate parallel conjunctions for implicit
- parallelism. This option uses the implicit parallelism
- settings above.
-
-",
- % This is obviously redundant but by spelling it out we allow the compiler
- % to check that the format string and arguments make sense.
- [s(ProgName), s(ProgName), s(ProgName), s(ProgName)]).
-
-:- pred write_help_message(string::in, io::di, io::uo) is det.
-
-write_help_message(ProgName, !IO) :-
- io.write_string(help_message(ProgName), !IO).
-
-:- pred write_version_message(string::in, io::di, io::uo) is det.
-
-write_version_message(ProgName, !IO) :-
- library.version(Version),
- io.write_string(ProgName, !IO),
- io.write_string(": Mercury deep profiler", !IO),
- io.nl(!IO),
- io.write_string(Version, !IO),
- io.nl(!IO).
-
- % Read a deep profiling data file.
- %
-:- pred read_deep_file(string::in, bool::in, maybe_error(deep)::out,
- io::di, io::uo) is det.
-
-read_deep_file(Input, Debug, MaybeDeep, !IO) :-
- server_name_port(Machine, !IO),
- script_name(ScriptName, !IO),
- (
- Debug = yes,
- io.stdout_stream(Stdout, !IO),
- MaybeOutput = yes(Stdout)
- ;
- Debug = no,
- MaybeOutput = no
- ),
- read_and_startup_default_deep_options(Machine, ScriptName, Input, no,
- MaybeOutput, [], MaybeDeep, !IO).
-
-%----------------------------------------------------------------------------%
-%
-% This section describes and processes command line options. Individual
-% feedback information can be requested by the user, as well as options named
-% after optimizations that may imply one or more feedback inforemation types,
-% which that optimization uses.
-%
-
- % Command line options.
- %
-:- type option
- ---> help
- ; version
- ; verbosity
- ; debug_read_profile
- ; report
-
- % A list of candidate parallel conjunctions is produced for the new
- % implicit parallelism implementation.
- ; candidate_parallel_conjunctions
-
- % Provide suitable feedback information for implicit parallelism
- ; implicit_parallelism
- ; desired_parallelism
- ; ipar_intermodule_var_use
- ; ipar_sparking_cost
- ; ipar_sparking_delay
- ; ipar_barrier_cost
- ; ipar_future_signal_cost
- ; ipar_future_wait_cost
- ; ipar_context_wakeup_delay
- ; ipar_clique_cost_threshold
- ; ipar_call_site_cost_threshold
- ; ipar_speedup_threshold
- ; ipar_dep_conjs
- ; ipar_speedup_alg
- ; ipar_best_par_alg.
-
-% TODO: Introduce an option to disable parallelisation of dependent
-% conjunctions, or switch to the simple calculations for independent
-% conjunctions.
-
-:- pred short(char::in, option::out) is semidet.
-
-short('h', help).
-short('v', verbosity).
-short('V', version).
-
-:- pred long(string::in, option::out) is semidet.
-
-long("help",
- help).
-long("verbosity",
- verbosity).
-long("version",
- version).
-long("debug-read-profile",
- debug_read_profile).
-long("report",
- report).
-long("candidate-parallel-conjunctions",
- candidate_parallel_conjunctions).
-long("implicit-parallelism",
- implicit_parallelism).
-long("desired-parallelism",
- desired_parallelism).
-long("implicit-parallelism-intermodule-var-use",
- ipar_intermodule_var_use).
-long("ipar-intermodule-var-use",
- ipar_intermodule_var_use).
-long("implicit-parallelism-sparking-cost",
- ipar_sparking_cost).
-long("ipar-sparking-cost",
- ipar_sparking_cost).
-long("implicit-parallelism-sparking-delay",
- ipar_sparking_delay).
-long("ipar-sparking-delay",
- ipar_sparking_delay).
-long("implicit-parallelism-future-signal-cost",
- ipar_future_signal_cost).
-long("ipar-future-signal-cost",
- ipar_future_signal_cost).
-long("implicit-parallelism-barrier-cost",
- ipar_barrier_cost).
-long("ipar-barrier-cost",
- ipar_barrier_cost).
-long("implicit-parallelism-future-wait-cost",
- ipar_future_wait_cost).
-long("ipar-future-wait-cost",
- ipar_future_wait_cost).
-long("implicit-parallelism-context-wakeup-delay",
- ipar_context_wakeup_delay).
-long("ipar-context-wakeup-delay",
- ipar_context_wakeup_delay).
-long("implicit-parallelism-clique-cost-threshold",
- ipar_clique_cost_threshold).
-long("ipar-clique-cost-threshold",
- ipar_clique_cost_threshold).
-long("implicit-parallelism-call-site-cost-threshold",
- ipar_call_site_cost_threshold).
-long("ipar-call-site-cost-threshold",
- ipar_call_site_cost_threshold).
-long("implicit-parallelism-dependant-conjunctions",
- ipar_dep_conjs).
-long("ipar-dep-conjs",
- ipar_dep_conjs).
-long("implicit-parallelism-dependant-conjunctions-algorithm",
- ipar_speedup_alg).
-long("ipar-speedup-alg",
- ipar_speedup_alg).
-long("implicit-parallelism-speedup-threshold",
- ipar_speedup_threshold).
-long("ipar-speedup-threshold",
- ipar_speedup_threshold).
-long("implicit-parallelism-best-parallelisation-algorithm",
- ipar_best_par_alg).
-long("ipar-best-par-alg",
- ipar_best_par_alg).
-
-:- pred defaults(option::out, option_data::out) is multi.
-
-defaults(help, bool(no)).
-defaults(verbosity, int(2)).
-defaults(version, bool(no)).
-defaults(debug_read_profile, bool(no)).
-defaults(report, bool(yes)).
-
-defaults(candidate_parallel_conjunctions, bool(no)).
-
-defaults(implicit_parallelism, bool(no)).
-defaults(desired_parallelism, string("8.0")).
-% XXX: These values have been chosen arbitrarily; we should set them
-% based on measurements.
-defaults(ipar_intermodule_var_use, bool(no)).
-defaults(ipar_sparking_cost, int(100)).
-defaults(ipar_sparking_delay, int(1000)).
-defaults(ipar_barrier_cost, int(100)).
-defaults(ipar_future_signal_cost, int(100)).
-defaults(ipar_future_wait_cost, int(200)).
-defaults(ipar_context_wakeup_delay, int(1000)).
-defaults(ipar_clique_cost_threshold, int(2000)).
-defaults(ipar_call_site_cost_threshold, int(2000)).
-defaults(ipar_dep_conjs, bool(yes)).
-defaults(ipar_speedup_threshold, string("1.01")).
-defaults(ipar_speedup_alg, string("overlap")).
-defaults(ipar_best_par_alg, string("complete-branches(1000)")).
-
-:- pred construct_measure(string::in, stat_measure::out) is semidet.
-
-construct_measure("mean", stat_mean).
-construct_measure("median", stat_median).
-
-:- pred post_process_options(string::in,
- option_table(option)::in, option_table(option)::out,
- io::di, io::uo) is det.
-
-post_process_options(ProgName, !Options, !IO) :-
- lookup_int_option(!.Options, verbosity, VerbosityLevel),
- io.stderr_stream(Stderr, !IO),
- ( VerbosityLevel < 0 ->
- io.format(Stderr,
- "%s: warning: verbosity level should not be negative.\n",
- [s(ProgName)], !IO),
- set_option(verbosity, int(0), !Options)
- ; VerbosityLevel > 4 ->
- io.format(Stderr,
- "%s: warning: verbosity level should not exceed 4.\n",
- [s(ProgName)], !IO),
- set_option(verbosity, int(4), !Options)
- ;
- true
- ),
- lookup_bool_option(!.Options, implicit_parallelism, ImplicitParallelism),
- (
- ImplicitParallelism = yes,
- set_option(candidate_parallel_conjunctions, bool(yes), !Options)
- ;
- ImplicitParallelism = no
- ).
-
- % This type defines the set of feedback_types that are to be calculated and
- % put into the feedback info file. They should correspond with the values
- % of feedback_type.
- %
-:- type requested_feedback_info
- ---> requested_feedback_info(
- rfi_parallel :: maybe(candidate_par_conjunctions_params)
- ).
-
-:- type maybe_found_error
- ---> have_not_found_error
- ; found_error.
-
- % Check all the command line options, and return a representation
- % of the user's request.
- %
-:- pred get_feedback_requests(string::in, option_table(option)::in,
- maybe_found_error::out, requested_feedback_info::out,
- io::di, io::uo) is det.
-
-get_feedback_requests(ProgName, Options, !:Error, Requested, !IO) :-
- io.stderr_stream(Stderr, !IO),
- !:Error = have_not_found_error,
- % For each feedback type, determine if it is requested, and fill in the
- % field in the RequestedFeedbackInfo structure.
- lookup_bool_option(Options, candidate_parallel_conjunctions,
- CandidateParallelConjunctions),
- (
- CandidateParallelConjunctions = yes,
- lookup_string_option(Options, desired_parallelism,
- DesiredParallelismStr),
- ( string.to_float(DesiredParallelismStr, DesiredParallelismPrime) ->
- DesiredParallelism = DesiredParallelismPrime,
- ( DesiredParallelism > 1.0 ->
- true
- ;
- io.format(Stderr,
- "%s: error: desired parallelism level should be > 1.\n",
- [s(ProgName)], !IO),
- !:Error = found_error
- )
- ;
- io.format(Stderr,
- "%s: error: desired parallelism level should be a number.\n",
- [s(ProgName)], !IO),
- !:Error = found_error,
- DesiredParallelism = 1.0 % dummy value
- ),
- lookup_string_option(Options, ipar_speedup_threshold,
- SpeedupThresholdStr),
- ( string.to_float(SpeedupThresholdStr, SpeedupThresholdPrime) ->
- SpeedupThreshold = SpeedupThresholdPrime,
- ( SpeedupThreshold >= 1.0 ->
- true
- ;
- io.format(Stderr,
- "%s: error: speedup threshold should be >= 1.\n",
- [s(ProgName)], !IO),
- !:Error = found_error
- )
- ;
- io.format(Stderr,
- "%s: error: speedup threshold should be a number.\n",
- [s(ProgName)], !IO),
- !:Error = found_error,
- SpeedupThreshold = 1.0 % dummy value
- ),
- lookup_bool_option(Options, ipar_intermodule_var_use,
- IntermoduleVarUse),
- lookup_int_option(Options, ipar_sparking_cost, SparkingCost),
- lookup_int_option(Options, ipar_sparking_delay, SparkingDelay),
- lookup_int_option(Options, ipar_barrier_cost, BarrierCost),
- lookup_int_option(Options, ipar_future_signal_cost, FutureSignalCost),
- lookup_int_option(Options, ipar_future_wait_cost, FutureWaitCost),
- lookup_int_option(Options, ipar_context_wakeup_delay,
- ContextWakeupDelay),
- lookup_int_option(Options, ipar_clique_cost_threshold,
- CPCCliqueThreshold),
- lookup_int_option(Options, ipar_call_site_cost_threshold,
- CPCCallSiteThreshold),
- lookup_bool_option(Options, ipar_dep_conjs, AllowDepConjs),
- lookup_string_option(Options, ipar_speedup_alg, SpeedupAlgString),
- (
- parse_parallelise_dep_conjs_string(AllowDepConjs,
- SpeedupAlgString, SpeedupAlgPrime)
- ->
- SpeedupAlg = SpeedupAlgPrime
- ;
- io.format(Stderr,
- "%s: error: %s is not a speedup estimate algorithm.\n",
- [s(ProgName), s(SpeedupAlgString)], !IO),
- !:Error = found_error,
- SpeedupAlg = do_not_parallelise_dep_conjs % dummy value
- ),
- lookup_string_option(Options, ipar_best_par_alg, BestParAlgStr),
- parse_best_par_algorithm(BestParAlgStr, MaybeBestParAlg),
- (
- MaybeBestParAlg = ok(BestParAlg)
- ;
- MaybeBestParAlg = error(MaybeMessage, _Line, _Col),
- (
- MaybeMessage = yes(Message),
- io.format(Stderr,
- "%s: error: %s is not a best parallelisation " ++
- "algorithm: %s.\n",
- [s(ProgName), s(BestParAlgStr), s(Message)], !IO)
- ;
- MaybeMessage = no,
- io.format(Stderr,
- "%s: error: %s is not a best parallelisation algorithm.\n",
- [s(ProgName), s(BestParAlgStr)], !IO)
- ),
- !:Error = found_error,
- BestParAlg = bpa_greedy % dummy value
- ),
- AutoParOpts =
- candidate_par_conjunctions_params(DesiredParallelism,
- IntermoduleVarUse,
- SparkingCost,
- SparkingDelay,
- BarrierCost,
- FutureSignalCost,
- FutureWaitCost,
- ContextWakeupDelay,
- CPCCliqueThreshold,
- CPCCallSiteThreshold,
- SpeedupThreshold,
- SpeedupAlg,
- BestParAlg),
- MaybeAutoParOpts = yes(AutoParOpts)
- ;
- CandidateParallelConjunctions = no,
- MaybeAutoParOpts = no
- ),
- Requested = requested_feedback_info(MaybeAutoParOpts).
-
-:- pred parse_best_par_algorithm(string::in,
- parse_result(best_par_algorithm)::out) is det.
-
-parse_best_par_algorithm(String, Result) :-
- promise_equivalent_solutions [Result] (
- parse(String, best_par_algorithm_parser, Result)
- ).
-
-:- pred best_par_algorithm_parser(src::in, best_par_algorithm::out,
- ps::in, ps::out) is semidet.
-
-best_par_algorithm_parser(Src, Algorithm, !PS) :-
- whitespace(Src, _, !PS),
- (
- keyword(idchars, "greedy", Src, _, !PS)
- ->
- Algorithm = bpa_greedy
- ;
- keyword(idchars, "complete-branches", Src, _, !PS),
- brackets("(", ")", int_literal, Src, N, !PS),
- N >= 0
- ->
- Algorithm = bpa_complete_branches(N)
- ;
- keyword(idchars, "complete-size", Src, _, !PS),
- brackets("(", ")", int_literal, Src, N, !PS),
- N >= 0
- ->
- Algorithm = bpa_complete_size(N)
- ;
- keyword(idchars, "complete", Src, _, !PS),
- Algorithm = bpa_complete
- ),
- eof(Src, _, !PS).
-
-:- func idchars = string.
-
-idchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".
-
-:- pred parse_parallelise_dep_conjs_string(bool::in, string::in,
- parallelise_dep_conjs::out) is semidet.
-
-parse_parallelise_dep_conjs_string(no, _, do_not_parallelise_dep_conjs).
-parse_parallelise_dep_conjs_string(yes, "naive",
- parallelise_dep_conjs(estimate_speedup_naively)).
-parse_parallelise_dep_conjs_string(yes, "num_vars",
- parallelise_dep_conjs(estimate_speedup_by_num_vars)).
-parse_parallelise_dep_conjs_string(yes, "overlap",
- parallelise_dep_conjs(estimate_speedup_by_overlap)).
-
- % Adjust command line options when one option implies other options.
- %
-:- pred option_implies(option::in, option::in, bool::in,
- option_table(option)::in, option_table(option)::out) is det.
-
-option_implies(Option, ImpliedOption, ImpliedValue, !Options) :-
- ( lookup_bool_option(!.Options, Option, yes) ->
- set_option(ImpliedOption, bool(ImpliedValue), !Options)
- ;
- true
- ).
-
- % Set the value of an option in the option table.
- %
-:- pred set_option(option::in, option_data::in,
- option_table(option)::in, option_table(option)::out) is det.
-
-set_option(Option, Value, !Options) :-
- map.set(Option, Value, !Options).
-
-%----------------------------------------------------------------------------%
-
- % process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages,
- % !Feedback)
- %
- % Process a deep profiling structure and update the feedback information
- % according to the RequestedFeedbackInfo parameter.
- %
-:- pred process_deep_to_feedback(requested_feedback_info::in, deep::in,
- cord(message)::out, feedback_info::in, feedback_info::out) is det.
-
-process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages, !Feedback) :-
- RequestedFeedbackInfo = requested_feedback_info(MaybeAutoParOpts),
- (
- MaybeAutoParOpts = yes(AutoParOpts),
- candidate_parallel_conjunctions(AutoParOpts, Deep, Messages, !Feedback)
- ;
- MaybeAutoParOpts = no,
- Messages = cord.empty
- ).
-
-%-----------------------------------------------------------------------------%
-:- end_module mdprof_feedback.
-%-----------------------------------------------------------------------------%
Index: deep_profiler/mdprof_report_feedback.m
===================================================================
RCS file: deep_profiler/mdprof_report_feedback.m
diff -N deep_profiler/mdprof_report_feedback.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ deep_profiler/mdprof_report_feedback.m 26 Sep 2011 05:21:54 -0000
@@ -0,0 +1,199 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2011 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_report_feedback.m.
+% Author: pbone.
+%
+% This module contains code for showing the contents of feedback files
+% in a human-readable form.
+%
+%-----------------------------------------------------------------------------%
+
+:- module mdprof_report_feedback.
+:- interface.
+
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module mdbcomp.
+:- import_module mdbcomp.feedback.
+:- import_module mdbcomp.feedback.automatic_parallelism.
+:- import_module mdprof_fb.
+:- import_module mdprof_fb.automatic_parallelism.
+:- import_module mdprof_fb.automatic_parallelism.autopar_reports.
+
+:- import_module bool.
+:- import_module char.
+:- import_module getopt.
+:- import_module int.
+:- import_module library.
+:- import_module list.
+:- import_module map.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+main(!IO) :-
+ io.progname_base("mdprof_report_feedback", ProgName, !IO),
+ io.command_line_arguments(Args0, !IO),
+ getopt.process_options(option_ops_multi(short, long, defaults),
+ Args0, Args, MaybeOptions),
+ io.stderr_stream(Stderr, !IO),
+ (
+ MaybeOptions = ok(Options0),
+ post_process_options(ProgName, Options0, Options, !IO),
+ lookup_bool_option(Options, help, Help),
+ lookup_bool_option(Options, version, Version),
+ ( Version = yes ->
+ write_version_message(ProgName, !IO)
+ ; Help = yes ->
+ write_help_message(ProgName, !IO)
+ ;
+ (
+ Args = [FeedbackFileName],
+ feedback.read_feedback_file(FeedbackFileName,
+ FeedbackReadResult, !IO),
+ (
+ FeedbackReadResult = ok(Feedback),
+ ProfileProgName = get_feedback_program_name(Feedback),
+ print_feedback_report(ProfileProgName, Feedback, !IO)
+ ;
+ FeedbackReadResult = error(FeedbackReadError),
+ feedback.read_error_message_string(FeedbackFileName,
+ FeedbackReadError, Message),
+ io.format(Stderr, "%s: %s\n",
+ [s(ProgName), s(Message)], !IO),
+ io.set_exit_status(1, !IO)
+ )
+ ;
+ ( Args = []
+ ; Args = [_, _ | _]
+ ),
+ write_help_message(ProgName, !IO),
+ io.set_exit_status(1, !IO)
+ )
+ )
+ ;
+ MaybeOptions = error(Msg),
+ io.format(Stderr, "%s: error parsing options: %s\n",
+ [s(ProgName), s(Msg)], !IO),
+ write_help_message(ProgName, !IO),
+ io.set_exit_status(1, !IO)
+ ).
+
+:- func help_message(string) = string.
+
+help_message(ProgName) = HelpMessage :-
+ FormatStr =
+"Usage: %s [options] <feedbackfile>
+ This command outputs a report that shows the contents of the named
+ feedback file in a human-readable form.
+
+ You may specify the following general options:
+
+ -h --help Generate this help message.
+ -V --version Report the program's version number.
+ -v --verbosity <0-4>
+ Generate messages. The higher the argument, the more
+ verbose the program becomes. 2 is recommended, and
+ is the default.
+",
+ HelpMessage = string.format(FormatStr, [s(ProgName)]).
+
+:- pred write_help_message(string::in, io::di, io::uo) is det.
+
+write_help_message(ProgName, !IO) :-
+ io.write_string(help_message(ProgName), !IO).
+
+:- pred write_version_message(string::in, io::di, io::uo) is det.
+
+write_version_message(ProgName, !IO) :-
+ library.version(Version),
+ io.write_string(ProgName, !IO),
+ io.write_string(": Mercury deep profiler", !IO),
+ io.nl(!IO),
+ io.write_string(Version, !IO),
+ io.nl(!IO).
+
+%----------------------------------------------------------------------------%
+%
+% This section describes and processes command line options. Individual
+% feedback information can be requested by the user, as well as options named
+% after optimizations that may imply one or more feedback inforemation types,
+% which that optimization uses.
+%
+
+ % Command line options.
+ %
+:- type option
+ ---> help
+ ; version
+ ; verbosity.
+
+% TODO: Introduce an option to disable parallelisation of dependent
+% conjunctions, or switch to the simple calculations for independent
+% conjunctions.
+
+:- pred short(char::in, option::out) is semidet.
+
+short('h', help).
+short('v', verbosity).
+short('V', version).
+
+:- pred long(string::in, option::out) is semidet.
+
+long("help", help).
+long("verbosity", verbosity).
+long("version", version).
+
+:- pred defaults(option::out, option_data::out) is multi.
+
+defaults(help, bool(no)).
+defaults(verbosity, int(2)).
+defaults(version, bool(no)).
+
+:- pred post_process_options(string::in,
+ option_table(option)::in, option_table(option)::out,
+ io::di, io::uo) is det.
+
+post_process_options(ProgName, !Options, !IO) :-
+ lookup_int_option(!.Options, verbosity, VerbosityLevel),
+ io.stderr_stream(Stderr, !IO),
+ ( VerbosityLevel < 0 ->
+ io.format(Stderr,
+ "%s: warning: verbosity level should not be negative.\n",
+ [s(ProgName)], !IO),
+ set_option(verbosity, int(0), !Options)
+ ; VerbosityLevel > 4 ->
+ io.format(Stderr,
+ "%s: warning: verbosity level should not exceed 4.\n",
+ [s(ProgName)], !IO),
+ set_option(verbosity, int(4), !Options)
+ ;
+ true
+ ).
+
+ % Set the value of an option in the option table.
+ %
+:- pred set_option(option::in, option_data::in,
+ option_table(option)::in, option_table(option)::out) is det.
+
+set_option(Option, Value, !Options) :-
+ map.set(Option, Value, !Options).
+
+%-----------------------------------------------------------------------------%
+:- end_module mdprof_report_feedback.
+%-----------------------------------------------------------------------------%
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.636
diff -u -b -r1.636 user_guide.texi
--- doc/user_guide.texi 15 Sep 2011 18:00:35 -0000 1.636
+++ doc/user_guide.texi 26 Sep 2011 05:26:58 -0000
@@ -9511,7 +9511,7 @@
@findex --implicit-parallelism
Introduce parallel conjunctions where it could be worthwhile (implicit
parallelism) using deep profiling feedback information generated by
-mdprof_feedback. The profiling feedback file can be specified using the
+mdprof_create_feedback. The profiling feedback file can be specified using the
--feedback-file option.
@sp 1
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/monte
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/lazy_list
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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