From 1ad42a194d4989542d20484551a91658a5eee835 Mon Sep 17 00:00:00 2001 From: Matthieu Dorier Date: Mon, 5 Feb 2024 17:02:48 +0000 Subject: [PATCH] added demo notebook --- examples/python/README.md | 27 + examples/python/demo.ipynb | 1475 ++++++++++++++++++++++++++++++ examples/python/requirements.txt | 1 + 3 files changed, 1503 insertions(+) create mode 100644 examples/python/README.md create mode 100644 examples/python/demo.ipynb create mode 100644 examples/python/requirements.txt diff --git a/examples/python/README.md b/examples/python/README.md new file mode 100644 index 0000000..103b3f6 --- /dev/null +++ b/examples/python/README.md @@ -0,0 +1,27 @@ +To use this example notebook, create a spack environment and +install Bedrock with Python support as follows. + +``` +spack env create my-bedrock-env +spack env activate my-bedrock-env +spack add mochi-bedrock+python +spack install +``` + +Then, with the `my-bedrock-env` spack environment activated, +create a Python virtual environment as follows. + +``` +python -m venv my-bedrock-env +source my-bedrock-env/bin/activate +python -m pip install -r requirements.txt +``` + +Finally, start Jupyterlab as follows. + +``` +jupyter notebook --ip 0.0.0.0 --port 8888 --no-browser +``` + +You will be able to connect to the notebook at the URL +displayed by jupyter on your terminal. diff --git a/examples/python/demo.ipynb b/examples/python/demo.ipynb new file mode 100644 index 0000000..e443071 --- /dev/null +++ b/examples/python/demo.ipynb @@ -0,0 +1,1475 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6aca1d08-00ba-445e-bfe1-f8cb8abbd041", + "metadata": {}, + "source": [ + "# Bedrock Python Tutorial" + ] + }, + { + "cell_type": "markdown", + "id": "a6ba426d-8fa5-4573-ba1c-cd09885e7884", + "metadata": {}, + "source": [ + "This notebook is a tutorial on how to use Bedrock and its Python binding to configure and launch Mochi daemons." + ] + }, + { + "cell_type": "markdown", + "id": "28cae129-008a-4e3d-8c5d-918990d457c5", + "metadata": {}, + "source": [ + "## Bedrock: the basics" + ] + }, + { + "cell_type": "markdown", + "id": "2f5a7db2-8dd9-457a-a024-c9cb2b2e6ee1", + "metadata": {}, + "source": [ + "Bedrock is a generic daemon program that can load a JSON configuration representing the composition and configuration of a Mochi microservice, and setup the microservice accordingly.\n", + "The following command shows how to start an \"empty\" bedrock daemon using the \"na+sm\" (shared memory) tranport." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "25ad8969-9895-4793-a535-2af1275525df", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2024-02-05 17:01:32.712] [\u001b[32minfo\u001b[m] Bedrock daemon now running at na+sm://12128-0\n", + "^C\n" + ] + } + ], + "source": [ + "# Kill this process by clicking the square button (interrupt the kernel) at the top of the notebook\n", + "!bedrock na+sm" + ] + }, + { + "cell_type": "markdown", + "id": "3063290b-3d83-4886-9cdd-2f510d0768d7", + "metadata": {}, + "source": [ + "More information about the parameters can be obtained as follows." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2097cd06-102d-414b-aaeb-54ac93954eec", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "USAGE: \n", + "\n", + " bedrock [--jx9-context ] [-j] [--stdin] [-o\n", + " ] [-c ] [-v ] [--] [--version]\n", + " [-h]
\n", + "\n", + "\n", + "Where: \n", + "\n", + " --jx9-context \n", + " Comma-separated list of Jx9 parameters for the Jx9 script\n", + "\n", + " -j, --jx9\n", + " Interpret configuration as a Jx9 script\n", + "\n", + " --stdin\n", + " Read configuration from standard input\n", + "\n", + " -o , --output-config \n", + " JSON file to write after deployment\n", + "\n", + " -c , --config \n", + " JSON or JX9 configuration file\n", + "\n", + " -v , --verbose \n", + " Log level (trace, debug, info, warning, error, critical, off)\n", + "\n", + " --, --ignore_rest\n", + " Ignores the rest of the labeled arguments following this flag.\n", + "\n", + " --version\n", + " Displays version information and exits.\n", + "\n", + " -h, --help\n", + " Displays usage information and exits.\n", + "\n", + "
\n", + " (required) Protocol (e.g. ofi+tcp) or address (e.g.\n", + " ofi+tcp://127.0.0.1:1234)\n", + "\n", + "\n", + " Spawns a Bedrock daemon\n", + "\n" + ] + } + ], + "source": [ + "!bedrock --help" + ] + }, + { + "cell_type": "markdown", + "id": "d981d014-bd64-4097-b92c-ac9a3d245eb1", + "metadata": {}, + "source": [ + "Let's ask bedrock to output its initial configuration to a file." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "23a4be06-1947-4bce-9e40-833d0a8b406f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[2024-02-05 17:01:33.768] [\u001b[32minfo\u001b[m] Bedrock daemon now running at na+sm://12132-0\n", + "^C\n" + ] + } + ], + "source": [ + "# Kill this process by clicking the square button (interrupt the kernel) at the top of the notebook\n", + "!bedrock na+sm -o config.json" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "36f8a2ba-e1d5-4bf2-bfcf-099eb79669ff", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"abt_io\": [],\n", + " \"bedrock\": {\n", + " \"pool\": \"__primary__\",\n", + " \"provider_id\": 0\n", + " },\n", + " \"clients\": [],\n", + " \"libraries\": {},\n", + " \"margo\": {\n", + " \"argobots\": {\n", + " \"abt_mem_max_num_stacks\": 8,\n", + " \"abt_thread_stacksize\": 2097152,\n", + " \"lazy_stack_alloc\": false,\n", + " \"pools\": [\n", + " {\n", + " \"access\": \"mpmc\",\n", + " \"kind\": \"fifo_wait\",\n", + " \"name\": \"__primary__\"\n", + " }\n", + " ],\n", + " \"profiling_dir\": \".\",\n", + " \"xstreams\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"scheduler\": {\n", + " \"pools\": [\n", + " 0\n", + " ],\n", + " \"type\": \"basic_wait\"\n", + " }\n", + " }\n", + " ]\n", + " },\n", + " \"enable_abt_profiling\": false,\n", + " \"handle_cache_size\": 32,\n", + " \"mercury\": {\n", + " \"address\": \"na+sm://12132-0\",\n", + " \"auto_sm\": false,\n", + " \"checksum_level\": \"none\",\n", + " \"input_eager_size\": 4080,\n", + " \"listening\": true,\n", + " \"max_contexts\": 0,\n", + " \"na_addr_format\": \"unspec\",\n", + " \"na_max_expected_size\": 0,\n", + " \"na_max_unexpected_size\": 0,\n", + " \"na_no_block\": false,\n", + " \"na_no_retry\": false,\n", + " \"na_request_mem_device\": false,\n", + " \"no_bulk_eager\": false,\n", + " \"no_loopback\": false,\n", + " \"output_eager_size\": 4080,\n", + " \"request_post_incr\": 256,\n", + " \"request_post_init\": 256,\n", + " \"stats\": false,\n", + " \"version\": \"2.3.1\"\n", + " },\n", + " \"progress_pool\": 0,\n", + " \"progress_timeout_ub_msec\": 100,\n", + " \"rpc_pool\": 0,\n", + " \"version\": \"0.15.0\"\n", + " },\n", + " \"mona\": [],\n", + " \"providers\": [],\n", + " \"ssg\": []\n", + "}\n" + ] + } + ], + "source": [ + "import json\n", + "with open(\"config.json\") as f:\n", + " print(json.dumps(json.load(f), indent=4))" + ] + }, + { + "cell_type": "markdown", + "id": "a8c971cd-cbe6-4299-b209-21fec2d7fe8d", + "metadata": {}, + "source": [ + "A bedrock configuration contains the following sections.\n", + "* `margo`: the configuration of the Margo instance, including its Argobots and Mercury configurations;\n", + "* `libraries`: a dictionary mapping bedrock module names to the path of the library to load;\n", + "* `bedrock`: the bedrock server configuration;\n", + "* `abt_io`: a list of ABT-IO instances;\n", + "* `ssg`: a list of SSG groups;\n", + "* `mona`: a list of MoNA instances;\n", + "* `providers`: a list of providers;\n", + "* `clients`: a list of clients;\n", + "\n", + "The `libraries`, `abt_io`, `ssg`, `mona`, `providers`, and `clients` sections are empty since we haven't provided components yet.\n", + "\n", + "This configuration can be a good starting point to start filling the bedrock daemon with actual components. Rather than writing JSON directly, however, it is recommended to use the `mochi.bedrock.spec` package to *programmatically* generate a configuration. This can be done in three different ways.\n", + "1. By using the `mochi.bedrock.spec` package to write the configuration, then by generating the corresponding JSON file and providing it as argument to the `bedrock` programm;\n", + "2. By using the `mochi.bedrock.spec` package in conjunction with the `mochi.bedrock.server` package to configure and start the server as a single Python program;\n", + "3. By starting an empty `bedrock` daemon, then using the `mochi.bedrock.spec` package in conjunction with the `mochi.bedrock.client` package to access the daemon remotely and reconfigure it at run time.\n", + "\n", + "The following will explore these three options." + ] + }, + { + "cell_type": "markdown", + "id": "94e4aa8e-f2e2-4d5c-a5d5-a8df2f5e39fd", + "metadata": {}, + "source": [ + "## Configuring bedrock using the mochi.bedrock.spec package" + ] + }, + { + "cell_type": "markdown", + "id": "0197f7d5-2d00-4ae5-a84c-6fd199c18b45", + "metadata": {}, + "source": [ + "### Getting started" + ] + }, + { + "cell_type": "markdown", + "id": "254c308d-bf77-423d-b17a-1b96814a1e3e", + "metadata": {}, + "source": [ + "The root of a Bedrock configuration is a `ProcSpec`, defined in the `mochi.bedrock.spec` package. It defines everything we want to run on a process." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "474f3883-a632-4ddf-8e9d-71eb6ee4649d", + "metadata": {}, + "outputs": [], + "source": [ + "import mochi.bedrock.spec as spec" + ] + }, + { + "cell_type": "markdown", + "id": "7c33ffbd-d4b2-437e-a441-8c20889da96e", + "metadata": {}, + "source": [ + "We can create a `ProcSpec` using a single `margo` key specifying the protocol we wish to use." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "002cdf56-a50e-4bdc-bfe4-31d847b8b53e", + "metadata": {}, + "outputs": [], + "source": [ + "my_process = spec.ProcSpec(margo='na+sm')" + ] + }, + { + "cell_type": "markdown", + "id": "136b47e3-4c49-4410-8e73-49bc62db542d", + "metadata": {}, + "source": [ + "All the specification objects have a `to_json()` method to generate their JSON configuration. Let's look at our proc's configuration:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0bb0cadf-95d1-4009-b10b-3ff6529b2481", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"margo\": {\n", + " \"progress_timeout_ub_msec\": 100,\n", + " \"enable_abt_profiling\": false,\n", + " \"enable_diagnostics\": false,\n", + " \"handle_cache_size\": 32,\n", + " \"profile_sparkline_timeslice_msec\": 1000,\n", + " \"version\": \"unknown\",\n", + " \"argobots\": {\n", + " \"abt_mem_max_num_stacks\": 8,\n", + " \"abt_thread_stacksize\": 2097152,\n", + " \"version\": \"unknown\",\n", + " \"lazy_stack_alloc\": false,\n", + " \"profiling_dir\": \".\",\n", + " \"pools\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"kind\": \"fifo_wait\",\n", + " \"access\": \"mpmc\"\n", + " }\n", + " ],\n", + " \"xstreams\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic_wait\",\n", + " \"pools\": [\n", + " \"__primary__\"\n", + " ]\n", + " }\n", + " }\n", + " ]\n", + " },\n", + " \"mercury\": {\n", + " \"address\": \"na+sm\",\n", + " \"listening\": true,\n", + " \"ip_subnet\": \"\",\n", + " \"auth_key\": \"\",\n", + " \"auto_sm\": false,\n", + " \"max_contexts\": 1,\n", + " \"na_no_block\": false,\n", + " \"na_no_retry\": false,\n", + " \"no_bulk_eager\": false,\n", + " \"no_loopback\": false,\n", + " \"request_post_incr\": 256,\n", + " \"request_post_init\": 256,\n", + " \"stats\": false,\n", + " \"version\": \"unknown\",\n", + " \"checksum_level\": \"none\",\n", + " \"input_eager_size\": 4080,\n", + " \"output_eager_size\": 4080,\n", + " \"na_addr_format\": \"unspec\",\n", + " \"na_max_expected_size\": 0,\n", + " \"na_max_unexpected_size\": 0,\n", + " \"na_request_mem_device\": false\n", + " },\n", + " \"progress_pool\": \"__primary__\",\n", + " \"rpc_pool\": \"__primary__\"\n", + " },\n", + " \"abt_io\": [],\n", + " \"ssg\": [],\n", + " \"mona\": [],\n", + " \"libraries\": {},\n", + " \"providers\": [],\n", + " \"clients\": [],\n", + " \"bedrock\": {\n", + " \"pool\": \"__primary__\",\n", + " \"provider_id\": 0\n", + " }\n", + "}\n" + ] + } + ], + "source": [ + "print(my_process.to_json(indent=4))" + ] + }, + { + "cell_type": "markdown", + "id": "798179ea-f2a4-4716-95c2-99a1bca98565", + "metadata": {}, + "source": [ + "The classes in Bedrock's `spec` package give us a very simple way of accessing sub-configurations. Objects that have a name can be accessed using their name or their index in the list that contains them. For example, accessing Argobots' primary pool:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "03d29eba-91a0-44eb-9b6e-95b76ffed80f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "PoolSpec(name='__primary__', kind='fifo_wait', access='mpmc')\n", + "PoolSpec(name='__primary__', kind='fifo_wait', access='mpmc')\n" + ] + } + ], + "source": [ + "print(my_process.margo.argobots.pools['__primary__'])\n", + "print(my_process.margo.argobots.pools[0])" + ] + }, + { + "cell_type": "markdown", + "id": "1928ac66-f337-422c-9b3c-f41e700cfaee", + "metadata": {}, + "source": [ + "Let's customize our process a little more. What about defining a pool for RPCs to run on, along with a few execution streams using that pool?" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "30028ad8-4538-4a14-8c50-d53173512c64", + "metadata": {}, + "outputs": [], + "source": [ + "# Create the new pool, it will be added automatically to the process\n", + "my_rpc_pool = my_process.margo.argobots.pools.add(name='my_rpc_pool', kind='fifo', access='mpmc')\n", + "# Create two execution streams using that pool\n", + "for i in range(0,4):\n", + " sched = spec.SchedulerSpec(type='basic', pools=[my_rpc_pool])\n", + " my_process.margo.argobots.xstreams.add(name=f'my_xstream_{i}', scheduler=sched)\n", + "# Now let's set the pools we want for handling RPCs\n", + "my_process.margo.rpc_pool = my_rpc_pool" + ] + }, + { + "cell_type": "markdown", + "id": "6c8531ba-f4d0-4cf0-aee0-11d028590f12", + "metadata": {}, + "source": [ + "Let's now print the resulting configuration:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "5368111c-34fb-4d42-9008-53dacf4d49ee", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"margo\": {\n", + " \"progress_timeout_ub_msec\": 100,\n", + " \"enable_abt_profiling\": false,\n", + " \"enable_diagnostics\": false,\n", + " \"handle_cache_size\": 32,\n", + " \"profile_sparkline_timeslice_msec\": 1000,\n", + " \"version\": \"unknown\",\n", + " \"argobots\": {\n", + " \"abt_mem_max_num_stacks\": 8,\n", + " \"abt_thread_stacksize\": 2097152,\n", + " \"version\": \"unknown\",\n", + " \"lazy_stack_alloc\": false,\n", + " \"profiling_dir\": \".\",\n", + " \"pools\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"kind\": \"fifo_wait\",\n", + " \"access\": \"mpmc\"\n", + " },\n", + " {\n", + " \"name\": \"my_rpc_pool\",\n", + " \"kind\": \"fifo\",\n", + " \"access\": \"mpmc\"\n", + " }\n", + " ],\n", + " \"xstreams\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic_wait\",\n", + " \"pools\": [\n", + " \"__primary__\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_0\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_1\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_2\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_3\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " }\n", + " ]\n", + " },\n", + " \"mercury\": {\n", + " \"address\": \"na+sm\",\n", + " \"listening\": true,\n", + " \"ip_subnet\": \"\",\n", + " \"auth_key\": \"\",\n", + " \"auto_sm\": false,\n", + " \"max_contexts\": 1,\n", + " \"na_no_block\": false,\n", + " \"na_no_retry\": false,\n", + " \"no_bulk_eager\": false,\n", + " \"no_loopback\": false,\n", + " \"request_post_incr\": 256,\n", + " \"request_post_init\": 256,\n", + " \"stats\": false,\n", + " \"version\": \"unknown\",\n", + " \"checksum_level\": \"none\",\n", + " \"input_eager_size\": 4080,\n", + " \"output_eager_size\": 4080,\n", + " \"na_addr_format\": \"unspec\",\n", + " \"na_max_expected_size\": 0,\n", + " \"na_max_unexpected_size\": 0,\n", + " \"na_request_mem_device\": false\n", + " },\n", + " \"progress_pool\": \"__primary__\",\n", + " \"rpc_pool\": \"my_rpc_pool\"\n", + " },\n", + " \"abt_io\": [],\n", + " \"ssg\": [],\n", + " \"mona\": [],\n", + " \"libraries\": {},\n", + " \"providers\": [],\n", + " \"clients\": [],\n", + " \"bedrock\": {\n", + " \"pool\": \"__primary__\",\n", + " \"provider_id\": 0\n", + " }\n", + "}\n" + ] + } + ], + "source": [ + "print(my_process.to_json(indent=4))" + ] + }, + { + "cell_type": "markdown", + "id": "51c0ae7b-d5f0-4088-ab53-c790859677f0", + "metadata": {}, + "source": [ + "### Adding ABT-IO instances" + ] + }, + { + "cell_type": "markdown", + "id": "64c52a25-bf0e-4da5-8acc-10d31598eb0f", + "metadata": {}, + "source": [ + "Let's add an ABT-IO instance. To do so, we need to give the instance a name, a pool in which it will submit its \n", + "ULTs, and a configuration (dictionary)." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "86d00d4a-54a5-4179-abef-8e606b43962b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "AbtIOSpec(name='my_abtio', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), config={})" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_process.abt_io.add(name='my_abtio', pool=my_rpc_pool, config={})" + ] + }, + { + "cell_type": "markdown", + "id": "04f18473-7cd5-44e1-8d19-239baca4b76d", + "metadata": {}, + "source": [ + "### Adding SSG groups" + ] + }, + { + "cell_type": "markdown", + "id": "f6389250-3e3c-459b-987d-cacb95b0ff04", + "metadata": {}, + "source": [ + "Let's add and SSG group." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "826e3b88-f126-4b80-8f7e-cd946d58a9ba", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "SSGSpec(name='my_group', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), credential=-1, bootstrap='init', group_file='my_group.ssg', swim=SwimSpec(period_length_ms=1000, suspect_timeout_periods=3, subgroup_member_count=0, disabled=False))" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "swim_config = spec.SwimSpec(\n", + " period_length_ms=1000,\n", + " suspect_timeout_periods=3,\n", + " subgroup_member_count=0,\n", + " disabled=False)\n", + "\n", + "my_process.ssg.add(name='my_group',\n", + " swim=swim_config,\n", + " bootstrap='init',\n", + " group_file='my_group.ssg',\n", + " pool=my_rpc_pool)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "4005439c-d5b3-4282-82cc-07e3c5ebcc4f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"margo\": {\n", + " \"progress_timeout_ub_msec\": 100,\n", + " \"enable_abt_profiling\": false,\n", + " \"enable_diagnostics\": false,\n", + " \"handle_cache_size\": 32,\n", + " \"profile_sparkline_timeslice_msec\": 1000,\n", + " \"version\": \"unknown\",\n", + " \"argobots\": {\n", + " \"abt_mem_max_num_stacks\": 8,\n", + " \"abt_thread_stacksize\": 2097152,\n", + " \"version\": \"unknown\",\n", + " \"lazy_stack_alloc\": false,\n", + " \"profiling_dir\": \".\",\n", + " \"pools\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"kind\": \"fifo_wait\",\n", + " \"access\": \"mpmc\"\n", + " },\n", + " {\n", + " \"name\": \"my_rpc_pool\",\n", + " \"kind\": \"fifo\",\n", + " \"access\": \"mpmc\"\n", + " }\n", + " ],\n", + " \"xstreams\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic_wait\",\n", + " \"pools\": [\n", + " \"__primary__\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_0\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_1\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_2\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_3\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " }\n", + " ]\n", + " },\n", + " \"mercury\": {\n", + " \"address\": \"na+sm\",\n", + " \"listening\": true,\n", + " \"ip_subnet\": \"\",\n", + " \"auth_key\": \"\",\n", + " \"auto_sm\": false,\n", + " \"max_contexts\": 1,\n", + " \"na_no_block\": false,\n", + " \"na_no_retry\": false,\n", + " \"no_bulk_eager\": false,\n", + " \"no_loopback\": false,\n", + " \"request_post_incr\": 256,\n", + " \"request_post_init\": 256,\n", + " \"stats\": false,\n", + " \"version\": \"unknown\",\n", + " \"checksum_level\": \"none\",\n", + " \"input_eager_size\": 4080,\n", + " \"output_eager_size\": 4080,\n", + " \"na_addr_format\": \"unspec\",\n", + " \"na_max_expected_size\": 0,\n", + " \"na_max_unexpected_size\": 0,\n", + " \"na_request_mem_device\": false\n", + " },\n", + " \"progress_pool\": \"__primary__\",\n", + " \"rpc_pool\": \"my_rpc_pool\"\n", + " },\n", + " \"abt_io\": [\n", + " {\n", + " \"name\": \"my_abtio\",\n", + " \"pool\": \"my_rpc_pool\",\n", + " \"config\": {}\n", + " }\n", + " ],\n", + " \"ssg\": [\n", + " {\n", + " \"name\": \"my_group\",\n", + " \"pool\": \"my_rpc_pool\",\n", + " \"credential\": -1,\n", + " \"bootstrap\": \"init\",\n", + " \"group_file\": \"my_group.ssg\",\n", + " \"swim\": {\n", + " \"period_length_ms\": 1000,\n", + " \"suspect_timeout_periods\": 3,\n", + " \"subgroup_member_count\": 0,\n", + " \"disabled\": false\n", + " }\n", + " }\n", + " ],\n", + " \"mona\": [],\n", + " \"libraries\": {},\n", + " \"providers\": [],\n", + " \"clients\": [],\n", + " \"bedrock\": {\n", + " \"pool\": \"__primary__\",\n", + " \"provider_id\": 0\n", + " }\n", + "}\n" + ] + } + ], + "source": [ + "print(my_process.to_json(indent=4))" + ] + }, + { + "cell_type": "markdown", + "id": "c475f79d-3d31-47c4-96ac-e7dffd59fd97", + "metadata": {}, + "source": [ + "### Adding MoNA instances\n", + "\n", + "Let's add a MoNA instance." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "9b4032c5-d16d-432d-becd-756d142c54ca", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "MonaSpec(name='my_mona', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), config={})" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_process.mona.add(name='my_mona', pool=my_rpc_pool, config={})" + ] + }, + { + "cell_type": "markdown", + "id": "a4e9a337-a782-4e75-bcb9-867b5b9c687e", + "metadata": {}, + "source": [ + "### Adding clients\n", + "\n", + "Let's add some module clients. First we need to add module libraries." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "29e4c23e-128c-488d-b65c-221832543f36", + "metadata": {}, + "outputs": [], + "source": [ + "# This requires Bedrock to have been compiled with -DENABLE_EXAMPLES=ON,\n", + "# please change the paths bellow to where the modules are actually located in your build\n", + "my_process.libraries['module_a'] = '/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-a.so'\n", + "my_process.libraries['module_b'] = '/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-b.so'" + ] + }, + { + "cell_type": "markdown", + "id": "c2832831-f3df-43e1-9d4e-94776f44d32f", + "metadata": {}, + "source": [ + "We can now add a couple of clients." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "f64e6fa0-689c-473b-b844-9cd57f644db0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ClientSpec(name='ClientB', type='module_b', config={}, dependencies={}, tags=[])" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_process.clients.add(\n", + " name='ClientA',\n", + " type='module_a',\n", + " config={},\n", + " dependencies={},\n", + " tags=[])\n", + "\n", + "my_process.clients.add(\n", + " name='ClientB',\n", + " type='module_b',\n", + " config={},\n", + " dependencies={},\n", + " tags=[])" + ] + }, + { + "cell_type": "markdown", + "id": "2d53e158-7a37-4062-b015-17940c0cc27a", + "metadata": {}, + "source": [ + "### Adding providers" + ] + }, + { + "cell_type": "markdown", + "id": "fd745e89-03c4-4836-ac8e-0e23a7d56132", + "metadata": {}, + "source": [ + "Now let's add providers. Bedrock has no idea what dependencies are required by providers of each module, so you need to make sure the dependencies and configurations are correct on your own." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "8767e039-3f5a-4499-8bfc-b8d8fbaf5a6e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ProviderSpec(name='ProviderB', type='module_b', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), provider_id=33, config={}, dependencies={'ssg_group': 'my_group', 'a_provider': 'module_a:42', 'a_provider_handle': ['ProviderA@ssg://my_group/0'], 'a_client': 'ClientA', 'mona_instance': 'my_mona'}, tags=[])" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "my_process.providers.add(\n", + " name='ProviderA',\n", + " type='module_a',\n", + " provider_id=42,\n", + " pool=my_rpc_pool,\n", + " config={},\n", + " dependencies={},\n", + " tags=[])\n", + "\n", + "my_process.providers.add(\n", + " name='ProviderB',\n", + " type='module_b',\n", + " provider_id=33,\n", + " pool=my_rpc_pool,\n", + " config={},\n", + " dependencies={\n", + " \"ssg_group\" : 'my_group',\n", + " \"a_provider\" : \"module_a:42\",\n", + " \"a_provider_handle\" : [ \"ProviderA@ssg://my_group/0\" ],\n", + " \"a_client\" : \"ClientA\",\n", + " \"mona_instance\": \"my_mona\"\n", + " },\n", + " tags=[])" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "2c618e17-fc8e-4dcc-9767-c98c74976d82", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"margo\": {\n", + " \"progress_timeout_ub_msec\": 100,\n", + " \"enable_abt_profiling\": false,\n", + " \"enable_diagnostics\": false,\n", + " \"handle_cache_size\": 32,\n", + " \"profile_sparkline_timeslice_msec\": 1000,\n", + " \"version\": \"unknown\",\n", + " \"argobots\": {\n", + " \"abt_mem_max_num_stacks\": 8,\n", + " \"abt_thread_stacksize\": 2097152,\n", + " \"version\": \"unknown\",\n", + " \"lazy_stack_alloc\": false,\n", + " \"profiling_dir\": \".\",\n", + " \"pools\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"kind\": \"fifo_wait\",\n", + " \"access\": \"mpmc\"\n", + " },\n", + " {\n", + " \"name\": \"my_rpc_pool\",\n", + " \"kind\": \"fifo\",\n", + " \"access\": \"mpmc\"\n", + " }\n", + " ],\n", + " \"xstreams\": [\n", + " {\n", + " \"name\": \"__primary__\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic_wait\",\n", + " \"pools\": [\n", + " \"__primary__\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_0\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_1\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_2\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " },\n", + " {\n", + " \"name\": \"my_xstream_3\",\n", + " \"cpubind\": -1,\n", + " \"affinity\": [],\n", + " \"scheduler\": {\n", + " \"type\": \"basic\",\n", + " \"pools\": [\n", + " \"my_rpc_pool\"\n", + " ]\n", + " }\n", + " }\n", + " ]\n", + " },\n", + " \"mercury\": {\n", + " \"address\": \"na+sm\",\n", + " \"listening\": true,\n", + " \"ip_subnet\": \"\",\n", + " \"auth_key\": \"\",\n", + " \"auto_sm\": false,\n", + " \"max_contexts\": 1,\n", + " \"na_no_block\": false,\n", + " \"na_no_retry\": false,\n", + " \"no_bulk_eager\": false,\n", + " \"no_loopback\": false,\n", + " \"request_post_incr\": 256,\n", + " \"request_post_init\": 256,\n", + " \"stats\": false,\n", + " \"version\": \"unknown\",\n", + " \"checksum_level\": \"none\",\n", + " \"input_eager_size\": 4080,\n", + " \"output_eager_size\": 4080,\n", + " \"na_addr_format\": \"unspec\",\n", + " \"na_max_expected_size\": 0,\n", + " \"na_max_unexpected_size\": 0,\n", + " \"na_request_mem_device\": false\n", + " },\n", + " \"progress_pool\": \"__primary__\",\n", + " \"rpc_pool\": \"my_rpc_pool\"\n", + " },\n", + " \"abt_io\": [\n", + " {\n", + " \"name\": \"my_abtio\",\n", + " \"pool\": \"my_rpc_pool\",\n", + " \"config\": {}\n", + " }\n", + " ],\n", + " \"ssg\": [\n", + " {\n", + " \"name\": \"my_group\",\n", + " \"pool\": \"my_rpc_pool\",\n", + " \"credential\": -1,\n", + " \"bootstrap\": \"init\",\n", + " \"group_file\": \"my_group.ssg\",\n", + " \"swim\": {\n", + " \"period_length_ms\": 1000,\n", + " \"suspect_timeout_periods\": 3,\n", + " \"subgroup_member_count\": 0,\n", + " \"disabled\": false\n", + " }\n", + " }\n", + " ],\n", + " \"mona\": [\n", + " {\n", + " \"name\": \"my_mona\",\n", + " \"pool\": \"my_rpc_pool\",\n", + " \"config\": {}\n", + " }\n", + " ],\n", + " \"libraries\": {\n", + " \"module_a\": \"/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-a.so\",\n", + " \"module_b\": \"/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-b.so\"\n", + " },\n", + " \"providers\": [\n", + " {\n", + " \"name\": \"ProviderA\",\n", + " \"type\": \"module_a\",\n", + " \"pool\": \"my_rpc_pool\",\n", + " \"provider_id\": 42,\n", + " \"dependencies\": {},\n", + " \"config\": {},\n", + " \"tags\": []\n", + " },\n", + " {\n", + " \"name\": \"ProviderB\",\n", + " \"type\": \"module_b\",\n", + " \"pool\": \"my_rpc_pool\",\n", + " \"provider_id\": 33,\n", + " \"dependencies\": {\n", + " \"ssg_group\": \"my_group\",\n", + " \"a_provider\": \"module_a:42\",\n", + " \"a_provider_handle\": [\n", + " \"ProviderA@ssg://my_group/0\"\n", + " ],\n", + " \"a_client\": \"ClientA\",\n", + " \"mona_instance\": \"my_mona\"\n", + " },\n", + " \"config\": {},\n", + " \"tags\": []\n", + " }\n", + " ],\n", + " \"clients\": [\n", + " {\n", + " \"name\": \"ClientA\",\n", + " \"type\": \"module_a\",\n", + " \"dependencies\": {},\n", + " \"config\": {},\n", + " \"tags\": []\n", + " },\n", + " {\n", + " \"name\": \"ClientB\",\n", + " \"type\": \"module_b\",\n", + " \"dependencies\": {},\n", + " \"config\": {},\n", + " \"tags\": []\n", + " }\n", + " ],\n", + " \"bedrock\": {\n", + " \"pool\": \"__primary__\",\n", + " \"provider_id\": 0\n", + " }\n", + "}\n" + ] + } + ], + "source": [ + "print(my_process.to_json(indent=4))" + ] + }, + { + "cell_type": "markdown", + "id": "7e7305ae-c624-408a-87f6-88a6ce2987b0", + "metadata": {}, + "source": [ + "### Deploying the service\n", + "\n", + "Once you have programmatically added everything you needed in your process specification `my_process`, you can convert it to JSON and write it to a file:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "6b26dba3-2798-4df8-acbf-45cabc29e936", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\"margo\": {\"progress_timeout_ub_msec\": 100, \"enable_abt_profiling\": false, \"enable_diagnostics\": false, \"handle_cache_size\": 32, \"profile_sparkline_timeslice_msec\": 1000, \"version\": \"unknown\", \"argobots\": {\"abt_mem_max_num_stacks\": 8, \"abt_thread_stacksize\": 2097152, \"version\": \"unknown\", \"lazy_stack_alloc\": false, \"profiling_dir\": \".\", \"pools\": [{\"name\": \"__primary__\", \"kind\": \"fifo_wait\", \"access\": \"mpmc\"}, {\"name\": \"my_rpc_pool\", \"kind\": \"fifo\", \"access\": \"mpmc\"}], \"xstreams\": [{\"name\": \"__primary__\", \"cpubind\": -1, \"affinity\": [], \"scheduler\": {\"type\": \"basic_wait\", \"pools\": [\"__primary__\"]}}, {\"name\": \"my_xstream_0\", \"cpubind\": -1, \"affinity\": [], \"scheduler\": {\"type\": \"basic\", \"pools\": [\"my_rpc_pool\"]}}, {\"name\": \"my_xstream_1\", \"cpubind\": -1, \"affinity\": [], \"scheduler\": {\"type\": \"basic\", \"pools\": [\"my_rpc_pool\"]}}, {\"name\": \"my_xstream_2\", \"cpubind\": -1, \"affinity\": [], \"scheduler\": {\"type\": \"basic\", \"pools\": [\"my_rpc_pool\"]}}, {\"name\": \"my_xstream_3\", \"cpubind\": -1, \"affinity\": [], \"scheduler\": {\"type\": \"basic\", \"pools\": [\"my_rpc_pool\"]}}]}, \"mercury\": {\"address\": \"na+sm\", \"listening\": true, \"ip_subnet\": \"\", \"auth_key\": \"\", \"auto_sm\": false, \"max_contexts\": 1, \"na_no_block\": false, \"na_no_retry\": false, \"no_bulk_eager\": false, \"no_loopback\": false, \"request_post_incr\": 256, \"request_post_init\": 256, \"stats\": false, \"version\": \"unknown\", \"checksum_level\": \"none\", \"input_eager_size\": 4080, \"output_eager_size\": 4080, \"na_addr_format\": \"unspec\", \"na_max_expected_size\": 0, \"na_max_unexpected_size\": 0, \"na_request_mem_device\": false}, \"progress_pool\": \"__primary__\", \"rpc_pool\": \"my_rpc_pool\"}, \"abt_io\": [{\"name\": \"my_abtio\", \"pool\": \"my_rpc_pool\", \"config\": {}}], \"ssg\": [{\"name\": \"my_group\", \"pool\": \"my_rpc_pool\", \"credential\": -1, \"bootstrap\": \"init\", \"group_file\": \"my_group.ssg\", \"swim\": {\"period_length_ms\": 1000, \"suspect_timeout_periods\": 3, \"subgroup_member_count\": 0, \"disabled\": false}}], \"mona\": [{\"name\": \"my_mona\", \"pool\": \"my_rpc_pool\", \"config\": {}}], \"libraries\": {\"module_a\": \"/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-a.so\", \"module_b\": \"/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-b.so\"}, \"providers\": [{\"name\": \"ProviderA\", \"type\": \"module_a\", \"pool\": \"my_rpc_pool\", \"provider_id\": 42, \"dependencies\": {}, \"config\": {}, \"tags\": []}, {\"name\": \"ProviderB\", \"type\": \"module_b\", \"pool\": \"my_rpc_pool\", \"provider_id\": 33, \"dependencies\": {\"ssg_group\": \"my_group\", \"a_provider\": \"module_a:42\", \"a_provider_handle\": [\"ProviderA@ssg://my_group/0\"], \"a_client\": \"ClientA\", \"mona_instance\": \"my_mona\"}, \"config\": {}, \"tags\": []}], \"clients\": [{\"name\": \"ClientA\", \"type\": \"module_a\", \"dependencies\": {}, \"config\": {}, \"tags\": []}, {\"name\": \"ClientB\", \"type\": \"module_b\", \"dependencies\": {}, \"config\": {}, \"tags\": []}], \"bedrock\": {\"pool\": \"__primary__\", \"provider_id\": 0}}" + ] + } + ], + "source": [ + "with open(\"my_config.json\", \"w+\") as f:\n", + " f.write(my_process.to_json())\n", + "\n", + "!cat my_config.json" + ] + }, + { + "cell_type": "markdown", + "id": "2598856f-3e39-46a4-88ca-47dabebd0f06", + "metadata": {}, + "source": [ + "You can now pass this file to the `bedrock` command to start your process:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "84143ba2-83b8-49e7-8d96-8edaabeacc50", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Registered a client from module A\n", + " -> mid = 0x5556661fdc30\n", + "Initializing client from module B\n", + "Registered a provider from module A\n", + " -> mid = 0x5556661fdc30\n", + " -> provider id = 42\n", + " -> pool = 0x5556661f7d80\n", + " -> config = {}\n", + " -> name = ProviderA\n", + "Created provider handle from module A\n", + "Registering a provider from module B\n", + " -> mid = 0x5556661fdc30\n", + " -> provider_id = 33\n", + " -> pool = 0x5556661f7d80\n", + " -> config = {}\n", + " -> name = ProviderB\n", + "[2024-02-05 17:01:35.956] [\u001b[32minfo\u001b[m] Bedrock daemon now running at na+sm://12136-0\n", + "^C\n" + ] + } + ], + "source": [ + "!bedrock na+sm -c my_config.json" + ] + }, + { + "cell_type": "markdown", + "id": "2f954b67-5025-45bf-b70f-6d8b609ee956", + "metadata": {}, + "source": [ + "## Starting bedrock from python using mochi.bedrock.server\n", + "\n", + "Having seen how to programmatically generate a Bedrock configuration, we can go one step further and actually use Python to start the server instance." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "d11f822c-e1cb-4c93-9a73-b0646c3a02e3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Registered a client from module A\n", + " -> mid = 0x555689575ce0\n", + "Initializing client from module B\n", + "Registered a provider from module A\n", + " -> mid = 0x555689575ce0\n", + " -> provider id = 42\n", + " -> pool = 0x555689571180\n", + " -> config = {}\n", + " -> name = ProviderA\n", + "Created provider handle from module A\n", + "Registering a provider from module B\n", + " -> mid = 0x555689575ce0\n", + " -> provider_id = 33\n", + " -> pool = 0x555689571180\n", + " -> config = {}\n", + " -> name = ProviderB\n", + "[2024-02-05 17:01:38.291] [info] Bedrock daemon now running at na+sm://12111-0\n" + ] + } + ], + "source": [ + "import mochi.bedrock.server as server\n", + "\n", + "daemon = server.Server.from_spec(my_process)" + ] + }, + { + "cell_type": "markdown", + "id": "1bf6a75e-178f-4022-8e49-7d1b5f5ac7a4", + "metadata": {}, + "source": [ + "Now our Python process runs a Bedrock daemon. We can access its runtime configuration and even convert it back to a spec:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "508f5180-7eff-453c-b475-6bd1e49297d4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'abt_io': [{'config': {'internal_pool_flag': False, 'null_io_read': False, 'null_io_write': False, 'trace_io': False, 'version': '0.6.0'}, 'name': 'my_abtio', 'pool': 'my_rpc_pool'}], 'bedrock': {'pool': '__primary__', 'provider_id': 0}, 'clients': [{'config': {}, 'dependencies': {}, 'name': 'ClientA', 'tags': [], 'type': 'module_a'}, {'config': {}, 'dependencies': {}, 'name': 'ClientB', 'tags': [], 'type': 'module_b'}], 'libraries': {'module_a': '/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-a.so', 'module_b': '/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-b.so'}, 'margo': {'argobots': {'abt_mem_max_num_stacks': 8, 'abt_thread_stacksize': 2097152, 'lazy_stack_alloc': False, 'pools': [{'access': 'mpmc', 'kind': 'fifo_wait', 'name': '__primary__'}, {'access': 'mpmc', 'kind': 'fifo', 'name': 'my_rpc_pool'}], 'profiling_dir': '.', 'xstreams': [{'name': '__primary__', 'scheduler': {'pools': [0], 'type': 'basic_wait'}}, {'name': 'my_xstream_0', 'scheduler': {'pools': [1], 'type': 'basic'}}, {'name': 'my_xstream_1', 'scheduler': {'pools': [1], 'type': 'basic'}}, {'name': 'my_xstream_2', 'scheduler': {'pools': [1], 'type': 'basic'}}, {'name': 'my_xstream_3', 'scheduler': {'pools': [1], 'type': 'basic'}}]}, 'enable_abt_profiling': False, 'handle_cache_size': 32, 'mercury': {'address': 'na+sm://12111-0', 'auth_key': '', 'auto_sm': False, 'checksum_level': 'none', 'input_eager_size': 4080, 'ip_subnet': '', 'listening': True, 'max_contexts': 1, 'na_addr_format': 'unspec', 'na_max_expected_size': 0, 'na_max_unexpected_size': 0, 'na_no_block': False, 'na_no_retry': False, 'na_request_mem_device': False, 'no_bulk_eager': False, 'no_loopback': False, 'output_eager_size': 4080, 'request_post_incr': 256, 'request_post_init': 256, 'stats': False, 'version': '2.3.1'}, 'progress_pool': 0, 'progress_timeout_ub_msec': 100, 'rpc_pool': 1, 'version': '0.15.0'}, 'mona': [{'address': 'na+sm://12111-1', 'config': {}, 'name': 'my_mona', 'pool': 'my_rpc_pool'}], 'providers': [{'config': {}, 'dependencies': {}, 'name': 'ProviderA', 'pool': 'my_rpc_pool', 'provider_id': 42, 'tags': [], 'type': 'module_a'}, {'config': {}, 'dependencies': {'a_client': 'ClientA', 'a_provider': 'ProviderA', 'a_provider_handle': ['42@na+sm://12111-0'], 'mona_instance': 'my_mona', 'ssg_group': 'my_group'}, 'name': 'ProviderB', 'pool': 'my_rpc_pool', 'provider_id': 33, 'tags': [], 'type': 'module_b'}], 'ssg': [{'bootstrap': 'init', 'credential': -1, 'group_file': 'my_group.ssg', 'name': 'my_group', 'pool': 'my_rpc_pool', 'swim': {'disabled': False, 'period_length_ms': 1000, 'subgroup_member_count': 0, 'suspect_timeout_periods': 3}}]}\n" + ] + } + ], + "source": [ + "print(daemon.config)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "b10ed455-ef43-4614-b3c0-ca1086a60243", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ProcSpec(margo=MargoSpec(mercury=MercurySpec(address='na+sm://12111-0', listening=True, ip_subnet='', auth_key='', auto_sm=False, max_contexts=1, na_no_block=False, na_no_retry=False, no_bulk_eager=False, no_loopback=False, request_post_incr=256, request_post_init=256, stats=False, version='2.3.1', checksum_level='none', input_eager_size=4080, output_eager_size=4080, na_addr_format='unspec', na_max_expected_size=0, na_max_unexpected_size=0, na_request_mem_device=False), argobots=ArgobotsSpec(abt_mem_max_num_stacks=8, abt_thread_stacksize=2097152, version='unknown', _pools=[PoolSpec(name='__primary__', kind='fifo_wait', access='mpmc'), PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc')], _xstreams=[XstreamSpec(name='__primary__', scheduler=SchedulerSpec(type='basic_wait', pools=[PoolSpec(name='__primary__', kind='fifo_wait', access='mpmc')]), cpubind=-1, affinity=[]), XstreamSpec(name='my_xstream_0', scheduler=SchedulerSpec(type='basic', pools=[PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc')]), cpubind=-1, affinity=[]), XstreamSpec(name='my_xstream_1', scheduler=SchedulerSpec(type='basic', pools=[PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc')]), cpubind=-1, affinity=[]), XstreamSpec(name='my_xstream_2', scheduler=SchedulerSpec(type='basic', pools=[PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc')]), cpubind=-1, affinity=[]), XstreamSpec(name='my_xstream_3', scheduler=SchedulerSpec(type='basic', pools=[PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc')]), cpubind=-1, affinity=[])], lazy_stack_alloc=False, profiling_dir='.'), progress_timeout_ub_msec=100, enable_abt_profiling=False, enable_diagnostics=False, handle_cache_size=32, profile_sparkline_timeslice_msec=1000, progress_pool=PoolSpec(name='__primary__', kind='fifo_wait', access='mpmc'), rpc_pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), version='0.15.0'), _abt_io=[AbtIOSpec(name='my_abtio', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), config={'internal_pool_flag': False, 'null_io_read': False, 'null_io_write': False, 'trace_io': False, 'version': '0.6.0'})], _mona=[MonaSpec(name='my_mona', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), config={})], _ssg=[SSGSpec(name='my_group', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), credential=-1, bootstrap='init', group_file='my_group.ssg', swim=SwimSpec(period_length_ms=1000, suspect_timeout_periods=3, subgroup_member_count=0, disabled=False))], libraries={'module_a': '/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-a.so', 'module_b': '/home/mdorier/Code/mochi-bedrock/build/examples/libexample-module-b.so'}, _providers=[ProviderSpec(name='ProviderA', type='module_a', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), provider_id=42, config={}, dependencies={}, tags=[]), ProviderSpec(name='ProviderB', type='module_b', pool=PoolSpec(name='my_rpc_pool', kind='fifo', access='mpmc'), provider_id=33, config={}, dependencies={'a_client': 'ClientA', 'a_provider': 'ProviderA', 'a_provider_handle': ['42@na+sm://12111-0'], 'mona_instance': 'my_mona', 'ssg_group': 'my_group'}, tags=[])], _clients=[ClientSpec(name='ClientA', type='module_a', config={}, dependencies={}, tags=[]), ClientSpec(name='ClientB', type='module_b', config={}, dependencies={}, tags=[])], bedrock=BedrockSpec(pool=PoolSpec(name='__primary__', kind='fifo_wait', access='mpmc'), provider_id=0))\n" + ] + } + ], + "source": [ + "print(daemon.spec)" + ] + }, + { + "cell_type": "markdown", + "id": "c1a562db-33c2-4267-8e1c-17ec6b878a7e", + "metadata": {}, + "source": [ + "You can manipulate the runtime configuration of your server. For instance, here is how to add a new Argobots pool and an execution stream that uses it." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "827481cb-7371-4467-8388-4b2252300166", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "daemon.margo.pools.create(spec.PoolSpec(name=\"new_pool\", kind=\"fifo_wait\", access=\"mpmc\"))\n", + "daemon.margo.xstreams.create(\n", + " spec.XstreamSpec(\n", + " name=\"new_xstream\",\n", + " scheduler=spec.SchedulerSpec(\n", + " type=\"basic_wait\",\n", + " pools=[daemon.margo.spec.argobots.pools[\"new_pool\"]])))" + ] + }, + { + "cell_type": "markdown", + "id": "96028d68-411a-4665-9973-f17a613f02de", + "metadata": {}, + "source": [ + "Finally, to block the process and keep running the daemon, use `daemon.wait_for_finalize()`. To finalize it, use `daemon.finalize()`." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "64fce899-f115-43fe-8b2c-fc6263c18fb8", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Destroyed provider handle from module A\n", + "Deregistered a provider from module A\n", + "Deregistring provider from module B\n", + "Finalized a client from module A\n", + "Finalizing client from module B\n" + ] + } + ], + "source": [ + "daemon.finalize()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbc9b2d2-84cb-4f63-9e80-48b8f4ba8f3b", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/python/requirements.txt b/examples/python/requirements.txt new file mode 100644 index 0000000..c9356a7 --- /dev/null +++ b/examples/python/requirements.txt @@ -0,0 +1 @@ +jupyterlab