This commit is contained in:
Vitor Santos Costa 2018-10-13 08:45:40 +01:00
parent 7772699ef7
commit e747b7f9c1
7 changed files with 324 additions and 413 deletions

View File

@ -35,7 +35,7 @@
* Revision 1.3 2006/01/17 14:10:40 vsc
* YENV may be an HW register (breaks some tabling code)
* All YAAM instructions are now brackedted, so Op introduced an { and EndOp introduces an }. This is because Ricardo assumes that.
* Fix attvars when COROUTING is undefined.
* Fix attvars
*
* Revision 1.2 2005/12/23 00:20:13 vsc
* updates to gprof
@ -47,40 +47,40 @@
* *
*************************************************************************/
/// @file gprof.c
/** @defgroup Tick_Profiler Tick Profiler
@ingroup Profiling
@{
The tick profiler works by interrupting the Prolog code every so often
and checking at each point the code was. The profiler must be able to
retrace the state of the abstract machine at every moment. The major
advantage of this approach is that it gives the actual amount of time
being spent per procedure, or whether garbage collection dominates
execution time. The major drawback is that tracking down the state of
the abstract machine may take significant time, and in the worst case
may slow down the whole execution.
The following procedures are available:
+ profinit
Initialise the data-structures for the profiler. Unnecessary for
dynamic profiler.
+ profon
Start profiling.
+ profoff
Stop profiling.
*/
/** @addtogroup Tick_Profiler
* @ingroup Profiling@{
*
* The tick profiler works by interrupting the Prolog code every so often
* and checking at each point the code was. The pro/filer must be able to
* retrace the state of the abstract machine at every moment. The major
* advantage of this approach is that it gives the actual amount of time
* being spent per procedure, or whether garbage collection dominates
* execution time. The major drawback is that tracking down the state of
* the abstract machine may take significant time, and in the worst case
* may slow down the whole execution.
*
* The following procedures are available:
*
* + profinit/0
* Initialise the data-structures for the profiler. Unnecessary for
* dynamic profiler.
*
* + profon/0
* Start profiling.
*
* + profoff/0
* Stop profiling.
*
* + profoff/0
* Stop profiling.
*
* + showprofres/0 and showprofres/1
* Stop tick counts per predicate.
*
*
*/
#ifdef SCCS
static char SccsId[] = "%W% %G%";
@ -841,7 +841,7 @@ static void RemoveCode(CODEADDR clau)
}
}
static int
static Int
showprofres( USES_REGS1 ) {
buf_ptr buf;

View File

@ -13,11 +13,11 @@ predicates in a language other than Prolog. Under Unix systems,
most language implementations were linkable to `C`, and the first interface exported the YAP machinery to the C language. YAP also implements most of the SWI-Prolog foreign language interface.
This gives portability with a number of SWI-Prolog packages and avoids garnage collection by using @ref slotInterface. Last, a new C++ based interface is
being designed to work with the swig (www.swig.orgv) interface compiler.
@}
@defgroup ChYInterface YAP original C-interface
@{
@ingroup fli_c_cxx
@{
Before describing in full detail how to interface to C code, we will examine
a brief example.
@ -50,8 +50,8 @@ system.
@}
@defgroup CallYAP Using the compiler:
@{
@ingroup ChYInterface
@{
Under Linux you should use:
@ -1588,4 +1588,4 @@ the future we plan to split this library into several smaller libraries
@}
@}
@}

View File

@ -833,7 +833,6 @@ gradient_descent :-
forall(tunable_fact(FactID,GroundTruth),
(XZ is 0.5, X[FactID] <== XZ,set_fact_probability(FactID,XZ))),
problog_flag(sigmoid_slope,Slope),
lbfgs_set_parameter(min_step, Solver, 0.0),
lbfgs_run(Solver,BestF),
format('~2nOptimization done~nWe found a minimum ~4f.~n',[BestF]),
forall(tunable_fact(FactID,GroundTruth), set_tunable(FactID,X)),

View File

@ -15,57 +15,61 @@
* *
*************************************************************************/
%% @{
/**
@file callcount.yap
@short support call counting.
@defgroup Profiling Profiling Prolog Programs
@ingroup extensions
YAP includes two profilers. The count profiler keeps information on the
number of times a predicate was called. This information can be used to
detect what are the most commonly called predicates in the program. The
count profiler can be compiled by setting YAP's flag profiling
to `on`. The time-profiler is a `gprof` profiler, and counts
how many ticks are being spent on specific predicates, or on other
system functions such as internal data-base accesses or garbage collects.
The YAP profiling sub-system is currently under
development. Functionality for this sub-system will increase with newer
implementation.
* @file callcount.yap
* @short support call counting.
*
* @defgroup Profiling Profiling Prolog Programs
* @brief the clock and the tick profilers.
* @ingroup extensions
* @{
*
* YAP includes two profilers. The count profiler keeps information on the
* number of times a predicate was called. This information can be used to
* detect what are the most commonly called predicates in the program. The
* count profiler can be compiled by setting YAP's flag profiling
* to `on`. The time-profiler is a `gprof` profiler, and counts
* how many ticks are being spent on specific predicates, or on other
* system functions such as internal data-base accesses or garbage collects.
*
* + Call_Counting
* +
*
*/
/**
@defgroup Call_Counting Counting Calls
@ingroup Profiling
@{
Predicates compiled with YAP's flag call_counting set to
`on` update counters on the numbers of calls and of
retries. Counters are actually decreasing counters, so that they can be
used as timers. Three counters are available:
+ `calls`: number of predicate calls since execution started or since
system was reset;
+ `retries`: number of retries for predicates called since
execution started or since counters were reset;
+ `calls_and_retries`: count both on predicate calls and
retries.
These counters can be used to find out how many calls a certain
goal takes to execute. They can also be used as timers.
The code for the call counters piggybacks on the profiling
code. Therefore, activating the call counters also activates the profiling
counters.
These are the predicates that access and manipulate the call counters.
@}
*/
/**
* @defgroup Call_Counting Counting Calls
* @ingroup Profiling
* @{
*
* Predicates compiled with YAP's flag call_counting set to
* `on` update counters on the numbers of calls and of
* retries. Counters are actually decreasing counters, so that they can be
* used as timers. Three counters are available:
*
* + `calls`: number of predicate calls since execution started or since
* system was reset;
* + `retries`: number of retries for predicates called since
* execution started or since counters were reset;
* + `calls_and_retries`: count both on predicate calls and
* retries.
*
* These counters can be used to find out how many calls a certain
* goal takes to execute. They can also be used as timers.
*
* The code for the call counters piggybacks on the profiling
* code. Therefore, activating the call counters also activates the profiling
* counters.
*
* These are the predicates that access and manipulate the call counters.
* */
:- system_module( '$_callcount', [call_count/3,
call_count_data/3,
call_count_reset/0], []).
@ -74,68 +78,68 @@ These are the predicates that access and manipulate the call counters.
/** @pred call_count_data(- _Calls_, - _Retries_, - _CallsAndRetries_)
Give current call count data. The first argument gives the current value
for the _Calls_ counter, next the _Retries_ counter, and last
the _CallsAndRetries_ counter.
*/
*
*
* Give current call count data. The first argument gives the current value
* for the _Calls_ counter, next the _Retries_ counter, and last
* the _CallsAndRetries_ counter.
*
* */
call_count_data(Calls, Retries, Both) :-
'$call_count_info'(Calls, Retries, Both).
/** @pred call_count_reset
Reset call count counters. All timers are also reset.
*/
*
*
* Reset call count counters. All timers are also reset.
*
*/
call_count_reset :-
'$call_count_reset'.
/** @pred call_count(? _CallsMax_, ? _RetriesMax_, ? _CallsAndRetriesMax_)
Set call counters as timers. YAP will generate an exception
if one of the instantiated call counters decreases to 0:
+ _CallsMax_
throw the exception `call_counter` when the
counter `calls` reaches 0;
+ _RetriesMax_
throw the exception `retry_counter` when the
counter `retries` reaches 0;
+ _CallsAndRetriesMax_
throw the exception
`call_and_retry_counter` when the counter `calls_and_retries`
reaches 0.
YAP will ignore counters that are called with unbound arguments.
Next, we show a simple example of how to use call counters:
~~~~~{.prolog}
?- yap_flag(call_counting,on), [-user]. l :- l. end_of_file. yap_flag(call_counting,off).
yes
yes
?- catch((call_count(10000,_,_),l),call_counter,format("limit_exceeded.~n",[])).
limit_exceeded.
yes
~~~~~
Notice that we first compile the looping predicate `l/0` with
call_counting `on`. Next, we catch/3 to handle an
exception when `l/0` performs more than 10000 reductions.
*
*
* Set call counters as timers. YAP will generate an exception
* if one of the instantiated call counters decreases to 0:
*
* + _CallsMax_
*
* throw the exception `call_counter` when the
* counter `calls` reaches 0;
*
* + _RetriesMax_
*
* throw the exception `retry_counter` when the
* counter `retries` reaches 0;
*
* + _CallsAndRetriesMax_
*
* throw the exception
* `call_and_retry_counter` when the counter `calls_and_retries`
* reaches 0.
*
* YAP will ignore counters that are called with unbound arguments.
*
* Next, we show a simple example of how to use call counters:
*
* ~~~~~{.prolog}
* ?- yap_flag(call_counting,on), [-user]. l :- l. end_of_file. yap_flag(call_counting,off).
*
* yes
*
* yes
* ?- catch((call_count(10000,_,_),l),call_counter,format("limit_exceeded.~n",[])).
*
* limit_exceeded.
*
* yes
* ~~~~~
* Notice that we first compile the looping predicate `l/0` with
* call_counting `on`. Next, we catch/3 to handle an
* exception when `l/0` performs more than 10000 reductions.
*
*
*/
call_count(Calls, Retries, Both) :-
'$check_if_call_count_on'(Calls, CallsOn),
@ -150,7 +154,3 @@ call_count(Calls, Retries, Both) :-
%% @}
/**
@}
*/

View File

@ -88,81 +88,81 @@
*/
/** @pred forall(: _Cond_,: _Action_)
For all alternative bindings of _Cond_ _Action_ can be
proven. The example verifies that all arithmetic statements in the list
_L_ are correct. It does not say which is wrong if one proves wrong.
~~~~~{.prolog}
?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]),
Result =:= Formula).
~~~~~
*/
*
*
* For all alternative bindings of _Cond_ _Action_ can be
* proven. The example verifies that all arithmetic statements in the list
* _L_ are correct. It does not say which is wrong if one proves wrong.
*
* ~~~~~{.prolog}
* ?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]),
* Result =:= Formula).
* ~~~~~
*
*
*/
forall(Cond, Action) :- \+((Cond, \+(Action))).
/** @pred ignore(: _Goal_)
Calls _Goal_ as once/1, but succeeds, regardless of whether
`Goal` succeeded or not. Defined as:
~~~~~{.prolog}
ignore(Goal) :-
Goal, !.
ignore(_).
~~~~~
*/
*
*
* Calls _Goal_ as once/1, but succeeds, regardless of whether
* `Goal` succeeded or not. Defined as:
*
* ~~~~~{.prolog}
* ignore(Goal) :-
* Goal, !.
* ignore(_).
* ~~~~~
*
*
*/
ignore(Goal) :- (Goal->true;true).
/** @pred if(? _G_,? _H_,? _I_)
Call goal _H_ once per each solution of goal _H_. If goal
_H_ has no solutions, call goal _I_.
The built-in `if/3` is similar to `->/3`, with the difference
that it will backtrack over the test. Consider the following
small data-base:
~~~~~{.prolog}
a(1). b(a). c(x).
a(2). b(b). c(y).
~~~~~
Execution of an `if/3` query will proceed as follows:
~~~~~{.prolog}
?- if(a(X),b(Y),c(Z)).
X = 1,
Y = a ? ;
X = 1,
Y = b ? ;
X = 2,
Y = a ? ;
X = 2,
Y = b ? ;
no
~~~~~
The system will backtrack over the two solutions for `a/1` and the
two solutions for `b/1`, generating four solutions.
Cuts are allowed inside the first goal _G_, but they will only prune
over _G_.
If you want _G_ to be deterministic you should use if-then-else, as
it is both more efficient and more portable.
*/
*
* Call goal _H_ once per each solution of goal _H_. If goal
* _H_ has no solutions, call goal _I_.
*
* The built-in `if/3` is similar to `->/3`, with the difference
* that it will backtrack over the test. Consider the following
* small data-base:
*
* ~~~~~{.prolog}
* a(1). b(a). c(x).
* a(2). b(b). c(y).
* ~~~~~
*
* Execution of an `if/3` query will proceed as follows:
*
* ~~~~~{.prolog}
* ?- if(a(X),b(Y),c(Z)).
*
* X = 1,
* Y = a ? ;
*
* X = 1,
* Y = b ? ;
*
* X = 2,
* Y = a ? ;
*
* X = 2,
* Y = b ? ;
*
* no
* ~~~~~
*
* The system will backtrack over the two solutions for `a/1` and the
* two solutions for `b/1`, generating four solutions.
*
* Cuts are allowed inside the first goal _G_, but they will only prune
* over _G_.
*
* If you want _G_ to be deterministic you should use if-then-else, as
* it is both more efficient and more portable.
*
*/
if(X,Y,Z) :-
(
CP is '$last_choice_pt',
@ -174,75 +174,14 @@ if(X,Y,Z) :-
'$call'(Z,CP,if(X,Y,Z),M)
).
/** @pred call(
Closure,...,? Ai,...) is iso
Meta-call with extractpattern arguments, where _Closure_ is a closure
that is converted into a goal by appending the _Ai_ additional
arguments. YAP supports up to 10 extra arguments.
*/
/** @pred call( Closure,...,? Ai,...) is iso
*
*
* Meta-call with extra pattern arguments, where _Closure_ is a closure
* that is converted into a goal by appending the _Ai_ additional
* arguments. YAP supports up to 10 extra arguments.
*
*/
call(X,A) :- '$execute'(X,A).
call(X,A1,A2) :- '$execute'(X,A1,A2).
@ -266,11 +205,11 @@ call(X,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) :- '$execute'(X,A1,A2,A3,A4,A5,A6,A7,A8,A
call(X,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11) :- '$execute'(X,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11).
/** @pred call_cleanup(: _Goal_, : _CleanUpGoal_)
This is similar to call_cleanup/1 but with an additional
_CleanUpGoal_ which gets called after _Goal_ is finished.
*/
*
* This is similar to call_cleanup/1 but with an additional
* _CleanUpGoal_ which gets called after _Goal_ is finished.
*
*/
call_cleanup(Goal, Cleanup) :-
'$gated_call'( false , Goal,_Catcher, Cleanup) .
@ -468,32 +407,20 @@ query_to_answer(G, V, Status, Bindings) :-
%% @}
%% @{
%% @addtogroup Global_Variables
%% @{
/** @pred nb_getval(+ _Name_, - _Value_)
The nb_getval/2 predicate is a synonym for b_getval/2,
introduced for compatibility and symmetry. As most scenarios will use
a particular global variable either using non-backtrackable or
backtrackable assignment, using nb_getval/2 can be used to
document that the variable is used non-backtrackable.
*/
/** @pred nb_getval(+ _Name_,- _Value_)
The nb_getval/2 predicate is a synonym for b_getval/2, introduced for
compatibility and symmetry. As most scenarios will use a particular
global variable either using non-backtrackable or backtrackable
assignment, using nb_getval/2 can be used to document that the
variable is used non-backtrackable.
*/
*
*
* The nb_getval/2 predicate is a synonym for b_getval/2, introduced for
* compatibility and symmetry. As most scenarios will use a particular
* global variable either using non-backtrackable or backtrackable
* assignment, using nb_getval/2 can be used to document that the
* variable is used non-backtrackable.
*
*/
nb_getval(GlobalVariable, Val) :-
'__NB_getval__'(GlobalVariable, Val, Error),
(var(Error)
@ -508,31 +435,19 @@ nb_getval(GlobalVariable, Val) :-
/** @pred b_getval(+ _Name_, - _Value_)
Get the value associated with the global variable _Name_ and unify
it with _Value_. Note that this unification may further
instantiate the value of the global variable. If this is undesirable
the normal precautions (double negation or copy_term/2) must be
taken. The b_getval/2 predicate generates errors if _Name_ is not
an atom or the requested variable does not exist.
Notice that for compatibility with other systems _Name_ <em>must</em> be already associated with a term: otherwise the system will generate an error.
*/
/** @pred b_getval(+ _Name_,- _Value_)
Get the value associated with the global variable _Name_ and unify
it with _Value_. Note that this unification may further instantiate
the value of the global variable. If this is undesirable the normal
precautions (double negation or copy_term/2) must be taken. The
b_getval/2 predicate generates errors if _Name_ is not an atom or
the requested variable does not exist.
*/
*
*
* Get the value associated with the global variable _Name_ and unify
* it with _Value_. Note that this unification may further
* instantiate the value of the global variable. If this is undesirable
* the normal precautions (double negation or copy_term/2) must be
* taken. The b_getval/2 predicate generates errors if _Name_ is not
* an atom or the requested variable does not exist.
*
* Notice that for compatibility with other systems _Name_ <em>must</em> be already associated with a term: otherwise the system will generate an error.
*
*
*/
b_getval(GlobalVariable, Val) :-
'__NB_getval__'(GlobalVariable, Val, Error),
(var(Error)
@ -548,9 +463,9 @@ b_getval(GlobalVariable, Val) :-
%% @}
%% @{
%% @addtogroup YAPControl
%% @{
/* This is the break predicate,
it saves the importante data about current streams and

View File

@ -23,83 +23,80 @@
showprofres/1], []).
/**
`* @defgroup Exc_Profiling The Exception Based Tick Profiler.
* @ingroup Profiling
* @{
The count profiler works by incrementing counters at procedure entry or
backtracking. It provides exact information:
+ Profiling works for both static and dynamic predicates.
+ Currently only information on entries and retries to a predicate
are maintained. This may change in the future.
+ As an example, the following user-level program gives a list of
the most often called procedures in a program. The procedure
list_profile/0 shows all procedures, irrespective of module, and
the procedure list_profile/1 shows the procedures being used in
a specific module.
~~~~~
list_profile :-
% get number of calls for each profiled procedure
setof(D-[M:P|D1],(current_module(M),profile_data(M:P,calls,D),profile_data(M:P,retries,D1)),LP),
% output so that the most often called
% predicates will come last:
write_profile_data(LP).
list_profile(Module) :-
% get number of calls for each profiled procedure
setof(D-[Module:P|D1],(profile_data(Module:P,calls,D),profile_data(Module:P,retries,D1)),LP),
% output so that the most often called
% predicates will come last:
write_profile_data(LP).
write_profile_data([]).
write_profile_data([D-[M:P|R]|SLP]) :-
% swap the two calls if you want the most often
% called predicates first.
format('~a:~w: ~32+~t~d~12+~t~d~12+~n', [M,P,D,R]),
write_profile_data(SLP).
~~~~~
These are the current predicates to access and clear profiling data:
*/
*
* The count profiler works by incrementing counters at procedure entry or
* backtracking. It provides exact information:
*
* + Profiling works for both static and dynamic predicates.
* + Currently only information on entries and retries to a predicate
* are maintained. This may change in the future.
* + As an example, the following user-level program gives a list of
* the most often called procedures in a program. The procedure
* list_profile/0 shows all procedures, irrespective of module, and
* the procedure list_profile/1 shows the procedures being used in
* a specific module.
*
* ~~~~~
* list_profile :-
* % get number of calls for each profiled procedure
* setof(D-[M:P|D1],(current_module(M),profile_data(M:P,calls,D),profile_data(M:P,retries,D1)),LP),
* % output so that the most often called
* % predicates will come last:
* write_profile_data(LP).
*
* list_profile(Module) :-
* % get number of calls for each profiled procedure
* setof(D-[Module:P|D1],(profile_data(Module:P,calls,D),profile_data(Module:P,retries,D1)),LP),
* % output so that the most often called
* % predicates will come last:
* write_profile_data(LP).
*
* write_profile_data([]).
* write_profile_data([D-[M:P|R]|SLP]) :-
* % swap the two calls if you want the most often
* % called predicates first.
* format('~a:~w: ~32+~t~d~12+~t~d~12+~n', [M,P,D,R]),
* write_profile_data(SLP).
* ~~~~~
*
*
* These are the current predicates to access and clear profiling data:
*
*
*
**/
:- use_system_module( '$_errors', ['$do_error'/2]).
%% user:prolog_predicate_name()/
%
% hook predicate, taken from SWI-Prolog, for converting possibly explicitly-
% qualified callable terms into an atom that can be used as a label for
% describing a predicate; used e.g. on the tick profiler defined below
:- multifile(user:prolog_predicate_name/2).
/** @pred profile_data( ?Na/Ar, ?Parameter, -Data_)
Give current profile data on _Parameter_ for a predicate described
by the predicate indicator _Na/Ar_. If any of _Na/Ar_ or
_Parameter_ are unbound, backtrack through all profiled predicates
or stored parameters. Current parameters are:
+ calls
Number of times a procedure was called.
+ retries
Number of times a call to the procedure was backtracked to and retried.
+ profile_reset
Reset all profiling information.
*
*
* Give current profile data on _Parameter_ for a predicate described
* by the predicate indicator _Na/Ar_. If any of _Na/Ar_ or
* _Parameter_ are unbound, backtrack through all profiled predicates
* or stored parameters. Current parameters are:
*
* + calls
* Number of times a procedure was called.
*
* + retries
* Number of times a call to the procedure was backtracked to and retried.
*
*
* + profile_reset
* Reset all profiling information.
*
*/
:- meta_predicate profile_data(:,+,-).
@ -144,24 +141,24 @@ profile_reset :-
profile_reset.
/** @pred showprofres
Show profiling info.
*/
*
*
* Show profiling counts for all predicates.
*
*
*/
showprofres :-
showprofres(-1).
/** @pred showprofres( _N_)
Show profiling info for the top-most _N_ predicates.
The showprofres/0 and `showprofres/1` predicates call a user-defined multifile hook predicate, `user:prolog_predicate_name/2`, that can be used for converting a possibly explicitly-qualified callable term into an atom that will used when printing the profiling information.
*
* Show profiling info for the top-most _N_ predicates.
*
*
*
* The showprofres/0 and `showprofres/1` predicates call a user-defined multifile hook predicate, `user:prolog_predicate_name/2`, that can be used for converting a possibly explicitly-qualified callable term into an atom that will used when printing the profiling information.
*
*
*/
showprofres(A) :-
'$offline_showprofres',

View File

@ -36,8 +36,8 @@
/**
@defgroup Sets Collecting Solutions to a Goal
@{
@ingroup builtins
@{
When there are several solutions to a goal, if the user wants to collect all
the solutions he may be led to use the data base, because backtracking will