diff --git a/CMakeLists.txt b/CMakeLists.txt index f74344a16..655789d60 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ set(PLSSVM_BASE_SOURCES ## create base library: linked against all backend libraries set(PLSSVM_BASE_LIBRARY_NAME plssvm-base) -add_library(${PLSSVM_BASE_LIBRARY_NAME} STATIC ${PLSSVM_BASE_SOURCES}) +add_library(${PLSSVM_BASE_LIBRARY_NAME} SHARED ${PLSSVM_BASE_SOURCES}) ## create all library: one target against all backends are linked set(PLSSVM_ALL_LIBRARY_NAME plssvm-all) add_library(${PLSSVM_ALL_LIBRARY_NAME} INTERFACE) @@ -158,15 +158,15 @@ if (cxxopts_FOUND) else () message(STATUS "Couldn't find package cxxopts. Building from source ...") set(PLSSVM_cxxopts_VERSION v3.1.1) + # set options for cxxopts + set(CXXOPTS_BUILD_EXAMPLES OFF CACHE INTERNAL "" FORCE) + set(CXXOPTS_BUILD_TESTS OFF CACHE INTERNAL "" FORCE) + set(CXXOPTS_ENABLE_WARNINGS OFF CACHE INTERNAL "" FORCE) # fetch command line parser library cxxopts FetchContent_Declare(cxxopts GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git GIT_TAG ${PLSSVM_cxxopts_VERSION} - GIT_SHALLOW TRUE QUIET - - set (CXXOPTS_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) - set (CXXOPTS_BUILD_TESTS OFF CACHE BOOL "" FORCE) ) FetchContent_MakeAvailable(cxxopts) add_dependencies(${PLSSVM_BASE_LIBRARY_NAME} cxxopts) @@ -184,16 +184,15 @@ if (fast_float_FOUND) target_include_directories(${PLSSVM_BASE_LIBRARY_NAME} PUBLIC ${fast_float_INCLUDE_DIR}) else () message(STATUS "Couldn't find package fast_float. Building from source ...") - set(PLSSVM_fast_float_VERSION v3.10.0) # TODO: 5.2.0: https://github.com/fastfloat/fast_float/issues/215 + set(PLSSVM_fast_float_VERSION v3.10.0) # TODO: 5.3.0: https://github.com/fastfloat/fast_float/issues/215 + # set options for fast_float + set(FASTFLOAT_TEST OFF CACHE INTERNAL "" FORCE) + set(FASTFLOAT_SANITIZE OFF CACHE INTERNAL "" FORCE) # fetch float parsing library fast_float FetchContent_Declare(fast_float GIT_REPOSITORY https://github.com/fastfloat/fast_float GIT_TAG ${PLSSVM_fast_float_VERSION} - GIT_SHALLOW TRUE QUIET - - set (FASTFLOAT_TEST OFF CACHE BOOL "" FORCE) - set (FASTFLOAT_SANITIZE OFF CACHE BOOL "" FORCE) ) FetchContent_GetProperties(fast_float) if (NOT fast_float_POPULATED) @@ -217,14 +216,13 @@ if (igor_FOUND) else () message(STATUS "Couldn't find package igor. Building from source ...") set(PLSSVM_igor_VERSION a5224c60d266974d3f407191583fe266cbe1c93d) + # set options for igor + set(IGOR_BUILD_TESTS OFF CACHE INTERNAL "" FORCE) # fetch named argument library igor FetchContent_Declare(igor GIT_REPOSITORY https://github.com/bluescarni/igor GIT_TAG ${PLSSVM_igor_VERSION} - GIT_SHALLOW TRUE QUIET - - set (IGOR_BUILD_TESTS OFF CACHE BOOL "" FORCE) ) FetchContent_GetProperties(igor) if (NOT igor_POPULATED) @@ -247,24 +245,29 @@ if (fmt_FOUND) else () message(STATUS "Couldn't find package fmt. Building from source ...") # TODO: change to next release; bug fix commit set(PLSSVM_fmt_VERSION d9063baf227882da0f48c761abcbb08247eb1296) + # set options for fmt if (PLSSVM_ENABLE_STL_DEBUG_MODE) set(CMAKE_CXX_FLAGS_OLD "${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLSSVM_STL_DEBUG_MODE_FLAGS}") endif () + set(FMT_PEDANTIC OFF CACHE INTERNAL "" FORCE) + set(FMT_WERROR OFF CACHE INTERNAL "" FORCE) + set(FMT_DOC OFF CACHE INTERNAL "" FORCE) + set(FMT_INSTALL OFF CACHE INTERNAL "" FORCE) + set(FMT_TEST OFF CACHE INTERNAL "" FORCE) + set(FMT_FUZZ OFF CACHE INTERNAL "" FORCE) + set(FMT_CUDA_TEST OFF CACHE INTERNAL "" FORCE) + set(FMT_MODULE OFF CACHE INTERNAL "" FORCE) + set(FMT_SYSTEM_HEADERS ON CACHE INTERNAL "" FORCE) # fetch string formatting library fmt FetchContent_Declare(fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG ${PLSSVM_fmt_VERSION} -# GIT_SHALLOW TRUE QUIET - -# set (FMT_TEST OFF CACHE BOOL "" FORCE) -# set (FMT_DOC OFF CACHE BOOL "" FORCE) -# set (FMT_INSTALL OFF CACHE BOOL "" FORCE) -# set (FMT_SYSTEM_HEADERS ON CACHE BOOL "" FORCE) ) FetchContent_MakeAvailable(fmt) set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON) + target_compile_definitions(fmt PRIVATE FMT_USE_FULL_CACHE_DRAGONBOX) add_dependencies(${PLSSVM_BASE_LIBRARY_NAME} fmt) target_include_directories(${PLSSVM_BASE_LIBRARY_NAME} PUBLIC $ diff --git a/README.md b/README.md index b7c070f97..4ae27ca5f 100644 --- a/README.md +++ b/README.md @@ -305,32 +305,33 @@ export LD_LIBRARY_PATH=${CMAKE_INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH} The repository comes with a Python3 script (in the `utility_scripts/` directory) to simply generate arbitrarily large data sets. In order to use all functionality, the following Python3 modules must be installed: -[`argparse`](https://docs.python.org/3/library/argparse.html), [`timeit`](https://docs.python.org/3/library/timeit.html), +[`argparse`](https://docs.python.org/3/library/argparse.html), [`timeit`](https://docs.python.org/3/library/timeit.html), [`numpy`](https://pypi.org/project/numpy/), [`pandas`](https://pypi.org/project/pandas/), [`sklearn`](https://scikit-learn.org/stable/), [`arff`](https://pypi.org/project/arff/), [`matplotlib`](https://pypi.org/project/matplotlib/), [`mpl_toolkits`](https://pypi.org/project/matplotlib/), and [`humanize`](https://pypi.org/project/humanize/). ```bash -python3 utility_scripts/generate_data.py --help -usage: generate_data.py [-h] --output OUTPUT --format FORMAT [--problem PROBLEM] --samples SAMPLES [--test_samples TEST_SAMPLES] --features FEATURES [--plot] +usage: generate_data.py [-h] [--output OUTPUT] [--format FORMAT] [--problem PROBLEM] --samples SAMPLES [--test_samples TEST_SAMPLES] --features FEATURES [--classes CLASSES] [--plot] -optional arguments: +options: -h, --help show this help message and exit --output OUTPUT the output file to write the samples to (without extension) - --format FORMAT the file format; either arff or libsvm - --problem PROBLEM the problem to solve; one of: blobs, blobs_merged, planes, planes_merged, ball + --format FORMAT the file format; either arff, libsvm, or csv + --problem PROBLEM the problem to solve; one of: blobs, blobs_merged, planes, ball --samples SAMPLES the number of training samples to generate --test_samples TEST_SAMPLES the number of test samples to generate; default: 0 --features FEATURES the number of features per data point + --classes CLASSES the number of classes to generate; default: 2 --plot plot training samples; only possible if 0 < samples <= 2000 and 1 < features <= 3 ``` -An example invocation generating a data set consisting of blobs with 1000 data points with 200 features each could look like: +An example invocation generating a data set consisting of blobs with 1000 data points with 200 features each and +4 classes could look like: ```bash -python3 generate_data.py --output data_file --format libsvm --problem blobs --samples 1000 --features 200 +python3 generate_data.py --output data_file --format libsvm --problem blobs --samples 1000 --features 200 --classes 4 ``` ### Training diff --git a/bindings/Python/detail/performance_tracker.cpp b/bindings/Python/detail/performance_tracker.cpp index 297fbc6bd..3a9ad72b9 100644 --- a/bindings/Python/detail/performance_tracker.cpp +++ b/bindings/Python/detail/performance_tracker.cpp @@ -32,7 +32,11 @@ void init_performance_tracker([[maybe_unused]] py::module_ &m) { .def( "resume", []() { plssvm::detail::global_tracker->resume_tracking(); }, "resume performance tracking") .def( - "save", [](const std::string &filename) { plssvm::detail::global_tracker->save(filename); }, "save the performance tracking results to the specified yaml file"); + "save", [](const std::string &filename) { plssvm::detail::global_tracker->save(filename); }, "save the performance tracking results to the specified yaml file") + .def( + "is_tracking", []() { return plssvm::detail::global_tracker->is_tracking(); }, "check whether performance tracking is currently enabled") + .def( + "clear_tracking_entries", []() { plssvm::detail::global_tracker->clear_tracking_entries(); }, "remove all currently tracked entries from the performance tracker"); #endif } \ No newline at end of file diff --git a/install/python_requirements.txt b/install/python_requirements.txt index 8a63ef570..c6e698aeb 100644 --- a/install/python_requirements.txt +++ b/install/python_requirements.txt @@ -1,15 +1,39 @@ ### optional and required python packages + +## for the data set generation +# LIBSVM argparse scikit-learn +humanize + +# additionally for generating ARFF files +numpy +arff +pandas + +# additionally for generation CSV files +# numpy + +# for plotting the generated data set (only available if #features <= 3) +matplotlib + + +## for the automatic PLSSVM target platform determination +# argparse py-cpuinfo GPUtil pyamdgpuinfo pylspci -numpy -pandas -arff -matplotlib -humanize + + +## for the performance tracker parser +# argparse +# matplotlib pyyaml pint + + +## for the performance analysis +# argparse +# scikit-learn wrapt-timeout-decorator \ No newline at end of file diff --git a/src/plssvm/backends/CUDA/csvm.cu b/src/plssvm/backends/CUDA/csvm.cu index 02dadace0..ef90291de 100644 --- a/src/plssvm/backends/CUDA/csvm.cu +++ b/src/plssvm/backends/CUDA/csvm.cu @@ -153,7 +153,7 @@ auto csvm::run_assemble_kernel_matrix_explicit(const parameter ¶ms, const de static_cast(std::ceil(static_cast(num_rows_reduced) / static_cast(block.y)))); #if defined(PLSSVM_USE_GEMM) - device_ptr_type kernel_matrix_d{ num_rows_reduced * num_rows_reduced }; // store full matrix + device_ptr_type kernel_matrix_d{ num_rows_reduced * num_rows_reduced, devices_[0] }; // store full matrix #else device_ptr_type kernel_matrix_d{ num_rows_reduced * (num_rows_reduced + 1) / 2, devices_[0] }; // only explicitly store the upper triangular matrix #endif diff --git a/src/plssvm/backends/HIP/csvm.hip.cpp b/src/plssvm/backends/HIP/csvm.hip.cpp index eb966f67e..c4781cf84 100644 --- a/src/plssvm/backends/HIP/csvm.hip.cpp +++ b/src/plssvm/backends/HIP/csvm.hip.cpp @@ -150,7 +150,7 @@ auto csvm::run_assemble_kernel_matrix_explicit(const parameter ¶ms, const de static_cast(std::ceil(static_cast(num_rows_reduced) / static_cast(block.y)))); #if defined(PLSSVM_USE_GEMM) - device_ptr_type kernel_matrix_d{ num_rows_reduced * num_rows_reduced }; // store full matrix + device_ptr_type kernel_matrix_d{ num_rows_reduced * num_rows_reduced, devices_[0] }; // store full matrix #else device_ptr_type kernel_matrix_d{ num_rows_reduced * (num_rows_reduced + 1) / 2, devices_[0] }; // only explicitly store the upper triangular matrix #endif diff --git a/src/plssvm/backends/OpenCL/CMakeLists.txt b/src/plssvm/backends/OpenCL/CMakeLists.txt index 3d58c4b1c..51b1ee1b0 100644 --- a/src/plssvm/backends/OpenCL/CMakeLists.txt +++ b/src/plssvm/backends/OpenCL/CMakeLists.txt @@ -36,7 +36,7 @@ set(PLSSVM_OPENCL_SOURCES # set target properties set_local_and_parent(PLSSVM_OPENCL_BACKEND_LIBRARY_NAME plssvm-OpenCL) -add_library(${PLSSVM_OPENCL_BACKEND_LIBRARY_NAME} STATIC ${PLSSVM_OPENCL_SOURCES}) +add_library(${PLSSVM_OPENCL_BACKEND_LIBRARY_NAME} SHARED ${PLSSVM_OPENCL_SOURCES}) target_include_directories(${PLSSVM_OPENCL_BACKEND_LIBRARY_NAME} PUBLIC ${OpenCL_INCLUDE_DIRS}) target_link_libraries(${PLSSVM_OPENCL_BACKEND_LIBRARY_NAME} PUBLIC OpenCL) diff --git a/src/plssvm/backends/OpenCL/detail/utility.cpp b/src/plssvm/backends/OpenCL/detail/utility.cpp index 426086347..059bd35c3 100644 --- a/src/plssvm/backends/OpenCL/detail/utility.cpp +++ b/src/plssvm/backends/OpenCL/detail/utility.cpp @@ -238,7 +238,7 @@ std::vector create_command_queues(const std::vector &con // ::plssvm::detail::replace_all(kernel_src_string, "THREAD_BLOCK_SIZE", fmt::format("{}", THREAD_BLOCK_SIZE)); // append number of device to influence checksum calculation - kernel_src_string.append(fmt::format("\n// num_devices: {}\n// OpenCL library: {}", contexts[0].devices.size(), PLSSVM_OPENCL_LIBRARY)); + kernel_src_string.append(fmt::format("\n// num_devices: {}\n// OpenCL library: {}\n// GEMM: {}", contexts[0].devices.size(), PLSSVM_OPENCL_LIBRARY, PLSSVM_IS_DEFINED(PLSSVM_USE_GEMM))); // create source code hash const std::string checksum = plssvm::detail::sha256{}(kernel_src_string); diff --git a/src/plssvm/backends/OpenMP/CMakeLists.txt b/src/plssvm/backends/OpenMP/CMakeLists.txt index d3366252a..ae149b484 100644 --- a/src/plssvm/backends/OpenMP/CMakeLists.txt +++ b/src/plssvm/backends/OpenMP/CMakeLists.txt @@ -41,7 +41,7 @@ set(PLSSVM_OPENMP_SOURCES # set target properties set_local_and_parent(PLSSVM_OPENMP_BACKEND_LIBRARY_NAME plssvm-OpenMP) -add_library(${PLSSVM_OPENMP_BACKEND_LIBRARY_NAME} STATIC ${PLSSVM_OPENMP_SOURCES}) +add_library(${PLSSVM_OPENMP_BACKEND_LIBRARY_NAME} SHARED ${PLSSVM_OPENMP_SOURCES}) target_link_libraries(${PLSSVM_OPENMP_BACKEND_LIBRARY_NAME} PUBLIC OpenMP::OpenMP_CXX) # special command line options for MSVC: # -openmp:llvm -> enables unsigned loop indexes in OpenMP parallel for loops diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6da9be792..2abd13945 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,7 +22,6 @@ else () FetchContent_Declare(googletest GIT_REPOSITORY https://github.com/google/googletest GIT_TAG ${PLSSVM_googletest_VERSION} - GIT_SHALLOW TRUE QUIET ) # For Windows: Prevent overriding the parent project's compiler/linker settings @@ -89,7 +88,7 @@ set(PLSSVM_BASE_TEST_LIBRARY_NAME_SOURCES ) # create base test library -add_library(${PLSSVM_BASE_TEST_LIBRARY_NAME} STATIC ${PLSSVM_BASE_TEST_LIBRARY_NAME_SOURCES}) +add_library(${PLSSVM_BASE_TEST_LIBRARY_NAME} SHARED ${PLSSVM_BASE_TEST_LIBRARY_NAME_SOURCES}) # set necessary include directories target_include_directories(${PLSSVM_BASE_TEST_LIBRARY_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")