From e664545429a2f454b98d0a4438a3950db862a802 Mon Sep 17 00:00:00 2001 From: Mark Eberlein Date: Tue, 28 Jan 2020 13:12:45 -0800 Subject: [PATCH 1/4] Add CMake build process, automatic KLU detection, and README to KLU_DLL library generation --- solver_klu/source/KLU_DLL/CMakeLists.txt | 34 +++++++++++ solver_klu/source/KLU_DLL/KLU_DLL.h | 14 +++-- solver_klu/source/KLU_DLL/README.md | 61 +++++++++++++++++++ solver_klu/source/KLU_DLL/cmake/FindKLU.cmake | 51 ++++++++++++++++ 4 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 solver_klu/source/KLU_DLL/CMakeLists.txt create mode 100644 solver_klu/source/KLU_DLL/README.md create mode 100644 solver_klu/source/KLU_DLL/cmake/FindKLU.cmake diff --git a/solver_klu/source/KLU_DLL/CMakeLists.txt b/solver_klu/source/KLU_DLL/CMakeLists.txt new file mode 100644 index 0000000..a3c7262 --- /dev/null +++ b/solver_klu/source/KLU_DLL/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.6) +project(solver_KLU) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") + +find_package(KLU REQUIRED) + +add_library(${PROJECT_NAME} SHARED + KLU_DLL.h + KLU_DLL.cpp + ) + +if (WIN32) + set(KLU_LIB_PREFIX "") +else () + set(KLU_LIB_PREFIX "lib_") +endif () +set_target_properties(${PROJECT_NAME} + PROPERTIES PREFIX ${KLU_LIB_PREFIX} + ) + +target_include_directories(${PROJECT_NAME} PRIVATE ${KLU_INCLUDES}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${KLU_LIBRARIES}) + +set(FILE_PERMISSIONS PERMISSIONS + OWNER_EXECUTE OWNER_READ OWNER_WRITE + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + +install(TARGETS ${PROJECT_NAME} + ${FILE_PERMISSIONS} + LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/gridlabd + ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/gridlabd + COMPONENT library) diff --git a/solver_klu/source/KLU_DLL/KLU_DLL.h b/solver_klu/source/KLU_DLL/KLU_DLL.h index 819f393..0c5005e 100644 --- a/solver_klu/source/KLU_DLL/KLU_DLL.h +++ b/solver_klu/source/KLU_DLL/KLU_DLL.h @@ -1,5 +1,11 @@ // KLU_DLL.h +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#else +#define EXPORT +#endif + typedef struct { double *a_LU; double *rhs_LU; @@ -15,14 +21,14 @@ typedef struct { } KLU_STRUCT; //Initialization function -extern "C" __declspec(dllexport) void *LU_init(void *ext_array); +extern "C" EXPORT void *LU_init(void *ext_array); // Allocation function -extern "C" __declspec(dllexport) void LU_alloc(void *ext_array, unsigned int rowcount, unsigned int colcount, bool admittance_change); +extern "C" EXPORT void LU_alloc(void *ext_array, unsigned int rowcount, unsigned int colcount, bool admittance_change); // Solver function -extern "C" __declspec(dllexport) int LU_solve(void *ext_array, NR_SOLVER_VARS *system_info_vars, unsigned int rowcount, unsigned int colcount); +extern "C" EXPORT int LU_solve(void *ext_array, NR_SOLVER_VARS *system_info_vars, unsigned int rowcount, unsigned int colcount); // Destructive function -extern "C" __declspec(dllexport) void LU_destroy(void *ext_array, bool new_iteration); +extern "C" EXPORT void LU_destroy(void *ext_array, bool new_iteration); diff --git a/solver_klu/source/KLU_DLL/README.md b/solver_klu/source/KLU_DLL/README.md new file mode 100644 index 0000000..6f1d9bd --- /dev/null +++ b/solver_klu/source/KLU_DLL/README.md @@ -0,0 +1,61 @@ +# GridLAB-D KLU External Powerflow Solver + +## Dependencies +### Installing KLU +The KLU External Solver requires an installation of KLU, now included in +the SuiteSparse Library package. + +SuiteSparse is available in Ubuntu as `suitesparse` and MinGW/MSYS2 as +`mingw-w64-x86_64-suitesparse` + +#### Ubuntu installation +to install SuiteSparse on Ubuntu run the following command: +`sudo apt install suitesparse` + +#### MSYS2 installation +to install SuiteSparse on MSYS2 run the following command: +`pacman -S mingw-w64-x86_64-suitesparse` + +### Other Dependencies +The build process for the KLU External Solver additionally requires the +following: +1. CMake (v3.6 or later) +2. Build tools and compilers used for GridLAB-D + + +## Building KLU External Solver +1. Open KLU_DLL directory in terminal +2. Create build directory (e.g. `mkdir build`) +3. Move into directory (e.g. `cd build`) +3. Invoke CMake, and set installation directory to GridLAB-D install +prefix (e.g. +`cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/gridlabd ../`) +4. Build and install the library (e.g. `cmake --build . --target install` +\[note: `sudo` may be required depending on installation target\]) + +The KLU External Solver will be compiled and installed in your GridLAB-D +install directory. + +If you are unable to directly install, step 4 can be replaced with +`cmake --build .` and the produced `solver_KLU.dll` or `lib_solver_KLU.so` +manually moved to GridLAB-D's install directory and placed in +`/lib/gridlabd` + +## GLM Formatting +To activate the library linkage, it is required to add the `lu_solver` +tag in powerflow module section of your .GLM file, +to indicate the external solver should be used. + +Example powerflow module invocation: +``` cpp +module powerflow { + lu_solver "KLU"; + solver_method NR; +} +``` + +## More Information +More extensive details related to the External LU Solver Interface can be found on the +[Powerflow External LU Solver Interface](http://gridlab-d.shoutwiki.com/wiki/Powerflow_External_LU_Solver_Interface) +page of the GridLAB-D Wiki. + diff --git a/solver_klu/source/KLU_DLL/cmake/FindKLU.cmake b/solver_klu/source/KLU_DLL/cmake/FindKLU.cmake new file mode 100644 index 0000000..b77a1e2 --- /dev/null +++ b/solver_klu/source/KLU_DLL/cmake/FindKLU.cmake @@ -0,0 +1,51 @@ +# This finder is a modified version of https://gitlab.com/libeigen/eigen/blob/master/cmake/FindKLU.cmake +# All rights and ownership belong to the author + +# KLU lib usually requires linking to a blas library. +# It is up to the user of this module to find a BLAS and link to it. + +if (KLU_INCLUDES AND KLU_LIBRARIES) + set(KLU_FIND_QUIETLY TRUE) +endif () + +find_path(KLU_INCLUDES + NAMES + klu.h + PATHS + $ENV{KLUDIR} + ${INCLUDE_INSTALL_DIR} + PATH_SUFFIXES + suitesparse + ufsparse + ) + +find_library(KLU_LIBRARIES klu PATHS $ENV{KLUDIR} ${LIB_INSTALL_DIR}) + +if (KLU_LIBRARIES) + + if (NOT KLU_LIBDIR) + get_filename_component(KLU_LIBDIR ${KLU_LIBRARIES} PATH) + endif () + + find_library(COLAMD_LIBRARY colamd PATHS ${KLU_LIBDIR} $ENV{KLUDIR} ${LIB_INSTALL_DIR}) + if (COLAMD_LIBRARY) + set(KLU_LIBRARIES ${KLU_LIBRARIES} ${COLAMD_LIBRARY}) + endif () + + find_library(AMD_LIBRARY amd PATHS ${KLU_LIBDIR} $ENV{KLUDIR} ${LIB_INSTALL_DIR}) + if (AMD_LIBRARY) + set(KLU_LIBRARIES ${KLU_LIBRARIES} ${AMD_LIBRARY}) + endif () + + find_library(BTF_LIBRARY btf PATHS $ENV{KLU_LIBDIR} $ENV{KLUDIR} ${LIB_INSTALL_DIR}) + if (BTF_LIBRARY) + set(KLU_LIBRARIES ${KLU_LIBRARIES} ${BTF_LIBRARY}) + endif () + +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(KLU DEFAULT_MSG + KLU_INCLUDES KLU_LIBRARIES) + +mark_as_advanced(KLU_INCLUDES KLU_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY BTF_LIBRARY) From 18b7cb0c174104159ca745d9cc6785411e010990 Mon Sep 17 00:00:00 2001 From: Mark Eberlein Date: Tue, 28 Jan 2020 13:27:58 -0800 Subject: [PATCH 2/4] Fix windows build inconsistencies --- solver_klu/source/KLU_DLL/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solver_klu/source/KLU_DLL/CMakeLists.txt b/solver_klu/source/KLU_DLL/CMakeLists.txt index a3c7262..ceb3f15 100644 --- a/solver_klu/source/KLU_DLL/CMakeLists.txt +++ b/solver_klu/source/KLU_DLL/CMakeLists.txt @@ -16,7 +16,7 @@ else () set(KLU_LIB_PREFIX "lib_") endif () set_target_properties(${PROJECT_NAME} - PROPERTIES PREFIX ${KLU_LIB_PREFIX} + PROPERTIES PREFIX "${KLU_LIB_PREFIX}" ) target_include_directories(${PROJECT_NAME} PRIVATE ${KLU_INCLUDES}) @@ -29,6 +29,7 @@ set(FILE_PERMISSIONS PERMISSIONS install(TARGETS ${PROJECT_NAME} ${FILE_PERMISSIONS} + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/gridlabd LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/gridlabd ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/gridlabd COMPONENT library) From e45fde7632dea1a710010019aa1db25ce7174c54 Mon Sep 17 00:00:00 2001 From: Mark Eberlein Date: Tue, 28 Jan 2020 13:32:19 -0800 Subject: [PATCH 3/4] Update README to mention recommended Windows generator --- solver_klu/source/KLU_DLL/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solver_klu/source/KLU_DLL/README.md b/solver_klu/source/KLU_DLL/README.md index 6f1d9bd..285c6ea 100644 --- a/solver_klu/source/KLU_DLL/README.md +++ b/solver_klu/source/KLU_DLL/README.md @@ -29,7 +29,7 @@ following: 3. Move into directory (e.g. `cd build`) 3. Invoke CMake, and set installation directory to GridLAB-D install prefix (e.g. -`cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/gridlabd ../`) +`cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/gridlabd ../` \[note: it is recommended for Windows builds to include `-G"CodeBlocks - Unix Makefiles"` in the `cmake` command, as MSVC compiler support is not guaranteed\]) 4. Build and install the library (e.g. `cmake --build . --target install` \[note: `sudo` may be required depending on installation target\]) From da14960ba82056ee619e632c6078b7837b28ecb2 Mon Sep 17 00:00:00 2001 From: Mark Eberlein Date: Tue, 4 Feb 2020 10:41:41 -0800 Subject: [PATCH 4/4] Fix typo in suitesparse and clarify formatting for build instructions --- solver_klu/source/KLU_DLL/README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/solver_klu/source/KLU_DLL/README.md b/solver_klu/source/KLU_DLL/README.md index 285c6ea..fb05778 100644 --- a/solver_klu/source/KLU_DLL/README.md +++ b/solver_klu/source/KLU_DLL/README.md @@ -5,12 +5,12 @@ The KLU External Solver requires an installation of KLU, now included in the SuiteSparse Library package. -SuiteSparse is available in Ubuntu as `suitesparse` and MinGW/MSYS2 as +SuiteSparse is available in Ubuntu as `libsuitesparse-dev` and MinGW/MSYS2 as `mingw-w64-x86_64-suitesparse` #### Ubuntu installation to install SuiteSparse on Ubuntu run the following command: -`sudo apt install suitesparse` +`sudo apt install libsuitesparse-dev` #### MSYS2 installation to install SuiteSparse on MSYS2 run the following command: @@ -25,13 +25,16 @@ following: ## Building KLU External Solver 1. Open KLU_DLL directory in terminal -2. Create build directory (e.g. `mkdir build`) -3. Move into directory (e.g. `cd build`) -3. Invoke CMake, and set installation directory to GridLAB-D install -prefix (e.g. -`cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/gridlabd ../` \[note: it is recommended for Windows builds to include `-G"CodeBlocks - Unix Makefiles"` in the `cmake` command, as MSVC compiler support is not guaranteed\]) -4. Build and install the library (e.g. `cmake --build . --target install` -\[note: `sudo` may be required depending on installation target\]) +2. Create build directory + * e.g., `mkdir build` +3. Move into directory + * e.g., `cd build` +3. Invoke CMake, and set installation directory to GridLAB-D install prefix + * e.g., `cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/gridlabd ../` + * **note**: it is recommended for Windows builds to include `-G"CodeBlocks - Unix Makefiles"` in the `cmake` command, as MSVC compiler support is not guaranteed +4. Build and install the library + * e.g., `cmake --build . --target install` + * **note**: `sudo` may be required depending on installation target The KLU External Solver will be compiled and installed in your GridLAB-D install directory.