Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions docs/trouble_shooting.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,8 +52,45 @@ The `coverage combine` command merges the data from the main process and subproc

## Python Version
Executorlib supports all current Python version ranging from 3.9 to 3.13. Still some of the dependencies and especially
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.12 and below. Consequently for high
performance computing installations Python 3.12 is the recommended Python verion.
the [flux](http://flux-framework.org) job scheduler are currently limited to Python 3.13 and below. Consequently for high
performance computing installations Python 3.13 is the recommended Python verion.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix spelling error.

"verion" should be "version".

📝 Proposed fix
-performance computing installations Python 3.13 is the recommended Python verion. +performance computing installations Python 3.13 is the recommended Python version.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
performance computing installations Python 3.13 is the recommended Python verion.
performance computing installations Python 3.13 is the recommended Python version.
🧰 Tools
🪛 LanguageTool

[grammar] ~56-~56: Ensure spelling is correct
Context: ...s Python 3.13 is the recommended Python verion. ## Cores, Threads per Core and Maximum Work...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` at line 56, Fix the spelling mistake in the
sentence "performance computing installations Python 3.13 is the recommended
Python verion." by changing "verion" to "version" so it reads "...recommended
Python version."; update that line in the troubleshooting document where that
exact sentence appears.


## Cores, Threads per Core and Maximum Workers
A common point of confusion is the difference between the `cores`, `threads_per_core` and `max_workers` (or `max_cores`)
parameters, as they all control how many compute resources executorlib uses, but on different levels:

* `max_workers` / `max_cores` are arguments of the `Executor` itself. They define the *total* number of compute cores
the executor is allowed to use in parallel across all submitted function calls - essentially the size of the resource
pool or allocation that all tasks share. `max_workers` exists for backwards compatibility with the
[Executor interface](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor) of the
Python standard library, while `max_cores` is the recommended way to express the same limit, as it makes clear that the
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
Comment on lines +67 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify defaulting behavior when neither max_cores nor max_workers is set.

This sentence is too absolute. The code path in src/executorlib/standalone/inputcheck.py shows fallback to CPU count is conditional (set_local_cores=True); otherwise it raises ValueError. Please scope this statement to the relevant executors/modes.

Suggested wording
- limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the- number of cores available on the machine.+ limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;+ in that case, when neither is provided, executorlib uses the number of cores available on the machine.
📝 Committable suggestion

‼️IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
limit refers to the number of compute cores. Setting either is optional - when neither is provided executorlib uses the
number of cores available on the machine.
limit refers to the number of compute cores. Setting either is optional in executors that support local-core fallback;
in that case, when neither is provided, executorlib uses the number of cores available on the machine.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/trouble_shooting.md` around lines 67 - 68, The doc line claiming "when
neither is provided executorlib uses the number of cores available on the
machine" is too absolute; update the wording to scope the fallback to CPU count
to executors/modes that enable local core fallback (see
src/executorlib/standalone/inputcheck.py and the set_local_cores=True path).
Mention that when set_local_cores is False the library raises a ValueError
instead, and clarify which executors or modes use the automatic CPU-count
fallback versus those that require explicit max_cores/max_workers.

* `cores` is an entry of the `resource_dict` and is defined *per function call*. It specifies how many Python processes
executorlib starts for a single task. These processes are connected via
[mpi4py](https://mpi4py.readthedocs.io) and together form one MPI application. Consequently, `cores` is primarily
intended for functions implemented with [mpi4py](https://mpi4py.readthedocs.io), where the same Python function is
executed once per MPI rank. For a typical serial Python function, increasing `cores` does **not** provide additional
parallelism. Instead, executorlib launches multiple copies of the function, which usually wastes resources and can
lead to incorrect behavior. Unless you are using MPI through [mpi4py](https://mpi4py.readthedocs.io), `cores`
should generally be left at its default value of `1`.
* `threads_per_core` is also an entry of the `resource_dict` and defined *per function call*. In contrast to `cores`,
executorlib starts only a single Python process for the task and reserves the requested resources for that process.
The number of reserved cores is communicated through environment variables such as `OMP_NUM_THREADS`. This parameter
should be used whenever the Python function itself is executed only once, but internally uses multiple cores. Common
examples include thread-parallel libraries such as NumPy, BLAS, MKL or OpenMP-enabled code, as well as Python
functions which launch external applications. In the latter case, executorlib starts a single Python process, which
then launches the external application. Whether that external application internally uses OpenMP, MPI or a hybrid
MPI/OpenMP parallelization strategy is transparent to executorlib. This functionality is demonstrated in the Quantum
ESPRESSO application example.

A useful rule of thumb is:

* Use `cores` when executorlib should start multiple Python processes which together form an MPI application via
`mpi4py`.
* Use `threads_per_core` when executorlib should start the Python function only once and reserve multiple cores for it
or for an external application launched by it.
* Use `max_cores` to limit how many resources all submitted tasks may consume collectively.

## Resource Dictionary
The resource dictionary parameter `resource_dict` can contain one or more of the following options:
Expand Down
Loading