Skip to content

Commit

Permalink
Update cp-opt implementation to be consistent with latest TTB
Browse files Browse the repository at this point in the history
  • Loading branch information
etphipp committed Jul 25, 2024
1 parent 19b8ba2 commit 5a1528e
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 88 deletions.
10 changes: 5 additions & 5 deletions data/aminoacid-cpopt-lbfgsb.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@
"cp-opt":
{
"method": "lbfgsb",
"maxiters": 20,
"tol": 1e-4
"maxiters": 200,
"gtol": 1e-4
},
"testing":
{
"final-fit":
{
"value": 0.98,
"absolute-tolerance": 0.1
"value": 0.99,
"absolute-tolerance": 0.05
},
"iterations":
{
"value": 19,
"value": 39,
"absolute-tolerance": 2
}
}
Expand Down
2 changes: 1 addition & 1 deletion data/aminoacid-cpopt-rol-hess.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"iterations":
{
"value": 17,
"value": 19,
"absolute-tolerance": 3
}
}
Expand Down
10 changes: 5 additions & 5 deletions data/aminoacid-cpopt-rol.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@
"cp-opt":
{
"method": "rol",
"maxiters": 20,
"tol": 1e-4
"maxiters": 200,
"gtol": 1e-4
},
"testing":
{
"final-fit":
{
"value": 0.98,
"absolute-tolerance": 0.1
"value": 0.99,
"absolute-tolerance": 0.05
},
"iterations":
{
"value": 20,
"value": 63,
"absolute-tolerance": 2
}
}
Expand Down
10 changes: 5 additions & 5 deletions data/aminoacid-gcpopt-rol.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@
"gcp-opt":
{
"method": "rol",
"maxiters": 20,
"tol": 1e-4,
"maxiters": 200,
"gtol": 1e-4,
"type": "gaussian",
"fit": true
},
"testing":
{
"final-fit":
{
"value": 0.98,
"absolute-tolerance": 0.1
"value": 0.99,
"absolute-tolerance": 0.05
},
"iterations":
{
"value": 20,
"value": 80,
"absolute-tolerance": 2
}
}
Expand Down
4 changes: 2 additions & 2 deletions data/rol_truncated_cg.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<ParameterList name="ROL">

<ParameterList name="Status Test">
<Parameter name="Gradient Tolerance" type="double" value="1.e-6" />
<Parameter name="Gradient Tolerance" type="double" value="1.e-4" />
<Parameter name="Step Tolerance" type="double" value="1.e-12" />
<Parameter name="Iteration Limit" type="int" value="20" />
<Parameter name="Iteration Limit" type="int" value="200" />
</ParameterList>

<ParameterList name="General">
Expand Down
6 changes: 3 additions & 3 deletions python/src/Genten_Pybind11_classes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ void pygenten_algparams(py::module &m){
cl.def_readwrite("lower", &Genten::AlgParams::lower);
cl.def_readwrite("upper", &Genten::AlgParams::upper);
cl.def_readwrite("rolfilename", &Genten::AlgParams::rolfilename);
cl.def_readwrite("factr", &Genten::AlgParams::factr);
cl.def_readwrite("pgtol", &Genten::AlgParams::pgtol);
cl.def_readwrite("ftol", &Genten::AlgParams::ftol);
cl.def_readwrite("gtol", &Genten::AlgParams::gtol);
cl.def_readwrite("memory", &Genten::AlgParams::memory);
cl.def_readwrite("max_total_iters", &Genten::AlgParams::max_total_iters);
cl.def_readwrite("sub_iters", &Genten::AlgParams::sub_iters);
cl.def_readwrite("hess_vec_method", &Genten::AlgParams::hess_vec_method);
cl.def_readwrite("hess_vec_tensor_method", &Genten::AlgParams::hess_vec_tensor_method);
cl.def_readwrite("hess_vec_prec_method", &Genten::AlgParams::hess_vec_prec_method);
Expand Down
30 changes: 15 additions & 15 deletions src/Genten_AlgParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ Genten::AlgParams::AlgParams() :
lower(-DOUBLE_MAX),
upper(DOUBLE_MAX),
rolfilename(""),
factr(1e7),
pgtol(1e-5),
ftol(1e-10),
gtol(1e-5),
memory(5),
max_total_iters(5000),
sub_iters(10),
hess_vec_method(Hess_Vec_Method::default_type),
hess_vec_tensor_method(Hess_Vec_Tensor_Method::default_type),
hess_vec_prec_method(Hess_Vec_Prec_Method::default_type),
Expand Down Expand Up @@ -211,10 +211,10 @@ void Genten::AlgParams::parse(std::vector<std::string>& args)
lower = parse_ttb_real(args, "--lower", lower, -DOUBLE_MAX, DOUBLE_MAX);
upper = parse_ttb_real(args, "--upper", upper, -DOUBLE_MAX, DOUBLE_MAX);
rolfilename = parse_string(args, "--rol", rolfilename.c_str());
factr = parse_ttb_real(args, "--factr", factr, 0.0, DOUBLE_MAX);
pgtol = parse_ttb_real(args, "--pgtol", pgtol, 0.0, DOUBLE_MAX);
ftol = parse_ttb_real(args, "--ftol", ftol, 0.0, DOUBLE_MAX);
gtol = parse_ttb_real(args, "--gtol", gtol, 0.0, DOUBLE_MAX);
memory = parse_ttb_indx(args, "--memory", memory, 0, INT_MAX);
max_total_iters = parse_ttb_indx(args, "--total-iters", max_total_iters, 0, INT_MAX);
sub_iters = parse_ttb_indx(args, "-sub-iters", sub_iters, 1, INT_MAX);
hess_vec_method = parse_ttb_enum(args, "--hess-vec", hess_vec_method,
Genten::Hess_Vec_Method::num_types,
Genten::Hess_Vec_Method::types,
Expand Down Expand Up @@ -397,10 +397,10 @@ void Genten::AlgParams::parse(const ptree& input)
parse_ptree_enum<Opt_Method>(cpopt_input, "method", opt_method);
parse_generic_solver_params(cpopt_input);
parse_ptree_value(cpopt_input, "rol-file", rolfilename);
parse_ptree_value(cpopt_input, "factr", factr, 0.0, DOUBLE_MAX);
parse_ptree_value(cpopt_input, "pgtol", pgtol, 0.0, DOUBLE_MAX);
parse_ptree_value(cpopt_input, "ftol", ftol, 0.0, DOUBLE_MAX);
parse_ptree_value(cpopt_input, "gtol", gtol, 0.0, DOUBLE_MAX);
parse_ptree_value(cpopt_input, "memory", memory, 0, INT_MAX);
parse_ptree_value(cpopt_input, "total-iters", max_total_iters, 0, INT_MAX);
parse_ptree_value(cpopt_input, "sub-iters", sub_iters, 1, INT_MAX);
parse_mttkrp(cpopt_input);
};

Expand Down Expand Up @@ -640,10 +640,10 @@ void Genten::AlgParams::print_help(std::ostream& out)
out << " --lower <float> lower bound of factorization" << std::endl;
out << " --upper <float> upper bound of factorization" << std::endl;
out << " --rol <string> path to ROL optimization settings file for CP-Opt method" << std::endl;
out << " --factr <float> factr parameter for L-BFGS-B" << std::endl;
out << " --pgtol <float> pgtol parameter for L-BFGS-B" << std::endl;
out << " --ftol <float> relative residual reduction tolerance for L-BFGS-B" << std::endl;
out << " --gtol <float> gradient tolerance for L-BFGS-B" << std::endl;
out << " --memory <int> memory parameter for L-BFGS-B" << std::endl;
out << " --total-iters <int> max total iterations for L-BFGS-B" << std::endl;
out << " --sub-iters <int> max inner iterations for L-BFGS-B" << std::endl;
out << " --hess-vec <method> Hessian-vector product method: ";
for (unsigned i=0; i<Genten::Hess_Vec_Method::num_types; ++i) {
out << Genten::Hess_Vec_Method::names[i];
Expand Down Expand Up @@ -843,10 +843,10 @@ void Genten::AlgParams::print(std::ostream& out) const
out << " lower = " << lower << std::endl;
out << " upper = " << upper << std::endl;
out << " rol = " << rolfilename << std::endl;
out << " factr = " << factr << std::endl;
out << " pgtol = " << pgtol << std::endl;
out << " ftol = " << ftol << std::endl;
out << " gtol = " << gtol << std::endl;
out << " memory = " << memory << std::endl;
out << " total-iters = " << max_total_iters << std::endl;
out << " sub-iters = " << sub_iters << std::endl;
out << " hess-vec = " << Genten::Hess_Vec_Method::names[hess_vec_method] << std::endl;
out << " hess-vec-tensor = " << Genten::Hess_Vec_Tensor_Method::names[hess_vec_tensor_method] << std::endl;
out << " hess-vec-prec = " << Genten::Hess_Vec_Prec_Method::names[hess_vec_prec_method] << std::endl;
Expand Down
6 changes: 3 additions & 3 deletions src/Genten_AlgParams.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ namespace Genten {
ttb_real lower; // Lower bound of factorization
ttb_real upper; // Upper bound of factorization
std::string rolfilename; // Filename for ROL solver options
ttb_real factr; // factr parameter for L-BFGS-B
ttb_real pgtol; // pgtol parameter for L-BFGS-B
ttb_real ftol; // residual tolerance for L-BFGS-B
ttb_real gtol; // gradient tolerance for L-BFGS-B
ttb_indx memory; // memory parameter for L-BFGS-B
ttb_indx max_total_iters; // maximum total iterations for L-BFGS-B
ttb_indx sub_iters; // inner iterations for L-BFGS-B
Hess_Vec_Method::type hess_vec_method; // Hessian-vector product method
Hess_Vec_Tensor_Method::type hess_vec_tensor_method; // Hessian-vector product method for tensor-only term
Hess_Vec_Prec_Method::type hess_vec_prec_method; // Preconditoning method for hessian-vector product
Expand Down
42 changes: 24 additions & 18 deletions src/Genten_CP_Model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ namespace Genten {
void update(const ktensor_type& M);

// Compute value of the objective function:
// 0.5 * ||X-M||^2 = 0.5* (||X||^2 + ||M||^2) - <X,M>
// ||X-M||^2/||X||^2 = (||X||^2 + ||M||^2 - 2*<X,M>)/||X||^2
ttb_real value(const ktensor_type& M) const;

// Compute gradient of objective function:
// G[m] = -X_(m)*Z_m*diag(w) + A_m*[diag(w)*Z_m^T*Z_m*diag(w)]
// G[m] = 2*(-X_(m)*Z_m*diag(w) + A_m*[diag(w)*Z_m^T*Z_m*diag(w)])/||X||^2
void gradient(ktensor_type& G, const ktensor_type& M) const;

// Compute value and gradient together, allowing reuse of some information
Expand Down Expand Up @@ -187,11 +187,11 @@ namespace Genten {
// compute MTTKRP in update()
const ttb_real ip = innerprod(X,M_overlap);

ttb_real f = ttb_real(0.5)*(nrm_X_sq + nrm_M_sq) - ip;
ttb_real f = (nrm_X_sq + nrm_M_sq - ttb_real(2.0)*ip) / nrm_X_sq;

if (algParams.penalty != ttb_real(0.0)) {
for (ttb_indx n=0; n<nd; ++n)
f += (algParams.penalty / ttb_real(2.0)) * M[n].normFsq();
f += algParams.penalty * M[n].normFsq() / nrm_X_sq;
}

return f;
Expand All @@ -208,12 +208,12 @@ namespace Genten {
dku->doExport(G, G_overlap);

const ttb_indx nd = M.ndims();
for (ttb_indx n=0; n<nd; ++n)
G[n].gemm(false, false, ttb_real(1.0), M[n], hada[n], ttb_real(-1.0));
for (ttb_indx n=0; n<nd; ++n) {
G[n].gemm(false, false, ttb_real(2.0)/nrm_X_sq, M[n], hada[n],
-ttb_real(2.0)/nrm_X_sq);

if (algParams.penalty != ttb_real(0.0)) {
for (ttb_indx n=0; n<nd; ++n)
G[n].plus(M[n], algParams.penalty);
if (algParams.penalty != ttb_real(0.0))
G[n].plus(M[n], algParams.penalty*ttb_real(2.0)/nrm_X_sq);
}
}

Expand All @@ -236,16 +236,16 @@ namespace Genten {
const ttb_real nrm_M_sq = gram[nd-1].innerprod(hada[nd-1], ones);

// Compute objective
ttb_real f = ttb_real(0.5)*(nrm_X_sq + nrm_M_sq) - ip;
ttb_real f = (nrm_X_sq + nrm_M_sq - ttb_real(2.0)*ip) / nrm_X_sq;

// Compute gradient
for (ttb_indx n=0; n<nd; ++n)
G[n].gemm(false, false, ttb_real(1.0), M[n], hada[n], ttb_real(-1.0));
for (ttb_indx n=0; n<nd; ++n) {
G[n].gemm(false, false, ttb_real(2.0)/nrm_X_sq, M[n], hada[n],
-ttb_real(2.0)/nrm_X_sq);

if (algParams.penalty != ttb_real(0.0)) {
for (ttb_indx n=0; n<nd; ++n) {
f += (algParams.penalty / ttb_real(2.0)) * M[n].normFsq();
G[n].plus(M[n], algParams.penalty);
if (algParams.penalty != ttb_real(0.0)) {
f += algParams.penalty * M[n].normFsq() / nrm_X_sq;
G[n].plus(M[n], algParams.penalty*ttb_real(2.0)/nrm_X_sq);
}
}

Expand All @@ -257,21 +257,27 @@ namespace Genten {
CP_Model<Tensor>::
hess_vec(ktensor_type& U, const ktensor_type& M, const ktensor_type& V)
{
const ttb_indx nd = M.ndims();

if (algParams.hess_vec_method == Hess_Vec_Method::Full) {
if (dku->overlapAliasesArg()) {
V_overlap = dku->createOverlapKtensor(V);
U_overlap = dku->createOverlapKtensor(U);
}
Genten::hess_vec(X, M, V, U, M_overlap, V_overlap, U_overlap, *dku,
algParams);
for (ttb_indx n=0; n<nd; ++n)
U[n].times(ttb_real(2.0)/nrm_X_sq);
}
else if (algParams.hess_vec_method == Hess_Vec_Method::GaussNewton)
else if (algParams.hess_vec_method == Hess_Vec_Method::GaussNewton) {
gauss_newton_hess_vec(X, M, V, U, algParams);
for (ttb_indx n=0; n<nd; ++n)
U[n].times(ttb_real(2.0)/nrm_X_sq);
}
else if (algParams.hess_vec_method == Hess_Vec_Method::FiniteDifference)
{
const ttb_real h = 1.0e-7;
const ttb_indx nc = M.ncomponents();
const ttb_indx nd = M.ndims();

KtensorT<exec_space> Mp(nc, nd, X.size(), M.getProcessorMap()),
Up(nc, nd, X.size(), U.getProcessorMap());
Expand Down
34 changes: 17 additions & 17 deletions src/Genten_JSON_Schema.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,14 @@ static nlohmann::json json_schema = R"(
"type": "string",
"default": ""
},
"factr": {
"description": "factr parameter for L-BFGS-B",
"ftol": {
"description": "relative residual reduction tolerance for L-BFGS-B",
"type": "number",
"minimum": 0.0,
"default": 1e7
"default": 1e-10
},
"pgtol": {
"description": "pgtol parameter for L-BFGS-B",
"gtol": {
"description": "gradient tolerance for L-BFGS-B",
"type": "number",
"minimum": 0.0,
"default": 1e-5
Expand All @@ -414,11 +414,11 @@ static nlohmann::json json_schema = R"(
"minimum": 1,
"default": 5
},
"total-iters": {
"description": "Max total iterations for L-BFGS-B",
"sub-iters": {
"description": "Max number of inner iterations for L-BFGS-B",
"type": "integer",
"minimum": 0,
"default": 5000
"default": 10
},
"hess-vec": {
"description": "Hessian-vector product method",
Expand Down Expand Up @@ -490,14 +490,14 @@ static nlohmann::json json_schema = R"(
"type": "string",
"default": ""
},
"factr": {
"description": "factr parameter for L-BFGS-B",
"ftol": {
"description": "relative residual reduction tolerance for L-BFGS-B",
"type": "number",
"minimum": 0.0,
"default": 1e7
"default": 1e-10
},
"pgtol": {
"description": "pgtol parameter for L-BFGS-B",
"gtol": {
"description": "gradient tolerance for L-BFGS-B",
"type": "number",
"minimum": 0.0,
"default": 1e-5
Expand All @@ -508,12 +508,12 @@ static nlohmann::json json_schema = R"(
"minimum": 1,
"default": 5
},
"total-iters": {
"description": "Max total iterations for L-BFGS-B",
"sub-iters": {
"description": "Max number of inner iterations for L-BFGS-B",
"type": "integer",
"minimum": 0,
"default": 5000
},
"default": 10
},
"fit": {
"description": "Compute fit metric",
"type": "boolean",
Expand Down
10 changes: 5 additions & 5 deletions src/lbfgsb/Genten_CP_Opt_Lbfgsb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@ namespace Genten {

// L-BFGS-B data
integer m = algParams.memory;
double factr = algParams.factr;
double pgtol = algParams.pgtol;
double factr = algParams.ftol/MACHINE_EPSILON;
double pgtol = algParams.gtol;
ttb_indx iterMax = algParams.maxiters;
ttb_indx total_iterMax = algParams.max_total_iters;
ttb_indx total_iterMax = iterMax * algParams.sub_iters;
std::vector<integer> iwa(3*n);
std::vector<double> wa(2*m*n + 5*n + 11*m*m + 8*m);
integer task = START;
Expand Down Expand Up @@ -283,7 +283,7 @@ namespace Genten {
history.resize(iters+1);
history[iters].iteration = iters;
history[iters].residual = f;
history[iters].fit = ttb_real(1.0) - f / (ttb_real(0.5)*nrm_X_sq);
history[iters].fit = ttb_real(1.0) - f;
history[iters].grad_norm = nrmg;
history[iters].cum_time = time;

Expand Down Expand Up @@ -346,7 +346,7 @@ namespace Genten {
std::cout << "Reached maximum number of total iterations." << std::endl;
else
std::cout << Impl::findTaskString(task) << std::endl;
const ttb_real fit = ttb_real(1.0) - f / (ttb_real(0.5)*nrm_X_sq);
const ttb_real fit = ttb_real(1.0) - f;
std::cout << "Final fit = " << std::setprecision(3) << std::scientific
<< fit << std::endl;
std::cout << "Total time = " << std::setprecision(2) << std::scientific
Expand Down
Loading

0 comments on commit 5a1528e

Please sign in to comment.