From cf3b5368bf6d5d03a7fdbf680a7a063fdfb2a19c Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 4 May 2024 18:24:41 +0000 Subject: [PATCH 01/24] MAINT: Silence -Wsign-compare In any case it is better to be consistent here --- src/qpsolver/feasibility_bounded.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/qpsolver/feasibility_bounded.hpp b/src/qpsolver/feasibility_bounded.hpp index 4a92c813e1..f28f5c5ca0 100644 --- a/src/qpsolver/feasibility_bounded.hpp +++ b/src/qpsolver/feasibility_bounded.hpp @@ -18,16 +18,16 @@ static void computeStartingPointBounded(Instance& instance, L.resize(instance.num_var * instance.num_var); // compute cholesky factorization of Q - for (size_t col = 0; col < (size_t)instance.num_var; col++) { - for (size_t idx = instance.Q.mat.start[col]; idx < (size_t)instance.Q.mat.start[col+1]; idx++) { + for (HighsInt col = 0; col < static_cast(instance.num_var); col++) { + for (HighsInt idx = instance.Q.mat.start[col]; idx < static_cast(instance.Q.mat.start[col+1]); idx++) { double sum = 0; - size_t row = instance.Q.mat.index[idx]; + HighsInt row = instance.Q.mat.index[idx]; if (row == col) { - for (size_t k = 0; k < row; k++) + for (HighsInt k = 0; k < row; k++) sum += L[k * instance.num_var + row] * L[k * instance.num_var + row]; L[row * instance.num_var + row] = sqrt(instance.Q.mat.value[idx] - sum); } else { - for (size_t k = 0; k < row; k++) + for (HighsInt k = 0; k < row; k++) sum += (L[k * instance.num_var + col] * L[k * instance.num_var + row]); L[row * instance.num_var + col] = (instance.Q.mat.value[idx] - sum) / L[row * instance.num_var + row]; From cb2556de8a4b5f7b385a7cc056ae8617ce3c81be Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 4 May 2024 18:36:12 +0000 Subject: [PATCH 02/24] MAINT: Silence -Wmaybe-uninitialized --- src/pdlp/cupdlp/cupdlp_scaling_cuda.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pdlp/cupdlp/cupdlp_scaling_cuda.c b/src/pdlp/cupdlp/cupdlp_scaling_cuda.c index c9b68e0159..f5ae4def66 100644 --- a/src/pdlp/cupdlp/cupdlp_scaling_cuda.c +++ b/src/pdlp/cupdlp/cupdlp_scaling_cuda.c @@ -54,8 +54,8 @@ cupdlp_retcode cupdlp_ruiz_scaling_cuda(CUPDLPcsc *csc, cupdlp_float *cost, cupdlp_int nRows = csc->nRows; cupdlp_int nCols = csc->nCols; - cupdlp_float *current_col_scaling; // for variable - cupdlp_float *current_row_scaling; // for constraint + cupdlp_float *current_col_scaling = NULL; // for variable + cupdlp_float *current_row_scaling = NULL; // for constraint CUPDLP_INIT_ZERO_DOUBLE(current_col_scaling, nCols); CUPDLP_INIT_ZERO_DOUBLE(current_row_scaling, nRows); @@ -128,8 +128,8 @@ cupdlp_retcode cupdlp_l2norm_scaling_cuda(CUPDLPcsc *csc, cupdlp_float *cost, cupdlp_int nRows = csc->nRows; cupdlp_int nCols = csc->nCols; - cupdlp_float *current_col_scaling; // for variable - cupdlp_float *current_row_scaling; // for constraint + cupdlp_float *current_col_scaling = NULL; // for variable + cupdlp_float *current_row_scaling = NULL; // for constraint CUPDLP_INIT_ZERO_DOUBLE(current_col_scaling, nCols); CUPDLP_INIT_ZERO_DOUBLE(current_row_scaling, nRows); @@ -179,8 +179,8 @@ cupdlp_retcode cupdlp_pc_scaling_cuda(CUPDLPcsc *csc, cupdlp_float *cost, cupdlp_int nCols = csc->nCols; cupdlp_float alpha = scaling->PcAlpha; - cupdlp_float *current_col_scaling; // for variable - cupdlp_float *current_row_scaling; // for constraint + cupdlp_float *current_col_scaling = NULL; // for variable + cupdlp_float *current_row_scaling = NULL; // for constraint CUPDLP_INIT_ZERO_DOUBLE(current_col_scaling, nCols); CUPDLP_INIT_ZERO_DOUBLE(current_row_scaling, nRows); From d226a6d69e328d689bb84f8927854f6815be71a5 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 4 May 2024 18:42:40 +0000 Subject: [PATCH 03/24] MAINT: Silence -Wcomment --- src/pdlp/CupdlpWrapper.h | 8 +- src/pdlp/cupdlp/glbopts.h | 154 +++++++++++++++++++------------------- 2 files changed, 81 insertions(+), 81 deletions(-) diff --git a/src/pdlp/CupdlpWrapper.h b/src/pdlp/CupdlpWrapper.h index 04444ccb7e..4444c955ce 100644 --- a/src/pdlp/CupdlpWrapper.h +++ b/src/pdlp/CupdlpWrapper.h @@ -46,10 +46,10 @@ typedef enum CONSTRAINT_TYPE { EQ = 0, LEQ, GEQ, BOUND } constraint_type; #define cupdlp_copy_vec(dst, src, type, size) \ memcpy(dst, src, sizeof(type) * (size)) -//#define cupdlp_init_csc_cpu(var, size) \ -// {\ -// (var) = (CUPDLPcsc*)malloc((size) * sizeof(CUPDLPcsc));\ -// } +/* #define cupdlp_init_csc_cpu(var, size) \ */ +/* {\ */ +/* (var) = (CUPDLPcsc*)malloc((size) * sizeof(CUPDLPcsc));\ */ +/* } */ cupdlp_retcode problem_create(CUPDLPproblem** prob); // cupdlp_retcode csc_create(CUPDLPcsc **csc_cpu); diff --git a/src/pdlp/cupdlp/glbopts.h b/src/pdlp/cupdlp/glbopts.h index ff6599c7ca..756d34be19 100644 --- a/src/pdlp/cupdlp/glbopts.h +++ b/src/pdlp/cupdlp/glbopts.h @@ -1,11 +1,11 @@ #ifndef GLB_H_GUARD #define GLB_H_GUARD -// #ifndef CUPDLP_CPU -// #include // cublas -// #include // cudaMalloc, cudaMemcpy, etc. -// #include // cusparseSpMV -// #endif +/* #ifndef CUPDLP_CPU */ +/* #include cublas */ +/* #include cudaMalloc, cudaMemcpy, etc. */ +/* #include cusparseSpMV */ +/* #endif */ #ifdef __cplusplus @@ -61,69 +61,69 @@ extern "C" { #define _cupdlp_realloc realloc #endif -// for cuda +/* for cuda */ #ifndef CUPDLP_CPU -// #define CUPDLP_FREE_VEC(x) \ -// { \ -// cudaFree(x); \ -// x = cupdlp_NULL; \ -// } - -// #define CUPDLP_COPY_VEC(dst, src, type, size) \ -// cudaMemcpy(dst, src, sizeof(type) * (size), cudaMemcpyDefault) - -// #define CUPDLP_INIT_VEC(var, size) \ -// { \ -// cusparseStatus_t status = \ -// cudaMalloc((void **)&var, (size) * sizeof(typeof(*var))); \ -// if (status != CUSPARSE_STATUS_SUCCESS) { \ -// printf("CUSPARSE API failed at line %d with error: %s (%d)\n", __LINE__, \ -// cusparseGetErrorString(status), status); \ -// goto exit_cleanup; \ -// } \ -// } -// #define CUPDLP_INIT_ZERO_VEC(var, size) \ -// { \ -// cusparseStatus_t status = \ -// cudaMalloc((void **)&var, (size) * sizeof(typeof(*var))); \ -// if (status != CUSPARSE_STATUS_SUCCESS) { \ -// printf("CUSPARSE API failed at line %d with error: %s (%d)\n", __LINE__, \ -// cusparseGetErrorString(status), status); \ -// goto exit_cleanup; \ -// } \ -// status = cudaMemset(var, 0, (size) * sizeof(typeof(*var))); \ -// if (status != CUSPARSE_STATUS_SUCCESS) { \ -// printf("CUSPARSE API failed at line %d with error: %s (%d)\n", __LINE__, \ -// cusparseGetErrorString(status), status); \ -// goto exit_cleanup; \ -// } \ -// } -// #define CUPDLP_ZERO_VEC(var, type, size) \ -// cudaMemset(var, 0, sizeof(type) * (size)) +/* #define CUPDLP_FREE_VEC(x) \ */ +/* { \ */ +/* cudaFree(x); \ */ +/* x = cupdlp_NULL; \ */ +/* } */ + +/* #define CUPDLP_COPY_VEC(dst, src, type, size) \ */ +/* cudaMemcpy(dst, src, sizeof(type) * (size), cudaMemcpyDefault) */ + +/* #define CUPDLP_INIT_VEC(var, size) \ */ +/* { \ */ +/* cusparseStatus_t status = \ */ +/* cudaMalloc((void **)&var, (size) * sizeof(typeof(*var))); \ */ +/* if (status != CUSPARSE_STATUS_SUCCESS) { \ */ +/* printf("CUSPARSE API failed at line %d with error: %s (%d)\n", __LINE__, \ */ +/* cusparseGetErrorString(status), status); \ */ +/* goto exit_cleanup; \ */ +/* } \ */ +/* } */ +/* #define CUPDLP_INIT_ZERO_VEC(var, size) \ */ +/* { \ */ +/* cusparseStatus_t status = \ */ +/* cudaMalloc((void **)&var, (size) * sizeof(typeof(*var))); \ */ +/* if (status != CUSPARSE_STATUS_SUCCESS) { \ */ +/* printf("CUSPARSE API failed at line %d with error: %s (%d)\n", __LINE__, \ */ +/* cusparseGetErrorString(status), status); \ */ +/* goto exit_cleanup; \ */ +/* } \ */ +/* status = cudaMemset(var, 0, (size) * sizeof(typeof(*var))); \ */ +/* if (status != CUSPARSE_STATUS_SUCCESS) { \ */ +/* printf("CUSPARSE API failed at line %d with error: %s (%d)\n", __LINE__, \ */ +/* cusparseGetErrorString(status), status); \ */ +/* goto exit_cleanup; \ */ +/* } \ */ +/* } */ +/* #define CUPDLP_ZERO_VEC(var, type, size) \ */ +/* cudaMemset(var, 0, sizeof(type) * (size)) */ #else #define CUPDLP_COPY_VEC(dst, src, type, size) \ memcpy(dst, src, sizeof(type) * (size)) - //CUPDLP_INIT_VEC is not used - // - //#define CUPDLP_INIT_VEC(var, size) \ -// { \ -// (var) = (typeof(var))malloc((size) * sizeof(typeof(*var))); \ -// if ((var) == cupdlp_NULL) { \ -// retcode = RETCODE_FAILED; \ -// goto exit_cleanup; \ -// } \ -// } - //#define CUPDLP_INIT_ZERO_VEC(var, size) \ -// { \ -// (var) = (typeof(var))calloc(size, sizeof(typeof(*var))); \ -// if ((var) == cupdlp_NULL) { \ -// retcode = RETCODE_FAILED; \ -// goto exit_cleanup; \ -// } \ -// } + /* CUPDLP_INIT_VEC is not used */ + +/* #define CUPDLP_INIT_VEC(var, size) \ */ + /* { \ */ + /* (var) = (typeof(var))malloc((size) * sizeof(typeof(*var))); \ */ + /* if ((var) == cupdlp_NULL) { \ */ + /* retcode = RETCODE_FAILED; \ */ + /* goto exit_cleanup; \ */ + /* } \ */ + /* } */ +/* #define CUPDLP_INIT_ZERO_VEC(var, size) \ */ + /* { \ */ + /* (var) = (typeof(var))calloc(size, sizeof(typeof(*var))); \ */ + /* if ((var) == cupdlp_NULL) { \ */ + /* retcode = RETCODE_FAILED; \ */ + /* goto exit_cleanup; \ */ + /* } \ */ + /* } */ #define CUPDLP_INIT_ZERO_DOUBLE_VEC(var, size) \ { \ (var) = (double*)calloc(size, sizeof(double)); \ @@ -160,14 +160,14 @@ extern "C" { #define cupdlp_zero(var, type, size) memset(var, 0, sizeof(type) * (size)) #define cupdlp_copy(dst, src, type, size) \ memcpy(dst, src, sizeof(type) * (size)) -//#define CUPDLP_INIT(var, size) \ -// { \ -// (var) = (typeof(var))malloc((size) * sizeof(typeof(*var))); \ -// if ((var) == cupdlp_NULL) { \ -// retcode = RETCODE_FAILED; \ -// goto exit_cleanup; \ -// } \ -// } +/* #define CUPDLP_INIT(var, size) \ */ +/* { \ */ +/* (var) = (typeof(var))malloc((size) * sizeof(typeof(*var))); \ */ +/* if ((var) == cupdlp_NULL) { \ */ +/* retcode = RETCODE_FAILED; \ */ +/* goto exit_cleanup; \ */ +/* } \ */ +/* } */ #define CUPDLP_INIT_DOUBLE(var, size) \ { \ (var) = (double*)malloc((size) * sizeof(double)); \ @@ -248,14 +248,14 @@ extern "C" { goto exit_cleanup; \ } \ } - //#define CUPDLP_INIT_ZERO(var, size) \ -// { \ -// (var) = (typeof(var))calloc(size, sizeof(typeof(*var))); \ -// if ((var) == cupdlp_NULL) { \ -// retcode = RETCODE_FAILED; \ -// goto exit_cleanup; \ -// } \ -// } +/* #define CUPDLP_INIT_ZERO(var, size) \ */ +/* { \ */ +/* (var) = (typeof(var))calloc(size, sizeof(typeof(*var))); \ */ +/* if ((var) == cupdlp_NULL) { \ */ +/* retcode = RETCODE_FAILED; \ */ +/* goto exit_cleanup; \ */ +/* } \ */ +/* } */ #define CUPDLP_INIT_ZERO_DOUBLE(var, size) \ { \ (var) = (double*)calloc(size, sizeof(double)); \ From e724f52d09fd7c8a3ecbdc4c81211fdc03e8950c Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 4 May 2024 18:37:53 +0000 Subject: [PATCH 04/24] BLD: Reduce the silenced warnings BLD: Remove more filtered warnings --- meson.build | 5 ----- 1 file changed, 5 deletions(-) diff --git a/meson.build b/meson.build index a689b4ad5e..63f2360580 100644 --- a/meson.build +++ b/meson.build @@ -22,13 +22,8 @@ is_mingw = is_windows and cc.get_id() == 'gcc' # Conditional arguments _args += cppc.get_supported_arguments([ - '-Wno-return-type', - '-Wno-switch', - '-Wno-comment', '-Wno-unused-variable', '-Wno-unused-but-set-variable', - '-Wno-unused-const-variable', - '-Wno-unused-function', '-Wno-unused-label', ]) From 9407f71d13896480d5ccf35ab4bd80284a5448f4 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 4 May 2024 19:00:28 +0000 Subject: [PATCH 05/24] BLD: Rework to harmonize with CMake Also simplify, C wrapper is always built evidently --- meson_options.txt | 3 -- src/meson.build | 87 ++++++++++++++++++----------------------------- 2 files changed, 34 insertions(+), 56 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index 9f763abd82..e92fb8d53b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -13,9 +13,6 @@ option('with_fortran', option('with_csharp', type : 'boolean', value : false) -option('with_c', - type : 'boolean', - value : false) option('debug_sol', type: 'boolean', value: false) diff --git a/src/meson.build b/src/meson.build index 61dd94f9e7..2836c6f417 100644 --- a/src/meson.build +++ b/src/meson.build @@ -194,84 +194,86 @@ _ipx_srcs = [ _srcs = [ '../extern/filereaderlp/reader.cpp', + 'interfaces/highs_c_api.cpp', 'io/Filereader.cpp', - 'io/FilereaderLp.cpp', 'io/FilereaderEms.cpp', + 'io/FilereaderLp.cpp', 'io/FilereaderMps.cpp', - 'io/HighsIO.cpp', 'io/HMPSIO.cpp', 'io/HMpsFF.cpp', + 'io/HighsIO.cpp', 'io/LoadOptions.cpp', + 'ipm/IpxWrapper.cpp', 'lp_data/Highs.cpp', 'lp_data/HighsCallback.cpp', 'lp_data/HighsDebug.cpp', + 'lp_data/HighsDeprecated.cpp', 'lp_data/HighsInfo.cpp', 'lp_data/HighsInfoDebug.cpp', - 'lp_data/HighsDeprecated.cpp', 'lp_data/HighsInterface.cpp', 'lp_data/HighsLp.cpp', 'lp_data/HighsLpUtils.cpp', 'lp_data/HighsModelUtils.cpp', + 'lp_data/HighsOptions.cpp', 'lp_data/HighsRanging.cpp', 'lp_data/HighsSolution.cpp', 'lp_data/HighsSolutionDebug.cpp', 'lp_data/HighsSolve.cpp', 'lp_data/HighsStatus.cpp', - 'lp_data/HighsOptions.cpp', - 'mip/HighsMipSolver.cpp', - 'mip/HighsMipSolverData.cpp', + 'mip/HighsCliqueTable.cpp', + 'mip/HighsConflictPool.cpp', + 'mip/HighsCutGeneration.cpp', + 'mip/HighsCutPool.cpp', + 'mip/HighsDebugSol.cpp', 'mip/HighsDomain.cpp', 'mip/HighsDynamicRowMatrix.cpp', + 'mip/HighsGFkSolve.cpp', + 'mip/HighsImplications.cpp', + 'mip/HighsLpAggregator.cpp', 'mip/HighsLpRelaxation.cpp', - 'mip/HighsSeparation.cpp', - 'mip/HighsSeparator.cpp', - 'mip/HighsTableauSeparator.cpp', + 'mip/HighsMipSolver.cpp', + 'mip/HighsMipSolverData.cpp', 'mip/HighsModkSeparator.cpp', + 'mip/HighsNodeQueue.cpp', + 'mip/HighsObjectiveFunction.cpp', 'mip/HighsPathSeparator.cpp', - 'mip/HighsCutGeneration.cpp', - 'mip/HighsSearch.cpp', - 'mip/HighsConflictPool.cpp', - 'mip/HighsCutPool.cpp', - 'mip/HighsCliqueTable.cpp', - 'mip/HighsGFkSolve.cpp', - 'mip/HighsTransformedLp.cpp', - 'mip/HighsLpAggregator.cpp', - 'mip/HighsDebugSol.cpp', - 'mip/HighsImplications.cpp', 'mip/HighsPrimalHeuristics.cpp', 'mip/HighsPseudocost.cpp', 'mip/HighsRedcostFixing.cpp', - 'mip/HighsNodeQueue.cpp', - 'mip/HighsObjectiveFunction.cpp', + 'mip/HighsSearch.cpp', + 'mip/HighsSeparation.cpp', + 'mip/HighsSeparator.cpp', + 'mip/HighsTableauSeparator.cpp', + 'mip/HighsTransformedLp.cpp', 'model/HighsHessian.cpp', 'model/HighsHessianUtils.cpp', 'model/HighsModel.cpp', 'parallel/HighsTaskExecutor.cpp', + 'pdlp/CupdlpWrapper.cpp', + 'presolve/HPresolve.cpp', + 'presolve/HPresolveAnalysis.cpp', + 'presolve/HighsPostsolveStack.cpp', + 'presolve/HighsSymmetry.cpp', 'presolve/ICrash.cpp', 'presolve/ICrashUtil.cpp', 'presolve/ICrashX.cpp', - 'presolve/HighsPostsolveStack.cpp', - 'presolve/HighsSymmetry.cpp', - 'presolve/HPresolve.cpp', - 'presolve/HPresolveAnalysis.cpp', 'presolve/PresolveComponent.cpp', 'qpsolver/a_asm.cpp', 'qpsolver/a_quass.cpp', 'qpsolver/basis.cpp', + 'qpsolver/perturbation.cpp', 'qpsolver/quass.cpp', 'qpsolver/ratiotest.cpp', 'qpsolver/scaling.cpp', - 'qpsolver/perturbation.cpp', 'simplex/HEkk.cpp', 'simplex/HEkkControl.cpp', 'simplex/HEkkDebug.cpp', - 'simplex/HEkkPrimal.cpp', 'simplex/HEkkDual.cpp', + 'simplex/HEkkDualMulti.cpp', 'simplex/HEkkDualRHS.cpp', 'simplex/HEkkDualRow.cpp', - 'simplex/HEkkDualMulti.cpp', 'simplex/HEkkInterface.cpp', - 'simplex/HighsSimplexAnalysis.cpp', + 'simplex/HEkkPrimal.cpp', 'simplex/HSimplex.cpp', 'simplex/HSimplexDebug.cpp', 'simplex/HSimplexNla.cpp', @@ -279,6 +281,7 @@ _srcs = [ 'simplex/HSimplexNlaFreeze.cpp', 'simplex/HSimplexNlaProductForm.cpp', 'simplex/HSimplexReport.cpp', + 'simplex/HighsSimplexAnalysis.cpp', 'test/DevKkt.cpp', 'test/KktCh2.cpp', 'util/HFactor.cpp', @@ -286,6 +289,8 @@ _srcs = [ 'util/HFactorExtend.cpp', 'util/HFactorRefactor.cpp', 'util/HFactorUtils.cpp', + 'util/HSet.cpp', + 'util/HVectorBase.cpp', 'util/HighsHash.cpp', 'util/HighsLinearSumBounds.cpp', 'util/HighsMatrixPic.cpp', @@ -293,16 +298,12 @@ _srcs = [ 'util/HighsSort.cpp', 'util/HighsSparseMatrix.cpp', 'util/HighsUtils.cpp', - 'util/HSet.cpp', - 'util/HVectorBase.cpp', 'util/stringutil.cpp', ] highslib_srcs = [ highs_conf_file, _srcs, - 'ipm/IpxWrapper.cpp', - 'pdlp/CupdlpWrapper.cpp', _cupdlp_srcs, _basiclu_srcs, _ipx_srcs @@ -360,26 +361,6 @@ if get_option('with_csharp') install: true) endif -# C -if get_option('with_c') - add_languages('c', required: true) - if not is_windows - m_dep = cppc.find_library('m', required: false) - _deps += m_dep - endif - _c_src = [ - 'interfaces/highs_c_api.cpp', - ] - c_lib = library('HighsC', - _c_src, - dependencies: _deps, - cpp_args: _args, - link_with: highslib, - include_directories: _incdirs, - pic: true, - install: true) -endif - highs_dep = declare_dependency(link_with: highslib, dependencies: _deps, include_directories: _incdirs, From 324f5c194de8333b425c38e8d86bf2ddf2fa7593 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 4 May 2024 19:06:17 +0000 Subject: [PATCH 06/24] BLD: Rework and sort-lines in meson --- src/meson.build | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/meson.build b/src/meson.build index 2836c6f417..825bd27c0a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -117,45 +117,45 @@ _incdirs += include_directories('.') # --------------------- Libraries _cupdlp_srcs = [ - 'pdlp/cupdlp/cupdlp_solver.c', - 'pdlp/cupdlp/cupdlp_scaling_cuda.c', - 'pdlp/cupdlp/cupdlp_restart.c', - 'pdlp/cupdlp/cupdlp_proj.c', - 'pdlp/cupdlp/cupdlp_linalg.c', 'pdlp/cupdlp/cupdlp_cs.c', - 'pdlp/cupdlp/cupdlp_utils.c', + 'pdlp/cupdlp/cupdlp_linalg.c', + 'pdlp/cupdlp/cupdlp_proj.c', + 'pdlp/cupdlp/cupdlp_restart.c', + 'pdlp/cupdlp/cupdlp_scaling_cuda.c', + 'pdlp/cupdlp/cupdlp_solver.c', 'pdlp/cupdlp/cupdlp_step.c', + 'pdlp/cupdlp/cupdlp_utils.c', ] _basiclu_srcs = [ 'ipm/basiclu/basiclu_factorize.c', - 'ipm/basiclu/basiclu_solve_dense.c', - 'ipm/basiclu/lu_build_factors.c', - 'ipm/basiclu/lu_factorize_bump.c', - 'ipm/basiclu/lu_initialize.c', - 'ipm/basiclu/lu_markowitz.c', - 'ipm/basiclu/lu_setup_bump.c', - 'ipm/basiclu/lu_solve_sparse.c', 'ipm/basiclu/basiclu_get_factors.c', + 'ipm/basiclu/basiclu_initialize.c', + 'ipm/basiclu/basiclu_object.c', + 'ipm/basiclu/basiclu_solve_dense.c', 'ipm/basiclu/basiclu_solve_for_update.c', + 'ipm/basiclu/basiclu_solve_sparse.c', + 'ipm/basiclu/basiclu_update.c', + 'ipm/basiclu/lu_build_factors.c', 'ipm/basiclu/lu_condest.c', + 'ipm/basiclu/lu_dfs.c', + 'ipm/basiclu/lu_factorize_bump.c', 'ipm/basiclu/lu_file.c', + 'ipm/basiclu/lu_garbage_perm.c', + 'ipm/basiclu/lu_initialize.c', 'ipm/basiclu/lu_internal.c', + 'ipm/basiclu/lu_markowitz.c', 'ipm/basiclu/lu_matrix_norm.c', - 'ipm/basiclu/lu_singletons.c', - 'ipm/basiclu/lu_solve_symbolic.c', - 'ipm/basiclu/lu_update.c', - 'ipm/basiclu/basiclu_initialize.c', - 'ipm/basiclu/basiclu_solve_sparse.c', 'ipm/basiclu/lu_pivot.c', - 'ipm/basiclu/lu_solve_dense.c', - 'ipm/basiclu/lu_solve_triangular.c', - 'ipm/basiclu/basiclu_object.c', - 'ipm/basiclu/basiclu_update.c', - 'ipm/basiclu/lu_dfs.c', - 'ipm/basiclu/lu_garbage_perm.c', 'ipm/basiclu/lu_residual_test.c', + 'ipm/basiclu/lu_setup_bump.c', + 'ipm/basiclu/lu_singletons.c', + 'ipm/basiclu/lu_solve_dense.c', 'ipm/basiclu/lu_solve_for_update.c', + 'ipm/basiclu/lu_solve_sparse.c', + 'ipm/basiclu/lu_solve_symbolic.c', + 'ipm/basiclu/lu_solve_triangular.c', + 'ipm/basiclu/lu_update.c', ] _ipx_srcs = [ From 749309bc74234c12f776d495e1b2ef61b264f1fa Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 12:30:48 +0000 Subject: [PATCH 07/24] BLD: Setup the newer python library in meson --- src/meson.build | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/meson.build b/src/meson.build index 825bd27c0a..066ab742e4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -367,6 +367,7 @@ highs_dep = declare_dependency(link_with: highslib, ) if get_option('with_pybind11') + _deps += highs_dep py = import('python').find_installation(pure: false) pyb11_dep = [ @@ -375,6 +376,7 @@ if get_option('with_pybind11') py.dependency(), dependency('pybind11') ] + _deps += pyb11_dep highspy_cpp = files([ 'highs_bindings.cpp' @@ -384,9 +386,9 @@ if get_option('with_pybind11') ]) py.extension_module( - '_highs', + '_core', sources : highspy_cpp, - dependencies: [pyb11_dep, highs_dep], + dependencies: _deps, cpp_args: _args, install: true, subdir: 'highspy', @@ -396,11 +398,19 @@ if get_option('with_pybind11') py.extension_module( '_highs_options', sources : highsoptions_cpp, - dependencies: [pyb11_dep, highs_dep], + dependencies: _deps, cpp_args: _args, install: true, subdir: 'highspy', include_directories: _incdirs, ) + py.install_sources([ + 'highspy/__init__.py', + 'highspy/highs.py', + ], + pure: false, + subdir: 'highspy' + ) + endif From d8fef70f099ec51e68634c0feabc59d399497553 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 12:31:03 +0000 Subject: [PATCH 08/24] MAINT: Switch back to meson-python --- pyproject.toml | 160 ++++--------------------------------------------- 1 file changed, 10 insertions(+), 150 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e3173dfedf..f586a4d2be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,8 +3,8 @@ "Bug Tracker" = "https://github.com/ERGO-Code/HiGHS/issues" [build-system] -requires = ["scikit-build-core>=0.3.3", "pybind11", "numpy"] -build-backend = "scikit_build_core.build" +requires = ["meson-python<0.14.0", "meson>=1.2.0"] +build-backend = "mesonpy" [project] name = "highspy" @@ -30,154 +30,14 @@ classifiers = [ [project.optional-dependencies] test = ["pytest", "numpy"] -[tool.scikit-build] -cmake.args = ["-DPYTHON_BUILD_SETUP=ON"] -wheel.expand-macos-universal-tags = true - -# A list of packages to auto-copy into the wheel. If this is not set, it will -# default to the first of ``src/``, ``python/``, or -# ```` if they exist. The prefix(s) will be stripped from the package -# name inside the wheel. -wheel.packages = ["src/highspy"] - -# Files to include in the SDist even if they are skipped by default. Supports -# gitignore syntax. -sdist.include = [ - "src/highspy/highs.py", - "tests/test_highspy.py", - "Version.txt", - "LICENSE", - "README.md", - "src/HConfig.h.in", - "src", - "external", - "cmake", -] - -sdist.exclude = [ - ".github", - ".gitattributes", - ".gitignore", - ".github", - "app", - "build", - "check", - "docs", - "subprojects", - ".coin-or", - "build_webdemo.sh", - ".clang-format", - "__setup.py", - "BUILD.bazel", - "meson*", - "MODS.md", - "WORKSPACE", -] - - -# # Verbose printout when building. -# cmake.verbose = false - -# # The build type to use when building the project. Valid options are: "Debug", -# # "Release", "RelWithDebInfo", "MinSizeRel", "", etc. -# cmake.build-type = "Release" - -# # The versions of Ninja to allow. If Ninja is not present on the system or does -# # not pass this specifier, it will be downloaded via PyPI if possible. An empty -# # string will disable this check. -# ninja.version = ">=1.5" - -# # If CMake is not present on the system or is older required, it will be -# # downloaded via PyPI if possible. An empty string will disable this check. -# ninja.make-fallback = true - -# # The logging level to display, "DEBUG", "INFO", "WARNING", and "ERROR" are -# # possible options. -# logging.level = "WARNING" - - -# # If set to True, try to build a reproducible distribution (Unix and Python 3.9+ -# # recommended). ``SOURCE_DATE_EPOCH`` will be used for timestamps, or a fixed -# # value if not set. -# sdist.reproducible = true - -# # If set to True, CMake will be run before building the SDist. -# sdist.cmake = false - -# # The Python tags. The default (empty string) will use the default Python -# # version. You can also set this to "cp37" to enable the CPython 3.7+ Stable ABI -# # / Limited API (only on CPython and if the version is sufficient, otherwise -# # this has no effect). Or you can set it to "py3" or "py2.py3" to ignore Python -# # ABI compatibility. The ABI tag is inferred from this tag. -# wheel.py-api = "" - -# # Fill out extra tags that are not required. This adds "x86_64" and "arm64" to -# # the list of platforms when "universal2" is used, which helps older Pip's -# # (before 21.0.1) find the correct wheel. -# # wheel.expand-macos-universal-tags = false - -# # The install directory for the wheel. This is relative to the platlib root. You -# # might set this to the package name. The original dir is still at -# # SKBUILD_PLATLIB_DIR (also SKBUILD_DATA_DIR, etc. are available). EXPERIMENTAL: -# # An absolute path will be one level higher than the platlib root, giving access -# # to "/platlib", "/data", "/headers", and "/scripts". -# # wheel.install-dir = "" - -# # A list of license files to include in the wheel. Supports glob patterns. -# wheel.license-files = ["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"] - -# # If set to True (the default), CMake will be run before building the wheel. -# wheel.cmake = true - -# # Target the platlib or the purelib. If not set, the default is to target the -# # platlib if wheel.cmake is true, and the purelib otherwise. -# # wheel.platlib = "" - -# # A set of patterns to exclude from the wheel. This is additive to the SDist -# # exclude patterns. This applies to the final paths in the wheel, and can -# # exclude files from CMake output as well. Editable installs may not respect -# # this exclusion. -# wheel.exclude = [] - -# # The build tag to use for the wheel. If empty, no build tag is used. -# wheel.build-tag = "" - -# # If CMake is less than this value, backport a copy of FindPython. Set to 0 -# # disable this, or the empty string. -# backport.find-python = "3.26.1" - -# # Select the editable mode to use. Can be "redirect" (default) or "inplace". -# editable.mode = "redirect" - -# # Turn on verbose output for the editable mode rebuilds. -# editable.verbose = true - -# # Rebuild the project when the package is imported. The build-directory must be -# # set. -# editable.rebuild = false - -# # The components to install. If empty, all default components are installed. -# install.components = [] - -# # Whether to strip the binaries. True for scikit-build-core 0.5+. -# install.strip = false - -# # List dynamic metadata fields and hook locations in this table. -# metadata = {} - -# # Strictly check all config options. If False, warnings will be printed for -# # unknown options. If True, an error will be raised. -# strict-config = true - -# # Enable early previews of features not finalized yet. -# experimental = false - -# # If set, this will provide a method for backward compatibility. -# # minimum-version = "0.8" # current version - -# # The build directory. Defaults to a temporary directory, but can be set. -# # build-dir = "" - +[tool.meson-python.args] +setup = ['-Dwith_pybind11=True', + '-Dhighsint64=False', + '-Dwrap_mode=forcefallback', + # ^-- collects pybind11, see https://github.com/ERGO-Code/HiGHS/pull/1343#discussion_r1252446966 + ] +dist = ['--include-subprojects'] +install = ['--skip-subprojects'] [tool.pytest.ini_options] minversion = "6.0" From 8ef97cbd6b4aa0f11aa1924ee9a8f9909d59f216 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 12:37:44 +0000 Subject: [PATCH 09/24] MAINT: Lint and cleanup excess enum exports --- src/highs_bindings.cpp | 52 ++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/src/highs_bindings.cpp b/src/highs_bindings.cpp index e7f9e49cac..5d747c1ec6 100644 --- a/src/highs_bindings.cpp +++ b/src/highs_bindings.cpp @@ -277,12 +277,13 @@ HighsStatus highs_changeColsIntegrality(Highs* h, HighsInt num_set_entries, // Same as deleteVars HighsStatus highs_deleteCols(Highs* h, HighsInt num_set_entries, - std::vector& indices) { + std::vector& indices) { return h->deleteCols(num_set_entries, indices.data()); } -HighsStatus highs_deleteRows(Highs* h, HighsInt num_set_entries, std::vector& indices) { - return h->deleteRows(num_set_entries, indices.data()); +HighsStatus highs_deleteRows(Highs* h, HighsInt num_set_entries, + std::vector& indices) { + return h->deleteRows(num_set_entries, indices.data()); } @@ -576,22 +577,9 @@ std::tuple highs_getRowByName(Highs* h, return std::make_tuple(status, row); } - PYBIND11_MODULE(_core, m) { - // enum classes - py::enum_(m, "ObjSense") - .value("kMinimize", ObjSense::kMinimize) - .value("kMaximize", ObjSense::kMaximize); - // // .export_values(); - py::enum_(m, "MatrixFormat") - .value("kColwise", MatrixFormat::kColwise) - .value("kRowwise", MatrixFormat::kRowwise) - .value("kRowwisePartitioned", MatrixFormat::kRowwisePartitioned); - // // .export_values(); - py::enum_(m, "HessianFormat") - .value("kTriangular", HessianFormat::kTriangular) - .value("kSquare", HessianFormat::kSquare); - // .export_values(); + // enumerations + // Older enums, need to have values exported py::enum_(m, "SolutionStatus") .value("kSolutionStatusNone", SolutionStatus::kSolutionStatusNone) .value("kSolutionStatusInfeasible", @@ -602,6 +590,17 @@ PYBIND11_MODULE(_core, m) { .value("kBasisValidityInvalid", BasisValidity::kBasisValidityInvalid) .value("kBasisValidityValid", BasisValidity::kBasisValidityValid) .export_values(); + // C++ enum classes do not need to have values exported + py::enum_(m, "ObjSense") + .value("kMinimize", ObjSense::kMinimize) + .value("kMaximize", ObjSense::kMaximize); + py::enum_(m, "MatrixFormat") + .value("kColwise", MatrixFormat::kColwise) + .value("kRowwise", MatrixFormat::kRowwise) + .value("kRowwisePartitioned", MatrixFormat::kRowwisePartitioned); + py::enum_(m, "HessianFormat") + .value("kTriangular", HessianFormat::kTriangular) + .value("kSquare", HessianFormat::kSquare); py::enum_(m, "HighsModelStatus") .value("kNotset", HighsModelStatus::kNotset) .value("kLoadError", HighsModelStatus::kLoadError) @@ -622,7 +621,6 @@ PYBIND11_MODULE(_core, m) { .value("kSolutionLimit", HighsModelStatus::kSolutionLimit) .value("kInterrupt", HighsModelStatus::kInterrupt) .value("kMemoryLimit", HighsModelStatus::kMemoryLimit); - // .export_values(); py::enum_(m, "HighsPresolveStatus") .value("kNotPresolved", HighsPresolveStatus::kNotPresolved) .value("kNotReduced", HighsPresolveStatus::kNotReduced) @@ -634,43 +632,36 @@ PYBIND11_MODULE(_core, m) { .value("kTimeout", HighsPresolveStatus::kTimeout) .value("kNullError", HighsPresolveStatus::kNullError) .value("kOptionsError", HighsPresolveStatus::kOptionsError); - // .export_values(); py::enum_(m, "HighsBasisStatus") .value("kLower", HighsBasisStatus::kLower) .value("kBasic", HighsBasisStatus::kBasic) .value("kUpper", HighsBasisStatus::kUpper) .value("kZero", HighsBasisStatus::kZero) .value("kNonbasic", HighsBasisStatus::kNonbasic); - // .export_values(); py::enum_(m, "HighsVarType") .value("kContinuous", HighsVarType::kContinuous) .value("kInteger", HighsVarType::kInteger) .value("kSemiContinuous", HighsVarType::kSemiContinuous) .value("kSemiInteger", HighsVarType::kSemiInteger); - // .export_values(); py::enum_(m, "HighsOptionType") .value("kBool", HighsOptionType::kBool) .value("kInt", HighsOptionType::kInt) .value("kDouble", HighsOptionType::kDouble) .value("kString", HighsOptionType::kString); - // .export_values(); py::enum_(m, "HighsInfoType") .value("kInt64", HighsInfoType::kInt64) .value("kInt", HighsInfoType::kInt) .value("kDouble", HighsInfoType::kDouble); - // .export_values(); py::enum_(m, "HighsStatus") .value("kError", HighsStatus::kError) .value("kOk", HighsStatus::kOk) .value("kWarning", HighsStatus::kWarning); - // .export_values(); py::enum_(m, "HighsLogType") .value("kInfo", HighsLogType::kInfo) .value("kDetailed", HighsLogType::kDetailed) .value("kVerbose", HighsLogType::kVerbose) .value("kWarning", HighsLogType::kWarning) .value("kError", HighsLogType::kError); - // .export_values(); // Classes py::class_(m, "HighsSparseMatrix") .def(py::init<>()) @@ -951,7 +942,7 @@ PYBIND11_MODULE(_core, m) { .def("changeColsBounds", &highs_changeColsBounds) .def("changeColsIntegrality", &highs_changeColsIntegrality) .def("deleteCols", &highs_deleteCols) - .def("deleteVars", &highs_deleteCols) // alias + .def("deleteVars", &highs_deleteCols) // alias .def("deleteRows", &highs_deleteRows) .def("setSolution", &highs_setSolution) .def("setSolution", &highs_setSparseSolution) @@ -1168,9 +1159,10 @@ PYBIND11_MODULE(_core, m) { HighsCallbackType::kCallbackMipImprovingSolution) .value("kCallbackMipLogging", HighsCallbackType::kCallbackMipLogging) .value("kCallbackMipInterrupt", HighsCallbackType::kCallbackMipInterrupt) - .value("kCallbackMipGetCutPool", HighsCallbackType::kCallbackMipGetCutPool) + .value("kCallbackMipGetCutPool", + HighsCallbackType::kCallbackMipGetCutPool) .value("kCallbackMipDefineLazyConstraints", - HighsCallbackType::kCallbackMipDefineLazyConstraints) + HighsCallbackType::kCallbackMipDefineLazyConstraints) .value("kCallbackMax", HighsCallbackType::kCallbackMax) .value("kNumCallbackType", HighsCallbackType::kNumCallbackType) .export_values(); @@ -1200,7 +1192,7 @@ PYBIND11_MODULE(_core, m) { return py::array(3, self.mip_solution); }, [](HighsCallbackDataOut& self, py::array_t new_mip_solution) { - self.mip_solution = new_mip_solution.mutable_data(); + self.mip_solution = new_mip_solution.mutable_data(); }); py::class_(callbacks, "HighsCallbackDataIn") .def(py::init<>()) From c51941fea4075bee8c3662d0e8c4c845dc5f854d Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 12:58:31 +0000 Subject: [PATCH 10/24] MAINT,BLD: Finish removing -Dwith_c for meson --- check/meson.build | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/check/meson.build b/check/meson.build index 1cf8e5663d..9c6c13abac 100644 --- a/check/meson.build +++ b/check/meson.build @@ -54,6 +54,7 @@ test_array = [ ['test_lpvalidation', 'TestLpValidation.cpp'], ['test_lpmodification', 'TestLpModification.cpp'], ['test_lporientation', 'TestLpOrientation.cpp'], + ['test_capi', 'TestCAPI.c'], ] foreach test : test_array test(test.get(0), @@ -70,11 +71,3 @@ foreach test : test_array timeout: 300, ) endforeach - -if get_option('with_c') - test('test_capi', - executable('capi_unit_tests', 'TestCAPI.c', - include_directories: _incdirs, - link_with : highslib, - )) -endif From fbf7d73af4f6425b2fcf2fa846ff4b288b2c2f2f Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 13:06:13 +0000 Subject: [PATCH 11/24] CI: Rework to have dependencies when building --- .github/workflows/build-python-package.yml | 54 +++++++++++----------- pyproject.toml | 2 +- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build-python-package.yml b/.github/workflows/build-python-package.yml index 96e21715e0..eb0dc2abcc 100644 --- a/.github/workflows/build-python-package.yml +++ b/.github/workflows/build-python-package.yml @@ -14,18 +14,19 @@ jobs: - name: Build sdist run: | - python3 -m pip install build + python3 -m pip install build --user python3 -m build --sdist - name: Install sdist run: | ls dist + python3 -m pip install meson-python meson pybind11 ninja --user python3 -m pip install dist/*.tar.gz - name: Test highspy run: | - python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pip install pytest --user + python3 -m pytest $GITHUB_WORKSPACE/tests build_sdist_mac: runs-on: macos-latest @@ -34,18 +35,19 @@ jobs: - name: Build sdist run: | - python3 -m pip install build --break-system-packages + python3 -m pip install build --user --break-system-packages python3 -m build --sdist - name: Install sdist run: | ls dist - python3 -m pip install dist/*.tar.gz --break-system-packages + python3 -m pip install meson-python meson pybind11 ninja --user --break-system-packages + python3 -m pip install dist/*.tar.gz --user --break-system-packages - name: Test highspy run: | - python3 -m pip install pytest --break-system-packages - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pip install pytest --user --break-system-packages + python3 -m pytest $GITHUB_WORKSPACE/tests build_sdist_win: runs-on: windows-2019 @@ -59,19 +61,20 @@ jobs: - name: Build sdist run: | - python -m pip install build + python -m pip install build --user python -m build --sdist - name: Install sdist run: | + python3 -m pip install meson-python meson pybind11 ninja --user $item = Get-ChildItem dist - python -m pip install "$item" + python -m pip install "$item" --user python -c "import highspy; print(dir(highspy))" - name: Test highspy run: | - python -m pip install pytest - python -m pytest + python -m pip install pytest --user + python -m pytest tests build_wheel_linux: # ubuntu 22 has a latest version of cmake, but setup-python @@ -103,7 +106,7 @@ jobs: - name: Test highspy run: | python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pytest $GITHUB_WORKSPACE/tests # macos 12 is Intel @@ -122,20 +125,20 @@ jobs: - name: Build wheel run: | - python3 -m pip install cibuildwheel + python3 -m pip install cibuildwheel --break-system-packages python3 -m cibuildwheel --only cp311-macosx_x86_64 $GITHUB_WORKSPACE - name: Install wheel run: | ls wheelhouse python3 --version - python3 -m pip install wheelhouse/*.whl + python3 -m pip install wheelhouse/*.whl --break-system-packages python3 -c "import highspy; print(dir(highspy))" - name: Test highspy run: | - python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pip install pytest --break-system-packages + python3 -m pytest $GITHUB_WORKSPACE/tests # macos 13 is Intel build_wheel_macos_13: @@ -153,20 +156,20 @@ jobs: - name: Build wheel run: | - python3 -m pip install cibuildwheel + python3 -m pip install cibuildwheel --break-system-packages python3 -m cibuildwheel --only cp311-macosx_x86_64 $GITHUB_WORKSPACE - name: Install wheel run: | ls wheelhouse python3 --version - python3 -m pip install wheelhouse/*.whl + python3 -m pip install wheelhouse/*.whl --break-system-packages python3 -c "import highspy; print(dir(highspy))" - name: Test highspy run: | - python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pip install pytest --break-system-packages + python3 -m pytest $GITHUB_WORKSPACE/tests # macos 14 is M1 (beta) build_wheel_macos_14: @@ -184,20 +187,20 @@ jobs: - name: Build wheel run: | - python3 -m pip install cibuildwheel + python3 -m pip install cibuildwheel --break-system-packages python3 -m cibuildwheel --only cp311-macosx_arm64 $GITHUB_WORKSPACE - name: Install wheel run: | ls wheelhouse python3 --version - python3 -m pip install wheelhouse/*.whl + python3 -m pip install wheelhouse/*.whl --break-system-packages python3 -c "import highspy; print(dir(highspy))" - name: Test highspy run: | - python3 -m pip install pytest - python3 -m pytest $GITHUB_WORKSPACE + python3 -m pip install pytest --break-system-packages + python3 -m pytest $GITHUB_WORKSPACE/tests build_wheel_windows: runs-on: windows-2019 @@ -224,5 +227,4 @@ jobs: - name: Test highspy run: | python -m pip install pytest - python -m pytest - \ No newline at end of file + python -m pytest diff --git a/pyproject.toml b/pyproject.toml index f586a4d2be..0c532603cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ "Bug Tracker" = "https://github.com/ERGO-Code/HiGHS/issues" [build-system] -requires = ["meson-python<0.14.0", "meson>=1.2.0"] +requires = ["meson-python<0.14.0", "meson>=1.2.0", "pybind11", "ninja"] build-backend = "mesonpy" [project] From 0a4ed1e5c167a5dade9fdce555eeae31270fdd2c Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 13:21:27 +0000 Subject: [PATCH 12/24] BLD: Add pack cibuildwheel config --- pyproject.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0c532603cb..9550208125 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,3 +56,21 @@ test-command = "pytest {project}/tests" test-extras = ["test", "numpy"] test-skip = ["*universal2:arm64"] build-verbosity = 1 + +[tool.cibuildwheel.linux] +manylinux-x86_64-image = "manylinux2014" +manylinux-i686-image = "manylinux2014" +repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}" + +[tool.cibuildwheel.macos] +archs = ["x86_64 arm64"] +environment = { RUNNER_OS="macOS" } +repair-wheel-command = [ + "delocate-listdeps {wheel}", + "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}", +] + +[tool.cibuildwheel.windows] +# Use delvewheel on windows, and install the project so delvewheel can find it +before-build = "pip install delvewheel meson ninja && meson setup bbdir && meson install -C bbdir" +repair-wheel-command = "delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/HiGHS/HiGHS/bbdir/src/ -w {dest_dir} {wheel}" From 56a4335acbcc8d0ae01b0fb8ecdd5d142e451747 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 13:32:41 +0000 Subject: [PATCH 13/24] BLD: Link with highs explicitly --- src/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/src/meson.build b/src/meson.build index 066ab742e4..6b0a9e1d72 100644 --- a/src/meson.build +++ b/src/meson.build @@ -390,6 +390,7 @@ if get_option('with_pybind11') sources : highspy_cpp, dependencies: _deps, cpp_args: _args, + link_with: highslib, install: true, subdir: 'highspy', include_directories: _incdirs, From f5c14c5be3b28015a93c1d44b85335c57a253605 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 13:32:50 +0000 Subject: [PATCH 14/24] CI: Test only highs/tests/ --- .github/workflows/build-python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-python-package.yml b/.github/workflows/build-python-package.yml index eb0dc2abcc..c408458a13 100644 --- a/.github/workflows/build-python-package.yml +++ b/.github/workflows/build-python-package.yml @@ -227,4 +227,4 @@ jobs: - name: Test highspy run: | python -m pip install pytest - python -m pytest + python -m pytest tests From 62ab499db02427ec6960c7c39ea6a1553c29f698 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 5 May 2024 14:12:13 +0000 Subject: [PATCH 15/24] BLD: Fix C_API test Doesn't use Catch2 --- check/meson.build | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/check/meson.build b/check/meson.build index 9c6c13abac..16dd5b41cf 100644 --- a/check/meson.build +++ b/check/meson.build @@ -54,7 +54,6 @@ test_array = [ ['test_lpvalidation', 'TestLpValidation.cpp'], ['test_lpmodification', 'TestLpModification.cpp'], ['test_lporientation', 'TestLpOrientation.cpp'], - ['test_capi', 'TestCAPI.c'], ] foreach test : test_array test(test.get(0), @@ -71,3 +70,11 @@ foreach test : test_array timeout: 300, ) endforeach + +test('test_capi', + executable('capi_unit_tests', + sources: ['TestCAPI.c', highs_conf_file], + include_directories: _incdirs, + link_with : highslib, + ) + ) From 251590a2ccefe6c4b9522d8459c93a6291d91576 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 19 May 2024 18:11:59 +0000 Subject: [PATCH 16/24] MAINT: Try to rebuild correctly on WIN --- pyproject.toml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9550208125..2f7c45b887 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ test = ["pytest", "numpy"] [tool.meson-python.args] setup = ['-Dwith_pybind11=True', - '-Dhighsint64=False', + '-Dhighsint64=True', '-Dwrap_mode=forcefallback', # ^-- collects pybind11, see https://github.com/ERGO-Code/HiGHS/pull/1343#discussion_r1252446966 ] @@ -71,6 +71,5 @@ repair-wheel-command = [ ] [tool.cibuildwheel.windows] -# Use delvewheel on windows, and install the project so delvewheel can find it -before-build = "pip install delvewheel meson ninja && meson setup bbdir && meson install -C bbdir" -repair-wheel-command = "delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/HiGHS/HiGHS/bbdir/src/ -w {dest_dir} {wheel}" +before-build = "pip install delvewheel" +repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}" \ No newline at end of file From c01795e82a1a35f7851455b491e781d6cf5ec9b6 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 19 May 2024 18:28:46 +0000 Subject: [PATCH 17/24] MAINT: Remove unused build date --- src/meson.build | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/meson.build b/src/meson.build index 6b0a9e1d72..2c9fa9aa31 100644 --- a/src/meson.build +++ b/src/meson.build @@ -22,33 +22,6 @@ if host_machine.cpu_family() == 'x86_64' else conf_data.set('HIGHSINT64', false) endif -# Date -# today_str = 'unknown' -# if (not meson.is_subproject()) -# python_getdate = ''' -# import datetime -# import os -# import time - -# (ig) -# Deprecate compilation date - -# build_date = datetime.datetime.utcfromtimestamp( -# int(os.environ.get('SOURCE_DATE_EPOCH', time.time())) -# ) -# build_date_str = build_date.strftime('%Y-%m-%d') -# print(build_date_str) -# ''' -# # Note: this is not guaranteed to work on Windows. This should be removed -# # (as proposed in gh-1735), and otherwise moved into a .py script with -# # a `#!/usr/bin/env python3` shebang, and `python3 -c` dropped. -# today_cmd = run_command('python3', '-c', -# python_getdate, -# check: false) -# today_str = today_cmd.stdout().strip() -# endif -# conf_data.set_quoted('HIGHS_COMPILATION_DATE', -# today_str) conf_data.set_quoted('HIGHS_COMPILATION_DATE', 'deprecated') From a0390a50b87c1bd41e5b2d690469417007d0ed91 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 19 May 2024 19:30:58 +0000 Subject: [PATCH 18/24] BLD,TMP: Try windows again --- .github/workflows/test-python-win.yml | 32 ++++++++++++--- meson.build | 8 ++-- pyproject.toml | 13 +++++-- scripts/post_install_win.bat | 10 +++++ src/HConfig.h.meson.in | 1 + src/highspy/__init__.py | 2 +- src/highspy/highs.py | 2 +- src/meson.build | 56 +++++++++++++++++++++------ 8 files changed, 99 insertions(+), 25 deletions(-) create mode 100644 scripts/post_install_win.bat diff --git a/.github/workflows/test-python-win.yml b/.github/workflows/test-python-win.yml index 3b2f141b55..14bb8e147f 100644 --- a/.github/workflows/test-python-win.yml +++ b/.github/workflows/test-python-win.yml @@ -18,12 +18,34 @@ jobs: python-version: ${{ matrix.python }} - name: Install build dependencies - run: python -m pip install numpy setuptools wheel pytest - - - name: Test python install + run: python -m pip install numpy setuptools wheel pytest meson ninja delvewheel build + + - name: Build project run: | - python -m pip install . - pytest + meson setup bbdir --prefix=${{ github.workspace }}/local_install + meson compile -C bbdir + + - name: Install project to custom directory + run: meson install -C bbdir + + - name: Build Python package + run: python -m build + + - name: Repair the wheel + shell: pwsh + run: | + $installedPath = "${{ github.workspace }}/local_install" + $wheels = Get-ChildItem -Path dist -Filter *.whl + foreach ($wheel in $wheels) { + delvewheel repair $wheel.FullName --add-path "$installedPath/bin;$installedPath/lib" -w repaired_wheels + } + + - name: Install the repaired wheel + run: | + $wheels = Get-ChildItem -Path repaired_wheels -Filter *.whl + foreach ($wheel in $wheels){ + pip install $wheel.FullName + } - name: Test Python Examples run: | diff --git a/meson.build b/meson.build index 63f2360580..167b44f46d 100644 --- a/meson.build +++ b/meson.build @@ -68,9 +68,6 @@ if is_mingw endif # --------------------- Dependencies -threads_dep = dependency('threads', required: false) -_deps += threads_dep - # Determine whether it is necessary to link libatomic. This could be the case # e.g. on 32-bit platforms when atomic operations are used on 64-bit types. # The check is copied from SciPy which in turn came from @@ -110,6 +107,11 @@ endif _deps += atomic_dep +threads_dep = null_dep +if not is_windows + threads_dep = dependency('threads', required: false) +endif +_deps += threads_dep # Optional zlib_dep = dependency('zlib', required: get_option('use_zlib')) diff --git a/pyproject.toml b/pyproject.toml index 2f7c45b887..56d9cb9fe5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ "Bug Tracker" = "https://github.com/ERGO-Code/HiGHS/issues" [build-system] -requires = ["meson-python<0.14.0", "meson>=1.2.0", "pybind11", "ninja"] +requires = ["meson-python>=0.16.0", "meson>=1.2.0", "pybind11", "ninja"] build-backend = "mesonpy" [project] @@ -32,7 +32,7 @@ test = ["pytest", "numpy"] [tool.meson-python.args] setup = ['-Dwith_pybind11=True', - '-Dhighsint64=True', + '-Dhighsint64=False', '-Dwrap_mode=forcefallback', # ^-- collects pybind11, see https://github.com/ERGO-Code/HiGHS/pull/1343#discussion_r1252446966 ] @@ -70,6 +70,11 @@ repair-wheel-command = [ "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}", ] +#[tool.cibuildwheel.windows] +#before-build = "pip install delvewheel" +#repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}" + [tool.cibuildwheel.windows] -before-build = "pip install delvewheel" -repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}" \ No newline at end of file +# Use delvewheel on windows, and install the project so delvewheel can find it +before-build = "pip install delvewheel meson ninja && meson setup bbdir && meson install -C bbdir" +repair-wheel-command = "delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/HiGHS/HiGHS/bbdir/src/ -w {dest_dir} {wheel}" diff --git a/scripts/post_install_win.bat b/scripts/post_install_win.bat new file mode 100644 index 0000000000..35ae5c49dd --- /dev/null +++ b/scripts/post_install_win.bat @@ -0,0 +1,10 @@ +pip install delvewheel meson ninja + +meson setup bbdir +meson compile -C bbdir + +REM Repair the wheel using delvewheel +set destDir=%1 +set wheel=%2 + +delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/HiGHS/HiGHS/bbdir/src/ -w %destDir% %wheel% diff --git a/src/HConfig.h.meson.in b/src/HConfig.h.meson.in index 7b2fb3318c..eff4bc810c 100644 --- a/src/HConfig.h.meson.in +++ b/src/HConfig.h.meson.in @@ -8,6 +8,7 @@ #mesondefine HIGHS_HAVE_MM_PAUSE #mesondefine HIGHS_HAVE_BUILTIN_CLZ #mesondefine HIGHS_HAVE_BITSCAN_REVERSE +#mesondefine HIGHS_NO_DEFAULT_THREADS #define HIGHS_GITHASH "_HIGHS_GITHASH_" #define HIGHS_VERSION_MAJOR @HIGHS_VERSION_MAJOR@ diff --git a/src/highspy/__init__.py b/src/highspy/__init__.py index 3638f094c2..78005667b7 100644 --- a/src/highspy/__init__.py +++ b/src/highspy/__init__.py @@ -1,6 +1,6 @@ # from __future__ import annotations -from ._core import \ +from highspy._core import \ ObjSense, \ MatrixFormat, \ HessianFormat, \ diff --git a/src/highspy/highs.py b/src/highspy/highs.py index 9abf20ea26..5576abfc91 100644 --- a/src/highspy/highs.py +++ b/src/highspy/highs.py @@ -1,4 +1,4 @@ -from ._core import ( +from highspy._core import ( # enum classes ObjSense, MatrixFormat, diff --git a/src/meson.build b/src/meson.build index 2c9fa9aa31..e7ebe859ee 100644 --- a/src/meson.build +++ b/src/meson.build @@ -10,12 +10,22 @@ conf_data.set('HIGHS_VERSION_PATCH', meson.project_version().split('.')[2]) conf_data.set('ZLIB_FOUND', zlib_dep.found()) -# Is the use of the following two lines the cause of the meson build -# failure? + +if is_windows +# There is a bug with threading on windows, see CMakeList.txt:307 +# Also https://github.com/ERGO-Code/HiGHS/issues/1382#issuecomment-1670967735 +# Generally, no point using threading with HiGHs at this point (May 2024) + conf_data.set('HIGHS_NO_DEFAULT_THREADS', + true) +else + conf_data.set('HIGHS_NO_DEFAULT_THREADS', + threads_dep.found()) +endif +# This dependency hasn't been setup.. #conf_data.set('CUPDLP_CPU', # cupdlp_cpu.found()) # 64 bit numbers -if host_machine.cpu_family() == 'x86_64' +if host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'amd64' # Get user's option, if it's not provided, enable highsint64 by default on x86_64 highsint64_opt = get_option('highsint64') conf_data.set('HIGHSINT64', highsint64_opt) @@ -290,6 +300,8 @@ if get_option('default_library') == 'static' symbol_visibility = 'inlineshidden' endif + +if not get_option('with_pybind11') highslib = library('highs', highslib_srcs, dependencies: _deps, @@ -299,6 +311,12 @@ highslib = library('highs', gnu_symbol_visibility: symbol_visibility, pic: true, install: true) + +highs_dep = declare_dependency(link_with: highslib, + dependencies: _deps, + include_directories: _incdirs, + ) +endif # --------------- Interfaces @@ -334,15 +352,27 @@ if get_option('with_csharp') install: true) endif -highs_dep = declare_dependency(link_with: highslib, - dependencies: _deps, - include_directories: _incdirs, - ) if get_option('with_pybind11') - _deps += highs_dep py = import('python').find_installation(pure: false) + highslib = library('highs', + highslib_srcs, + dependencies: _deps, + cpp_args: _args, + c_args: _args, + include_directories: _incdirs, + gnu_symbol_visibility: symbol_visibility, + pic: true, + install: true, + install_dir: py.get_install_dir() / 'highspy') + +highs_dep = declare_dependency(link_with: highslib, + dependencies: _deps, + include_directories: _incdirs, + ) + _deps += highs_dep + pyb11_dep = [ # py_dep is auto-added for Python >= 3.9, so it can be dropped here when # that is the minimum supported Python version @@ -360,10 +390,9 @@ if get_option('with_pybind11') py.extension_module( '_core', - sources : highspy_cpp, + sources : highspy_cpp + highs_conf_file, dependencies: _deps, cpp_args: _args, - link_with: highslib, install: true, subdir: 'highspy', include_directories: _incdirs, @@ -371,7 +400,7 @@ if get_option('with_pybind11') py.extension_module( '_highs_options', - sources : highsoptions_cpp, + sources : highsoptions_cpp + highs_conf_file, dependencies: _deps, cpp_args: _args, install: true, @@ -387,4 +416,9 @@ if get_option('with_pybind11') subdir: 'highspy' ) +if is_windows + rootdir = meson.source_root() + meson.add_install_script(f'@rootdir@' / 'scripts' / 'post_install_win.bat', '{dest_dir}', '{wheel}') +endif + endif From 12ba85a68f0973ceab52785e20412dcf88294938 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 14 Jul 2024 22:46:14 +0000 Subject: [PATCH 19/24] BLD: Rework meson slightly --- meson.build | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index 167b44f46d..3c02480b0a 100644 --- a/meson.build +++ b/meson.build @@ -28,7 +28,7 @@ _args += cppc.get_supported_arguments([ ]) if cppc.get_id() == 'msvc' - add_project_arguments( +_args += cppc.get_supported_arguments([ '/wd4018', # Disable warning: 'expression' : signed/unsigned mismatch '/wd4061', # Disable warning: enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label '/wd4100', # Disable warning: 'identifier' : unreferenced formal parameter @@ -48,9 +48,8 @@ if cppc.get_id() == 'msvc' '/wd4514', # Disable warning: 'function' : unreferenced inline function has been removed '/wd4701', # Disable warning: potentially uninitialized local variable 'name' used '/wd4820', # Disable warning: 'bytes' bytes padding added after construct 'member_name' - language: 'cpp', - ) - _args += '-D_CRT_SECURE_NO_WARNINGS' + ]) +_args += '-D_CRT_SECURE_NO_WARNINGS' endif cpu_family = host_machine.cpu_family() @@ -64,7 +63,7 @@ endif if is_mingw # For mingw-w64, don't use LTO - add_project_arguments('-fno-use-linker-plugin', language: ['c', 'cpp']) + add_project_arguments(cppc.get_supported_arguments('-fno-use-linker-plugin'), language: ['c', 'cpp']) endif # --------------------- Dependencies From 7ed8ca2b2a988e350630425827801adf171edc3c Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sun, 14 Jul 2024 22:46:32 +0000 Subject: [PATCH 20/24] BLD: Revert back to scikit-build --- pyproject.toml | 182 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 150 insertions(+), 32 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 56d9cb9fe5..e3173dfedf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,8 +3,8 @@ "Bug Tracker" = "https://github.com/ERGO-Code/HiGHS/issues" [build-system] -requires = ["meson-python>=0.16.0", "meson>=1.2.0", "pybind11", "ninja"] -build-backend = "mesonpy" +requires = ["scikit-build-core>=0.3.3", "pybind11", "numpy"] +build-backend = "scikit_build_core.build" [project] name = "highspy" @@ -30,14 +30,154 @@ classifiers = [ [project.optional-dependencies] test = ["pytest", "numpy"] -[tool.meson-python.args] -setup = ['-Dwith_pybind11=True', - '-Dhighsint64=False', - '-Dwrap_mode=forcefallback', - # ^-- collects pybind11, see https://github.com/ERGO-Code/HiGHS/pull/1343#discussion_r1252446966 - ] -dist = ['--include-subprojects'] -install = ['--skip-subprojects'] +[tool.scikit-build] +cmake.args = ["-DPYTHON_BUILD_SETUP=ON"] +wheel.expand-macos-universal-tags = true + +# A list of packages to auto-copy into the wheel. If this is not set, it will +# default to the first of ``src/``, ``python/``, or +# ```` if they exist. The prefix(s) will be stripped from the package +# name inside the wheel. +wheel.packages = ["src/highspy"] + +# Files to include in the SDist even if they are skipped by default. Supports +# gitignore syntax. +sdist.include = [ + "src/highspy/highs.py", + "tests/test_highspy.py", + "Version.txt", + "LICENSE", + "README.md", + "src/HConfig.h.in", + "src", + "external", + "cmake", +] + +sdist.exclude = [ + ".github", + ".gitattributes", + ".gitignore", + ".github", + "app", + "build", + "check", + "docs", + "subprojects", + ".coin-or", + "build_webdemo.sh", + ".clang-format", + "__setup.py", + "BUILD.bazel", + "meson*", + "MODS.md", + "WORKSPACE", +] + + +# # Verbose printout when building. +# cmake.verbose = false + +# # The build type to use when building the project. Valid options are: "Debug", +# # "Release", "RelWithDebInfo", "MinSizeRel", "", etc. +# cmake.build-type = "Release" + +# # The versions of Ninja to allow. If Ninja is not present on the system or does +# # not pass this specifier, it will be downloaded via PyPI if possible. An empty +# # string will disable this check. +# ninja.version = ">=1.5" + +# # If CMake is not present on the system or is older required, it will be +# # downloaded via PyPI if possible. An empty string will disable this check. +# ninja.make-fallback = true + +# # The logging level to display, "DEBUG", "INFO", "WARNING", and "ERROR" are +# # possible options. +# logging.level = "WARNING" + + +# # If set to True, try to build a reproducible distribution (Unix and Python 3.9+ +# # recommended). ``SOURCE_DATE_EPOCH`` will be used for timestamps, or a fixed +# # value if not set. +# sdist.reproducible = true + +# # If set to True, CMake will be run before building the SDist. +# sdist.cmake = false + +# # The Python tags. The default (empty string) will use the default Python +# # version. You can also set this to "cp37" to enable the CPython 3.7+ Stable ABI +# # / Limited API (only on CPython and if the version is sufficient, otherwise +# # this has no effect). Or you can set it to "py3" or "py2.py3" to ignore Python +# # ABI compatibility. The ABI tag is inferred from this tag. +# wheel.py-api = "" + +# # Fill out extra tags that are not required. This adds "x86_64" and "arm64" to +# # the list of platforms when "universal2" is used, which helps older Pip's +# # (before 21.0.1) find the correct wheel. +# # wheel.expand-macos-universal-tags = false + +# # The install directory for the wheel. This is relative to the platlib root. You +# # might set this to the package name. The original dir is still at +# # SKBUILD_PLATLIB_DIR (also SKBUILD_DATA_DIR, etc. are available). EXPERIMENTAL: +# # An absolute path will be one level higher than the platlib root, giving access +# # to "/platlib", "/data", "/headers", and "/scripts". +# # wheel.install-dir = "" + +# # A list of license files to include in the wheel. Supports glob patterns. +# wheel.license-files = ["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"] + +# # If set to True (the default), CMake will be run before building the wheel. +# wheel.cmake = true + +# # Target the platlib or the purelib. If not set, the default is to target the +# # platlib if wheel.cmake is true, and the purelib otherwise. +# # wheel.platlib = "" + +# # A set of patterns to exclude from the wheel. This is additive to the SDist +# # exclude patterns. This applies to the final paths in the wheel, and can +# # exclude files from CMake output as well. Editable installs may not respect +# # this exclusion. +# wheel.exclude = [] + +# # The build tag to use for the wheel. If empty, no build tag is used. +# wheel.build-tag = "" + +# # If CMake is less than this value, backport a copy of FindPython. Set to 0 +# # disable this, or the empty string. +# backport.find-python = "3.26.1" + +# # Select the editable mode to use. Can be "redirect" (default) or "inplace". +# editable.mode = "redirect" + +# # Turn on verbose output for the editable mode rebuilds. +# editable.verbose = true + +# # Rebuild the project when the package is imported. The build-directory must be +# # set. +# editable.rebuild = false + +# # The components to install. If empty, all default components are installed. +# install.components = [] + +# # Whether to strip the binaries. True for scikit-build-core 0.5+. +# install.strip = false + +# # List dynamic metadata fields and hook locations in this table. +# metadata = {} + +# # Strictly check all config options. If False, warnings will be printed for +# # unknown options. If True, an error will be raised. +# strict-config = true + +# # Enable early previews of features not finalized yet. +# experimental = false + +# # If set, this will provide a method for backward compatibility. +# # minimum-version = "0.8" # current version + +# # The build directory. Defaults to a temporary directory, but can be set. +# # build-dir = "" + [tool.pytest.ini_options] minversion = "6.0" @@ -56,25 +196,3 @@ test-command = "pytest {project}/tests" test-extras = ["test", "numpy"] test-skip = ["*universal2:arm64"] build-verbosity = 1 - -[tool.cibuildwheel.linux] -manylinux-x86_64-image = "manylinux2014" -manylinux-i686-image = "manylinux2014" -repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}" - -[tool.cibuildwheel.macos] -archs = ["x86_64 arm64"] -environment = { RUNNER_OS="macOS" } -repair-wheel-command = [ - "delocate-listdeps {wheel}", - "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}", -] - -#[tool.cibuildwheel.windows] -#before-build = "pip install delvewheel" -#repair-wheel-command = "delvewheel repair -w {dest_dir} {wheel}" - -[tool.cibuildwheel.windows] -# Use delvewheel on windows, and install the project so delvewheel can find it -before-build = "pip install delvewheel meson ninja && meson setup bbdir && meson install -C bbdir" -repair-wheel-command = "delvewheel repair --add-path c:/bin;c:/lib;c:/bin/src;c:/lib/src;D:/a/HiGHS/HiGHS/bbdir/src/ -w {dest_dir} {wheel}" From 1ca67197a42f10bdeb522cf1f027200a1545b93b Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 20 Jul 2024 18:47:16 +0000 Subject: [PATCH 21/24] BLD: Export python sources via variable --- src/meson.build | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/meson.build b/src/meson.build index e7ebe859ee..7788c9e0d7 100644 --- a/src/meson.build +++ b/src/meson.build @@ -408,10 +408,11 @@ highs_dep = declare_dependency(link_with: highslib, include_directories: _incdirs, ) - py.install_sources([ + highs_py_srcs = files( 'highspy/__init__.py', - 'highspy/highs.py', - ], + 'highspy/highs.py',) + + py.install_sources(highs_py_srcs, pure: false, subdir: 'highspy' ) From 8dc335eb802f23fc40a17b9e215163c0ca75b28a Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 20 Jul 2024 18:47:57 +0000 Subject: [PATCH 22/24] BIND: Use module local scope for exports --- src/highs_bindings.cpp | 75 +++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/src/highs_bindings.cpp b/src/highs_bindings.cpp index 5d747c1ec6..99563a4486 100644 --- a/src/highs_bindings.cpp +++ b/src/highs_bindings.cpp @@ -580,28 +580,28 @@ std::tuple highs_getRowByName(Highs* h, PYBIND11_MODULE(_core, m) { // enumerations // Older enums, need to have values exported - py::enum_(m, "SolutionStatus") + py::enum_(m, "SolutionStatus", py::module_local()) .value("kSolutionStatusNone", SolutionStatus::kSolutionStatusNone) .value("kSolutionStatusInfeasible", SolutionStatus::kSolutionStatusInfeasible) .value("kSolutionStatusFeasible", SolutionStatus::kSolutionStatusFeasible) .export_values(); - py::enum_(m, "BasisValidity") + py::enum_(m, "BasisValidity", py::module_local()) .value("kBasisValidityInvalid", BasisValidity::kBasisValidityInvalid) .value("kBasisValidityValid", BasisValidity::kBasisValidityValid) .export_values(); // C++ enum classes do not need to have values exported - py::enum_(m, "ObjSense") + py::enum_(m, "ObjSense", py::module_local()) .value("kMinimize", ObjSense::kMinimize) .value("kMaximize", ObjSense::kMaximize); - py::enum_(m, "MatrixFormat") + py::enum_(m, "MatrixFormat", py::module_local()) .value("kColwise", MatrixFormat::kColwise) .value("kRowwise", MatrixFormat::kRowwise) .value("kRowwisePartitioned", MatrixFormat::kRowwisePartitioned); - py::enum_(m, "HessianFormat") + py::enum_(m, "HessianFormat", py::module_local()) .value("kTriangular", HessianFormat::kTriangular) .value("kSquare", HessianFormat::kSquare); - py::enum_(m, "HighsModelStatus") + py::enum_(m, "HighsModelStatus", py::module_local()) .value("kNotset", HighsModelStatus::kNotset) .value("kLoadError", HighsModelStatus::kLoadError) .value("kModelError", HighsModelStatus::kModelError) @@ -621,7 +621,7 @@ PYBIND11_MODULE(_core, m) { .value("kSolutionLimit", HighsModelStatus::kSolutionLimit) .value("kInterrupt", HighsModelStatus::kInterrupt) .value("kMemoryLimit", HighsModelStatus::kMemoryLimit); - py::enum_(m, "HighsPresolveStatus") + py::enum_(m, "HighsPresolveStatus", py::module_local()) .value("kNotPresolved", HighsPresolveStatus::kNotPresolved) .value("kNotReduced", HighsPresolveStatus::kNotReduced) .value("kInfeasible", HighsPresolveStatus::kInfeasible) @@ -632,38 +632,38 @@ PYBIND11_MODULE(_core, m) { .value("kTimeout", HighsPresolveStatus::kTimeout) .value("kNullError", HighsPresolveStatus::kNullError) .value("kOptionsError", HighsPresolveStatus::kOptionsError); - py::enum_(m, "HighsBasisStatus") + py::enum_(m, "HighsBasisStatus", py::module_local()) .value("kLower", HighsBasisStatus::kLower) .value("kBasic", HighsBasisStatus::kBasic) .value("kUpper", HighsBasisStatus::kUpper) .value("kZero", HighsBasisStatus::kZero) .value("kNonbasic", HighsBasisStatus::kNonbasic); - py::enum_(m, "HighsVarType") + py::enum_(m, "HighsVarType", py::module_local()) .value("kContinuous", HighsVarType::kContinuous) .value("kInteger", HighsVarType::kInteger) .value("kSemiContinuous", HighsVarType::kSemiContinuous) .value("kSemiInteger", HighsVarType::kSemiInteger); - py::enum_(m, "HighsOptionType") + py::enum_(m, "HighsOptionType", py::module_local()) .value("kBool", HighsOptionType::kBool) .value("kInt", HighsOptionType::kInt) .value("kDouble", HighsOptionType::kDouble) .value("kString", HighsOptionType::kString); - py::enum_(m, "HighsInfoType") + py::enum_(m, "HighsInfoType", py::module_local()) .value("kInt64", HighsInfoType::kInt64) .value("kInt", HighsInfoType::kInt) .value("kDouble", HighsInfoType::kDouble); - py::enum_(m, "HighsStatus") + py::enum_(m, "HighsStatus", py::module_local()) .value("kError", HighsStatus::kError) .value("kOk", HighsStatus::kOk) .value("kWarning", HighsStatus::kWarning); - py::enum_(m, "HighsLogType") + py::enum_(m, "HighsLogType", py::module_local()) .value("kInfo", HighsLogType::kInfo) .value("kDetailed", HighsLogType::kDetailed) .value("kVerbose", HighsLogType::kVerbose) .value("kWarning", HighsLogType::kWarning) .value("kError", HighsLogType::kError); // Classes - py::class_(m, "HighsSparseMatrix") + py::class_(m, "HighsSparseMatrix", py::module_local()) .def(py::init<>()) .def_readwrite("format_", &HighsSparseMatrix::format_) .def_readwrite("num_col_", &HighsSparseMatrix::num_col_) @@ -672,7 +672,7 @@ PYBIND11_MODULE(_core, m) { .def_readwrite("p_end_", &HighsSparseMatrix::p_end_) .def_readwrite("index_", &HighsSparseMatrix::index_) .def_readwrite("value_", &HighsSparseMatrix::value_); - py::class_(m, "HighsLp") + py::class_(m, "HighsLp", py::module_local()) .def(py::init<>()) .def_readwrite("num_col_", &HighsLp::num_col_) .def_readwrite("num_row_", &HighsLp::num_row_) @@ -692,18 +692,18 @@ PYBIND11_MODULE(_core, m) { .def_readwrite("is_scaled_", &HighsLp::is_scaled_) .def_readwrite("is_moved_", &HighsLp::is_moved_) .def_readwrite("mods_", &HighsLp::mods_); - py::class_(m, "HighsHessian") + py::class_(m, "HighsHessian", py::module_local()) .def(py::init<>()) .def_readwrite("dim_", &HighsHessian::dim_) .def_readwrite("format_", &HighsHessian::format_) .def_readwrite("start_", &HighsHessian::start_) .def_readwrite("index_", &HighsHessian::index_) .def_readwrite("value_", &HighsHessian::value_); - py::class_(m, "HighsModel") + py::class_(m, "HighsModel", py::module_local()) .def(py::init<>()) .def_readwrite("lp_", &HighsModel::lp_) .def_readwrite("hessian_", &HighsModel::hessian_); - py::class_(m, "HighsInfo") + py::class_(m, "HighsInfo", py::module_local()) .def(py::init<>()) .def_readwrite("valid", &HighsInfo::valid) .def_readwrite("mip_node_count", &HighsInfo::mip_node_count) @@ -740,7 +740,7 @@ PYBIND11_MODULE(_core, m) { &HighsInfo::max_complementarity_violation) .def_readwrite("sum_complementarity_violations", &HighsInfo::sum_complementarity_violations); - py::class_(m, "HighsOptions") + py::class_(m, "HighsOptions", py::module_local()) .def(py::init<>()) .def_readwrite("presolve", &HighsOptions::presolve) .def_readwrite("solver", &HighsOptions::solver) @@ -828,7 +828,7 @@ PYBIND11_MODULE(_core, m) { &HighsOptions::mip_heuristic_effort) .def_readwrite("mip_min_logging_interval", &HighsOptions::mip_min_logging_interval); - py::class_(m, "_Highs") + py::class_(m, "_Highs", py::module_local()) .def(py::init<>()) .def("version", &Highs::version) .def("versionMajor", &Highs::versionMajor) @@ -967,7 +967,7 @@ PYBIND11_MODULE(_core, m) { .def("stopCallbackInt", static_cast( &Highs::stopCallback)); // structs - py::class_(m, "HighsSolution") + py::class_(m, "HighsSolution", py::module_local()) .def(py::init<>()) .def_readwrite("value_valid", &HighsSolution::value_valid) .def_readwrite("dual_valid", &HighsSolution::dual_valid) @@ -975,11 +975,11 @@ PYBIND11_MODULE(_core, m) { .def_readwrite("col_dual", &HighsSolution::col_dual) .def_readwrite("row_value", &HighsSolution::row_value) .def_readwrite("row_dual", &HighsSolution::row_dual); - py::class_(m, "HighsObjectiveSolution") + py::class_(m, "HighsObjectiveSolution", py::module_local()) .def(py::init<>()) .def_readwrite("objective", &HighsObjectiveSolution::objective) .def_readwrite("col_value", &HighsObjectiveSolution::col_value); - py::class_(m, "HighsBasis") + py::class_(m, "HighsBasis", py::module_local()) .def(py::init<>()) .def_readwrite("valid", &HighsBasis::valid) .def_readwrite("alien", &HighsBasis::alien) @@ -989,13 +989,13 @@ PYBIND11_MODULE(_core, m) { .def_readwrite("debug_origin_name", &HighsBasis::debug_origin_name) .def_readwrite("col_status", &HighsBasis::col_status) .def_readwrite("row_status", &HighsBasis::row_status); - py::class_(m, "HighsRangingRecord") + py::class_(m, "HighsRangingRecord", py::module_local()) .def(py::init<>()) .def_readwrite("value_", &HighsRangingRecord::value_) .def_readwrite("objective_", &HighsRangingRecord::objective_) .def_readwrite("in_var_", &HighsRangingRecord::in_var_) .def_readwrite("ou_var_", &HighsRangingRecord::ou_var_); - py::class_(m, "HighsRanging") + py::class_(m, "HighsRanging", py::module_local()) .def(py::init<>()) .def_readwrite("valid", &HighsRanging::valid) .def_readwrite("col_cost_up", &HighsRanging::col_cost_up) @@ -1016,7 +1016,7 @@ PYBIND11_MODULE(_core, m) { py::module_ simplex_constants = m.def_submodule("simplex_constants", "Submodule for simplex constants"); - py::enum_(simplex_constants, "SimplexStrategy") + py::enum_(simplex_constants, "SimplexStrategy", py::module_local()) .value("kSimplexStrategyMin", SimplexStrategy::kSimplexStrategyMin) .value("kSimplexStrategyChoose", SimplexStrategy::kSimplexStrategyChoose) .value("kSimplexStrategyDual", SimplexStrategy::kSimplexStrategyDual) @@ -1031,7 +1031,7 @@ PYBIND11_MODULE(_core, m) { .value("kSimplexStrategyNum", SimplexStrategy::kSimplexStrategyNum) .export_values(); // needed since it isn't an enum class py::enum_(simplex_constants, - "SimplexUnscaledSolutionStrategy") + "SimplexUnscaledSolutionStrategy", py::module_local()) .value( "kSimplexUnscaledSolutionStrategyMin", SimplexUnscaledSolutionStrategy::kSimplexUnscaledSolutionStrategyMin) @@ -1051,7 +1051,7 @@ PYBIND11_MODULE(_core, m) { "kSimplexUnscaledSolutionStrategyNum", SimplexUnscaledSolutionStrategy::kSimplexUnscaledSolutionStrategyNum) .export_values(); - py::enum_(simplex_constants, "SimplexSolvePhase") + py::enum_(simplex_constants, "SimplexSolvePhase", py::module_local()) .value("kSolvePhaseMin", SimplexSolvePhase::kSolvePhaseMin) .value("kSolvePhaseError", SimplexSolvePhase::kSolvePhaseError) .value("kSolvePhaseExit", SimplexSolvePhase::kSolvePhaseExit) @@ -1067,7 +1067,7 @@ PYBIND11_MODULE(_core, m) { .value("kSolvePhaseMax", SimplexSolvePhase::kSolvePhaseMax) .export_values(); py::enum_(simplex_constants, - "SimplexEdgeWeightStrategy") + "SimplexEdgeWeightStrategy", py::module_local()) .value("kSimplexEdgeWeightStrategyMin", SimplexEdgeWeightStrategy::kSimplexEdgeWeightStrategyMin) .value("kSimplexEdgeWeightStrategyChoose", @@ -1081,7 +1081,7 @@ PYBIND11_MODULE(_core, m) { .value("kSimplexEdgeWeightStrategyMax", SimplexEdgeWeightStrategy::kSimplexEdgeWeightStrategyMax) .export_values(); - py::enum_(simplex_constants, "SimplexPriceStrategy") + py::enum_(simplex_constants, "SimplexPriceStrategy", py::module_local()) .value("kSimplexPriceStrategyMin", SimplexPriceStrategy::kSimplexPriceStrategyMin) .value("kSimplexPriceStrategyCol", @@ -1096,7 +1096,7 @@ PYBIND11_MODULE(_core, m) { SimplexPriceStrategy::kSimplexPriceStrategyMax) .export_values(); py::enum_( - simplex_constants, "SimplexPivotalRowRefinementStrategy") + simplex_constants, "SimplexPivotalRowRefinementStrategy", py::module_local()) .value("kSimplexInfeasibilityProofRefinementMin", SimplexPivotalRowRefinementStrategy:: kSimplexInfeasibilityProofRefinementMin) @@ -1114,7 +1114,7 @@ PYBIND11_MODULE(_core, m) { kSimplexInfeasibilityProofRefinementMax) .export_values(); py::enum_(simplex_constants, - "SimplexPrimalCorrectionStrategy") + "SimplexPrimalCorrectionStrategy", py::module_local()) .value( "kSimplexPrimalCorrectionStrategyNone", SimplexPrimalCorrectionStrategy::kSimplexPrimalCorrectionStrategyNone) @@ -1125,7 +1125,7 @@ PYBIND11_MODULE(_core, m) { SimplexPrimalCorrectionStrategy:: kSimplexPrimalCorrectionStrategyAlways) .export_values(); - py::enum_(simplex_constants, "SimplexNlaOperation") + py::enum_(simplex_constants, "SimplexNlaOperation", py::module_local()) .value("kSimplexNlaNull", SimplexNlaOperation::kSimplexNlaNull) .value("kSimplexNlaBtranFull", SimplexNlaOperation::kSimplexNlaBtranFull) .value("kSimplexNlaPriceFull", SimplexNlaOperation::kSimplexNlaPriceFull) @@ -1142,14 +1142,15 @@ PYBIND11_MODULE(_core, m) { .value("kNumSimplexNlaOperation", SimplexNlaOperation::kNumSimplexNlaOperation) .export_values(); - py::enum_(simplex_constants, "EdgeWeightMode") + py::enum_(simplex_constants, "EdgeWeightMode", py::module_local()) .value("kDantzig", EdgeWeightMode::kDantzig) .value("kDevex", EdgeWeightMode::kDevex) .value("kSteepestEdge", EdgeWeightMode::kSteepestEdge) .value("kCount", EdgeWeightMode::kCount); + py::module_ callbacks = m.def_submodule("cb", "Callback interface submodule"); // Types for interface - py::enum_(callbacks, "HighsCallbackType") + py::enum_(callbacks, "HighsCallbackType", py::module_local()) .value("kCallbackMin", HighsCallbackType::kCallbackMin) .value("kCallbackLogging", HighsCallbackType::kCallbackLogging) .value("kCallbackSimplexInterrupt", @@ -1167,7 +1168,7 @@ PYBIND11_MODULE(_core, m) { .value("kNumCallbackType", HighsCallbackType::kNumCallbackType) .export_values(); // Classes - py::class_(callbacks, "HighsCallbackDataOut") + py::class_(callbacks, "HighsCallbackDataOut", py::module_local()) .def(py::init<>()) .def_readwrite("log_type", &HighsCallbackDataOut::log_type) .def_readwrite("running_time", &HighsCallbackDataOut::running_time) @@ -1194,7 +1195,7 @@ PYBIND11_MODULE(_core, m) { [](HighsCallbackDataOut& self, py::array_t new_mip_solution) { self.mip_solution = new_mip_solution.mutable_data(); }); - py::class_(callbacks, "HighsCallbackDataIn") + py::class_(callbacks, "HighsCallbackDataIn", py::module_local()) .def(py::init<>()) .def_readwrite("user_interrupt", &HighsCallbackDataIn::user_interrupt); } From cc6528009214f7e3476108cb531587cb1b73f9ae Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 20 Jul 2024 23:21:32 +0000 Subject: [PATCH 23/24] MAINT: Rework options for scipy --- src/highs_options.cpp | 53 +++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/src/highs_options.cpp b/src/highs_options.cpp index c043b0d697..a7f6e140d7 100644 --- a/src/highs_options.cpp +++ b/src/highs_options.cpp @@ -8,16 +8,10 @@ namespace py = pybind11; -bool log_to_console = false; -bool output_flag = true; - -// HighsLogOptions highs_log_options = {nullptr, &output_flag, &log_to_console, -// nullptr}; -HighsLogOptions highs_log_options = {}; - class HighsOptionsManager { public: HighsOptionsManager() { + initialize_log_options(); for (const auto& record : highs_options_.records) { record_type_lookup_.emplace(record->name, record->type); } @@ -55,6 +49,21 @@ class HighsOptionsManager { HighsOptions highs_options_; std::mutex highs_options_mutex; std::map record_type_lookup_; + HighsLogOptions highs_log_options; + + static constexpr bool log_to_console = false; + static constexpr bool output_flag = true; + + void initialize_log_options() { + highs_log_options.log_stream = nullptr; + highs_log_options.output_flag = const_cast(&output_flag); + highs_log_options.log_to_console = const_cast(&log_to_console); + highs_log_options.log_dev_level = nullptr; + highs_log_options.user_log_callback = nullptr; + highs_log_options.user_log_callback_data = nullptr; + highs_log_options.user_callback_data = nullptr; + highs_log_options.user_callback_active = false; + } }; PYBIND11_MODULE(_highs_options, m) { @@ -79,16 +88,32 @@ PYBIND11_MODULE(_highs_options, m) { }) .def("check_int_option", [](HighsOptionsManager& self, const std::string& name, int value) { - return self.check_option(name, value); + try { + return self.check_option(name, value); + } catch (const std::exception& e) { + py::print("Exception caught in check_int_option:", e.what()); + return false; + } }) .def( "check_double_option", [](HighsOptionsManager& self, const std::string& name, double value) { - return self.check_option(name, value); + try { + return self.check_option(name, value); + } catch (const std::exception& e) { + py::print("Exception caught in check_double_option:", e.what()); + return false; + } }) - .def("check_string_option", [](HighsOptionsManager& self, - const std::string& name, - const std::string& value) { - return self.check_option(name, value); - }); + .def("check_string_option", + [](HighsOptionsManager& self, const std::string& name, + const std::string& value) { + try { + return self.check_option(name, + value); + } catch (const std::exception& e) { + py::print("Exception caught in check_string_option:", e.what()); + return false; + } + }); } From 4097a89d3e50ad2f7f61e99b988fd64fba297128 Mon Sep 17 00:00:00 2001 From: Rohit Goswami Date: Sat, 20 Jul 2024 23:48:48 +0000 Subject: [PATCH 24/24] BLD: Use newer script location --- src/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meson.build b/src/meson.build index 7788c9e0d7..5fb54a97c2 100644 --- a/src/meson.build +++ b/src/meson.build @@ -418,7 +418,7 @@ highs_dep = declare_dependency(link_with: highslib, ) if is_windows - rootdir = meson.source_root() + rootdir = meson.project_source_root() meson.add_install_script(f'@rootdir@' / 'scripts' / 'post_install_win.bat', '{dest_dir}', '{wheel}') endif