firefly/ember/hermes/merlin: add NetworkIO storage subsystem - #2699
Open
deanchester wants to merge 2 commits into
Open
firefly/ember/hermes/merlin: add NetworkIO storage subsystem#2699deanchester wants to merge 2 commits into
deanchester wants to merge 2 commits into
Conversation
Model storage I/O that contends with MPI traffic on a shared fabric.
Storage is served by dedicated I/O nodes reached over the same Merlin
network as compute endpoints, so reads and writes traverse the real NIC,
switch, and link models and share links, buffers, and arbitration with
message traffic. Modelling the two together exposes contention that
per-resource models hide.
Architecture
------------
compute node I/O node (per pool)
+----------------+ +----------------------+
| Ember motif | | firefly NIC (recv) |
| (TestNetworkIO)| | permit check -> |
+-------+--------+ | AckDeny if absent |
| hermes::NetworkIO | capacity check -> |
| open/read_at/iwrite_at/... | ShortRead/NoSpace |
+-------v--------+ +----------+-----------+
| hadesNetworkIO | |
| stripe mapper | Merlin fabric v
| Block/RR/Hash +====[ NIC | router | link ]==> SimpleSSD
| -> target nid | (shared w/ MPI traffic) t = lat + B/bw
+----------------+ +-----------+
pool state (SharedArray/SharedSet, published at init):
IoPool.<name> : nid membership
IoPoolPermit.<name> : senders allowed to reach pool
Node model
----------
merlin's System.allocateIoNodes() reserves endpoints from a shared pool
and setIoNetworkInterface() attaches a NIC to them. Pools are named, so
single-pool (back-compatible) and multi-pool isolation are both
expressible; name collisions are detected, not silently merged. Each
pool publishes its membership and a permit set of allowed senders; the
storage receive path rejects unpermitted senders with an explicit
permission-denied ack rather than dropping silently.
API (hermes)
------------
SST::Hermes::NetworkIO is shaped after MPI-IO: open/close yield file
handles; read_at/write_at block; iread_at/iwrite_at complete via
wait/waitall/test/testany with best-effort cancel. Every completion
carries an IOStatus (bytes transferred + error), so short and denied
transfers are observable. A legacy networkIORead/networkIOWrite shim
targets an implicit file, keeping pre-handle motifs working.
Non-blocking completion uses the OpenMPI wait-sync pattern: each request
owns a completion slot signalled on ack; waitall fills statuses in
request order; testany on an empty set completes immediately; cancel
succeeds without a distinct cancelled status (as with MPI_Cancel). The
caller owns request lifetime until a completion call consumes it, so
freeing a completed or cancelled request has no use-after-free window.
Data placement (firefly)
------------------------
Files stripe across a pool by a configurable unit (default 1 MiB) over
at most MAX_STRIPE_NIDS (64) targets. The mapper is pluggable: Block maps
contiguous ranges, Round-Robin cycles fixed blocks, Hash scatters to
balance load. Capacity is enforced at the storage node -- overruns
surface as ShortRead/NoSpace, never silent clamping. OpenMode::Create is
accepted but ignored (implicit create); handles open at finish() are
auto-closed with a warning.
Permits must publish after the virtual NIC resolves its real network id
but before pool state locks. This is enforced structurally: permit setup
runs in the storage provider's init phase and the Ember engine threads
the init phase through to the API, so permits can never bind an
unresolved nid.
Storage timing (firefly)
------------------------
A SimpleSSD backend serves each request in lat + bytes/bandwidth, with
independent read/write bandwidth and overhead, so response time tracks
request size and offered load. NIC statistics expose per-target
read/write counts and latencies for post-run per-I/O-node inspection.
Motif support (ember)
---------------------
EmberNetworkIOGenerator supplies the base plumbing; the TestNetworkIO
motif drives the full surface (read/write, handles, striping, permit/
deny, async batches with cancel) and doubles as a worked example for
storage-aware motif authors.
Scope
-----
Collective I/O, file views and derived datatypes, individual/shared file
pointers, typed buffers, and explicit sync/atomicity are out of scope
here; the handle- and status-based model leaves room to add them without
breaking callers.
Testing
-------
Adds 24 tests across six suites to demonstrate the implementation:
networkIO basic read/write and statistics output (2)
networkIO_handles open/close, multiple files, short reads (3)
networkIO_stripe Block/RR/Hash placement and balance (6)
networkIO_pools isolation, permit/deny, byte budgets,
name-collision, back-compat (9)
networkIO_async non-blocking issue, waitall, cancel (3)
networkIO_interference compute/I/O contention on shared fabric (1)
All run at np=1 and np=2.
Contributor
|
Status Flag 'Pre-Test Inspection' - - This Pull Request Requires Inspection... The code must be inspected by a member of the Team before Testing/Merging |
Contributor
|
Status Flag 'Pre-Test Inspection' - - This Pull Request Requires Inspection... The code must be inspected by a member of the Team before Testing/Merging |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
NetworkIO: file-like storage I/O over the SST fabric
Model storage I/O that contends with MPI traffic on a shared fabric. A
subset of nodes act as dedicated I/O nodes, serving file-like
open/read/write/closetraffic over the same merlin interconnect asordinary messages. Because storage and message traffic share links,
buffers, and arbitration, the two can be studied together in a single
simulation — contention that per-resource models hide.
Lands as the consolidated PR1–PR10 series, rebased onto current
devel(base
c1014f6). 71 files, +6923 / −21.Architecture
What's in it
The feature spans four element libraries:
networkIOapi.h— the abstractSST::Hermes::NetworkIO::Interfaceand its types (Status,IOStatus,OpenMode,FileInfo,FileHandle,IORequest).hadesNetworkIO(compute-side provider),hadesStorageController(pool publisher),Block/RR/Hashstriping mappers,storageModel/simpleSSDbacking model, NIC send/recv NetworkIO path + statistics.TestNetworkIOreference motif + generator base,libs/networkIOEvents/(oneEmberEventper API op), 6 test drivers + 6 test suites.System.allocateIoNodes()/setIoNodeJobFactory()/setIoNetworkInterface()inpymerlin-base.pyto reserve I/O nodes from the node pool.Incidental:
.gitignore(test scratch files) andCONTRIBUTORS.TXT.How it works
Node model.
System.allocateIoNodes()reserves endpoints from ashared pool;
setIoNetworkInterface()attaches a NIC to them. Pools arenamed, so single-pool (back-compatible) and multi-pool isolation are both
expressible, and name collisions are detected rather than silently
merged. Each pool publishes its membership and a permit set of allowed
senders; the storage receive path rejects unpermitted senders with an
explicit
PermissionDeniedack rather than dropping silently.API (hermes).
SST::Hermes::NetworkIOis shaped after MPI-IO somotif authors reason in familiar terms:
open/closeyield file handles;read_at/write_atblock;iread_at/iwrite_atcomplete viawait/waitall/test/testanywith best-effortcancel. Everycompletion carries an
IOStatus(bytes transferred + error), so short anddenied transfers are observable. A legacy
networkIORead/networkIOWriteshim targets an implicit file, keeping pre-handle motifs working.
Non-blocking completion follows the OpenMPI wait-sync pattern: each
request owns a completion slot signalled on ack;
waitallfills statusesin request order;
testanyon an empty set completes immediately;cancelsucceeds without a distinct cancelled status (as withMPI_Cancel). The caller owns request lifetime until a completion callconsumes it, so freeing a completed or cancelled request has no
use-after-free window.
Data placement (firefly). Files stripe across a pool by a
configurable unit (default 1 MiB) over at most
MAX_STRIPE_NIDS(64)targets. The mapper is pluggable:
Blockmaps contiguous ranges,Round-Robincycles fixed blocks,Hashscatters to balance load.Capacity is enforced at the storage node — overruns surface as
ShortRead/NoSpace, never silent clamping.OpenMode::Createisaccepted but ignored (implicit create); handles left open at
finish()are auto-closed with a warning.
Permits must publish after the virtual NIC resolves its real network id
but before pool state locks. This is enforced structurally: permit
setup runs in the storage provider's
initphase and the Ember enginethreads the
initphase through to the API, so permits can never bind anunresolved nid.
Storage timing (firefly). A
SimpleSSDbackend serves each requestin
lat + bytes/bandwidth, with independent read/write bandwidth andoverhead, so response time tracks request size and offered load. NIC
statistics expose per-target read/write counts and latencies for
post-run per-I/O-node inspection.
Relationship to MPI-IO
The interface is deliberately shaped after
MPI_File_*, so the mapping isdirect:
open/closeMPI_File_open/MPI_File_closeread_at/write_atMPI_File_read_at/MPI_File_write_atiread_at/iwrite_atMPI_File_iread_at/MPI_File_iwrite_atwait/waitallMPI_Wait/MPI_Waitall(index-order fill)test/testanyMPI_Test/MPI_TestanycancelMPI_Cancel(best-effort, no cancelled status)IOStatusMPI_Statusstriping_unithintOut of scope for this revision: collective I/O (
read_at_all/write_at_all), file views and derived datatypes, individual/shared filepointers, typed buffers, and explicit sync/atomicity. The handle- and
status-based model leaves room to add these without breaking callers.
How to try it
Full driver:
src/sst/elements/ember/test/testIO.py. Reference motif:src/sst/elements/ember/networkIO/motifs/emberTestNetworkIO.cc.Testing
Adds 24 tests across six suites to demonstrate the implementation:
networkIOnetworkIO_handlesnetworkIO_stripenetworkIO_poolsnetworkIO_asyncnetworkIO_interferenceAll run at np=1 and np=2. Suites use a seeded RNG for deterministic
statistics output.