diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000000..4d81c2e38a
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# PRRTE Community Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the PRRTE project or its community. Examples of representing the project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of the project may be further defined and clarified by PRRTE maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at maintainers@pmix.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/.gitignore b/.gitignore
index 2e103ff9f0..7102cecab7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -205,6 +205,9 @@ docs/_build
docs/_static
docs/_static/css/custom.css
docs/_templates
+
+# Generated RST files
+docs/code-of-conduct.rst
src/docs/_build
src/docs/mca/mca.rst
src/docs/mca/help*rst
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 44e0bbac5a..3e4cffff2f 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -12,6 +12,9 @@ build:
os: ubuntu-22.04
tools:
python: "3.10"
+ jobs:
+ pre_build:
+ - python3 docs/generate-code-of-conduct-rst.py --input .github/CODE_OF_CONDUCT.md --output docs/code-of-conduct.rst
python:
install:
diff --git a/AGENTS.md b/AGENTS.md
index 257f6b4334..9b25f47bc4 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -202,6 +202,7 @@ Do not use `PMIX_` or `pmix_` prefixes for new PRRTE symbols.
### New files need the standard copyright/license header.
+Copy the multi-institution BSD header block — including the `Copyright (c) 2026 Nanook Consulting All rights reserved.
Copy the multi-institution BSD header block — including the `$COPYRIGHT$` and
`$HEADER$` tokens — from a neighboring file. If you substantially
change an existing file, add your copyright line to its block.
@@ -292,6 +293,16 @@ buffers unless interfacing with PMIx routines that require it.
PRRTE targets C11. Do not add `-Wno-*` flags to suppress warnings —
fix the underlying issue.
+### Use the `__prte_attribute_*__` macros for compiler attributes.**
+ [`src/include/prte_config_bottom.h`](src/include/prte_config_bottom.h),
+ pulled in transitively by `prte_config.h`, defines portable wrappers —
+ `__prte_attribute_unused__`, `__prte_attribute_noreturn__`,
+ `__prte_attribute_format__`, `__prte_attribute_deprecated__`, and many
+ more — that expand to the appropriate `__attribute__((...))` on
+ compilers that support it and to nothing elsewhere. Reach for these
+ (for example, to mark an unused function parameter) rather than writing
+ a bare `__attribute__` or leaving a warning unaddressed.
+
---
## Build System
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000000..9abb2cc2ed
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,396 @@
+# AGENTS.md — Orientation for AI Coding Agents and Human Contributors
+
+This document is an orientation guide for AI coding agents and their human operators working in the PRRTE code base.
+This file is an *orientation map*, not the
+full rulebook: the authoritative, human-maintained documentation lives
+under [`docs/developers/`](docs/developers/) and
+[`docs/contributing.rst`](docs/contributing.rst) (rendered at
+). When this file and those docs disagree,
+**the docs win** — and please fix this file.
+
+AI-assisted contributions are welcome. But PRRTE runs on the largest
+supercomputers in the world and across a huge range of operating
+systems and hardware. It is also used by numerous research groups
+looking at developments such as elastic environments. We want careful,
+portable code — not plausible-looking code that solves one problem in
+one environment or use-case at the expense of others. Hold yourself to
+the same bar as a thoughtful human contributor.
+
+---
+
+## What is PRRTE?
+
+PRRTE (PMIx Reference RunTime Environment) is an open-source, production
+runtime system for launching and managing parallel jobs in HPC environments.
+Unlike a library, PRRTE exposes no public API for callers — it is a
+collection of executable tools that users invoke directly. PRRTE acts as a
+reference implementation of the PMIx-defined runtime services, and it relies
+heavily on the PMIx project for its internal infrastructure: MCA
+(Modular Component Architecture), utility routines, data structures, and
+threading primitives. Many PMIx symbols and headers PRRTE uses are internal
+PMIx interfaces, **not** the PMIx public library API.
+
+Source repository: https://github.com/openpmix/prrte
+Documentation: https://docs.prrte.org/
+
+---
+
+## Terminology
+
+Understanding PRRTE's vocabulary is essential before reading or modifying
+code.
+
+| Term | Meaning |
+|------|---------|
+| **DVM** | Distributed Virtual Machine — a persistent set of PRRTE daemons spread across an allocation, ready to launch jobs on demand. |
+| **HNP** | Head Node Process — the `prte` process that acts as the DVM controller. Also called the DVM master. |
+| **prted** | PRRTE daemon — one instance runs on each node in the DVM and manages local processes. |
+| **job** | A set of processes launched together under a single `prun` invocation. Each job has a unique namespace. |
+| **namespace** | A string that uniquely identifies a job within a DVM session (inherited from PMIx). |
+| **rank** | A process's integer identifier within its namespace (global rank), within its node (node rank), or within the local set of processes on a node (local rank). |
+| **app context** | A description of one executable to run: path, argv, environment, and process count. A single `prun` may specify multiple app contexts. |
+| **session** | The lifetime of a DVM — from `prte` startup through `pterm` shutdown. |
+| **schizo** | The "personality" framework. Schizo components translate between PRRTE's internal model and the command-line conventions of specific launchers (e.g., Open MPI's `mpirun`, SLURM's `srun`). |
+| **MCA** | Modular Component Architecture — the plugin system, inherited from PMIx, that PRRTE uses for every swappable subsystem. |
+| **framework** | An MCA abstraction layer that defines the interface for one functional area (e.g., `plm`, `rmaps`). |
+| **component** | A plugin that implements a framework's interface for a specific environment or algorithm (e.g., `plm/slurm`). |
+| **module** | The active instance of a component, returned after it wins selection. |
+
+---
+
+## User-Facing Tools
+
+PRRTE provides no linkable library. All user interaction is through
+executables.
+
+| Tool | Source | Purpose |
+|------|--------|---------|
+| `prte` | `src/tools/prte/` | Start a DVM (the HNP process). Allocates and connects daemons across an allocation. |
+| `prun` | `src/tools/prun/` | Submit and manage a job within a running DVM. The everyday launch command. |
+| `pterm` | `src/tools/pterm/` | Terminate a running DVM cleanly. |
+| `prted` | `src/tools/prted/` | The per-node daemon, normally launched by the HNP — not invoked directly by users. |
+| `prte_info` | `src/tools/prte_info/` | Query build configuration, list available MCA components, and display version information. |
+| `pcc` | `src/tools/pcc/` | Compiler wrapper for applications that directly embed PMIx (not PRRTE — PRRTE has no linkable library). |
+
+---
+
+## Source Layout
+
+```
+src/
+ tools/ # Executable entry points (prte, prun, pterm, prted, prte_info, pcc)
+ mca/ # All MCA frameworks and their components
+ runtime/ # Global state, init/finalize, job/node/proc data structures
+ rml/ # Runtime Messaging Layer (point-to-point communication between daemons)
+ util/ # Internal utilities (hostfile parsing, name formatting, attributes, ...)
+ include/ # Internal header files (types.h, constants.h, ...)
+ pmix/ # Thin shim connecting PRRTE to its PMIx dependency
+ event/ # Libevent integration
+ hwloc/ # hwloc integration (topology, binding)
+```
+
+The three central data structures — `prte_job_t`, `prte_node_t`, and
+`prte_proc_t` — are defined in `src/runtime/prte_globals.h` and carry
+all runtime state for a running job. Code throughout the tree reaches
+for these; understand them before touching launch, mapping, or error
+handling paths.
+
+---
+
+## MCA Frameworks
+
+Every swappable PRRTE subsystem is an MCA framework. The framework
+directory contains a `base/` subdirectory (selection, default behaviors,
+utility stubs) and one or more component subdirectories.
+
+| Framework | Location | Responsibility |
+|-----------|----------|----------------|
+| `ess` | `src/mca/ess/` | Environment-Specific Services — init/finalize for each process role (HNP, daemon, tool). |
+| `plm` | `src/mca/plm/` | Process Launch Manager — spawns prted daemons across the system. Components: `ssh`, `slurm`, `lsf`, `pals`. |
+| `ras` | `src/mca/ras/` | Resource Allocation Subsystem — discovers nodes and slots. Components: `slurm`, `pbs`, `lsf`, `flux`, `gridengine`, `hosts`. |
+| `rmaps` | `src/mca/rmaps/` | Resource Mapping — assigns processes to nodes/slots. Components: `round_robin`, `ppr`, `rank_file`, `seq`. |
+| `odls` | `src/mca/odls/` | PRRTE Daemon Local Launch Subsystem — the per-node daemon (prted) forks/execs application processes. |
+| `iof` | `src/mca/iof/` | I/O Forwarding — routes stdout/stderr/stdin between daemons and the HNP. |
+| `grpcomm` | `src/mca/grpcomm/` | Group Communication — collective operations among daemons (broadcast, barrier). |
+| `errmgr` | `src/mca/errmgr/` | Error Manager — handles process faults, abnormal exits, and propagation of errors. |
+| `state` | `src/mca/state/` | State Machine — drives the DVM and job lifecycle through defined states/transitions. |
+| `schizo` | `src/mca/schizo/` | Personality layer — parses CLI options and environment for specific launcher personalities (prte, ompi). |
+| `filem` | `src/mca/filem/` | File Management — pre-positions files across nodes before launch. |
+| `prtereachable` | `src/mca/prtereachable/` | Reachability — determines which network interfaces can reach each node. |
+| `prtebacktrace` | `src/mca/prtebacktrace/` | Backtrace support for crash diagnostics. |
+| `prtedl` | `src/mca/prtedl/` | Dynamic linker abstraction (dlopen/dlclose). |
+| `prteinstalldirs` | `src/mca/prteinstalldirs/` | Installation directory queries. |
+
+### MCA component structure
+
+Each component directory must contain:
+- `.h` — component struct (`prte___component_t`)
+- `.c` — component registration, open, query, close
+- `_module.c` (or similar) — module implementation
+- `Makefile.am`
+
+The component's `query` function returns a priority; the highest-priority
+component that successfully opens wins selection.
+
+---
+
+## PRRTE's Relationship with PMIx
+
+PRRTE depends on PMIx (minimum version `6.1.0`) and uses PMIx internals
+extensively. This is not the same as calling the PMIx public library API.
+
+**What PRRTE takes from PMIx:**
+
+- **MCA infrastructure** (`src/mca/base/`, `src/mca/mca.h`) — the entire
+ plugin/component system is PMIx's code, not PRRTE's.
+- **Data structures and classes** — `pmix_list_t`, `pmix_pointer_array_t`,
+ `pmix_hash_table_t`, `pmix_ring_buffer_t`, `pmix_value_array_t`.
+- **Threading primitives** — `pmix_mutex_t`, `pmix_condition_t`,
+ `pmix_threads_*`.
+- **Utility functions** — `pmix_argv_*`, `pmix_environ_*`,
+ `pmix_output_*`, `pmix_cmd_line_*`.
+- **Event loop** — PMIx's libevent integration and progress threads.
+- **Data packing/unpacking** — PMIx's buffer and bfrops subsystem.
+
+Include paths for these symbols come from PMIx's installed headers (found
+via `pkg-config` or `--with-pmix=`). The shim at `src/pmix/pmix-internal.h`
+and `src/pmix/pmix.c` is PRRTE's integration point — consult it before
+reaching for PMIx symbols elsewhere.
+
+### Check capability flags
+
+PRRTE uses the `AC_PREPROC_IFELSE` idiom in its configure script to test for PMIx capability flags at build time. PRRTE's `config/prte_setup_pmix.m4` defines a helper macro `PRTE_CHECK_PMIX_CAP` that reduces the check to:
+
+```m4
+PRTE_CHECK_PMIX_CAP([MY_NEW_FEATURE],
+ [action if supported],
+ [action if not supported])
+```
+
+The macro succeeds when `PMIX_CAP_MY_NEW_FEATURE` is defined in the installed `pmix_version.h`; it fails (and triggers the third argument) when the definition is absent, meaning the running PMIx predates the feature.
+
+Code requiring a specific PMIx feature that is covered by a capability flag must be protected by an appropriate `#if FOO` clause.
+
+---
+
+## Coding Rules
+
+These rules apply to **all** PRRTE C source files without exception.
+
+### Mandatory header order
+
+`prte_config.h` **must be the first `#include`** in every `.c` file.
+Nothing comes before it — not system headers, not other PRRTE headers.
+
+```c
+#include "prte_config.h"
+
+#include /* system headers follow */
+...
+#include "src/util/name_fns.h" /* then PRRTE/PMIx headers */
+```
+
+### Symbol prefixes
+
+| Scope | Prefix |
+|-------|--------|
+| Exported (tools, public data) | `PRTE_` (macros) / `prte_` (functions, types) |
+| Internal only | `prte_` with no `PRTE_EXPORT` annotation |
+| MCA component | `prte___` |
+
+Do not use `PMIX_` or `pmix_` prefixes for new PRRTE symbols.
+
+### New files need the standard copyright/license header.
+
+Copy the multi-institution BSD header block — including the `Copyright (c) 2026 Nanook Consulting All rights reserved.
+Copy the multi-institution BSD header block — including the `$COPYRIGHT$` and
+`$HEADER$` tokens — from a neighboring file. If you substantially
+change an existing file, add your copyright line to its block.
+
+### `#define` logical macros to `0` or `1`; never `#undef` them.
+
+Test with `#if FOO`, not `#ifdef FOO`, so a misspelling is a compiler
+error, not a silent false.
+
+### Constant-on-left comparisons
+
+Always put the constant or NULL on the left side of an equality test:
+
+```c
+if (NULL == ptr) /* correct */
+if (ptr == NULL) /* wrong — easy to mistype as assignment */
+
+if (PRTE_SUCCESS == rc) /* correct */
+```
+
+### Always brace blocks
+
+Use `{ }` around every conditional or loop body, even single-line ones.
+
+### Indentation
+
+4 spaces, never tab characters.
+
+
+### Stay compiler-warning-free
+
+PRRTE strives to build with zero compiler warnings. Do not introduce
+code that adds new warnings. `--enable-devel-check` is implied when
+building from a git repo with `--enable-debug`; it instructs the compiler
+to treat all warnings as errors and enables maximum warning coverage
+(e.g., unused variables). CI runs with this setting, so your code must
+be warning-free before submitting.
+
+### No hand-editing of generated files
+
+Do not modify files produced by autotools (`configure`, `Makefile.in`, etc.), pre-rendered documentation, or third-party vendored code. Edit the source code instead.
+
+
+### Error handling
+
+Functions that can fail return `int`. Check every return value. Use
+`PRTE_ERROR_LOG(rc)` to record unexpected errors. Use
+`PRTE_ACTIVATE_JOB_STATE(jdata, PRTE_JOB_STATE_*)` to trigger state
+transitions rather than handling errors inline in launch paths.
+
+### Thread model
+
+PRRTE is event-driven and single-threaded on the progress thread. Use
+the PRRTE event loop (`prte_event_base`) for deferred work. Do not block on
+the progress thread.
+
+### Thread-shifting with caddies
+
+A **caddy** is a short-lived heap object whose sole job is to carry a request's parameters across states within the progress thread. Every caddy struct must contain at minimum:
+
+| Field | Type | Purpose |
+|-------|------|---------|
+| ev | `pmix_event_t` | Required by Libevent to queue the caddy; **must be named `ev`** |
+| lock | `pmix_lock_t` | Thread synchronization (blocking operations wait on this; handlers wake it) |
+| cbdata | `void *` | Opaque pointer passed through to the callback |
+| callback pointer(s) | function pointer(s) | Cache the caller-supplied callback function(s) |
+
+The pattern:
+
+1. Allocate a caddy with `PMIX_NEW(caddy_type_t)`.
+2. Assign the caddy's fields to point at the caller's parameters — **do not copy the data**.
+3. Call `PRTE_PMIX_THREADSHIFT(cd, evbase, handler_fn)` to post the caddy to the progress thread's event queue.
+4. The progress thread fires `handler_fn(cd)`, which performs the actual work.
+
+Never read or write shared library state outside of the progress thread; do it only inside the handler that runs on the progress thread.
+Do not allocate a caddy on the stack — it must outlive the function that creates it.
+
+
+### Memory management
+
+Use `PMIX_NEW` / `PMIX_RELEASE` (PMIx's reference-counted object system)
+for all PRRTE objects that embed `pmix_object_t`. Raw allocations use
+`malloc`/`free` directly — avoid `PMIX_MALLOC`/`PMIX_FREE` for plain
+buffers unless interfacing with PMIx routines that require it.
+
+### C standard
+
+PRRTE targets C11. Do not add `-Wno-*` flags to suppress warnings —
+fix the underlying issue.
+
+---
+
+## Build System
+
+PRRTE uses GNU Autotools. The generated `configure` script is **not** in
+the git repository; it is produced by running:
+
+```sh
+./autogen.pl
+```
+
+This must be re-run whenever `configure.ac`, any `Makefile.am`, or any
+`*.m4` file under `config/` is modified. After `autogen.pl`:
+
+```sh
+./configure [options]
+make -j$(nproc)
+make install
+```
+
+Common configure options:
+
+| Option | Purpose |
+|--------|---------|
+| `--with-pmix=` | Path to PMIx installation (required if not in default search path) |
+| `--with-hwloc=` | Path to hwloc installation |
+| `--with-libevent=` | Path to libevent installation |
+| `--with-slurm` | Enable SLURM support |
+| `--with-lsf=` | Enable LSF support |
+| `--with-pbs` | Enable PBS/Torque support |
+| `--with-flux=` | Enable Flux support |
+| `--enable-debug` | Build with debug symbols and extra assertions |
+| `--enable-devel-check` | Enable strict compiler warnings (treat warnings as errors); on by default when `--enable-debug` is used in a git repo build |
+
+Version requirements: PMIx ≥ 6.1.0, hwloc ≥ 2.1.0, libevent ≥ 2.0.21.
+
+---
+
+## State Machines
+
+PRRTE drives both the DVM lifecycle and individual job lifecycles through
+explicit state machines defined in `src/mca/state/`. Process and job
+states are declared in `src/mca/state/state_types.h`. When debugging
+launch or termination problems, enable framework verbosity to trace
+state transitions:
+
+```sh
+prte --prtemca state_base_verbose 5 ... # trace job state transitions
+prte --prtemca plm_base_verbose 5 ... # trace daemon launch
+prte --prtemca rmaps_base_verbose 5 ... # trace process mapping
+```
+
+Key job states in order: `PRTE_JOB_STATE_INIT` →
+`PRTE_JOB_STATE_ALLOCATE` → `PRTE_JOB_STATE_MAP` →
+`PRTE_JOB_STATE_LAUNCH_DAEMONS` → `PRTE_JOB_STATE_RUNNING` →
+`PRTE_JOB_STATE_TERMINATED`.
+
+---
+
+## Contributing
+
+### Commit messages
+
+Write prose commit messages, not bullet lists. The subject line should
+complete the sentence "If applied, this commit will …". The body must
+explain **why** the change is needed, not just what it does. Keep the
+subject line under 72 characters.
+
+All commits require a `Signed-off-by:` line (DCO):
+
+```
+git commit -s
+```
+
+### Pull requests
+
+- Open PRs against the `master` branch (development trunk).
+- One logical change per PR. Split unrelated fixes.
+- Describe the problem being solved in the PR description, not just the
+ solution.
+- Documentation updates (`docs/`) are required for user-visible changes.
+
+### Testing
+
+PRRTE does not have a standalone unit test suite. Integration-level
+testing is done by running actual parallel jobs through the DVM. When
+modifying launch, mapping, or I/O forwarding paths, test with:
+
+```sh
+prte --daemonize # start DVM
+prun -n 4 hostname # basic launch smoke test
+pterm # shut down DVM
+```
+
+For resource manager integration (SLURM, PBS, LSF), test within an actual
+allocation on the relevant system.
+
+### Reporting bugs
+
+File issues at https://github.com/openpmix/prrte/issues. Include the
+output of `prte_info --all` and a minimal reproduction case.
diff --git a/docs/Makefile.am b/docs/Makefile.am
index db02b64a69..f458512f8a 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -31,6 +31,9 @@ OUTDIR = _build
SPHINX_CONFIG = conf.py
SPHINX_OPTS ?= -W --keep-going -j auto
+MARKDOWN_SOURCE_FILES = \
+ $(top_srcdir)/.github/CODE_OF_CONDUCT.md
+
# Note: it is significantly more convenient to list all the source
# files here using wildcards (vs. listing every single .rst file).
# However, it is necessary to list $(srcdir) when using wildcards.
@@ -50,8 +53,10 @@ RST_SOURCE_FILES = \
EXTRA_DIST = \
requirements.txt \
+ generate-code-of-conduct-rst.py \
_templates/configurator.html \
$(SPHINX_CONFIG) \
+ $(MARKDOWN_SOURCE_FILES) \
$(RST_SOURCE_FILES)
###########################################################################
@@ -93,6 +98,10 @@ if PRTE_BUILD_DOCS
include $(top_srcdir)/Makefile.prte-rules
+# Generate this file from CODE_OF_CONDUCT.md as part of the Sphinx
+# docs build.
+CODE_OF_CONDUCT_RST = $(srcdir)/code-of-conduct.rst
+
# Have to not list these targets in EXTRA_DIST outside of the
# PRTE_BUILD_DOCS conditional because "make dist" will fail due to
# these missing targets (and therefore not run the "dist-hook" target
@@ -109,6 +118,12 @@ ALL_MAN_BUILT = \
$(PRTE_MAN1_BUILT) $(PRTE_MAN5_BUILT)
$(ALL_MAN_BUILT): $(RST_SOURCE_FILES) $(IMAGE_SOURCE_FILES)
$(ALL_MAN_BUILT): $(TEXT_SOURCE_FILES) $(SPHINX_CONFIG)
+$(ALL_MAN_BUILT): $(CODE_OF_CONDUCT_RST)
+
+$(CODE_OF_CONDUCT_RST): $(top_srcdir)/.github/CODE_OF_CONDUCT.md
+$(CODE_OF_CONDUCT_RST): generate-code-of-conduct-rst.py
+ $(PRTE_V_GEN) python3 $(srcdir)/generate-code-of-conduct-rst.py \
+ --input $(top_srcdir)/.github/CODE_OF_CONDUCT.md --output $@
# List both commands (HTML and man) in a single rule because they
# really need to be run in serial. Specifically, if they were two
@@ -130,12 +145,13 @@ linkcheck:
maintainer-clean-local:
$(SPHINX_BUILD) -M clean "$(srcdir)" "$(OUTDIR)" $(SPHINX_OPTS)
+ rm -f $(CODE_OF_CONDUCT_RST)
# List all the built man pages here in the Automake BUILT_SOURCES
# macro. This hooks into the normal Automake build mechanisms, and
# will ultimately cause the invocation of the above rule that runs
# Sphinx to build the HTML and man pages.
-BUILT_SOURCES = $(ALL_MAN_BUILT)
+BUILT_SOURCES = $(CODE_OF_CONDUCT_RST) $(ALL_MAN_BUILT)
endif PRTE_BUILD_DOCS
diff --git a/docs/developers/gnu-autotools.rst b/docs/developers/gnu-autotools.rst
index bdaee51c0c..9a2b7c081a 100644
--- a/docs/developers/gnu-autotools.rst
+++ b/docs/developers/gnu-autotools.rst
@@ -88,7 +88,7 @@ to at least the versions listed below.
:class: error
The table below is almost certainly wrong; it has all the values
- from Open MPI. Need to update the table below with the appropriate
+ from PRRTE. Need to update the table below with the appropriate
values for PRRTE.
.. list-table::
diff --git a/docs/generate-code-of-conduct-rst.py b/docs/generate-code-of-conduct-rst.py
new file mode 100644
index 0000000000..3a2cc66d07
--- /dev/null
+++ b/docs/generate-code-of-conduct-rst.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2026 Nanook Consulting All rights reserved.
+# $COPYRIGHT$
+#
+# Additional copyrights may follow
+#
+# $HEADER$
+#
+
+"""Convert PRRTE's Markdown CODE_OF_CONDUCT.md to reStructuredText."""
+
+import argparse
+import re
+from pathlib import Path
+
+HEADING_RE = re.compile(r"^(#{1,6})\s+(.+?)\s*#*\s*$")
+REF_DEF_RE = re.compile(r"^\[([^\]]+)\]:\s*(\S+)\s*$")
+REF_LINK_RE = re.compile(r"\[([^\]]+)\]\[([^\]]+)\]")
+INLINE_LINK_RE = re.compile(r"\[([^\]]+)\]\(([^)]+)\)")
+BULLET_RE = re.compile(r"^\s*[*+-]\s+")
+UNDERLINES = ["=", "-", "~", "^", '"', "'"]
+
+
+def _rst_link(text, url):
+ return "`{} <{}>`_".format(text, url)
+
+
+def _convert_links(line, refs):
+ def repl_ref(match):
+ text = match.group(1)
+ ref = match.group(2)
+ return _rst_link(text, refs.get(ref, ref))
+
+ def repl_inline(match):
+ return _rst_link(match.group(1), match.group(2))
+
+ line = REF_LINK_RE.sub(repl_ref, line)
+ line = INLINE_LINK_RE.sub(repl_inline, line)
+ return line
+
+
+def convert(lines):
+ refs = {}
+ for line in lines:
+ match = REF_DEF_RE.match(line.strip())
+ if match:
+ refs[match.group(1)] = match.group(2)
+
+ out = [
+ "..",
+ " This file was generated from .github/CODE_OF_CONDUCT.md by docs/Makefile.am.",
+ " Do not edit directly.",
+ "",
+ ]
+
+ skip_next_blank = False
+ prev_bullet = False
+ for line in lines:
+ if REF_DEF_RE.match(line.strip()):
+ continue
+ if skip_next_blank and not line.strip():
+ skip_next_blank = False
+ continue
+ skip_next_blank = False
+
+ match = HEADING_RE.match(line)
+ if match:
+ if out and out[-1] != "":
+ out.append("")
+ title = _convert_links(match.group(2), refs)
+ level = min(len(match.group(1)) - 1, len(UNDERLINES) - 1)
+ out.extend([title, UNDERLINES[level] * len(title), ""])
+ skip_next_blank = True
+ prev_bullet = False
+ else:
+ is_bullet = bool(BULLET_RE.match(line))
+ if is_bullet and out and out[-1] != "" and not prev_bullet:
+ out.append("")
+ out.append(_convert_links(line, refs))
+ prev_bullet = is_bullet
+
+ while out and out[-1] == "":
+ out.pop()
+ return "\n".join(out) + "\n"
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--input", required=True)
+ parser.add_argument("--output", required=True)
+ args = parser.parse_args()
+
+ input_path = Path(args.input)
+ output_path = Path(args.output)
+ output_path.parent.mkdir(parents=True, exist_ok=True)
+ output_path.write_text(
+ convert(input_path.read_text(encoding="utf-8").splitlines()),
+ encoding="utf-8")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/docs/index.rst b/docs/index.rst
index fbd3161e05..47eafee5b4 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -40,6 +40,7 @@ Table of contents
session-directory
developers/index
contributing
+ code-of-conduct
license
man/index
versions
diff --git a/docs/launching-apps/lsf.rst b/docs/launching-apps/lsf.rst
index eeed2c88d3..8e8aca91af 100644
--- a/docs/launching-apps/lsf.rst
+++ b/docs/launching-apps/lsf.rst
@@ -1,13 +1,18 @@
Launching with LSF
==================
+.. warning:: Problems have been reported with using the most recent releases of LSF, in particular
+ the version supplied with IBM Spectrum LSF Version 10.1 Fix Pack 15.
+ The suggested workaround is to use an older release of the LSF 10.1 package or to
+ configure PRRTE without LSF support.
+
PRRTE supports the LSF resource manager.
Verify LSF support
------------------
The ``prte_info`` command can be used to determine whether or not an
-installed Open MPI includes LSF support:
+installed PRRTE includes LSF support:
.. code-block::
diff --git a/docs/launching-apps/quickstart.rst b/docs/launching-apps/quickstart.rst
index 73c78e6ee3..3427b1ae9c 100644
--- a/docs/launching-apps/quickstart.rst
+++ b/docs/launching-apps/quickstart.rst
@@ -7,7 +7,7 @@ Although this section skips many details, it offers examples that will
probably work in many environments.
.. caution:: Note that this section is a "Quick start" |mdash| it does
- not attempt to be comprehensive or describe how to build Open MPI
+ not attempt to be comprehensive or describe how to build PRRTE
in all supported environments. The examples below may therefore
not work exactly as shown in your environment.
diff --git a/docs/launching-apps/slurm.rst b/docs/launching-apps/slurm.rst
index 154d703af1..046b74d4c1 100644
--- a/docs/launching-apps/slurm.rst
+++ b/docs/launching-apps/slurm.rst
@@ -33,7 +33,7 @@ For example:
shell$ salloc -n 4
salloc: Granted job allocation 1234
- # Now run an Open MPI job on all the slots allocated by Slurm
+ # Now run an PRRTE job on all the slots allocated by Slurm
shell$ prterun mpi-hello-world
This will run the 4 processes on the node(s) that were allocated
diff --git a/docs/launching-apps/tm.rst b/docs/launching-apps/tm.rst
index 13a5ce2c36..a65b1cbe92 100644
--- a/docs/launching-apps/tm.rst
+++ b/docs/launching-apps/tm.rst
@@ -8,7 +8,7 @@ Verify PBS/Torque support
-------------------------
The ``prte_info`` command can be used to determine whether or not an
-installed Open MPI includes Torque/PBS Pro support:
+installed PRRTE includes Torque/PBS Pro support:
.. code-block::
@@ -16,7 +16,7 @@ installed Open MPI includes Torque/PBS Pro support:
If the PRRTE installation includes support for PBS/Torque, you
should see a line similar to that below. Note the MCA version
-information varies depending on which version of Open MPI is
+information varies depending on which version of PRRTE is
installed.
.. code-block::
diff --git a/docs/launching-apps/unusual.rst b/docs/launching-apps/unusual.rst
index 193a050915..1b05517a03 100644
--- a/docs/launching-apps/unusual.rst
+++ b/docs/launching-apps/unusual.rst
@@ -120,14 +120,14 @@ from the command line.
Connecting independent MPI applications
---------------------------------------
-In certain environments, Open MPI supports connecting multiple,
+In certain environments, PRRTE supports connecting multiple,
independent MPI applications using mechanisms defined in the MPI
specification such as ``MPI_Comm_connect() / MPI_Comm_accept()`` and
publishing connection information using ``MPI_Publish_name() /
MPI_Lookup_name()``. These mechanisms require a centralized service
to exchange contact information across multiple jobs.
-Beginning with Open MPI v5.0.0 this can be achieved by starting an
+This can be achieved by starting an
instance of the prte server with the ``report-uri`` option to
display the contact information of the prte server. This information
can then be used for launching subsequent MPI applications.
diff --git a/src/mca/ras/base/ras_base_node.c b/src/mca/ras/base/ras_base_node.c
index 627eececda..87e4bca1be 100644
--- a/src/mca/ras/base/ras_base_node.c
+++ b/src/mca/ras/base/ras_base_node.c
@@ -40,6 +40,32 @@
#include "src/mca/ras/base/base.h"
+/* Normalize a node name to the short form, storing the FQDN as rawname
+ * and as an alias so both forms resolve via prte_quickmatch / prte_nptr_match.
+ * No-op when keep_fqdn_hostnames is set or the name is an IP address. */
+static void normalize_node(prte_node_t *node)
+{
+ char *ptr, *fqdn;
+
+ if (prte_keep_fqdn_hostnames || pmix_net_isaddr(node->name)) {
+ return;
+ }
+ ptr = strchr(node->name, '.');
+ if (NULL == ptr) {
+ return;
+ }
+ /* copy the full FQDN, then truncate node->name in place to the short name */
+ fqdn = strdup(node->name);
+ *ptr = '\0';
+ if (NULL == node->rawname) {
+ node->rawname = fqdn;
+ } else {
+ PMIx_Argv_append_unique_nosize(&node->aliases, fqdn);
+ free(fqdn);
+ }
+ PMIx_Argv_append_unique_nosize(&node->aliases, node->rawname);
+}
+
/*
* Add the specified node definitions to the global data store
* NOTE: this removes all items from the list!
@@ -197,6 +223,11 @@ int prte_ras_base_node_insert(pmix_list_t *nodes, prte_job_t *jdata)
*/
PRTE_FLAG_SET(node, PRTE_NODE_FLAG_SLOTS_GIVEN);
}
+ /* detect FQDN before normalizing, then normalize to short name */
+ if (!pmix_net_isaddr(node->name) && NULL != strchr(node->name, '.')) {
+ prte_have_fqdn_allocation = true;
+ }
+ normalize_node(node);
/* insert it into the array */
node->index = pmix_pointer_array_add(prte_node_pool, (void *) node);
if (PRTE_SUCCESS > (rc = node->index)) {
@@ -221,10 +252,6 @@ int prte_ras_base_node_insert(pmix_list_t *nodes, prte_job_t *jdata)
}
/* update the total slots in the job */
prte_ras_base.total_slots_alloc += node->slots;
- /* check if we have fqdn names in the allocation */
- if (!pmix_net_isaddr(node->name) && NULL != strchr(node->name, '.')) {
- prte_have_fqdn_allocation = true;
- }
/* duplicate the node if requested */
for (i = 1; i < prte_ras_base.multiplier; i++) {
rc = prte_node_copy(&nptr, node);
diff --git a/src/mca/rmaps/lsf/rmaps_lsf.c b/src/mca/rmaps/lsf/rmaps_lsf.c
index f73aeb8171..ae2a6f8c68 100644
--- a/src/mca/rmaps/lsf/rmaps_lsf.c
+++ b/src/mca/rmaps/lsf/rmaps_lsf.c
@@ -142,6 +142,7 @@ static int lsf_map(prte_job_t *jdata,
free(jdata->map->last_mapper);
}
jdata->map->last_mapper = strdup(c->pmix_mca_component_name);
+ options->map = PRTE_MAPPING_BYUSER;
/* setup the node list */
PMIX_CONSTRUCT(&node_list, pmix_list_t);
@@ -156,6 +157,7 @@ static int lsf_map(prte_job_t *jdata,
/* start at the beginning... */
vpid_start = 0;
jdata->num_procs = 0;
+ num_ranks = 0;
PMIX_CONSTRUCT(&rankmap, pmix_pointer_array_t);
rc = pmix_pointer_array_init(&rankmap,
PRTE_GLOBAL_ARRAY_BLOCK_SIZE,
@@ -171,6 +173,13 @@ static int lsf_map(prte_job_t *jdata,
rc = PRTE_ERR_SILENT;
goto error;
}
+ if (0 == num_ranks) {
+ /* empty affinity file means LSF set no pinning for this job -
+ * let the next mapper handle it normally */
+ PMIX_DESTRUCT(&rankmap);
+ PMIX_LIST_DESTRUCT(&node_list);
+ return PRTE_ERR_TAKE_NEXT_OPTION;
+ }
/* cycle through the app_contexts, mapping them sequentially */
for (i = 0; i < jdata->apps->size; i++) {
@@ -312,7 +321,6 @@ static int lsf_map(prte_job_t *jdata,
if (PRTE_SUCCESS != rc) {
goto error;
}
- options->map = PRTE_MAPPING_BYUSER;
proc = prte_rmaps_base_setup_proc(jdata, app->idx, node, NULL, options);
if (NULL == proc) {
PRTE_ERROR_LOG(PRTE_ERR_OUT_OF_RESOURCE);
@@ -432,34 +440,28 @@ static int lsf_map(prte_job_t *jdata,
error:
PMIX_LIST_DESTRUCT(&node_list);
+ for (i = 0; i < rankmap.size; i++) {
+ if (NULL != (rfmap = pmix_pointer_array_get_item(&rankmap, i))) {
+ PMIX_RELEASE(rfmap);
+ }
+ }
+ PMIX_DESTRUCT(&rankmap);
+ num_ranks = 0;
return rc;
}
static int file_parse(const char *affinity_file)
{
- int rc = PRTE_SUCCESS;
int i, j;
prte_rmaps_lsf_map_t *rfmap = NULL;
- pmix_pointer_array_t *assigned_ranks_array;
struct stat buf;
FILE *fp;
char *hstname, *membind_opt;
- char *sep, *eptr, **cpus, *ptr;
+ char *sep = NULL, *eptr, **cpus, *ptr;
prte_node_t *nptr, *node;
hwloc_obj_t obj;
- /* keep track of rank assignments */
- assigned_ranks_array = PMIX_NEW(pmix_pointer_array_t);
- rc = pmix_pointer_array_init(assigned_ranks_array,
- PRTE_GLOBAL_ARRAY_BLOCK_SIZE,
- PRTE_GLOBAL_ARRAY_MAX_SIZE,
- PRTE_GLOBAL_ARRAY_BLOCK_SIZE);
- if (PMIX_SUCCESS != rc) {
- PMIX_RELEASE(assigned_ranks_array);
- return PRTE_ERROR;
- }
-
/* check to see if the file is empty - if it is,
* then affinity wasn't actually set for this job */
if (0 != stat(affinity_file, &buf)) {
diff --git a/src/prted/prun_common.c b/src/prted/prun_common.c
index 1f58c1d832..79112b3ce3 100644
--- a/src/prted/prun_common.c
+++ b/src/prted/prun_common.c
@@ -541,6 +541,7 @@ int prun_common(pmix_cli_result_t *results,
}
/* we want to be notified upon job completion */
+ flag = true;
PMIX_INFO_LIST_ADD(ret, jinfo, PMIX_NOTIFY_COMPLETION, &flag, PMIX_BOOL);
/* pickup any relevant envars */
@@ -772,6 +773,16 @@ int prte_prun_parse_common_cli(void *jinfo, pmix_cli_result_t *results,
/* pass the personality */
PMIX_INFO_LIST_ADD(ret, jinfo, PMIX_PERSONALITY, schizo->name, PMIX_STRING);
+ /* Display directives are job-level only: there is no way to scope a map,
+ * binding, or allocation display to an individual app context. A second
+ * instance therefore almost always means the user attached one to an app
+ * in an MPMD line, which we cannot honor - reject it rather than silently
+ * applying just one. */
+ if (1 < pmix_cmd_line_get_ninsts(results, PRTE_CLI_DISPLAY)) {
+ pmix_show_help("help-schizo-base.txt", "multi-instances", true, PRTE_CLI_DISPLAY);
+ return PRTE_ERR_BAD_PARAM;
+ }
+
/* get display options */
opt = pmix_cmd_line_get_param(results, PRTE_CLI_DISPLAY);
if (NULL != opt) {
diff --git a/src/util/dash_host/dash_host.c b/src/util/dash_host/dash_host.c
index 04d81e3177..668b7fe969 100644
--- a/src/util/dash_host/dash_host.c
+++ b/src/util/dash_host/dash_host.c
@@ -93,8 +93,6 @@ int prte_util_add_dash_host_nodes(pmix_list_t *nodes, char *hosts, bool allocati
int slots = 0;
bool slots_given;
char *cptr;
- char *shortname;
- char *rawname;
bool add_slots = false;
PMIX_OUTPUT_VERBOSE((1, prte_ras_base_framework.framework_output,
@@ -250,34 +248,15 @@ int prte_util_add_dash_host_nodes(pmix_list_t *nodes, char *hosts, bool allocati
}
}
- /* check for local name and compute non-fqdn name */
- shortname = NULL;
- rawname = NULL;
-
+ /* check for local name */
if (prte_check_host_is_local(mini_map[i])) {
ndname = prte_process_info.nodename;
} else {
ndname = mini_map[i];
}
- if (!prte_keep_fqdn_hostnames) {
- // Strip off the FQDN if present, ignore IP addresses
- if (!pmix_net_isaddr(mini_map[i])) {
- cptr = strchr(ndname, '.');
- if (NULL != cptr) {
- rawname = strdup(ndname);
- *cptr = '\0';
- shortname = strdup(ndname);
- *cptr = '.';
- }
- }
- }
-
/* see if a node of this name is already on the list */
node = prte_node_match(&adds, ndname);
- if (NULL == node && NULL != shortname) {
- node = prte_node_match(&adds, shortname);
- }
if (NULL != node) {
if (slots_given) {
node->slots += slots;
@@ -296,36 +275,14 @@ int prte_util_add_dash_host_nodes(pmix_list_t *nodes, char *hosts, bool allocati
PMIX_OUTPUT_VERBOSE((1, prte_ras_base_framework.framework_output,
"%s dashhost: node %s already on list - slots %d",
PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), node->name, node->slots));
- if (NULL != shortname) {
- free(shortname);
- shortname = NULL;
- }
- if (NULL != rawname) {
- node->rawname = rawname;
- rawname = NULL;
- }
} else {
/* if we didn't find it, add it to the list */
node = PMIX_NEW(prte_node_t);
if (NULL == node) {
PMIx_Argv_free(mapped_nodes);
- if (NULL != shortname) {
- free(shortname);
- }
- if (NULL != rawname) {
- free(rawname);
- }
return PRTE_ERR_OUT_OF_RESOURCE;
}
- if (prte_keep_fqdn_hostnames || NULL == shortname) {
- node->name = strdup(ndname);
- } else {
- node->name = strdup(shortname);
- }
- if (NULL != rawname) {
- node->rawname = rawname;
- rawname = NULL;
- }
+ node->name = strdup(ndname);
PMIX_OUTPUT_VERBOSE((1, prte_ras_base_framework.framework_output,
"%s dashhost: added node %s to list - slots %d",
PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), node->name, slots));
@@ -349,19 +306,9 @@ int prte_util_add_dash_host_nodes(pmix_list_t *nodes, char *hosts, bool allocati
pmix_list_append(&adds, &node->super);
}
if (0 != strcmp(node->name, mini_map[i])) {
- // add the mini_map name to the list of aliases
+ // add the mini_map entry as an alias if it differs from the resolved name
PMIx_Argv_append_unique_nosize(&node->aliases, mini_map[i]);
}
- // ensure the non-fqdn version is saved
- if (NULL != shortname && 0 != strcmp(shortname, node->name)) {
- PMIx_Argv_append_unique_nosize(&node->aliases, shortname);
- }
- if (NULL != shortname) {
- free(shortname);
- }
- if (NULL != rawname) {
- free(rawname);
- }
}
PMIx_Argv_free(mini_map);
diff --git a/src/util/hostfile/hostfile.c b/src/util/hostfile/hostfile.c
index b10ee35b5b..4151590c10 100644
--- a/src/util/hostfile/hostfile.c
+++ b/src/util/hostfile/hostfile.c
@@ -115,7 +115,6 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
int cnt;
int number_of_slots = 0;
char buff[64];
- char *alias = NULL;
if (PRTE_HOSTFILE_STRING == token || PRTE_HOSTFILE_HOSTNAME == token ||
PRTE_HOSTFILE_INT == token || PRTE_HOSTFILE_IPV4 == token ||
@@ -142,17 +141,6 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
}
PMIx_Argv_free(argv);
- if (!prte_keep_fqdn_hostnames) {
- // Strip off the FQDN if present, ignore IP addresses
- if (!pmix_net_isaddr(node_name)) {
- char *ptr;
- alias = strdup(node_name);
- if (NULL != (ptr = strchr(node_name, '.'))) {
- *ptr = '\0';
- }
- }
- }
-
/* if the first letter of the name is '^', then this is a node
* to be excluded. Remove the ^ character so the nodename is
* usable, and put it on the exclude list
@@ -181,20 +169,11 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
node = prte_node_match(exclude, node_name);
if (NULL == node) {
node = PMIX_NEW(prte_node_t);
- if (prte_keep_fqdn_hostnames || NULL == alias) {
- node->name = strdup(node_name);
- } else {
- node->name = strdup(alias);
- node->rawname = strdup(node_name);
- }
+ node->name = strdup(node_name);
if (NULL != username) {
prte_set_attribute(&node->attributes, PRTE_NODE_USERNAME, PRTE_ATTR_LOCAL,
username, PMIX_STRING);
}
- if (NULL != alias && 0 != strcmp(alias, node->name)) {
- // new node object, so alias must be unique
- PMIx_Argv_append_nosize(&node->aliases, alias);
- }
pmix_list_append(exclude, &node->super);
} else {
/* the node name may not match the prior entry, so ensure we
@@ -203,13 +182,6 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
PMIx_Argv_append_unique_nosize(&node->aliases, node_name);
}
free(node_name);
- if (NULL != alias && 0 != strcmp(alias, node->name)) {
- PMIx_Argv_append_unique_nosize(&node->aliases, alias);
- }
- }
- if (NULL != alias) {
- free(alias);
- alias = NULL;
}
if (NULL != username) {
free(username);
@@ -222,10 +194,9 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
*/
PMIX_OUTPUT_VERBOSE((3, prte_ras_base_framework.framework_output,
- "%s hostfile: node %s is being included - keep all is %s alias %s",
+ "%s hostfile: node %s is being included - keep all is %s",
PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), node_name,
- keep_all ? "TRUE" : "FALSE",
- (NULL == alias) ? "NULL" : alias));
+ keep_all ? "TRUE" : "FALSE"));
/* see if this is another name for us */
if (prte_check_host_is_local(node_name)) {
@@ -237,22 +208,13 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
/* Do we need to make a new node object? */
if (keep_all || NULL == (node = prte_node_match(updates, node_name))) {
node = PMIX_NEW(prte_node_t);
- if (prte_keep_fqdn_hostnames || NULL == alias) {
- node->name = strdup(node_name);
- } else {
- node->name = strdup(node_name);
- node->rawname = strdup(alias);
- }
+ node->name = strdup(node_name);
free(node_name);
node->slots = 1;
if (NULL != username) {
prte_set_attribute(&node->attributes, PRTE_NODE_USERNAME, PRTE_ATTR_LOCAL, username,
PMIX_STRING);
}
- if (NULL != alias && 0 != strcmp(alias, node->name)) {
- // new node object, so alias must be unique
- PMIx_Argv_append_nosize(&node->aliases, alias);
- }
pmix_list_append(updates, &node->super);
} else {
/* this node was already found once - add a slot and mark slots as "given" */
@@ -264,44 +226,13 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
PMIx_Argv_append_unique_nosize(&node->aliases, node_name);
}
free(node_name);
- if (NULL != alias && 0 != strcmp(alias, node->name)) {
- PMIx_Argv_append_unique_nosize(&node->aliases, alias);
- }
- }
- if (NULL != alias) {
- free(alias);
- alias = NULL;
}
} else if (PRTE_HOSTFILE_RELATIVE == token) {
/* store this for later processing */
node = PMIX_NEW(prte_node_t);
- // Strip off the FQDN if present, ignore IP addresses
- if (!pmix_net_isaddr(prte_util_hostfile_value.sval)) {
- char *ptr;
- alias = strdup(prte_util_hostfile_value.sval);
- if (NULL != (ptr = strchr(alias, '.'))) {
- *ptr = '\0';
- } else {
- free(alias);
- alias = NULL;
- }
- }
- if (prte_keep_fqdn_hostnames || NULL == alias) {
- node->name = strdup(prte_util_hostfile_value.sval);
- } else {
- node->name = strdup(alias);
- node->rawname = strdup(prte_util_hostfile_value.sval);
- }
- if (NULL != alias && 0 != strcmp(alias, node->name)) {
- // new node object, so alias must be unique
- PMIx_Argv_append_nosize(&node->aliases, alias);
- }
+ node->name = strdup(prte_util_hostfile_value.sval);
pmix_list_append(updates, &node->super);
- if (NULL != alias) {
- free(alias);
- alias = NULL;
- }
} else if (PRTE_HOSTFILE_RANK == token) {
/* we can ignore the rank, but we need to extract the node name. we
@@ -339,15 +270,6 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
}
PMIx_Argv_free(argv);
- // Strip off the FQDN if present, ignore IP addresses
- if (!prte_keep_fqdn_hostnames && !pmix_net_isaddr(node_name)) {
- char *ptr;
- alias = strdup(node_name);
- if (NULL != (ptr = strchr(alias, '.'))) {
- *ptr = '\0';
- }
- }
-
/* Do we need to make a new node object? */
if (NULL == (node = prte_node_match(updates, node_name))) {
node = PMIX_NEW(prte_node_t);
@@ -367,12 +289,6 @@ static int hostfile_parse_line(int token, pmix_list_t *updates,
PMIx_Argv_append_unique_nosize(&node->aliases, node_name);
}
}
- if (NULL != alias) {
- PMIx_Argv_append_unique_nosize(&node->aliases, alias);
- free(alias);
- node->rawname = strdup(node_name);
- alias = NULL;
- }
PMIX_OUTPUT_VERBOSE((1, prte_ras_base_framework.framework_output,
"%s hostfile: node %s slots %d nodes-given %s",
PRTE_NAME_PRINT(PRTE_PROC_MY_NAME), node->name, node->slots,