### Flock Python quickstart example Source: https://mochi.readthedocs.io/en/latest/flock/14_python.html Complete quickstart example for Flock Python bindings. It creates a Margo engine, initializes a GroupView, configures a static backend provider, creates a client, and makes a group handle. The example prints the provider address and group members, then finalizes the engine. ```python """ Quickstart example for Flock Python bindings. Demonstrates basic server and client setup. """ import mochi.flock.server as server import mochi.flock.client as client from mochi.flock.view import GroupView import mochi.margo import json # Create Margo engine engine = mochi.margo.Engine("na+sm", mochi.margo.server) # Create initial group view initial_view = GroupView() initial_view.members.add(str(engine.address), 42) # Configure Flock provider with static backend config = { "group": { "type": "static", "config": {} } } # Create Flock provider provider = server.Provider( engine=engine, provider_id=42, config=json.dumps(config), initial_view=initial_view ) print(f"Flock provider created at {engine.address} with provider_id 42") # Create client flock_client = client.Client(engine) # Create group handle group = flock_client.make_group_handle( address=str(engine.address), provider_id=42 ) print(f"Group handle created") print(f"Group view has {len(group.view.members)} members") # Access group view for i, member in enumerate(group.view.members): print(f" Member {i}: {member.address} (provider_id={member.provider_id})") # Cleanup engine.finalize() print("\nQuickstart completed successfully!") ``` -------------------------------- ### Quick start example (quickstart.py) Source: https://mochi.readthedocs.io/en/latest/_sources/yokan/12_python.rst.txt Demonstrates creating a Margo engine, starting a Yokan provider, creating a client and database handle, and performing basic put/get operations. ```python .. literalinclude:: ../../examples/yokan/12_python/quickstart.py :language: python ``` -------------------------------- ### Quick start example using Warabi Python bindings Source: https://mochi.readthedocs.io/en/latest/warabi/12_python.html Demonstrates creating a Margo engine, starting a Warabi provider with memory backend, creating a client and target handle, and performing write/read operations. ```python import mochi.margo from mochi.warabi.server import Provider from mochi.warabi.client import Client # Create a Margo engine engine = mochi.margo.Engine("na+sm", mochi.margo.server) # Start a Warabi provider with memory backend provider = Provider( engine=engine, provider_id=42, config={ "target": { "type": "memory" } } ) # Create a client client = Client(engine=engine) # Get a target handle target = client.make_target_handle( address=str(engine.addr()), provider_id=42 ) # Create a region and write data data = b"Hello, Warabi!" region = target.create_and_write(data, persist=True) print(f"Created region: {region}") # Read the data back result = target.read(region, offset=0, size=len(data)) print(f"Read data: {result}") # Verify assert result == data print("Success!") # Cleanup engine.finalize() ``` -------------------------------- ### Example output for installing from the Mochi Spack repository Source: https://mochi.readthedocs.io/en/latest/_sources/hello-mochi.rst.txt Example terminal output showing the commands and their results, including cloning the repository, adding it to Spack, installing mochi-ch-placement, and removing the repository. Note the typo in the final command (spack repo rm moch). ```text carns-x1-7g ~> cd /tmp/hello-mochi carns-x1-7g /t/hello-mochi> git clone https://github.com/mochi-hpc/mochi-spack-packages.git Cloning into 'mochi-spack-packages'... carns-x1-7g ~> cd /tmp/hello-mochi carns-x1-7g /t/hello-mochi> git clone https://github.com/mochi-hpc/mochi-spack-packages.git Cloning into 'mochi-spack-packages'... remote: Enumerating objects: 4432, done. remote: Counting objects: 100% (750/750), done. remote: Compressing objects: 100% (92/92), done. remote: Total 4432 (delta 637), reused 728 (delta 619), pack-reused 3682 Receiving objects: 100% (4432/4432), 439.71 KiB | 4.27 MiB/s, done. Resolving deltas: 100% (2671/2671), done. carns-x1-7g /t/hello-mochi [1]> spack repo add /tmp/hello-mochi/mochi-spack-packages ==> Added repo with namespace 'mochi'. carns-x1-7g /t/hello-mochi> spack install mochi-ch-placement [+] /usr (external autoconf-2.71-x7siqslynwavupcbrqxd3lu5ejfmqw33) [+] /usr (external automake-1.16.5-uiai5gcqq4cpcvolmkj4nzddgthvmaje) [+] /usr (external libtool-2.4.6-zqwp5nep4ud7vq2yl2oui247k6caerok) [+] /usr (external m4-1.4.18-sb5p7lz7gmfh3qba7tf72clw7vbpyhj5) ==> Installing mochi-ch-placement-0.1-zwfrofwevasjdo7pk5s3nrqqqb7y3u2t ==> No binary for mochi-ch-placement-0.1-zwfrofwevasjdo7pk5s3nrqqqb7y3u2t found: installing from source ==> No patches needed for mochi-ch-placement ==> mochi-ch-placement: Executing phase: 'autoreconf' ==> mochi-ch-placement: Executing phase: 'configure' ==> mochi-ch-placement: Executing phase: 'build' ==> mochi-ch-placement: Executing phase: 'install' ==> mochi-ch-placement: Successfully installed mochi-ch-placement-0.1-zwfrofwevasjdo7pk5s3nrqqqb7y3u2t Fetch: 1.28s. Build: 7.27s. Total: 8.55s. [+] /home/carns/working/src/spack/opt/spack/linux-ubuntu22.04-skylake/gcc-11.2.0/mochi-ch-placement-0.1-zwfrofwevasjdo7pk5s3nrqqqb7y3u2t carns-x1-7g /t/hello-mochi> spack repo rm moch ``` -------------------------------- ### Example Spack environment creation with output Source: https://mochi.readthedocs.io/en/latest/_sources/hello-mochi.rst.txt Shows an example of spack.yaml contents and the output from the commands to create, activate, and install the environment, including the concretized package list and installation progress for mochi-margo and its dependencies. ```text carns-x1-7g /t/hello-mochi> cat spack.yaml # This is a Spack Environment file. # # It describes a set of packages to be installed, along with # configuration settings. spack: specs: - mochi-margo repos: - /tmp/hello-mochi/mochi-spack-packages modules: prefix_inspections: lib: [LD_LIBRARY_PATH] lib64: [LD_LIBRARY_PATH] packages: libfabric: variants: fabrics=rxm,tcp mercury: variants: ~boostsys ~checksum view: true carns-x1-7g /t/hello-mochi> spack env create hello-mochi ./spack.yaml ==> Created environment 'hello-mochi' in /home/carns/working/src/spack/var/spack/environments/hello-mochi ==> You can activate this environment with: ==> spack env activate hello-mochi carns-x1-7g /t/hello-mochi> spack env activate hello-mochi carns-x1-7g /t/hello-mochi> spack install ==> Starting concretization ==> Environment concretized in 21.16 seconds. ==> Concretized mochi-margo - mjvnk7r mochi-margo@0.9.10%gcc@11.2.0~pvar arch=linux-ubuntu22.04-skylake - hxtr2qr ^argobots@1.1%gcc@11.2.0~affinity~debug~lazy_stack_alloc+perf~stackunwind~tool~valgrind stackguard=none arch=linux-ubuntu22.04-skylake [+] x7siqsl ^autoconf@2.71%gcc@11.2.0 arch=linux-ubuntu22.04-skylake [+] u0i5gc ^automake@1.16.5%gcc@11.2.0 arch=linux-ubuntu22.04-skylake [+] zcjnfn3 ^json-c@0.16%gcc@11.2.0~ipo build_type=RelWithDebInfo arch=linux-ubuntu22.04-skylake [+] qjgfk6r ^cmake@3.22.1%gcc@11.2.0~doc+ncurses+ownlibs~qt build_type=Release arch=linux-ubuntu22.04-skylake [+] zqwp5ne ^libtool@2.4.6%gcc@11.2.0 arch=linux-ubuntu22.04-skylake [+] sb5p7lz ^m4@1.4.18%gcc@11.2.0+sigsegv patches=3877ab5,fc9b616 arch=linux-ubuntu22.04-skylake [+] 6auh76q ^mercury@2.2.0%gcc@11.2.0 cflags:="-fsanitize=address -fno-omit-frame-pointer -g -Wall" ldflags:="-fsanitize=address" ~bmi~boostsys~checksum~debug~hwloc~ipo~mpi+ofi~psm~psm2+shared+sm~ucx~udreg build_type=RelWithDebInfo arch=linux-ubuntu22.04-skylake [+] di35yy4 ^cmake@3.22.1%gcc@11.2.0 cflags:="-fsanitize=address -fno-omit-frame-pointer -g -Wall" ldflags:="-fsanitize=address" ~doc+ncurses+ownlibs~qt build_type=Release arch=linux-ubuntu22.04-skylake [+] d6moqm3 ^libfabric@1.15.1%gcc@11.2.0 cflags:="-fsanitize=address -fno-omit-frame-pointer -g -Wall" ldflags:="-fsanitize=address" ~debug~disable-spinlocks~kdreg fabrics=rxm,sockets,tcp arch=linux-ubuntu22.04-skylake [+] uvo7kjt ^pkgconf@1.8.0%gcc@11.2.0 arch=linux-ubuntu22.04-skylake ==> Installing environment hello-mochi ==> Installing argobots-1.1-hxtr2qrrl7jxdhtw5ccdryqcjae3opu ==> No binary for argobots-1.1-hxtr2qrrl7jxdhtw5ccdryqcajee3opu found; installing from source ==> Using cached archive: /home/carns/working/src/spack/var/spack/cache/_source-cache/archive/f0/f0f971196fc8354881681cde2282a2fadb6d48ff5e84cf820ca657daad1549005.tar.gz ==> No patches needed for argobots ==> argobots: Executing phase: 'autoreconf' ==> argobots: Executing phase: 'configure' ==> argobots: Executing phase: 'build' ==> argobots: Executing phase: 'install' ==> argobots: Successfully installed argobots-1.1-hxtr5qrrl7jxdhtlw5ccdryqcajee3opu Fetch: 0.01s. Build: 7.35s. Total: 7.35s. [+] /home/corns/working/src/spack/opt/spack/linux-ubuntu22.04-skylake/gcc-11.2.0/argobots-1.1-hxtr5qrrjtjxdhjw5ccdryqcajee3opu [+] /usr (external autoconf-2.71-x3sdslynwaeacsy5gbxq2nm7f5nal3.cs3.pyph ``` -------------------------------- ### Install and launch a bedrock server daemon Source: https://mochi.readthedocs.io/en/latest/_sources/hello-mochi.rst.txt These commands install mochi-bedrock as a root spec, install new packages, and launch the server with the appropriate address string from Artifact 1d and 5. The example shows the command `bedrock tcp://`. ```bash # add mochi-bedrock as a root spec in your environment $ spack add mochi-bedrock # install new packages $ spack install # launch the server, substituting the command line argument with the # appropriate address string from Artifact 1d and 5 $ bedrock tcp:// ``` -------------------------------- ### Yokan C++ Quick Start: put and get with yokan::Client Source: https://mochi.readthedocs.io/en/latest/yokan/13_cpp.html Minimal C++ example using the Yokan header-only bindings. Initializes a Thallium engine in client mode, creates a yokan::Client, resolves a server endpoint, and connects to database ID 42. Demonstrates RAII resource management, exception-based error handling with yokan::Exception, and the put/get API. ```cpp /* * (C) 2024 The University of Chicago * * See COPYRIGHT in top-level directory. */ #include #include #include #include #include namespace tl = thallium; int main() { try { // Initialize Thallium engine tl::engine engine("na+sm", THALLIUM_CLIENT_MODE); // Create a client using the Margo instance from Thallium yokan::Client client(engine.get_margo_instance()); // Look up the server address tl::endpoint server_ep = engine.lookup("na+sm://localhost:1234"); // Connect to a database using the resolved address yokan::Database db = client.makeDatabaseHandle( server_ep.get_addr(), 42); // Put a value std::string key = "greeting"; std::string value = "Hello, Yokan!"; db.put(key.data(), key.size(), value.data(), value.size()); // Get the value back std::vector buffer(256); size_t vsize = buffer.size(); db.get(key.data(), key.size(), buffer.data(), &vsize); std::string retrieved(buffer.data(), vsize); std::cout << "Retrieved: " << retrieved << std::endl; } catch(const yokan::Exception& ex) { std::cerr << "Error: " << ex.what() << std::endl; return 1; } return 0; } ``` -------------------------------- ### Start initial group member with self bootstrap Source: https://mochi.readthedocs.io/en/latest/_sources/flock/05_bootstrap_join.rst.txt Step 1 of the example workflow: start the initial group member with "self" bootstrap. The output shows the server address, provider registration, and that the group file was written. ```console $ ./initial_server Server running at address na+sm://12345-0 Flock provider registered Group file written to: mygroup.flock ``` -------------------------------- ### Create and manage collections with client.c (C++) Source: https://mochi.readthedocs.io/en/latest/_sources/yokan/06_docs.rst.txt Check the show/hide client.c example that demonstrates creating a collection, checking its existence, getting its size and last identifier, and dropping it. These functions are extensively documented in yokan/collection.h and are available to the client library. ```cpp No visible source code on this page (literalinclude reference to ../../examples/yokan/05_coll/client.c). ``` -------------------------------- ### Client basic operations example (client_basic.py) Source: https://mochi.readthedocs.io/en/latest/_sources/yokan/12_python.rst.txt Demonstrates basic client operations: put, get, exists, length, erase, erase_range, and count. Note that get requires a pre-sized buffer. ```python .. literalinclude:: ../../examples/yokan/12_python/client_basic.py :language: python ``` -------------------------------- ### Install a package from the Mochi Spack repository Source: https://mochi.readthedocs.io/en/latest/_sources/hello-mochi.rst.txt Commands to clone the Mochi Spack repository, add it to Spack, install the mochi-ch-placement package, and remove the repository. The example uses /tmp/hello-mochi as the checkout directory. ```bash # choose a directory where you will check out a copy of the current Mochi # Spack package repository. We use /tmp/hello-mochi in this example, but # you should choose a more permanent path. $ cd /tmp/hello-mochi # clone the repository $ git clone https://github.com/mochi-hpc/mochi-spack-packages.git # add the repository to spack $ spack repo add /tmp/hello-mochi/mochi-spack-packages # install an example package that is only available in the Mochi repository $ spack install mochi-ch-placement # remove repository from spack (we will make this persistent as part of an # environment later) $ spack repo rm mochi ``` -------------------------------- ### margo_start_abt_profiling Source: https://mochi.readthedocs.io/en/latest/margo/c_api.html Starts Argobots profiling. Argobots must have been installed with the +tool variant. ```APIDOC ## margo_start_abt_profiling ### Description Start Argobots profiling. Argobots must have been installed with the +tool variant. ### Function Signature `int margo_start_abt_profiling(margo_instance_id mid, bool detailed)` ### Parameters - **mid** (margo_instance_id) - Margo instance. - **detailed** (bool) - Whether profiling should be detailed or not. ### Returns 0 on success, -1 on failure (e.g. if ABT profiling was already started or if Argobots was not compiled with tools). ``` -------------------------------- ### Run Bedrock with example config Source: https://mochi.readthedocs.io/en/latest/tutorials/margo/03_ex3.html Launch the Bedrock daemon with the example configuration. The daemon prints its address on the last log line, which you copy for the next query. ```bash bedrock na+sm -c ../examples/bedrock-config.json ``` -------------------------------- ### Set up Spack environment and build Source: https://mochi.readthedocs.io/en/latest/_sources/tutorials/margo/01_ex1.rst.txt Set up the Spack environment and build the existing client and server programs. Run these commands from the margo-tutorial-exercises directory. ```console spack env create margo-tuto-env spack.yaml spack env activate margo-tuto-env spack install mkdir build cd build cmake .. make ``` -------------------------------- ### Client Class initialization Source: https://mochi.readthedocs.io/en/latest/_sources/flock/14_python.rst.txt Shows how to initialize a Client from an address or from an existing engine. ```python from mochi.flock.client import Client # Initialize from address client = Client("ofi+tcp") # Or from existing engine client = Client(engine) ``` -------------------------------- ### Create mochi-tutorial directory and clone exercise repositories Source: https://mochi.readthedocs.io/en/latest/_sources/tutorials/01_setup.rst.txt Creates the mochi-tutorial subdirectory and clones the margo-tutorial-exercises and thallium-tutorial-exercises repositories into it. Run these commands from your machine before setting up the development environment. ```console mkdir mochi-tutorial cd mochi-tutorial git clone https://github.com/mochi-hpc-experiments/margo-tutorial-exercises.git git clone https://github.com/mochi-hpc-experiments/thallium-tutorial-exercises.git cd .. ``` -------------------------------- ### Create client, target handle, and perform region operations Source: https://mochi.readthedocs.io/en/latest/warabi/01_intro.html This example shows how to use the Warabi client library to create a client object, create a target handle, and interact with storage. It creates a region of 1KB, writes a string, reads it back, and erases the region. The client is created with `warabi::Client`, and the target handle is created with `client.makeTargetHandle` using the server address and provider ID. The example requires a server address and provider ID as command-line arguments. ```cpp /* * (C) 2024 The University of Chicago * * See COPYRIGHT in top-level directory. */ #include #include #include "../warabi_common.hpp" #include namespace tl = thallium; int main(int argc, char** argv) { if(argc != 3) { std::cerr << "Usage: " << argv[0] << " \n"; return -1; } const char* server_addr_str = argv[1]; uint16_t provider_id = std::atoi(argv[2]); // Initialize Thallium in client mode tl::engine engine("na+sm", THALLIUM_CLIENT_MODE); try { // Create Warabi client warabi::Client client(engine); // Create target handle warabi::TargetHandle target = client.makeTargetHandle( server_addr_str, provider_id ); // Create a region with 1KB size warabi::RegionID region_id; target.create(®ion_id, 1024); std::cout << "Created region with ID: " << regionid_to_string(region_id) << std::endl; // Write data to the region std::string data = "Hello, Warabi!"; target.write(region_id, 0, data.data(), data.size()); std::cout << "Wrote " << data.size() << " bytes\n"; // Read data back std::vector buffer(data.size()); target.read(region_id, 0, buffer.data(), buffer.size()); std::string result(buffer.begin(), buffer.end()); std::cout << "Read: " << result << std::endl; // Clean up target.erase(region_id); } catch(const warabi::Exception& ex) { std::cerr << "Error: " << ex.what() << std::endl; return -1; } return 0; } ``` -------------------------------- ### ABT-IO configuration examples for abt_io_init_ext Source: https://mochi.readthedocs.io/en/latest/_sources/abt-io/01_init.rst.txt JSON configuration specifier examples for abt_io_init_ext. Shows parameters like backing_thread_count, internal_pool_flag, and internal_pool with kind, access, and num_xstreams. ```c /* ------- abt-io configuration examples ------ * * optional input field for convenience. This will cause abt-io to create * an internal service pool with N execution streams in it. * -------------- * {"backing_thread_count": 16} * * The user may also pass in an explicit pool. If so, the resulting json * will look like this: * -------------- * {"internal_pool_flag": 0} * * This is the fully resolved json description of an internal pool (may be * passed in explicitly, or will be generated based on the * backing_thread_count json parameter). * -------------- * {"internal_pool_flag": 1, * "internal_pool":{ * "kind":"fifo_wait", * "access":"mpmc", * "num_xstreams": 4 * } * } */ ``` -------------------------------- ### Set up spack environment and build the code Source: https://mochi.readthedocs.io/en/latest/tutorials/thallium/01_ex1.html Creates and activates a spack environment, installs dependencies, and builds the client and server programs. ```bash spack env create thallium-tuto-env spack.yaml spack env activate thallium-tuto-env spack install mkdir build cd build cmake .. make ``` -------------------------------- ### Run the mochi-tutorial container (mt1) Source: https://mochi.readthedocs.io/en/latest/_sources/tutorials/01_setup.rst.txt Starts a detached container named 'mt1' from the mochi-tutorial image and mounts the host's ./mochi-tutorial directory to /home/mochi/mochi-tutorial inside the container. The container runs indefinitely and allows login for the user 'mochi' with no password. ```console docker run --detach --name mt1 --volume $(pwd)/mochi-tutorial:/home/mochi/mochi-tutorial mochi-tutorial ``` -------------------------------- ### Build project with cmake Source: https://mochi.readthedocs.io/en/latest/templates/02_thallium.html Builds the project with tests, examples, and Bedrock enabled. Run from the project root after installing dependencies. ```bash mkdir build cd build cmake .. -DENABLE_TESTS=ON -DENABLE_EXAMPLES=ON -DENABLE_BEDROCK=ON make ``` -------------------------------- ### yk_erase_range usage example Source: https://mochi.readthedocs.io/en/latest/_sources/yokan/03_basics.rst.txt This example shows how to use yk_erase_range to erase all keys starting with a prefix and to clear the entire database. The first call erases keys with prefix "user:", the second clears all keys by passing NULL and 0. ```c /* Erase every key starting with "user:" */ ret = yk_erase_range(db_handle, YOKAN_MODE_DEFAULT, "user:", 5); /* Clear the entire database */ ret = yk_erase_range(db_handle, YOKAN_MODE_DEFAULT, NULL, 0); ``` -------------------------------- ### Set up spack environment and build code Source: https://mochi.readthedocs.io/en/latest/_sources/tutorials/thallium/01_ex1.rst.txt Create and activate a spack environment, install dependencies, then configure and build the project with CMake. ```console spack env create thallium-tuto-env spack.yaml spack env activate thallium-tuto-env spack install mkdir build cd build cmake .. make ``` -------------------------------- ### Partial read from a region Source: https://mochi.readthedocs.io/en/latest/_sources/warabi/02_basics.rst.txt Reads a partial portion of a region by specifying an offset and size. This example reads 10 bytes starting at offset 10. ```cpp // Read bytes 10-19 (10 bytes starting at offset 10) std::vector partial(10); target.read(region_id, 10, partial.data(), 10); ``` -------------------------------- ### Complete Bedrock runtime configuration example (C++) Source: https://mochi.readthedocs.io/en/latest/bedrock/07_runtime_config.html Complete C++ example using the Bedrock client API to query the initial configuration, add an Argobots pool, add an execution stream, add a provider, query the updated configuration, and run a Jx9 script to list pools. Requires a running Bedrock server address as the single command-line argument. Uses thallium engine in client mode and the bedrock::Client and bedrock::ServiceHandle classes. ```cpp /* * (C) 2024 The University of Chicago * * See COPYRIGHT in top-level directory. */ #include #include #include #include #include int main(int argc, char** argv) { if(argc != 2) { std::cerr << "Usage: " << argv[0] << " " << std::endl; return 1; } try { thallium::engine engine("na+sm", THALLIUM_CLIENT_MODE); bedrock::Client client(engine); bedrock::ServiceHandle service = client.makeServiceHandle(argv[1], 0); std::cout << "=== Runtime Configuration Example ===" << std::endl; // 1. Query initial configuration std::cout << "\n1. Querying initial configuration..." << std::endl; std::string config_str; service.getConfig(&config_str); auto config = nlohmann::json::parse(config_str); size_t initial_providers = config["providers"].size(); std::cout << " Initial providers: " << initial_providers << std::endl; // 2. Add a new pool std::cout << "\n2. Adding new Argobots pool..." << std::endl; std::string pool_config = R"( { "name": "runtime_pool", "kind": "fifo_wait", "access": "mpmc" } )"; service.addPool(pool_config); std::cout << " Pool 'runtime_pool' added" << std::endl; // 3. Add a new execution stream std::cout << "\n3. Adding new execution stream..." << std::endl; std::string xstream_config = R"( { "name": "runtime_xstream", "scheduler": { "type": "basic_wait", "pools": ["runtime_pool"] } } )"; service.addXstream(xstream_config); std::cout << " Execution stream 'runtime_xstream' added" << std::endl; // 4. Add a provider using the new pool std::cout << "\n4. Adding provider with new pool..." << std::endl; std::string provider_desc = R"( { "name": "runtime_provider", "type": "yokan", "provider_id": 200, "dependencies": { "pool": "runtime_pool" }, "config": { "database": {"type": "map"} } } )"; uint16_t provider_id; bedrock::AsyncRequest request; service.addProvider(provider_desc, &provider_id, &request); request.wait(); std::cout << " Provider added with ID: " << provider_id << std::endl; // 5. Query updated configuration std::cout << "\n5. Querying updated configuration..." << std::endl; service.getConfig(&config_str); config = nlohmann::json::parse(config_str); size_t final_providers = config["providers"].size(); std::cout << " Final providers: " << final_providers << std::endl; // 6. Use Jx9 to list all pools std::cout << "\n6. Listing all pools via Jx9..." << std::endl; std::string jx9_script = R"( $result = []; if(array_key_exists('margo', $__config__) && array_key_exists('argobots', $__config__['margo']) && array_key_exists('pools', $__config__['margo']['argobots'])) { foreach($__config__['margo']['argobots']['pools'] as $pool) { $result[] = $pool['name']; } } return $result; )"; std::string result; service.queryConfig(jx9_script, &result); auto pools = nlohmann::json::parse(result); std::cout << " Pools:" << std::endl; for(auto& pool : pools) { std::cout << " - " << pool << std::endl; } std::cout << "\n=== Runtime configuration operations completed ===" << std::endl; } catch(const bedrock::Exception& ex) { std::cerr << "Error: " << ex.what() << std::endl; return 1; } return 0; } ``` -------------------------------- ### Basic Yokan client operations: put, exists, length, get, erase Source: https://mochi.readthedocs.io/en/latest/yokan/12_python.html Demonstrates basic client operations: put, exists, length, get, and erase on a database handle. The get method requires a pre-sized bytearray because Yokan uses RDMA to write directly into the provided buffer. The example runs inside a with Engine('tcp') block and finalizes the engine at the end. ```python from mochi.margo import Engine from mochi.yokan.server import Provider from mochi.yokan.client import Client def main(engine): provider = Provider(engine=engine, provider_id=42, config='{"database":{"type":"map"}}') client = Client(engine=engine) db = client.make_database_handle(address=engine.addr(), provider_id=42) # Put operation db.put(key="user:1", value="Alice") print("Stored user:1 = Alice") # Exists operation exists = db.exists(key="user:1") print(f"Key exists: {exists}") # Length operation length = db.length(key="user:1") print(f"Value length: {length} bytes") # Get operation value = bytearray(length) db.get(key="user:1", value=value) print(f"Retrieved: {value.decode()}") # Erase operation db.erase(key="user:1") print("Key erased") # Verify erasure exists_after = db.exists(key="user:1") print(f"Key exists after erase: {exists_after}") engine.finalize() with Engine('tcp') as engine: main(engine) ``` -------------------------------- ### Argobots Hello World ULT Example Source: https://mochi.readthedocs.io/en/latest/argobots/01_intro.html Initializes Argobots, gets the primary execution stream and its main pool, creates a ULT that prints a message, joins and frees the ULT, then finalizes Argobots. ```c /* * Basic Argobots example: Creating and executing a simple ULT */ #include #include /* Thread function that will be executed by the ULT */ void hello_world_fn(void *arg) { int thread_id = *((int *)arg); printf("Hello from ULT %d!\n", thread_id); } int main(int argc, char **argv) { ABT_xstream xstream; /* Execution stream handle */ ABT_pool pool; /* Pool handle */ ABT_thread thread; /* ULT handle */ int thread_arg = 1; /* Step 1: Initialize Argobots */ ABT_init(argc, argv); printf("Argobots initialized\n"); /* Step 2: Get the primary execution stream (created automatically by ABT_init) */ ABT_xstream_self(&xstream); printf("Got primary execution stream\n"); /* Step 3: Get the pool associated with the primary execution stream */ ABT_xstream_get_main_pools(xstream, 1, &pool); printf("Got main pool\n"); /* Step 4: Create a ULT and add it to the pool */ ABT_thread_create(pool, hello_world_fn, &thread_arg, ABT_THREAD_ATTR_NULL, &thread); printf("Created ULT\n"); /* Step 5: Wait for the ULT to complete */ ABT_thread_join(thread); printf("ULT completed\n"); /* Step 6: Free the ULT */ ABT_thread_free(&thread); printf("ULT freed\n"); /* Step 7: Finalize Argobots */ ABT_finalize(); printf("Argobots finalized\n"); return 0; } ``` -------------------------------- ### Run bedrock with example config Source: https://mochi.readthedocs.io/en/latest/_sources/tutorials/margo/03_ex3.rst.txt Run the bedrock program with the example configuration file. The address printed on the last line of the log is used for subsequent queries. ```console bedrock na+sm -c ../examples/bedrock-config.json ``` -------------------------------- ### Listing pmem pool file Source: https://mochi.readthedocs.io/en/latest/warabi/04_backends_pmem.html Example output of listing the pmem directory showing the created pool file. The pool file persists across provider restarts and is opened again when the provider starts with the same configuration. ```bash $ ls -lh /mnt/pmem -rw-r--r-- 1 user group 10G Dec 31 10:00 warabi.pmem ``` -------------------------------- ### Example session: exec into container and list contents Source: https://mochi.readthedocs.io/en/latest/_sources/tutorials/01_setup.rst.txt Shows a sample interactive session after opening a shell. The prompt mochi@... indicates you are logged in as the 'mochi' user. The 'ls' command shows the content of the home directory and the cloned tutorial exercises. ```console > docker exec -it mt1 /bin/bash mochi@d3c9c489a2c1:~$ ls mochi-spack-packages mochi-tutorial spack mochi@d3c9c489a2c1:~$ ls mochi-tutorial margo-tutorial-exercises thallium-tutorial-exercises ``` -------------------------------- ### Elastic service example: initial primary output Source: https://mochi.readthedocs.io/en/latest/_sources/flock/08_backends_centralized.rst.txt Console output showing the initial primary starting with the centralized backend. It indicates the provider is registered, group membership can change dynamically, and the initial group size is 1. ```console $ ./server Flock provider registered with CENTRALIZED backend Group membership can change dynamically Initial group size: 1 ``` -------------------------------- ### Async write and read with warabi_write, warabi_read, warabi_test Source: https://mochi.readthedocs.io/en/latest/warabi/11_c_api.html Complete C example for asynchronous write and read with Warabi. Initializes Margo, creates a client and target handle, creates a region, issues an async write, waits for completion, then issues an async read and polls with warabi_test until done. Requires a running server and provider ID as command-line arguments; prints progress and final read data. ```c /* * (C) 2024 The University of Chicago * * See COPYRIGHT in top-level directory. */ #include #include #include #include #include int main(int argc, char** argv) { if(argc != 3) { fprintf(stderr, "Usage: %s \n", argv[0]); return -1; } const char* server_addr = argv[1]; uint16_t provider_id = (uint16_t)atoi(argv[2]); warabi_err_t ret; /* Initialize Margo */ margo_instance_id mid = margo_init("na+sm", MARGO_CLIENT_MODE, 0, 0); if(mid == MARGO_INSTANCE_NULL) { fprintf(stderr, "Failed to initialize Margo\n"); return -1; } /* Create Warabi client */ warabi_client_t client; ret = warabi_client_create(mid, &client); if(ret != WARABI_SUCCESS) { fprintf(stderr, "Failed to create client\n"); margo_finalize(mid); return -1; } /* Create target handle */ warabi_target_handle_t target; ret = warabi_client_make_target_handle(client, server_addr, provider_id, &target); if(ret != WARABI_SUCCESS) { fprintf(stderr, "Failed to create target handle\n"); warabi_client_free(client); margo_finalize(mid); return -1; } /* Create a region */ warabi_region_t region; ret = warabi_create(target, 1024, ®ion, WARABI_ASYNC_REQUEST_IGNORE); if(ret != WARABI_SUCCESS) { fprintf(stderr, "Failed to create region\n"); goto cleanup; } /* Async write example */ const char* data = "Async write test"; warabi_async_request_t write_req; printf("Issuing async write...\n"); ret = warabi_write( target, region, 0, /* offset */ data, strlen(data), false, /* persist */ &write_req /* Async request */ ); if(ret != WARABI_SUCCESS) { fprintf(stderr, "Failed to issue async write\n"); goto cleanup; } /* Do other work while write is in progress */ printf("Write in progress, doing other work...\n"); /* Wait for write to complete */ ret = warabi_wait(write_req); if(ret != WARABI_SUCCESS) { fprintf(stderr, "Async write failed\n"); goto cleanup; } printf("Async write completed\n"); /* Async read example */ char buffer[1024]; warabi_async_request_t read_req; printf("Issuing async read...\n"); ret = warabi_read( target, region, 0, /* offset */ buffer, strlen(data), &read_req /* Async request */ ); if(ret != WARABI_SUCCESS) { fprintf(stderr, "Failed to issue async read\n"); goto cleanup; } /* Test for completion */ bool completed = false; int iterations = 0; while(!completed) { ret = warabi_test(read_req, &completed); if(completed) { printf("Async read completed after %d checks\n", iterations); } else { iterations++; /* Do other work... */ } } buffer[strlen(data)] = '\0'; printf("Read: %s\n", buffer); /* Cleanup */ warabi_erase(target, region, WARABI_ASYNC_REQUEST_IGNORE); cleanup: warabi_target_handle_free(target); warabi_client_free(client); margo_finalize(mid); return (ret == WARABI_SUCCESS) ? 0 : -1; } ``` -------------------------------- ### Store and retrieve binary data with Yokan C++ API Source: https://mochi.readthedocs.io/en/latest/yokan/13_cpp.html This example shows how to use yokan::Database::put and get to handle binary data. It stores a UserRecord struct, a 1024-byte blob, and an array of int32_t, then retrieves and verifies them. Requires a running Yokan server and provider ID. ```cpp /* * (C) 2024 The University of Chicago * * See COPYRIGHT in top-level directory. */ #include #include #include #include #include #include #include namespace tl = thallium; // Example struct for binary data struct UserRecord { uint64_t id; char name[32]; double balance; uint32_t age; }; int main(int argc, char** argv) { if(argc != 3) { std::cerr << "Usage: " << argv[0] << " " << std::endl; return 1; } try { tl::engine engine("na+sm", THALLIUM_CLIENT_MODE); yokan::Client client(engine.get_margo_instance()); tl::endpoint server_ep = engine.lookup(argv[1]); yokan::Database db = client.makeDatabaseHandle( server_ep.get_addr(), std::atoi(argv[2])); // Store binary struct UserRecord user; user.id = 12345; std::strncpy(user.name, "Alice Johnson", sizeof(user.name)); user.balance = 1234.56; user.age = 30; std::string key = "user:12345"; db.put(key.data(), key.size(), &user, sizeof(UserRecord)); std::cout << "Stored binary record" << std::endl; // Retrieve binary struct UserRecord retrieved_user; size_t vsize = sizeof(UserRecord); db.get(key.data(), key.size(), &retrieved_user, &vsize); std::cout << "Retrieved user:" << std::endl; std::cout << " ID: " << retrieved_user.id << std::endl; std::cout << " Name: " << retrieved_user.name << std::endl; std::cout << " Balance: $" << retrieved_user.balance << std::endl; std::cout << " Age: " << retrieved_user.age << std::endl; // Store binary blob (e.g., image data) std::vector blob_data(1024); for(size_t i = 0; i < blob_data.size(); i++) { blob_data[i] = static_cast(i % 256); } std::string blob_key = "image:001"; db.put(blob_key.data(), blob_key.size(), blob_data.data(), blob_data.size()); std::cout << "\nStored binary blob of " << blob_data.size() << " bytes" << std::endl; // Retrieve blob std::vector retrieved_blob(1024); size_t blob_size = retrieved_blob.size(); db.get(blob_key.data(), blob_key.size(), retrieved_blob.data(), &blob_size); // Verify data bool match = (blob_data == retrieved_blob); std::cout << "Binary data matches: " << (match ? "yes" : "no") << std::endl; // Store array of integers std::vector int_array = {10, 20, 30, 40, 50}; std::string array_key = "array:001"; db.put(array_key.data(), array_key.size(), int_array.data(), int_array.size() * sizeof(int32_t)); // Retrieve array std::vector retrieved_array(5); size_t array_size = retrieved_array.size() * sizeof(int32_t); db.get(array_key.data(), array_key.size(), retrieved_array.data(), &array_size); std::cout << "\nRetrieved array: "; for(const auto& val : retrieved_array) { std::cout << val << " "; } std::cout << std::endl; } catch(const yokan::Exception& ex) { std::cerr << "Error: " << ex.what() << std::endl; return 1; } return 0; } ``` -------------------------------- ### Server API example (server_example.py) Source: https://mochi.readthedocs.io/en/latest/_sources/yokan/12_python.rst.txt Shows how to use the Provider class from mochi.yokan.server to create Yokan providers. Provider configuration uses the same JSON format as the C++ API. ```python .. literalinclude:: ../../examples/yokan/12_python/server_example.py :language: python ```