Skip to content

Commit

Permalink
src layout
Browse files Browse the repository at this point in the history
  • Loading branch information
tlambert03 committed Dec 15, 2024
1 parent b971338 commit b763fe4
Show file tree
Hide file tree
Showing 36 changed files with 31,433 additions and 84 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ repository = "https://github.com/funkelab/ilpy"

[tool.setuptools]
packages = ["ilpy"]
package-dir = {"" = "src"}
package-data = { "ilpy" = ["py.typed", "*.pyi"] }

[tool.setuptools.dynamic]
Expand Down
50 changes: 20 additions & 30 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
define_macros = [("CYTHON_TRACE", CYTHON_TRACE)]


include_dirs = ["ilpy/impl"]
include_dirs = ["src/ilpy/impl"]
library_dirs = []
if os.name == "nt":
compile_args = ["/O2", "/std:c++17", "/wd4702"]
Expand All @@ -34,7 +34,7 @@

wrapper = Extension(
"ilpy.wrapper",
sources=["ilpy/wrapper.pyx"],
sources=["src/ilpy/wrapper.pyx"],
extra_compile_args=compile_args,
include_dirs=include_dirs,
define_macros=define_macros,
Expand All @@ -51,9 +51,9 @@


BACKEND_SOURCES = [
"ilpy/impl/solvers/Solution.cpp",
"ilpy/impl/solvers/Constraint.cpp",
"ilpy/impl/solvers/Objective.cpp",
"src/ilpy/impl/solvers/Solution.cpp",
"src/ilpy/impl/solvers/Constraint.cpp",
"src/ilpy/impl/solvers/Objective.cpp",
]


Expand All @@ -62,40 +62,30 @@ def _find_lib(lib: str) -> str | None:
for prefix in ("lib", ""):
libname = f"{prefix}{lib}" # only using gurobi 11 at the moment
if found := util.find_library(libname):
print("FOUND library: ", found, libname)
print(f"FOUND library: {found} @ {libname}")
return libname
return None


if gurobi_lib := _find_lib("gurobi110"):
gurobi_backend = Extension(
name="ilpy.ilpybackend-gurobi",
sources=["ilpy/impl/solvers/GurobiBackend.cpp", *BACKEND_SOURCES],
for backend_name, lib_name in [
("Gurobi", "gurobi110"),
("Scip", "scip")
]:
if not (libname := _find_lib(lib_name)):
print(f"{backend_name} library NOT found, skipping {backend_name} backend")
continue
ext = Extension(
name=f"ilpy.ilpybackend-{backend_name.lower()}",
sources=[f"src/ilpy/impl/solvers/{backend_name}Backend.cpp", *BACKEND_SOURCES],
include_dirs=include_dirs,
libraries=[gurobi_lib],
libraries=[libname],
library_dirs=library_dirs,
extra_compile_args=compile_args,
define_macros=define_macros,
)
ext_modules.append(gurobi_backend)
else:
print("Gurobi library NOT found, skipping Gurobi backend")


if scip_lib := _find_lib("scip"):
scip_backend = Extension(
name="ilpy.ilpybackend-scip",
sources=["ilpy/impl/solvers/ScipBackend.cpp", *BACKEND_SOURCES],
include_dirs=include_dirs,
libraries=["scip"],
library_dirs=library_dirs,
extra_compile_args=compile_args,
define_macros=define_macros,
)
ext_modules.append(scip_backend)
else:
print("SCIP library NOT found, skipping SCIP backend")

ext_modules.append(ext)



################ Custom build_ext command ################

Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion ilpy/decl.pxd → src/ilpy/decl.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ cdef extern from "impl/solvers/SolverFactory.cpp":

cdef extern from "impl/solvers/SolverFactory.h":
cdef cppclass SolverFactory:
shared_ptr[SolverBackend] createSolverBackend(Preference) except +
shared_ptr[SolverBackend] createSolverBackend(const string& directory, Preference) except +
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "SolverFactory.h"
#include "SolverBackend.h"
#include <Python.h> // For Py_GetPath
#include <iostream>
#include <memory>
#include <stdexcept>
Expand Down Expand Up @@ -30,46 +29,12 @@
#define SCIP_LIB_NAME "ilpybackend-scip.so"
#endif

// Load a library and return a handle
// This function attempts to locate the ilpy.wrapper module and load the library
// from the same directory.
void *loadLibrary(const std::string &libName) {
// Get the path to the `ilpy.wrapper` module
PyObject *module = PyImport_ImportModule("ilpy.wrapper");
if (!module) {
throw std::runtime_error("Failed to import ilpy.wrapper module");
}
PyObject *module_path = PyObject_GetAttrString(module, "__file__");
if (!module_path) {
Py_DECREF(module);
throw std::runtime_error("Failed to get ilpy.wrapper module path");
}
std::string path(PyUnicode_AsUTF8(module_path));
Py_DECREF(module_path);
Py_DECREF(module);

// Strip the module filename to get the directory
auto pos = path.find_last_of('/');
std::string dir = path.substr(0, pos);

// Append the library name to the directory
std::string fullPath = dir + "/" + libName;

// Load the library
void *handle = DLOPEN(fullPath.c_str());
if (!handle) {
throw std::runtime_error("Failed to load library: " + fullPath + " - " +
DLERROR());
}
return handle;
}

// Free function for loading a backend
std::shared_ptr<SolverBackend> loadBackend(const char *libName) {
std::shared_ptr<SolverBackend> loadBackend(const char *libPath) {
// Load the library
void *handle = loadLibrary((std::string)libName);
void *handle = DLOPEN(libPath);
if (!handle) {
throw std::runtime_error(std::string("Failed to load library: ") + libName +
throw std::runtime_error(std::string("Failed to load library: ") + libPath +
" - " + DLERROR());
}

Expand All @@ -80,7 +45,7 @@ std::shared_ptr<SolverBackend> loadBackend(const char *libName) {
DLCLOSE(handle);
throw std::runtime_error(
std::string("Failed to find symbol 'createSolverBackend' in ") +
libName + " - " + DLERROR());
libPath + " - " + DLERROR());
}

// Create the backend
Expand All @@ -101,31 +66,35 @@ std::shared_ptr<SolverBackend> loadBackend(const char *libName) {
* @return A shared pointer to the created solver backend.
*/
std::shared_ptr<SolverBackend>
SolverFactory::createSolverBackend(Preference preference) const {
std::vector<const char *> libraries;
SolverFactory::createSolverBackend(const std::string &directory,
Preference preference) const {
std::vector<std::string> libraries;

// Determine which libraries to try based on preference
if (preference == Gurobi) {
libraries.push_back(GUROBI_LIB_NAME);
libraries.push_back(directory + "/" + GUROBI_LIB_NAME);
} else if (preference == Scip) {
libraries.push_back(SCIP_LIB_NAME);
libraries.push_back(directory + "/" + SCIP_LIB_NAME);
} else if (preference == Any) {
libraries = {GUROBI_LIB_NAME, SCIP_LIB_NAME}; // Specify the order
libraries = {directory + "/" + GUROBI_LIB_NAME,
directory + "/" + SCIP_LIB_NAME};
} else {
throw std::runtime_error("Invalid solver preference.");
}

// Attempt to load backends in order
for (const char *libName : libraries) {
for (const auto& libPath : libraries) {
try {
return loadBackend(libName);
std::cout << "Trying to load backend from " << libPath << std::endl;
return loadBackend(libPath.c_str());
} catch (const std::exception &e) {
std::cerr << "Warning: Failed to load backend from " << libName << ": "
std::cerr << "Warning: Failed to load backend from " << libPath << ": "
<< e.what() << std::endl;
}
}

// If no backends were successfully loaded
throw std::runtime_error("No suitable solver backend available for preference " +
preferenceToString(preference));
throw std::runtime_error(
"No suitable solver backend available for preference " +
preferenceToString(preference));
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
class SolverFactory {

public:

std::shared_ptr<SolverBackend> createSolverBackend(Preference preference = Any) const;
std::shared_ptr<SolverBackend>
createSolverBackend(const std::string &directory,
Preference preference = Any) const;
};

#endif // INFERENCE_DEFAULT_FACTORY_H__

File renamed without changes.
File renamed without changes.
Loading

0 comments on commit b763fe4

Please sign in to comment.