5#ifndef IDOL_OPTIMIZERS_JUMP_H
6#define IDOL_OPTIMIZERS_JUMP_H
8#include "idol/general/optimizers/OptimizerWithLazyUpdates.h"
9#include "idol/general/utils/Set.h"
11namespace idol::Optimizers {
18 typedef struct _jl_value_t jl_value_t;
21 typedef struct _jl_function_t jl_function_t;
24 typedef struct _jl_module_t jl_module_t;
27 typedef struct _jl_array_t jl_array_t;
30 typedef struct _jl_datatype_t jl_datatype_t;
32 typedef struct _jl_sym_t jl_sym_t;
34 extern jl_module_t* jl_main_module;
35 extern jl_module_t* jl_base_module;
37 extern jl_value_t* jl_float64_type;
38 extern jl_value_t* jl_int64_type;
39 extern jl_value_t* jl_uint64_type;
40 extern jl_value_t* jl_bool_type;
41 extern jl_value_t* jl_any_type;
42 extern jl_value_t* jl_array_type;
45 void jl_atexit_hook(
int exitcode);
46 jl_value_t *jl_eval_string(
const char *str);
47 jl_value_t *jl_apply_array_type(jl_value_t *type,
size_t dim);
48 jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype,
void *data,
size_t nel,
int own_buffer);
49 jl_sym_t *jl_symbol(
const char *str);
50 jl_value_t *jl_get_global(jl_module_t *m, jl_sym_t *var);
52 jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, uint32_t nargs);
53 jl_value_t* jl_call0(jl_function_t* f);
54 jl_value_t* jl_call1(jl_function_t* f, jl_value_t* arg0);
55 jl_value_t* jl_call2(jl_function_t* f, jl_value_t* arg0, jl_value_t* arg1);
56 jl_value_t* jl_call3(jl_function_t* f, jl_value_t* arg0, jl_value_t* arg1, jl_value_t* arg2);
58 jl_value_t* jl_box_float64(
double x);
59 jl_value_t* jl_box_uint64(uint64_t x);
60 jl_value_t* jl_box_uint16(uint16_t x);
61 jl_value_t* jl_box_int64(int64_t x);
62 jl_value_t* jl_cstr_to_string(
const char* str);
64 double jl_unbox_float64(jl_value_t* v);
65 uint64_t jl_unbox_uint64(jl_value_t* v);
66 uint16_t jl_unbox_uint16(jl_value_t* v);
67 int64_t jl_unbox_int64(jl_value_t* v);
69 jl_datatype_t* jl_typeof(jl_value_t* v);
70 const char* jl_symbol_name(jl_sym_t* s);
72 jl_value_t* jl_exception_occurred(
void);
73 void jl_exception_clear(
void);
75 void jl_gc_collect(
int);
76 void jl_gc_enable(
int);
82 std::optional<uint64_t> m_model_id = 0;
83 const std::string m_optimizer;
84 const std::list<std::string> m_modules;
85 bool m_is_continuous_relaxation;
88 static std::unique_ptr<DynamicLib> m_dynamic_lib;
90 JuMP(
const Model& t_parent,
91 std::string t_optimizer,
92 const std::list<std::string>& t_modules,
93 bool t_is_continuous_relaxation);
97 static bool is_available();
98 static std::string get_version();
100 [[nodiscard]] std::string name()
const override;
101 [[nodiscard]] SolutionStatus get_status()
const override;
102 [[nodiscard]] SolutionReason get_reason()
const override;
103 [[nodiscard]]
double get_best_obj()
const override;
104 [[nodiscard]]
double get_best_bound()
const override;
105 [[nodiscard]]
double get_var_primal(
const Var &t_var)
const override;
106 [[nodiscard]]
double get_var_reduced_cost(
const Var &t_var)
const override;
107 [[nodiscard]]
double get_var_ray(
const Var &t_var)
const override;
108 [[nodiscard]]
double get_ctr_dual(
const Ctr &t_ctr)
const override;
109 [[nodiscard]]
double get_ctr_farkas(
const Ctr &t_ctr)
const override;
110 [[nodiscard]]
double get_relative_gap()
const override;
111 [[nodiscard]]
double get_absolute_gap()
const override;
112 [[nodiscard]]
unsigned int get_n_solutions()
const override;
113 [[nodiscard]]
unsigned int get_solution_index()
const override;
114 void debug_print()
const;
116 static DynamicLib& get_dynamic_lib(
bool t_throw_on_fail =
true);
118 void hook_optimize()
override;
120 virtual uint64_t hook_create_julia_model(jl_value_t* t_optimizer);
122 void set_solution_index(
unsigned int t_index)
override;
123 void hook_build()
override;
124 void hook_write(
const std::string &t_name)
override;
125 bool hook_add(
const Var &t_var,
bool t_add_column)
override;
126 bool hook_add(
const Ctr &t_ctr)
override;
127 bool hook_add(
const QCtr &t_ctr)
override;
128 bool hook_add(
const SOSCtr &t_ctr)
override;
129 void hook_update_objective_sense()
override;
130 void hook_update_matrix(
const Ctr &t_ctr,
const Var &t_var,
double t_constant)
override;
131 void hook_update()
override;
132 void hook_update(
const Var &t_var)
override;
133 void hook_update(
const Ctr &t_ctr)
override;
134 void hook_update_objective()
override;
135 void hook_update_rhs()
override;
136 void hook_remove(
const Var &t_var)
override;
137 void hook_remove(
const Ctr &t_ctr)
override;
138 void hook_remove(
const QCtr &t_ctr)
override;
139 void hook_remove(
const SOSCtr &t_ctr)
override;
142 jl_value_t* make_julia_vector(
const std::vector<T>& t_vector);
146#define JULIA_SYM_PTR(name) \
147typedef decltype(::name)* name##_t; \
148name##_t name = nullptr
151 void* m_handle =
nullptr;
153 static std::string find_library();
155 JULIA_SYM_PTR(jl_init);
156 JULIA_SYM_PTR(jl_atexit_hook);
157 JULIA_SYM_PTR(jl_eval_string);
158 JULIA_SYM_PTR(jl_apply_array_type);
159 JULIA_SYM_PTR(jl_ptr_to_array_1d);
160 JULIA_SYM_PTR(jl_symbol);
161 JULIA_SYM_PTR(jl_get_global);
163 JULIA_SYM_PTR(jl_call);
164 JULIA_SYM_PTR(jl_call0);
165 JULIA_SYM_PTR(jl_call1);
166 JULIA_SYM_PTR(jl_call2);
167 JULIA_SYM_PTR(jl_call3);
169 JULIA_SYM_PTR(jl_box_float64);
170 JULIA_SYM_PTR(jl_box_uint64);
171 JULIA_SYM_PTR(jl_box_uint16);
172 JULIA_SYM_PTR(jl_box_int64);
173 JULIA_SYM_PTR(jl_cstr_to_string);
175 JULIA_SYM_PTR(jl_unbox_float64);
176 JULIA_SYM_PTR(jl_unbox_uint64);
177 JULIA_SYM_PTR(jl_unbox_uint16);
178 JULIA_SYM_PTR(jl_unbox_int64);
180 JULIA_SYM_PTR(jl_typeof);
183 JULIA_SYM_PTR(jl_exception_occurred);
184 JULIA_SYM_PTR(jl_exception_clear);
186 JULIA_SYM_PTR(jl_gc_collect);
187 JULIA_SYM_PTR(jl_gc_enable);
189 JULIA_SYM_PTR(jl_main_module);
195 jl_value_t *jl_get_function(jl_module_t *m,
const char *name) {
196 auto& lib = idol::Optimizers::JuMP::get_dynamic_lib();
197 assert(m !=
nullptr);
198 return (jl_value_t*) lib.jl_get_global(m, lib.jl_symbol(name));
201 [[nodiscard]]
bool is_available()
const {
return m_handle; }
205jl_value_t* idol::Optimizers::JuMP::make_julia_vector(
const std::vector<T>& t_vector) {
207 auto& lib = get_dynamic_lib();
209 jl_value_t* julia_type;
210 if constexpr (std::is_same_v<T, double>) {
211 julia_type = (jl_value_t*) jl_float64_type;
212 }
else if constexpr (std::is_same_v<T, uint64_t>) {
213 julia_type = (jl_value_t*) jl_uint64_type;
218 jl_value_t* array_type = lib.jl_apply_array_type(julia_type, 1);
219 jl_array_t *result = lib.jl_ptr_to_array_1d(array_type, (T*) t_vector.data(), t_vector.size(), 0);
221 return (jl_value_t*) result;
224namespace idol::impl {
226 class JuliaSessionManager {
227 bool m_idol_jump_module_is_loaded =
false;
228 bool m_idol_coluna_is_loaded =
false;
229 Set<std::string> m_loaded_modules;
230 static JuliaSessionManager* s_julia_session_manager;
232 static JuliaSessionManager& get();
234 JuliaSessionManager();
235 JuliaSessionManager(
const JuliaSessionManager&) =
delete;
236 JuliaSessionManager(JuliaSessionManager&&) =
delete;
237 JuliaSessionManager& operator=(
const JuliaSessionManager&) =
delete;
238 JuliaSessionManager& operator=(JuliaSessionManager&&) =
delete;
240 static void load_idol_jump_module();
241 static void load_idol_coluna_module();
242 static void load_module(
const std::string &t_module);
244 ~JuliaSessionManager();
246 static void throw_if_julia_error();