{"id":18046583,"url":"https://github.com/ltla/subpar","last_synced_at":"2025-07-12T00:05:47.201Z","repository":{"id":254769622,"uuid":"847426043","full_name":"LTLA/subpar","owner":"LTLA","description":"Substitutable parallelization for C++ libraries","archived":false,"fork":false,"pushed_at":"2025-07-08T18:10:14.000Z","size":271,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-08T18:53:46.360Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://ltla.github.io/subpar/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LTLA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-08-25T19:35:24.000Z","updated_at":"2025-07-08T18:09:09.000Z","dependencies_parsed_at":"2024-12-15T04:22:41.534Z","dependency_job_id":"a6490c1d-7782-4113-a747-3ac01bc48caa","html_url":"https://github.com/LTLA/subpar","commit_stats":null,"previous_names":["ltla/subpar"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/LTLA/subpar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Fsubpar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Fsubpar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Fsubpar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Fsubpar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LTLA","download_url":"https://codeload.github.com/LTLA/subpar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LTLA%2Fsubpar/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264915991,"owners_count":23682957,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-30T19:08:00.050Z","updated_at":"2025-07-12T00:05:47.178Z","avatar_url":"https://github.com/LTLA.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Substitutable parallelization for C++ libraries\n\n![Unit tests](https://github.com/LTLA/subpar/actions/workflows/run-tests.yaml/badge.svg)\n![Documentation](https://github.com/LTLA/subpar/actions/workflows/doxygenate.yaml/badge.svg)\n[![Codecov](https://codecov.io/gh/LTLA/subpar/branch/master/graph/badge.svg?token=GByG4StuqU)](https://codecov.io/gh/LTLA/subpar)\n\n## Overview\n\nThis repository implements a simple `parallelize_range()` function that can be used throughout all of my C++ libaries.\nBy default, it just splits the range of tasks into equi-sized intervals that are executed by different workers.\nOpenMP is used if it is available, otherwise we spin up a new `std::thread` for each interval.\nAdvanced users can define a macro to instruct `parallelize_range()` to use their own parallelization mechanism.\nThis allows applications to quickly substitute all instances of `parallelize_range()` across all libraries with something more appropriate.\n\n## Quick start\n\nThe `subpar::parallelize_range()` function requires the number of workers, the number of tasks,\nand a function that iterates over the range of tasks and executes them in a single worker.\n\n```cpp\n#include \"subpar/subpar.hpp\"\n\nsubpar::parallelize_range(\n    /* num_workers = */ 10,\n    /* num_tasks = */ 12345,\n    /* run = */ [\u0026](int worker, int start, int len) {\n        // ... do some per-worker set-up ...\n        for (int task = start, end = start + len; task \u003c end; ++task) {\n            // ...process each task ...\n        }\n    }\n);\n```\n\n`subpar::parallelize_range()` functions will correctly handle exceptions thrown in the user-supplied function.\nThis comes with some slight overhead so the user can set the `nothrow_` template parameter to `false` if they can guarantee that their supplied functions will not throw.\n\nOn occasion, the user has already assigned a task to each worker outside of **subpar**.\nThis is handled by `subpar::parallelize_simple()`, which will execute each task in its own worker without the overhead of task range partitioning.\n\n```cpp\n#include \"subpar/subpar.hpp\"\n\nsubpar::parallelize_simple(\n    /* num_tasks = */ 4,\n    /* run = */ [\u0026](int task) {\n        // ...process each task ...\n    }\n);\n```\n\nCheck out the [reference documentation](https://ltla.github.io/subpar) for more details.\n\n## Custom parallelization \n\nIf the `SUBPAR_CUSTOM_PARALLELIZE_RANGE` macro is defined, it is used in place of the default behavior whenever `subpar::parallelize_range()` is called.\nThe macro should accept exactly the same arguments as `subpar::parallelize_range()`, but the macro author is now responsible for distributing tasks among workers.\nThis can be used to inject other parallelization mechanisms like Intel's TBB, TinyThread, Boost, etc.\nThe same approach can be applied to `subpar::parallelize_simple()` via the `SUBPAR_CUSTOM_PARALLELIZE_SIMPLE` macro.\n\n```cpp\ntemplate\u003ctypename Task_, class Run_\u003e\nvoid silly_parallelize(int workers, Task_ jobs, Run_ run) {\n    // Doesn't actually parallelize at all; hence, silly!\n    run(0, 0, jobs); \n}\n\n// Can define a macro:\n#define SUBPAR_CUSTOM_PARALLELIZE_RANGE ::silly_parallelize\n\n// Or, can define a function-like macro\n#define SUBPAR_CUSTOM_PARALLELIZE_RANGE(w, j, r) ::silly_parallelize(w, j, r)\n\n// Finally, include the subpar headers:\n#include \"subpar/subpar.hpp\"\n\n// And now use the subpar functions...\n```\n\nUsers can additionally define the `SUBPAR_CUSTOM_PARALLELIZE_RANGE_NOTHROW` or `SUBPAR_CUSTOM_PARALLELIZE_SIMPLE_NOTHROW` macros.\nThese will be used in place of their non-`NOTHROW` counterparts in the `nothrow_ = true` case,\nproviding an optimization opportunity for custom parallelization schemes when exception handling is not required.\nNote that the non-`NOTHROW` macros still need to be defined before the `NOTHROW` macros can be used, even if all calls to **subpar** functions use `nothrow_ = true`.\n\n## Building projects \n\n### CMake with `FetchContent`\n\nIf you're using CMake, you just need to add something like this to your `CMakeLists.txt`:\n\n```cmake\ninclude(FetchContent)\n\nFetchContent_Declare(\n  subpar\n  GIT_REPOSITORY https://github.com/LTLA/subpar\n  GIT_TAG master # or any version of interest \n)\n\nFetchContent_MakeAvailable(subpar)\n```\n\nThen you can link to **subpar** to make the headers available during compilation:\n\n```cmake\n# For executables:\ntarget_link_libraries(myexe subpar)\n\n# For libaries\ntarget_link_libraries(mylib INTERFACE subpar)\n```\n\n### CMake with `find_package()`\n\nYou can install the library by cloning a suitable version of this repository and running the following commands:\n\n```sh\nmkdir build \u0026\u0026 cd build\ncmake .. -DSUBPAR_TESTS=OFF\ncmake --build . --target install\n```\n\nThen you can use `find_package()` as usual:\n\n```cmake\nfind_package(ltla_subpar CONFIG REQUIRED)\ntarget_link_libraries(mylib INTERFACE ltla::subpar)\n```\n\n### Manual\n\nIf you're not using CMake, the simple approach is to just copy the files in the `include/` subdirectory - \neither directly or with Git submodules - and include their path during compilation with, e.g., GCC's `-I`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltla%2Fsubpar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fltla%2Fsubpar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltla%2Fsubpar/lists"}