Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion HISTORY
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
1.1.1 -- Dec 2024
- Added basic license logging via Unix sendmail for ease of monthly billing

1.1.0 -- Jan 2024
- Changed diver function signature to return the minimum value of the objective function, as well as the values of the parameters and any derived quantities at the minimum.
- Replaced "outputSamples" with "outputSam" and "outputRaw" to allow turning off .raw and .sam output separately.
- Replaced "outputSamples" with "outputSam" and "outputRaw" to allow turning off .raw and .sam output separately.
- Added option "disableIO" for turning off creation of all output files; note that setting this true makes restarting impossible.
- Added a bit more explanation to the in-code documentation of the context pointer.
- Added note about potential gotcha with objectives including MPI calls and discard_unfit_points=true.
Expand Down
5 changes: 3 additions & 2 deletions example_c/example_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ const int max_init_attempts = 10000; // Maximu
const double max_acceptable_val = 1e6; // Maximum fitness to accept for the initial generation if init_population_strategy > 0, or any generation if discard_unfit_points = true.
const int seed = 1234567; // base seed for random number generation; non-positive or absent means seed from the system clock
const int verbose = 2; // Output verbosity: 0=only error messages, 1=basic info, 2=civ-level info, 3+=population info
const int license = 0; // License: 0=none, 1=monthly, 2=annual, 3+=academic use


//Function to be minimized. Corresponds to -ln(Likelihood).
//Plain Gaussian centred at the origin. Valid for any number of dimensions. Minimum value is the number of dimensions.
double gauss(double params[], const int param_dim, int *fcall, bool *quit, const bool validvector, void** context)
{
//Fill up the two derived parameters with some example quantities
//Fill up the two derived parameters with some example quantities
params[param_dim-2] = params[0]*params[1];
params[param_dim-1] = params[2]*params[3];

Expand All @@ -69,7 +70,7 @@ int main(int argc, char** argv)
double result = cdiver(gauss, nPar, lowerbounds, upperbounds, path, nDerived, bestFitParams, bestFitDerived, nDiscrete,
discrete, partitionDiscrete, maxciv, maxgen, NP, nF, F, Cr, lambda, current, expon, bndry, jDE, lambdajDE, convthresh,
convsteps, removeDuplicates, doBayesian, NULL, maxNodePop, Ztolerance, savecount, resume, disableIO, outputRaw,
outputSam, init_pop_strategy, discard_unfit_points, max_init_attempts, max_acceptable_val, seed, context, verbose);
outputSam, init_pop_strategy, discard_unfit_points, max_init_attempts, max_acceptable_val, seed, context, verbose, license);
//Note that prior, maxNodePop and Ztolerance are just ignored if doBayesian = false
printf("Best fit returned: %e\n", result);
for (int i = 0; i < nPar; i++) printf("Parameter %i at best fit: %e\n", i, bestFitParams[i]);
Expand Down
3 changes: 2 additions & 1 deletion example_cpp/example_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const int max_init_attempts = 10000; // Maximu
const double max_acceptable_val = 1e6; // Maximum fitness to accept for the initial generation if init_population_strategy > 0, or any generation if discard_unfit_points = true.
const int seed = -1; // base seed for random number generation; non-positive or absent means seed from the system clock
const int verbose = 1; // Output verbosity: 0=only error messages, 1=basic info, 2=civ-level info, 3+=population info
const int license = 0; // License: 0=none, 1=monthly, 2=annual, 3+=academic use

const double Pi = 3.14159265359; // Tasty
typedef double (*likelihood)(double[], const int, int&, bool&, const bool); // This example's internal standard likelihood function signature
Expand Down Expand Up @@ -122,7 +123,7 @@ int main(int argc, char** argv)
double result = cdiver(objective, nPar, lowerbounds, upperbounds, path, nDerived, bestFitParams, bestFitDerived, nDiscrete,
discrete, partitionDiscrete, maxciv, maxgen, NP, nF, F, Cr, lambda, current, expon, bndry, jDE, lambdajDE, convthresh,
convsteps, removeDuplicates, doBayesian, flatprior, maxNodePop, Ztolerance, savecount, resume, disableIO, outputRaw,
outputSam, init_pop_strategy, discard_unfit_points, max_init_attempts, max_acceptable_val, seed, context, verbose);
outputSam, init_pop_strategy, discard_unfit_points, max_init_attempts, max_acceptable_val, seed, context, verbose, license);
//Note that prior, maxNodePop and Ztolerance are just ignored if doBayesian = false

std::cout << "Best fit returned: " << result << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion include/diver.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
extern double cdiver(double (*)(double[], const int, int*, bool*, const bool, void**), int, const double[], const double[],
const char[], int, double[], double[], int, const int[], bool, int, int, int, int, const double[], double,
double, bool, bool, int, bool, bool, double, int, bool, bool, double(*)(const double[], const int, void**),
double, double, int, bool, bool, bool, bool, int, bool, int, double, int, void**, int);
double, double, int, bool, bool, bool, bool, int, bool, int, double, int, void**, int, int);
2 changes: 1 addition & 1 deletion include/diver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
extern "C" double cdiver(double (*)(double[], const int, int&, bool&, const bool, void*&), int, const double[], const double[],
const char[], int, double[], double[], int, const int[], bool, int, int, int, int, const double[], double,
double, bool, bool, int, bool, bool, double, int, bool, bool, double(*)(const double[], const int, void*&),
double, double, int, bool, bool, bool, bool, int, bool, int, double, int, void*&, int);
double, double, int, bool, bool, bool, bool, int, bool, int, double, int, void*&, int, int);
18 changes: 11 additions & 7 deletions src/cwrapper.f90
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
! int max_initialisation_attempts,
! double max_acceptable_value,
! void*& context,
! int verbose)
! int verbose,
! int license)

! double minusloglike(double params[],
! const int param_dim,
Expand Down Expand Up @@ -112,7 +113,8 @@ function cdiver(minusloglike_in, &
max_acceptable_value, &
seed, &
context, &
verbose &
verbose, &
license &
) bind(c)

use iso_c_binding, only: c_int, c_bool, c_double, c_char, c_funptr, c_ptr, C_NULL_CHAR
Expand All @@ -124,7 +126,7 @@ function cdiver(minusloglike_in, &
type(c_funptr), intent(in), value :: minusloglike_in, prior_in
type(c_ptr), intent(inout) :: context
integer(c_int), intent(in), value :: nPar, nDerived, nDiscrete, maxciv, maxgen, NP, nF, bndry, convsteps, savecount, verbose
integer(c_int), intent(in), value :: init_population_strategy, max_initialisation_attempts, seed
integer(c_int), intent(in), value :: init_population_strategy, max_initialisation_attempts, seed, license
integer(c_int), intent(in), target :: discrete(nDiscrete)
logical(c_bool), intent(in), value :: partitionDiscrete, current, expon, jDE, lambdajDE, removeDuplicates, doBayesian, resume
logical(c_bool), intent(in), value :: disableIO, outputRaw, outputSam, discard_unfit_points
Expand Down Expand Up @@ -183,7 +185,7 @@ function cdiver(minusloglike_in, &
discrete=discrete_f, &
partitionDiscrete=logical(partitionDiscrete), &
maxciv=maxciv, &
maxgen=maxgen, &
maxgen=maxgen, &
NP=NP, &
F=F, &
Cr=Cr, &
Expand All @@ -210,7 +212,8 @@ function cdiver(minusloglike_in, &
max_acceptable_value=max_acceptable_value, &
seed=seed, &
context=context, &
verbose=verbose)
verbose=verbose, &
license=license)

else

Expand All @@ -225,7 +228,7 @@ function cdiver(minusloglike_in, &
discrete=discrete_f, &
partitionDiscrete=logical(partitionDiscrete), &
maxciv=maxciv, &
maxgen=maxgen, &
maxgen=maxgen, &
NP=NP, &
F=F, &
Cr=Cr, &
Expand All @@ -252,7 +255,8 @@ function cdiver(minusloglike_in, &
max_acceptable_value=max_acceptable_value, &
seed=seed, &
context=context, &
verbose=verbose)
verbose=verbose, &
license=license)

endif

Expand Down
10 changes: 8 additions & 2 deletions src/de.f90
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ function diver(func, &
max_acceptable_value, &
seed, &
context, &
verbose)
verbose, &
license)

use iso_c_binding, only: c_ptr

Expand Down Expand Up @@ -103,11 +104,12 @@ function diver(func, &
logical, intent(in), optional :: outputSam !output rounded and derived parameter samples to a .sam file
integer, intent(in), optional :: seed !base seed for random number generation; non-positive or absent means seed from the system clock
integer, intent(in), optional :: verbose !output verbosity: 0=only error messages, 1=basic info, 2=civ-level info, 3+=population info
integer, intent(in), optional :: license !license: 0=none, 1=monthly, 2=annual, 3+=academic use
type(c_ptr), intent(inout), optional :: context !context pointer, used for passing info from the caller to likelihood/prior. Use this for passing a pointer
!to a callback function that can be used for I/O, harvesting samples in situ, printing or whatever else you like.

real(dp), dimension(size(lowerbounds)) :: params !parameters at the best-fit point

type(codeparams) :: run_params !carries the code parameters

type(population), target :: X, BF !population of target vectors, best-fit vector
Expand All @@ -133,6 +135,10 @@ function diver(func, &

call cpu_time(t1)


!Log license type
call log_license(license=license)

#ifdef MPI
call MPI_Initialized(mpi_already_init, ierror) !check if MPI has been initialized by the calling routine
if (.not. mpi_already_init) call MPI_Init(ierror)
Expand Down
24 changes: 21 additions & 3 deletions src/deutils.f90
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module deutils
implicit none

private
public int_to_string, quit_de, quit_all_processes, roundvector, newBFs, update_acceptance, sync
public int_to_string, quit_de, quit_all_processes, roundvector, newBFs, update_acceptance, sync, log_license

contains

Expand Down Expand Up @@ -89,7 +89,7 @@ subroutine update_acceptance(accept, fcall, totaccept, totfcall, verbose, NP)
integer, intent(IN) :: accept, fcall, NP
integer, intent(OUT) :: totaccept, totfcall
integer :: ierror

#ifdef MPI
call MPI_Allreduce(accept, totaccept, 1, MPI_integer, MPI_sum, MPI_COMM_WORLD, ierror)
call MPI_Allreduce(fcall, totfcall, 1, MPI_integer, MPI_sum, MPI_COMM_WORLD, ierror)
Expand All @@ -107,7 +107,7 @@ end subroutine update_acceptance
logical function sync(flag)
logical, intent(INOUT) :: flag
integer :: ierror

sync = flag
#ifdef MPI
call MPI_AllReduce(flag, sync, 1, MPI_LOGICAL, MPI_LOR, MPI_COMM_WORLD, ierror)
Expand All @@ -116,4 +116,22 @@ logical function sync(flag)
end function sync


!Logs usage according to license type
subroutine log_license(license)
integer, intent(IN), optional :: license
integer :: istat
character :: cmd*100

! Log license only for unlicensed (license not specified or=0) or monthly (=1) use; skip for annual (=2) and academic licenses (=3)
if (.not. present(license) .or. (present (license) .and. license .lt. 2)) then
!Check that user actually has sendmail
call execute_command_line('command -v sendmail > /dev/null 2>&1', exitstat=istat)
if (istat .eq. 0) then
!Log usage
call execute_command_line('printf "Subject: POLICY0001 Diver license log\n\nuser: ' &
// '$(whoami)\nhost: $(hostname)" | sendmail -v diver.optimisation@gmail.com', wait=.false.)
endif
endif
end subroutine log_license

end module deutils
2 changes: 1 addition & 1 deletion src/init.f90
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module init
private
public param_assign, initialize, init_all_random_seeds

character (len=*), parameter :: version_number = "1.1.0"
character (len=*), parameter :: version_number = "1.1.1"

contains

Expand Down