diff --git a/.cirrus.yml b/.cirrus.yml
new file mode 100644
index 0000000000..6fb67ed14c
--- /dev/null
+++ b/.cirrus.yml
@@ -0,0 +1,237 @@
+# only run for releases
+only_if: $CIRRUS_TAG != ''
+
+env:
+ MACOSX_DEPLOYMENT_TARGET: "10.15"
+
+macosx_arm64_wheel_task:
+ macos_instance:
+ image: ghcr.io/cirruslabs/macos-monterey-base:latest
+
+ checkout_script:
+ - git submodule init
+ - git submodule update
+
+ install_deps_script:
+ - brew update
+ # go 1.22 doesn't work, see also: https://github.com/golang/go/issues/37602
+ - brew install coreutils go@1.21 pyenv python
+
+ install_various_python_script:
+ - pyenv install 3.8.18
+ - pyenv install 3.9.18
+ - pyenv install 3.10.13
+ - pyenv install 3.11.8
+ - pyenv install 3.12.2
+
+ install_apache_arrow_script: |
+ echo "Installing apache-arrow ..."
+ mkdir -p /tmp/install
+ cd /tmp/install
+ curl -L https://github.com/apache/arrow/archive/refs/tags/apache-arrow-8.0.1.tar.gz --output apache-arrow-8.0.1.tar.gz
+ tar zxf apache-arrow-8.0.1.tar.gz
+ cd arrow-apache-arrow-8.0.1
+ mkdir -p build-dir
+ cd build-dir
+ cmake ../cpp \
+ -DARROW_COMPUTE=OFF \
+ -DARROW_WITH_UTF8PROC=OFF \
+ -DARROW_CSV=OFF \
+ -DARROW_CUDA=OFF \
+ -DARROW_DATASET=OFF \
+ -DARROW_FILESYSTEM=ON \
+ -DARROW_FLIGHT=OFF \
+ -DARROW_GANDIVA=OFF \
+ -DARROW_GANDIVA_JAVA=OFF \
+ -DARROW_HDFS=OFF \
+ -DARROW_HIVESERVER2=OFF \
+ -DARROW_JSON=OFF \
+ -DARROW_ORC=OFF \
+ -DARROW_PARQUET=OFF \
+ -DARROW_PLASMA=OFF \
+ -DARROW_PLASMA_JAVA_CLIENT=OFF \
+ -DARROW_PYTHON=OFF \
+ -DARROW_S3=OFF \
+ -DARROW_WITH_BZ2=OFF \
+ -DARROW_WITH_ZLIB=OFF \
+ -DARROW_WITH_LZ4=OFF \
+ -DARROW_WITH_SNAPPY=OFF \
+ -DARROW_WITH_ZSTD=OFF \
+ -DARROW_WITH_BROTLI=OFF \
+ -DARROW_IPC=ON \
+ -DARROW_BUILD_BENCHMARKS=OFF \
+ -DARROW_BUILD_EXAMPLES=OFF \
+ -DARROW_BUILD_INTEGRATION=OFF \
+ -DARROW_BUILD_UTILITIES=OFF \
+ -DARROW_BUILD_TESTS=OFF \
+ -DARROW_ENABLE_TIMING_TESTS=OFF \
+ -DARROW_FUZZING=OFF \
+ -DARROW_USE_ASAN=OFF \
+ -DARROW_USE_TSAN=OFF \
+ -DARROW_USE_UBSAN=OFF \
+ -DARROW_JEMALLOC=OFF \
+ -DARROW_BUILD_SHARED=OFF \
+ -DARROW_BUILD_STATIC=ON
+ sudo make install -j$(sysctl -n hw.ncpu)
+ cd /tmp
+ sudo rm -rf /tmp/install
+
+ install_boost_script: |
+ echo "Installing boost ..."
+ mkdir -p /tmp/install
+ cd /tmp/install
+ wget -q https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz
+ tar zxf boost_1_75_0.tar.gz
+ cd boost_1_75_0
+ ./bootstrap.sh
+ sudo ./b2 install -j`nproc` variant=release threading=multi \
+ --with-atomic \
+ --with-chrono \
+ --with-date_time \
+ --with-filesystem \
+ --with-random \
+ --with-regex \
+ --with-system \
+ --with-thread
+ cd /tmp
+ sudo rm -rf /tmp/install
+
+ install_gflags_script: |
+ echo "Installing gflags ..."
+ mkdir -p /tmp/install
+ cd /tmp/install
+ curl -L https://github.com/gflags/gflags/archive/v2.2.2.tar.gz --output gflags-v2.2.2.tar.gz
+ tar zxf gflags-v2.2.2.tar.gz
+ cd gflags-2.2.2
+ mkdir -p build-dir
+ cd build-dir
+ cmake .. -DBUILD_SHARED_LIBS=OFF
+ sudo make install -j$(sysctl -n hw.ncpu)
+ cd /tmp
+ sudo rm -rf /tmp/install
+
+ install_glog_script: |
+ echo "Installing glog ..."
+ mkdir -p /tmp/install
+ cd /tmp/install
+ curl -L https://github.com/google/glog/archive/v0.6.0.tar.gz --output glog-v0.6.0.tar.gz
+ tar zxf glog-v0.6.0.tar.gz
+ cd glog-0.6.0
+ mkdir -p build-dir
+ cd build-dir
+ cmake .. -DBUILD_SHARED_LIBS=OFF \
+ -DWITH_GFLAGS=OFF \
+ -DBUILD_TESTING=OFF
+ sudo make install -j$(sysctl -n hw.ncpu)
+ cd /tmp
+ sudo rm -rf /tmp/install
+
+ install_protobuf_grpc_script: |
+ echo "Installing protobuf & grpc ..."
+ mkdir -p /tmp/install
+ cd /tmp/install
+ wget -q https://github.com/unsafecoerce/git-submodules-tarball/releases/download/grpc%2Fgrpc-v1.36.x/grpc-grpc-1.36.x.tar.gz
+ tar zxf grpc-grpc-1.36.x.tar.gz
+ cd grpc-grpc-1.36.x
+ mkdir -p cmake-build
+ cd cmake-build
+ cmake .. -DCMAKE_BUILD_TYPE=MinSizeRel \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DgRPC_INSTALL=ON \
+ -DgRPC_BUILD_TESTS=OFF \
+ -DgRPC_BUILD_CSHARP_EXT=OFF \
+ -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF \
+ -DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF \
+ -DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF \
+ -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \
+ -DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF \
+ -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \
+ -DgRPC_SSL_PROVIDER=package \
+ -DgRPC_ZLIB_PROVIDER=package \
+ -DOPENSSL_ROOT_DIR=$(brew --prefix openssl) \
+ -DgRPC_BACKWARDS_COMPATIBILITY_MODE=ON
+ sudo make install -j$(sysctl -n hw.ncpu)
+ cd /tmp
+ sudo rm -rf /tmp/install
+
+ build_vineyardctl_script:
+ - |
+ export PATH=$(brew --prefix go@1.21)/bin:$PATH
+ make -C k8s vineyardctl
+
+ vineyardctl_artifacts:
+ path: k8s/vineyardctl
+
+ build_vineyardd_script:
+ - mkdir -p build
+ - cd build
+ - |
+ pyenv global 3.11.8
+ cmake .. -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_CXX_STANDARD=17 \
+ -DCMAKE_CXX_STANDARD_REQUIRED=TRUE \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DBUILD_VINEYARD_SERVER=ON \
+ -DBUILD_VINEYARD_CLIENT=OFF \
+ -DBUILD_VINEYARD_PYTHON_BINDINGS=OFF \
+ -DBUILD_VINEYARD_PYPI_PACKAGES=OFF \
+ -DBUILD_VINEYARD_BASIC=OFF \
+ -DBUILD_VINEYARD_GRAPH=OFF \
+ -DBUILD_VINEYARD_IO=OFF \
+ -DBUILD_VINEYARD_HOSSEINMOEIN_DATAFRAME=OFF \
+ -DBUILD_VINEYARD_TESTS=OFF \
+ -DBUILD_VINEYARD_TESTS_ALL=OFF \
+ -DBUILD_VINEYARD_PROFILING=OFF
+ make vineyardd -j$(sysctl -n hw.ncpu)
+
+ vineyardd_artifacts:
+ path: build/bin/vineyardd
+
+ build_vineyard_bdist_script:
+ - pyenv global 3.11.8
+ - cp k8s/vineyardctl ./python/vineyard/bdist/vineyardctl
+ - cp build/bin/vineyardd ./python/vineyard/bdist/vineyardd
+ - strip ./python/vineyard/bdist/vineyardctl
+ - strip ./python/vineyard/bdist/vineyardd
+ - python3 setup_bdist.py bdist_wheel --plat=macosx_11_0_arm64
+
+ build_vineyard_python_script:
+ - |
+ for py in 3.8.18 3.9.18 3.10.13 3.11.8 3.12.2; do
+ current_python=$(pyenv root)/versions/$py/bin/python
+ echo "Python is: $current_python, $($current_python --version)"
+ $current_python -m pip install delocate setuptools wheel
+ rm -rf build/lib* build/bdist.* python/vineyard/*.dylib python/vineyard/*.so
+ mkdir -p build
+ cd build
+ cmake .. -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_CXX_STANDARD=17 \
+ -DCMAKE_CXX_STANDARD_REQUIRED=TRUE \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DBUILD_VINEYARD_SERVER=OFF \
+ -DBUILD_VINEYARD_CLIENT=ON \
+ -DBUILD_VINEYARD_PYTHON_BINDINGS=ON \
+ -DBUILD_VINEYARD_PYPI_PACKAGES=ON \
+ -DPYTHON_EXECUTABLE=$current_python \
+ -DBUILD_VINEYARD_BASIC=OFF \
+ -DBUILD_VINEYARD_GRAPH=OFF \
+ -DBUILD_VINEYARD_IO=OFF \
+ -DBUILD_VINEYARD_HOSSEINMOEIN_DATAFRAME=OFF \
+ -DBUILD_VINEYARD_TESTS=OFF \
+ -DBUILD_VINEYARD_TESTS_ALL=OFF \
+ -DBUILD_VINEYARD_PROFILING=OFF
+ make vineyard_client_python -j$(sysctl -n hw.ncpu)
+ cd ..
+ $current_python setup.py bdist_wheel
+ done
+
+ delocate_wheel_script:
+ - |
+ $(brew --prefix python)/bin/python3 -m pip install delocate wheel
+ for wheel in dist/*.whl; do
+ delocate-wheel -w fixed_wheels -v $wheel
+ done
+ ls -la ./fixed_wheels
+
+ macosx_arm64_wheel_artifacts:
+ path: fixed_wheels/*.whl
diff --git a/.cspell.json b/.cspell.json
new file mode 100644
index 0000000000..dd5596ce48
--- /dev/null
+++ b/.cspell.json
@@ -0,0 +1,327 @@
+// cSpell Settings
+{
+ // Version of the setting file. Always 0.2
+ "version": "0.2",
+ // language - current active spelling language
+ "language": "en",
+ // a list of globs to specify which files are to be ignored
+ "ignorePaths": [
+ "**/go.mod",
+ "**/thirdparty/**",
+ "**/vendor/**",
+ "**/target/**",
+ "**/dist/**",
+ "**/build/**",
+ "**/_build/**",
+ "**/*.egg-info/**",
+ "**/*.eggs/**",
+ "**/__pycache__/**",
+ "**/default.etcd/**",
+ "**/*.log",
+ "**/*.jar",
+ "**/.cache/**",
+ "**/.ossutil_checkpoint",
+ "**/metastore_db/**",
+ "docs/_static",
+ "misc/cpplint.py",
+ "python/vineyard/drivers/io/tests/test_ossfs.py",
+ "python/vineyard/contrib/kedro/benchmark/mlops/data/**",
+ "k8s/vineyardctl",
+ ],
+ // words - list of words to be always considered correct
+ "words": [
+ "Aliyun",
+ "allclose",
+ "ALLOC",
+ "Alluxio",
+ "apierrors",
+ "apiextensions",
+ "apimachinery",
+ "apiv",
+ "Appender",
+ "arange",
+ "asio",
+ "astype",
+ "Backoff",
+ "bdist",
+ "bigdata",
+ "bitcode",
+ "bitwidth",
+ "buildx",
+ "bulkstore",
+ "bytecode",
+ "chatgpt",
+ "checkpointing",
+ "chrono",
+ "cindex",
+ "CLASSNAME",
+ "clientref",
+ "clientset",
+ "clippy",
+ "cloudpickle",
+ "CNCF",
+ "codecov",
+ "codegen",
+ "codereview",
+ "composability",
+ "configmap",
+ "Consolidatable",
+ "consts",
+ "coreutils",
+ "cout",
+ "coveragerc",
+ "cpplint",
+ "cpprestsdk",
+ "crds",
+ "CUDA",
+ "cycleclock",
+ "daemonset",
+ "dask",
+ "dataframe",
+ "dataframes",
+ "datafusion",
+ "datalens",
+ "datasource",
+ "datatypes",
+ "davinci",
+ "DCPPREST",
+ "debruijn",
+ "dedup",
+ "defaultscheme",
+ "Deque",
+ "deserialization",
+ "destaticize",
+ "distro",
+ "divein",
+ "dlist",
+ "dlmalloc",
+ "dlog",
+ "doctest",
+ "dropna",
+ "dtype",
+ "DVLOG",
+ "endl",
+ "etcdctl",
+ "etcdserverpb",
+ "etcdv",
+ "exitfirst",
+ "fastpath",
+ "filesystems",
+ "flajolet",
+ "Flink",
+ "flyteconsole",
+ "flytectl",
+ "flytesnacks",
+ "formatcp",
+ "fsspec",
+ "genieai",
+ "gensym",
+ "getset",
+ "getxattr",
+ "Giraph",
+ "gitbook",
+ "globalobject",
+ "GLOO",
+ "goccy",
+ "gopath",
+ "GPTAPI",
+ "graphlearn",
+ "graphscope",
+ "hashable",
+ "hasher",
+ "hashers",
+ "hdfs",
+ "Healthz",
+ "HOSSEINMOEIN",
+ "htap",
+ "htpasswd",
+ "HUGETLB",
+ "hyperloglog",
+ "hyperparameters",
+ "idxmax",
+ "idxmin",
+ "impls",
+ "Infof",
+ "inlines",
+ "inuse",
+ "iocontext",
+ "ipcserver",
+ "iproduct",
+ "irecv",
+ "isend",
+ "isinstance",
+ "issigned",
+ "iszero",
+ "itertools",
+ "izip",
+ "Kaggle",
+ "kedro",
+ "KEEPALIVE",
+ "kprobe",
+ "kretprobe",
+ "kubebuilder",
+ "kubeconfig",
+ "kustomization",
+ "Kustomize",
+ "lambdafy",
+ "ldbc",
+ "leaseid",
+ "leasekeepalive",
+ "LLMKV",
+ "libboost",
+ "libclang",
+ "libgrape",
+ "libgrpc",
+ "libprotobuf",
+ "livegraph",
+ "localobject",
+ "localobjects",
+ "loglog",
+ "logr",
+ "lossen",
+ "makefun",
+ "malloc",
+ "mallocinfo",
+ "manylinux",
+ "mathjax",
+ "maxdepth",
+ "memmap",
+ "memoryview",
+ "metadatas",
+ "metakv",
+ "metas",
+ "metastore",
+ "metatree",
+ "microbatches",
+ "mimalloc",
+ "minio",
+ "mmap",
+ "multierr",
+ "multispace",
+ "MVCC",
+ "nbytes",
+ "NCCL",
+ "ndarray",
+ "nfilters",
+ "nobuffer",
+ "NODENAME",
+ "noindex",
+ "nonblocking",
+ "nonminimal",
+ "nonoverlapping",
+ "nonspaces",
+ "nopython",
+ "nproc",
+ "nslices",
+ "Numpy",
+ "objectfs",
+ "ogbn",
+ "oneof",
+ "Oobleck",
+ "OPENAI",
+ "ossfs",
+ "PARTITIONER",
+ "persuing",
+ "pflag",
+ "platlib",
+ "Pluggable",
+ "pointee",
+ "popen",
+ "POSIX",
+ "pplx",
+ "Preprocess",
+ "printk",
+ "privkey",
+ "protobuf",
+ "ptrguard",
+ "purelib",
+ "pyarrow",
+ "pyenv",
+ "Pylance",
+ "pylint",
+ "pylintrc",
+ "pyorc",
+ "pypa",
+ "pytest",
+ "pythonapi",
+ "quickstart",
+ "rcfile",
+ "rdtsc",
+ "rdzv",
+ "readwrite",
+ "Readyz",
+ "realpath",
+ "rebalance",
+ "Rebalancer",
+ "rechunk",
+ "recordbatch",
+ "recordbatches",
+ "reinit",
+ "reinterpert",
+ "relu",
+ "replicaset",
+ "repr",
+ "Reprable",
+ "Retryable",
+ "rfind",
+ "roadmap",
+ "rpcserver",
+ "rustdoc",
+ "rustfmt",
+ "scikit",
+ "sendfd",
+ "serde",
+ "setxattr",
+ "sharded",
+ "sighingnow",
+ "significand",
+ "SIGUSR",
+ "SIMD",
+ "skipna",
+ "skywalking",
+ "SLURM",
+ "softwareupdate",
+ "staticize",
+ "staticized",
+ "strategized",
+ "streamable",
+ "subdir",
+ "subhealthy",
+ "Succ",
+ "thirdparty",
+ "thiserror",
+ "TENSORBYTES",
+ "Timepoint",
+ "toctree",
+ "TORCHELASTIC",
+ "tparam",
+ "traceback",
+ "transformative",
+ "typecheck",
+ "typekind",
+ "UDFs",
+ "ujson",
+ "unittests",
+ "Unpublish",
+ "unsafecoerce",
+ "Unstage",
+ "uprobe",
+ "uretprobe",
+ "varint",
+ "VCDL",
+ "vectorize",
+ "vfile",
+ "vineyardcloudnative",
+ "vineyardctl",
+ "VINEYARDD",
+ "Wattributes",
+ "WEBSOCKETS",
+ "whitegrid",
+ "Wrapf",
+ "xattr",
+ "xmls",
+ "xxhash",
+ "zapcore",
+ "zxvf",
+ ],
+}
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000..e151f36845
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,59 @@
+.git
+**/.git
+
+# contents from .gitignore
+build/
+build-mac/
+install/
+build-static/
+build-static-mac/
+install-static/
+build-docker/
+install-docker/
+build-docker-gsa/
+install-docker-gsa/
+*.code-workspace
+.vscode
+.idea
+.DS_store
+cmake-build-debug/
+modules/graph/thirdparty/**/build/
+
+# for python packaging
+dist/
+**/*.egg-info/
+**/*.so
+**/*.dylib
+**/*.a
+**/*.pyc
+**/*.bin
+**/*.egg
+
+# generated files
+*.vineyard.h
+
+# etcd data directory during testing
+default.etcd/
+
+# tmp data directory during building image
+docker/dist/
+
+# docs
+docs/_build/
+
+# go vendor
+/**/vendor/
+
+# Rust build
+/**/target/
+
+# k8s
+k8s/bin/
+k8s/vendor/
+k8s/examples/
+k8s/test/
+k8s/hack/
+!k8s/config/scheduler/config.yaml
+
+# artifacts
+wheels/
diff --git a/.gitleaks.toml b/.gitleaks.toml
new file mode 100644
index 0000000000..8833043ae7
--- /dev/null
+++ b/.gitleaks.toml
@@ -0,0 +1,85 @@
+title = "Gitleaks for Vineyard"
+
+[extend]
+useDefault = true
+
+[[rules]]
+description = "Alibaba AccessKey ID"
+id = "alibaba-access-key-id"
+regex = '''(?i)((LTAI)[a-z0-9]+)'''
+keywords = [
+ "ltai",
+]
+
+[[rules]]
+description = "Alibaba AccessKey ID"
+id = "alibaba-access-id-in-config"
+regex = '''(?i)((access).?id\s*=\s*.+)'''
+keywords = [
+ "access",
+]
+
+[[rules]]
+description = "Alibaba AccessKey ID"
+id = "alibaba-access-key-in-config"
+regex = '''(?i)((access).?key\s*=\s*.+)'''
+keywords = [
+ "access",
+]
+
+[[rules]]
+description = "Alibaba AccessKey ID"
+id = "alibaba-access-secret-in-config"
+regex = '''(?i)((access).?secret\s*=\s*.+)'''
+keywords = [
+ "access",
+ "secret",
+]
+
+[[rules]]
+description = "Alibaba AccessKey ID"
+id = "alibaba-access-key-id-in-config"
+regex = '''(?i)((access).?key.?id\s*=\s*.+)'''
+keywords = [
+ "access",
+]
+
+[rules.allowlist]
+paths = [
+ '''python/vineyard/drivers/io/tests/test_open.py''',
+ '''python/vineyard/drivers/io/tests/test_serialize.py''',
+]
+
+[[rules]]
+description = "Alibaba AccessKey ID"
+id = "alibaba-access-key-secret-in-config"
+regex = '''(?i)((access).?key.?secret\s*=\s*.+)'''
+keywords = [
+ "access",
+ "secret",
+]
+
+[rules.allowlist]
+paths = [
+ '''python/vineyard/drivers/io/tests/test_open.py''',
+ '''python/vineyard/drivers/io/tests/test_serialize.py''',
+]
+
+[[rules]]
+description = "Alibaba AccessKey ID"
+id = "alibaba-secret-access-key-in-config"
+regex = '''(?i)((secret).?access.?key\s*=\s*.+)'''
+keywords = [
+ "access",
+ "secret",
+]
+
+[allowlist]
+paths = [
+ '''build''',
+ '''docs/_build''',
+ '''docs/_templates/footer.html''',
+ '''thirdparty''',
+ '''modules/graph/thirdparty''',
+]
+
diff --git a/.nojekyll b/.nojekyll
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000..657d0c7b52
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,7 @@
+repos:
+ - repo: https://github.com/zricethezav/gitleaks
+ rev: v8.15.0
+ hooks:
+ - id: gitleaks
+ args:
+ - '--verbose'
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000000..4b3b599d40
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,614 @@
+[MASTER]
+
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code.
+extension-pkg-whitelist=numpy,
+ vineyard
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Add files or directories matching the regex patterns to the blacklist. The
+# regex matches against base names, not paths.
+ignore-patterns=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
+# number of processors available to use.
+jobs=1
+
+# Control the amount of potential inferred values when inferring a single
+# object. This can help the performance when dealing with large functions or
+# complex, nested conditions.
+limit-inference-results=100
+
+# List of plugins (as comma separated values of python module names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# Specify a configuration file.
+#rcfile=
+
+# When enabled, pylint would attempt to guess common misconfiguration and emit
+# user-friendly hints instead of false-positive error messages.
+suggestion-mode=yes
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=yes
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
+confidence=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once). You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use "--disable=all --enable=classes
+# --disable=W".
+disable=abstract-method,
+ apply-builtin,
+ attribute-defined-outside-init,
+ backtick,
+ bad-continuation,
+ bad-inline-option,
+ bad-option-value,
+ bad-python3-import,
+ bare-except,
+ basestring-builtin,
+ buffer-builtin,
+ cmp-builtin,
+ cmp-method,
+ coerce-builtin,
+ coerce-method,
+ comprehension-escape,
+ consider-using-f-string,
+ delslice-method,
+ deprecated-itertools-function,
+ deprecated-operator-function,
+ deprecated-pragma,
+ deprecated-str-translate-call,
+ deprecated-string-function,
+ deprecated-sys-function,
+ deprecated-types-field,
+ deprecated-urllib-function,
+ dict-items-not-iterating,
+ dict-iter-method,
+ dict-keys-not-iterating,
+ dict-values-not-iterating,
+ dict-view-method,
+ div-method,
+ duplicate-code,
+ eq-without-hash,
+ exception-escape,
+ exception-message-attribute,
+ execfile-builtin,
+ file-builtin,
+ file-ignored,
+ filter-builtin-not-iterating,
+ fixme,
+ getslice-method,
+ global-statement,
+ hex-method,
+ idiv-method,
+ import-star-module-level,
+ indexing-exception,
+ input-builtin,
+ intern-builtin,
+ invalid-name,
+ invalid-str-codec,
+ locally-disabled,
+ long-builtin,
+ long-suffix,
+ map-builtin-not-iterating,
+ metaclass-assignment,
+ missing-class-docstring,
+ missing-function-docstring,
+ missing-docstring,
+ missing-module-docstring,
+ next-method-called,
+ next-method-defined,
+ no-absolute-import,
+ no-else-continue,
+ no-else-raise,
+ no-else-return,
+ no-self-use,
+ non-ascii-bytes-literal,
+ nonzero-method,
+ oct-method,
+ old-division,
+ old-ne-operator,
+ old-octal-literal,
+ old-raise-syntax,
+ parameter-unpacking,
+ print-statement,
+ protected-access,
+ raising-string,
+ range-builtin-not-iterating,
+ raw-checker-failed,
+ raw_input-builtin,
+ rdiv-method,
+ redefined-builtin,
+ redefined-outer-name,
+ reduce-builtin,
+ reload-builtin,
+ round-builtin,
+ setslice-method,
+ standarderror-builtin,
+ suppressed-message,
+ sys-max-int,
+ too-few-public-methods,
+ too-many-ancestors,
+ too-many-arguments,
+ too-many-branches,
+ too-many-locals,
+ unichr-builtin,
+ unicode-builtin,
+ unnecessary-comprehension,
+ unpacking-in-except,
+ unrecognized-option,
+ unsubscriptable-object,
+ use-dict-literal,
+ use-list-literal,
+ use-symbolic-message-instead,
+ useless-else-on-loop,
+ useless-option-value,
+ useless-suppression,
+ using-cmp-argument,
+ xrange-builtin,
+ xreadlines-attribute,
+ zip-builtin-not-iterating,
+ django-not-configured
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time (only on the command line, not in the configuration file where
+# it should appear only once). See also the "--disable" option for examples.
+enable=c-extension-no-member
+
+
+[REPORTS]
+
+# Python expression which should return a score less than or equal to 10. You
+# have access to the variables 'error', 'warning', 'refactor', and 'convention'
+# which contain the number of messages in each category, as well as 'statement'
+# which is the total number of statements analyzed. This score is used by the
+# global evaluation report (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details.
+#msg-template=
+
+# Set the output format. Available formats are text, parseable, colorized, json
+# and msvs (visual studio). You can also give a reporter class, e.g.
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Tells whether to display a full report or only the messages.
+reports=no
+
+# Activate the evaluation score.
+score=yes
+
+
+[REFACTORING]
+
+# Maximum number of nested blocks for function / method body
+max-nested-blocks=5
+
+# Complete name of functions that never returns. When checking for
+# inconsistent-return-statements if a never returning function is called then
+# it will be considered as an explicit return statement and no message will be
+# printed.
+never-returning-functions=sys.exit
+
+
+[LOGGING]
+
+# Format style used to check logging format string. `old` means using %
+# formatting, `new` is for `{}` formatting,and `fstr` is for f-strings.
+logging-format-style=old
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format.
+logging-modules=logging
+
+
+[SPELLING]
+
+# Limits count of emitted suggestions for spelling mistakes.
+max-spelling-suggestions=4
+
+# Spelling dictionary name. Available dictionaries: none. To make it work,
+# install the python-enchant package.
+spelling-dict=
+
+# List of comma separated words that should not be checked.
+spelling-ignore-words=
+
+# A path to a file that contains the private dictionary; one word per line.
+spelling-private-dict-file=
+
+# Tells whether to store unknown words to the private dictionary (see the
+# --spelling-private-dict-file option) instead of raising a message.
+spelling-store-unknown-words=no
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,
+ XXX,
+ TODO
+
+
+[TYPECHECK]
+
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators=contextlib.contextmanager
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E1101 when accessed. Python regular
+# expressions are accepted.
+generated-members=
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# Tells whether to warn about missing members when the owner of the attribute
+# is inferred to be None.
+ignore-none=yes
+
+# This flag controls whether pylint should warn about no-member and similar
+# checks whenever an opaque object is returned when inferring. The inference
+# can return multiple potential results while evaluating a Python object, but
+# some branches might not be evaluated, which results in partial inference. In
+# that case, it might be useful to still emit no-member and other checks for
+# the rest of the inferred objects.
+ignore-on-opaque-inference=yes
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes=optparse.Values,thread._local,_thread._local
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis). It
+# supports qualified module names, as well as Unix pattern matching.
+ignored-modules=
+
+# Show a hint with possible names when a member name was not found. The aspect
+# of finding the hint is based on edit distance.
+missing-member-hint=yes
+
+# The minimum edit distance a name should have in order to be considered a
+# similar match for a missing member name.
+missing-member-hint-distance=1
+
+# The total number of similar names that should be taken in consideration when
+# showing a hint for a missing member.
+missing-member-max-choices=1
+
+# List of decorators that change the signature of a decorated function.
+signature-mutators=
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid defining new builtins when possible.
+additional-builtins=
+
+# Tells whether unused global variables should be treated as a violation.
+allow-global-unused-variables=yes
+
+# List of strings which can identify a callback function by name. A callback
+# name must start or end with one of those strings.
+callbacks=cb_,
+ _cb
+
+# A regular expression matching the name of dummy variables (i.e. expected to
+# not be used).
+dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore.
+ignored-argument-names=_.*|^ignored_|^unused_
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
+
+
+[FORMAT]
+
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format=
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )??$
+
+# Number of spaces of indent required inside a hanging or continued line.
+indent-after-paren=4
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string=' '
+
+# Maximum number of characters on a single line.
+max-line-length=128
+
+# Maximum number of lines in a module.
+max-module-lines=4294967296
+
+# List of optional constructs for which whitespace checking is disabled. `dict-
+# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
+# `empty-line` allows space-only lines.
+no-space-check=trailing-comma,
+ dict-separator
+
+# Allow the body of a class to be on the same line as the declaration if body
+# contains single statement.
+single-line-class-stmt=no
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[BASIC]
+
+# Naming style matching correct argument names.
+argument-naming-style=snake_case
+
+# Regular expression matching correct argument names. Overrides argument-
+# naming-style.
+#argument-rgx=
+
+# Naming style matching correct attribute names.
+attr-naming-style=snake_case
+
+# Regular expression matching correct attribute names. Overrides attr-naming-
+# style.
+#attr-rgx=
+
+# Bad variable names which should always be refused, separated by a comma.
+bad-names=foo,
+ bar,
+ baz,
+ toto,
+ tutu,
+ tata
+
+# Naming style matching correct class attribute names.
+class-attribute-naming-style=any
+
+# Regular expression matching correct class attribute names. Overrides class-
+# attribute-naming-style.
+#class-attribute-rgx=
+
+# Naming style matching correct class names.
+class-naming-style=PascalCase
+
+# Regular expression matching correct class names. Overrides class-naming-
+# style.
+#class-rgx=
+
+# Naming style matching correct constant names.
+const-naming-style=UPPER_CASE
+
+# Regular expression matching correct constant names. Overrides const-naming-
+# style.
+#const-rgx=
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=-1
+
+# Naming style matching correct function names.
+function-naming-style=snake_case
+
+# Regular expression matching correct function names. Overrides function-
+# naming-style.
+#function-rgx=
+
+# Good variable names which should always be accepted, separated by a comma.
+good-names=i,
+ j,
+ k,
+ ex,
+ Run,
+ _
+
+# Include a hint for the correct naming format with invalid-name.
+include-naming-hint=no
+
+# Naming style matching correct inline iteration names.
+inlinevar-naming-style=any
+
+# Regular expression matching correct inline iteration names. Overrides
+# inlinevar-naming-style.
+#inlinevar-rgx=
+
+# Naming style matching correct method names.
+method-naming-style=snake_case
+
+# Regular expression matching correct method names. Overrides method-naming-
+# style.
+#method-rgx=
+
+# Naming style matching correct module names.
+module-naming-style=snake_case
+
+# Regular expression matching correct module names. Overrides module-naming-
+# style.
+#module-rgx=
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+name-group=
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=^_
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+# These decorators are taken in consideration only for invalid-name.
+property-classes=abc.abstractproperty
+
+# Naming style matching correct variable names.
+variable-naming-style=snake_case
+
+# Regular expression matching correct variable names. Overrides variable-
+# naming-style.
+#variable-rgx=
+
+
+[STRING]
+
+# This flag controls whether the implicit-str-concat-in-sequence should
+# generate a warning on implicit string concatenation in sequences defined over
+# several lines.
+check-str-concat-over-line-jumps=no
+
+
+[IMPORTS]
+
+# List of modules that can be imported at any level, not just the top level
+# one.
+allow-any-import-level=
+
+# Allow wildcard imports from modules that define __all__.
+allow-wildcard-with-all=no
+
+# Analyse import fallback blocks. This can be used to support both Python 2 and
+# 3 compatible code, which means that the block might have code that exists
+# only in one or another interpreter, leading to false positives when analysed.
+analyse-fallback-blocks=no
+
+# Deprecated modules which should not be used, separated by a comma.
+deprecated-modules=optparse,tkinter.tix
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled).
+ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled).
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled).
+int-import-graph=
+
+# Force import order to recognize a module as part of the standard
+# compatibility libraries.
+known-standard-library=
+
+# Force import order to recognize a module as part of a third party library.
+known-third-party=enchant
+
+# Couples of modules and preferred modules, separated by a comma.
+preferred-modules=
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,
+ __new__,
+ setUp
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected=_asdict,
+ _fields,
+ _replace,
+ _source,
+ _make
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=cls
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method.
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Maximum number of boolean expressions in an if statement (see R0916).
+max-bool-expr=5
+
+# Maximum number of branch for function / method body.
+max-branches=12
+
+# Maximum number of locals for function / method body.
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body.
+max-returns=6
+
+# Maximum number of statements in function / method body.
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "BaseException, Exception".
+overgeneral-exceptions=BaseException,
+ Exception
diff --git a/.stoat/config.yaml b/.stoat/config.yaml
new file mode 100644
index 0000000000..02f7dd8e6d
--- /dev/null
+++ b/.stoat/config.yaml
@@ -0,0 +1,80 @@
+---
+version: 1
+enabled: true
+plugins:
+ static_hosting:
+ e2e-tests-airflow-integration-logs:
+ metadata:
+ name: "airflow-integration-logs"
+ path: e2e-tests-airflow-integration-logs
+ file_viewer: true
+ e2e-tests-assembly-local-logs:
+ metadata:
+ name: "assembly-local-logs"
+ path: e2e-tests-assembly-local-logs
+ file_viewer: true
+ e2e-tests-assembly-distributed-logs:
+ metadata:
+ name: "assembly-distributed-logs"
+ path: e2e-tests-assembly-distributed-logs
+ file_viewer: true
+ e2e-tests-autogenerated-helm-chart-logs:
+ metadata:
+ name: "autogenerated-helm-chart-logs"
+ path: e2e-tests-autogenerated-helm-chart-logs
+ file_viewer: true
+ e2e-tests-failover-logs:
+ metadata:
+ name: "failover-logs"
+ path: e2e-tests-failover-logs
+ file_viewer: true
+ e2e-tests-repartition-dask-logs:
+ metadata:
+ name: "repartition-dask-logs"
+ path: e2e-tests-repartition-dask-logs
+ file_viewer: true
+ e2e-tests-schedule-workflow-logs:
+ metadata:
+ name: "schedule-workflow-logs"
+ path: e2e-tests-schedule-workflow-logs
+ file_viewer: true
+ e2e-tests-schedule-workflow-without-crd-logs:
+ metadata:
+ name: "schedule-workflow-without-crd-logs"
+ path: e2e-tests-schedule-workflow-without-crd-logs
+ file_viewer: true
+ e2e-tests-serialize-logs:
+ metadata:
+ name: "serialize-logs"
+ path: e2e-tests-serialize-logs
+ file_viewer: true
+ e2e-tests-sidecar-logs:
+ metadata:
+ name: "sidecar-logs"
+ path: e2e-tests-sidecar-logs
+ file_viewer: true
+ e2e-tests-spill-logs:
+ metadata:
+ name: "spill-logs"
+ path: e2e-tests-spill-logs
+ file_viewer: true
+ e2e-tests-workflow-logs:
+ metadata:
+ name: "workflow-logs"
+ path: e2e-tests-workflow-logs
+ file_viewer: true
+ e2e-tests-vineyardctl-logs:
+ metadata:
+ name: "vineyardctl-logs"
+ path: e2e-tests-vineyardctl-logs
+ file_viewer: true
+ e2e-tests-deploy-raw-backup-and-recover-logs:
+ metadata:
+ name: "deploy-raw-backup-and-recover-logs"
+ path: e2e-tests-deploy-raw-backup-and-recover-logs
+ file_viewer: true
+ e2e-tests-schedule-workload-logs:
+ metadata:
+ name: "schedule-workload-logs"
+ path: e2e-tests-schedule-workload-logs
+ file_viewer: true
\ No newline at end of file
diff --git a/CNAME b/CNAME
new file mode 100644
index 0000000000..f14607a400
--- /dev/null
+++ b/CNAME
@@ -0,0 +1 @@
+v6d.io
\ No newline at end of file
diff --git a/_images/dask-tf.jpg b/_images/dask-tf.jpg
new file mode 100644
index 0000000000..e33dddd526
Binary files /dev/null and b/_images/dask-tf.jpg differ
diff --git a/_images/data_sharing_with_deployment.jpg b/_images/data_sharing_with_deployment.jpg
new file mode 100644
index 0000000000..7053b4875e
Binary files /dev/null and b/_images/data_sharing_with_deployment.jpg differ
diff --git a/_images/data_sharing_with_sidecar.jpg b/_images/data_sharing_with_sidecar.jpg
new file mode 100644
index 0000000000..99f6b909ac
Binary files /dev/null and b/_images/data_sharing_with_sidecar.jpg differ
diff --git a/_images/fraud-detection-job.jpg b/_images/fraud-detection-job.jpg
new file mode 100644
index 0000000000..34005ee5a7
Binary files /dev/null and b/_images/fraud-detection-job.jpg differ
diff --git a/_images/kubeflow_create_run.png b/_images/kubeflow_create_run.png
new file mode 100644
index 0000000000..84ac8dd621
Binary files /dev/null and b/_images/kubeflow_create_run.png differ
diff --git a/_images/kubeflow_upload_pipeline.png b/_images/kubeflow_upload_pipeline.png
new file mode 100644
index 0000000000..bd9321fa06
Binary files /dev/null and b/_images/kubeflow_upload_pipeline.png differ
diff --git a/_images/vineyard-logo-rect.png b/_images/vineyard-logo-rect.png
new file mode 100644
index 0000000000..2c3ca4dae7
Binary files /dev/null and b/_images/vineyard-logo-rect.png differ
diff --git a/_images/vineyard_arch.jpg b/_images/vineyard_arch.jpg
new file mode 100644
index 0000000000..813ab5d29e
Binary files /dev/null and b/_images/vineyard_arch.jpg differ
diff --git a/_images/vineyard_composable.jpg b/_images/vineyard_composable.jpg
new file mode 100644
index 0000000000..f4541b655d
Binary files /dev/null and b/_images/vineyard_composable.jpg differ
diff --git a/_images/vineyard_distributed_tensor.jpg b/_images/vineyard_distributed_tensor.jpg
new file mode 100644
index 0000000000..2b0ce68980
Binary files /dev/null and b/_images/vineyard_distributed_tensor.jpg differ
diff --git a/_images/vineyard_operator_arch.png b/_images/vineyard_operator_arch.png
new file mode 100644
index 0000000000..68283ed017
Binary files /dev/null and b/_images/vineyard_operator_arch.png differ
diff --git a/_modules/index.html b/_modules/index.html
new file mode 100644
index 0000000000..2745f72fc0
--- /dev/null
+++ b/_modules/index.html
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+
+ Overview: module code - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ All modules for which code is available
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard.html b/_modules/vineyard.html
new file mode 100644
index 0000000000..3dfdbb70e4
--- /dev/null
+++ b/_modules/vineyard.html
@@ -0,0 +1,980 @@
+
+
+
+
+
+
+
+ vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import contextlib
+import logging
+import os
+import sys
+from typing import Any
+from typing import Dict
+from typing import Generator
+from typing import Optional
+from typing import Tuple
+from typing import Union
+
+from .version import __version__
+
+__doc__ = """
+Vineyard - an in-memory immutable data manager. (Project under CNCF)
+====================================================================
+
+Vineyard (v6d) is an in-memory immutable data manager that provides
+out-of-the-box high-level abstraction and zero-copy in-memory
+sharing for distributed data in big data tasks, such as graph analytics
+(e.g., GraphScope), numerical computing (e.g., Mars), and machine learning.
+"""
+
+# pylint: disable=import-outside-toplevel,wrong-import-position
+
+logger = logging . getLogger ( 'vineyard' )
+
+
+@contextlib . contextmanager
+def envvars (
+ key : Union [ str , Dict [ str , str ]],
+ value : Union [ str , None ] = None ,
+ append : bool = False ,
+) -> Generator [ os . _Environ , Any , Any ]:
+ """Create a context with specified environment variables set.
+
+ It is useful for setting the :code`VINEYARD_IPC_SOCKET` environment
+ variable to obtain a proper default vineyard client.
+
+ This context macro can be used as
+
+ .. code:: python
+
+ with environment('KEY'):
+ # env :code:`KEY` will be set to None.
+
+ with environment('KEY', 'value'):
+ # env :code:`KEY` will be set as :code:`value`.
+
+ with environment({'KEY1': None, 'KEY2': 'value2'}):
+ # env :code:`KEY1` will be set as None and :code:`KEY2` will
+ # be set as :code:`value2`.
+ """
+ if isinstance ( key , str ):
+ if value is None :
+ items = dict ()
+ else :
+ items : Dict [ str , str ] = { key : value }
+ else :
+ items : Dict [ str , str ] = key
+ original_items = dict ()
+ for k , v in items . items ():
+ original_items [ k ] = os . environ . get ( k , None )
+ if append and original_items [ k ] is not None :
+ os . environ [ k ] = original_items [ k ] + ':' + v
+ else :
+ os . environ [ k ] = v
+
+ yield os . environ
+
+ for k , v in original_items . items ():
+ if v is not None :
+ os . environ [ k ] = v
+ else :
+ del os . environ [ k ]
+
+
+def _init_global_context ():
+ import os as _dl_flags # pylint: disable=reimported
+
+ if sys . platform == 'linux' :
+ registry = os . path . join (
+ os . path . dirname ( __file__ ), 'libvineyard_internal_registry.so'
+ )
+ elif sys . platform == 'darwin' :
+ registry = os . path . join (
+ os . path . dirname ( __file__ ), 'libvineyard_internal_registry.dylib'
+ )
+ else :
+ raise RuntimeError ( "Unsupported platform: %s " % sys . platform )
+
+ ctx = { '__VINEYARD_INTERNAL_REGISTRY' : registry }
+
+ if os . environ . get ( 'VINEYARD_DEVELOP' , None ) is None :
+ with envvars ( ctx ): # n.b., no append
+ from . import _C
+ return
+
+ if not hasattr ( _dl_flags , 'RTLD_GLOBAL' ) or not hasattr ( _dl_flags , 'RTLD_LAZY' ):
+ try :
+ # next try if DLFCN exists
+ import DLFCN as _dl_flags # noqa: N811
+ except ImportError :
+ _dl_flags = None
+
+ if _dl_flags is not None :
+ old_flags = sys . getdlopenflags ()
+
+ # import the extension module
+ sys . setdlopenflags ( _dl_flags . RTLD_GLOBAL | _dl_flags . RTLD_LAZY )
+ with envvars ( ctx ): # n.b., no append
+ from . import _C # noqa: F811
+ # restore
+ sys . setdlopenflags ( old_flags )
+
+
+_init_global_context ()
+del _init_global_context
+
+
+from . import core
+from . import csi
+from . import data
+from . import deploy
+from . import io
+from . import launcher
+from . import shared_memory
+from ._C import ArrowErrorException
+from ._C import AssertionFailedException
+from ._C import Blob
+from ._C import BlobBuilder
+from ._C import ConnectionErrorException
+from ._C import ConnectionFailedException
+from ._C import EndOfFileException
+from ._C import EtcdErrorException
+from ._C import InstanceStatus
+from ._C import InvalidException
+from ._C import InvalidStreamStateException
+from ._C import IOErrorException
+from ._C import IPCClient
+from ._C import KeyErrorException
+from ._C import MetaTreeInvalidException
+from ._C import MetaTreeLinkInvalidException
+from ._C import MetaTreeNameInvalidException
+from ._C import MetaTreeNameNotExistsException
+from ._C import MetaTreeSubtreeNotExistsException
+from ._C import MetaTreeTypeInvalidException
+from ._C import MetaTreeTypeNotExistsException
+from ._C import NotEnoughMemoryException
+from ._C import NotImplementedException
+from ._C import Object
+from ._C import ObjectBuilder
+from ._C import ObjectExistsException
+from ._C import ObjectID
+from ._C import ObjectMeta
+from ._C import ObjectName
+from ._C import ObjectNotExistsException
+from ._C import ObjectNotSealedException
+from ._C import ObjectSealedException
+from ._C import RemoteBlob
+from ._C import RemoteBlobBuilder
+from ._C import RPCClient
+from ._C import StreamDrainedException
+from ._C import StreamFailedException
+from ._C import TypeErrorException
+from ._C import UnknownErrorException
+from ._C import UserInputErrorException
+from ._C import VineyardServerNotReadyException
+from ._C import _connect
+from ._C import memory_copy
+from .core import Client
+from .core import builder_context
+from .core import default_builder_context
+from .core import default_driver_context
+from .core import default_resolver_context
+from .core import driver_context
+from .core import resolver_context
+from .core.builder import BuilderContext
+from .core.resolver import ResolverContext
+from .data import register_builtin_types
+from .data.graph import Graph
+from .deploy.local import get_current_socket
+from .deploy.local import shutdown
+from .deploy.local import try_init
+
+
+def _init_vineyard_modules (): # noqa: C901
+ """Resolve registered vineyard modules in the following order:
+
+ * /etc/vineyard/config.py
+ * {sys.prefix}/etc/vineyard/config.py
+ * /usr/share/vineyard/01-xxx.py
+ * /usr/local/share/vineyard/01-xxx.py
+ * {sys.prefix}/share/vineyard/02-xxxx.py
+ * $HOME/.vineyard/03-xxxxx.py
+
+ Then import packages like vineyard.drivers.*:
+
+ * vineyard.drivers.io
+ """
+
+ import glob
+ import importlib.util
+ import pkgutil
+ import site
+ import sysconfig
+
+ def _import_module_from_file ( filepath ):
+ filepath = os . path . expanduser ( os . path . expandvars ( filepath ))
+ if os . path . exists ( filepath ):
+ try :
+ spec = importlib . util . spec_from_file_location (
+ "vineyard._contrib" , filepath
+ )
+ mod = importlib . util . module_from_spec ( spec )
+ spec . loader . exec_module ( mod )
+ except Exception : # pylint: disable=broad-except
+ logger . debug ( "Failed to load %s " , filepath , exc_info = True )
+
+ def _import_module_from_qualified_name ( module ):
+ try :
+ importlib . import_module ( module )
+ except Exception : # pylint: disable=broad-except
+ logger . debug ( 'Failed to load module %s ' , module , exc_info = True )
+
+ _import_module_from_file ( '/etc/vineyard/config.py' )
+ _import_module_from_file ( os . path . join ( sys . prefix , '/etc/vineyard/config.py' ))
+ for filepath in glob . glob ( '/usr/share/vineyard/*-*.py' ):
+ _import_module_from_file ( filepath )
+ for filepath in glob . glob ( '/usr/local/share/vineyard/*-*.py' ):
+ _import_module_from_file ( filepath )
+ for filepath in glob . glob ( os . path . join ( sys . prefix , '/share/vineyard/*-*.py' )):
+ _import_module_from_file ( filepath )
+ for filepath in glob . glob ( os . path . expanduser ( '$HOME/.vineyard/*-*.py' )):
+ _import_module_from_file ( filepath )
+
+ package_sites = set ()
+ pkg_sites = site . getsitepackages ()
+ if not isinstance ( pkg_sites , ( list , tuple )):
+ pkg_sites = [ pkg_sites ]
+ package_sites . update ( pkg_sites )
+ pkg_sites = site . getusersitepackages ()
+ if not isinstance ( pkg_sites , ( list , tuple )):
+ pkg_sites = [ pkg_sites ]
+ package_sites . update ( pkg_sites )
+
+ paths = sysconfig . get_paths ()
+ if 'purelib' in paths :
+ package_sites . add ( paths [ 'purelib' ])
+ if 'platlib' in paths :
+ package_sites . add ( paths [ 'purelib' ])
+
+ # add relative path
+ package_sites . add ( os . path . join ( os . path . dirname ( __file__ ), '..' ))
+
+ # dedup
+ deduped = set ()
+ for pkg_site in package_sites :
+ deduped . add ( os . path . abspath ( pkg_site ))
+
+ for pkg_site in deduped :
+ for _ , mod , _ in pkgutil . iter_modules (
+ [ os . path . join ( pkg_site , 'vineyard' , 'drivers' )]
+ ):
+ _import_module_from_qualified_name ( 'vineyard.drivers. %s ' % mod )
+
+
+try :
+ _init_vineyard_modules ()
+except Exception : # pylint: disable=broad-except
+ pass
+del _init_vineyard_modules
+
+
+[docs] def connect ( * args , ** kwargs ):
+
"""
+
Connect to vineyard by specified UNIX-domain socket or TCP endpoint.
+
+
If no arguments are provided and failed to resolve both the environment
+
variables :code:`VINEYARD_IPC_SOCKET`, :code:`VINEYARD_RPC_ENDPOINT`,
+
:code:`VINEYARD_CONFIG`, and the default configuration file
+
:code:`/var/run/vineyard-config.yaml` and
+
:code:`/var/run/vineyard/vineyard-config.yaml`, it will launch a standalone
+
vineyardd server in the background and then connect to it.
+
+
The `connect()` method has various overloading:
+
+
.. function:: connect(socket: str,
+
username: str = None,
+
password: str = None) -> IPCClient
+
:noindex:
+
+
Connect to vineyard via UNIX domain socket for IPC service:
+
+
.. code:: python
+
+
client = vineyard.connect('/var/run/vineyard.sock')
+
+
Parameters:
+
socket: str
+
UNIX domain socket path to setup an IPC connection.
+
username: str
+
Username to login, default to None.
+
password: str
+
Password to login, default to None.
+
+
Returns:
+
IPCClient: The connected IPC client.
+
+
.. function:: connect(host: str,
+
port: int or str,
+
username: str = None,
+
password: str = None) -> RPCClient
+
:noindex:
+
+
Connect to vineyard via TCP socket.
+
+
Parameters:
+
host: str
+
Hostname to connect to.
+
port: int or str
+
The TCP that listened by vineyard TCP service.
+
username: str
+
Username to login, default to None.
+
password: str
+
Password to login, default to None.
+
+
Returns:
+
RPCClient: The connected RPC client.
+
+
.. function:: connect(endpoint: (str, int or str),
+
username: str = None,
+
password: str = None) -> RPCClient
+
:noindex:
+
+
Connect to vineyard via TCP socket.
+
+
Parameters:
+
endpoint: tuple(str, int or str)
+
Endpoint to connect to. The parameter is a tuple, in which the first
+
element is the host, and the second parameter is the port (can be int
+
a str).
+
username: str
+
Username to login, default to None.
+
password: str
+
Password to login, default to None.
+
+
Returns:
+
RPCClient: The connected RPC client.
+
+
.. function:: connect(username: str = None,
+
password: str = None) -> IPCClient or RPCClient
+
:noindex:
+
+
Connect to vineyard via UNIX domain socket or TCP endpoint. This method normally
+
usually no arguments, and will first tries to resolve IPC socket from the
+
environment variable `VINEYARD_IPC_SOCKET` and connect to it. If it fails to
+
establish a connection with vineyard server, the method will tries to resolve
+
RPC endpoint from the environment variable `VINEYARD_RPC_ENDPOINT`. If both
+
tries are failed, this method will try to resolve the configuration file that
+
contains IPC socket and RPC endpoint from the environment variable
+
`VINEYARD_CONFIG`, and then connect to the vineyard server with the
+
resolved configuration.
+
+
If above all are failed, this method will raise a :class:`ConnectionFailed`
+
exception.
+
+
In rare cases, user may be not sure about if the IPC socket or RPC endpoint
+
is available, i.e., the variable might be :code:`None`. In such cases this
+
method can accept a `None` as arguments, and do resolution as described above.
+
+
Parameters:
+
username: str
+
Username to login, default to None.
+
password: str
+
Password to login, default to None.
+
+
Raises:
+
ConnectionFailed
+
"""
+
if (
+
not args
+
and not kwargs
+
and 'VINEYARD_IPC_SOCKET' not in os . environ
+
and 'VINEYARD_RPC_ENDPOINT' not in os . environ
+
and 'VINEYARD_CONFIG' not in os . environ
+
and not any (
+
os . path . exists ( path )
+
for path in [
+
"/var/run/vineyard-config.yaml" ,
+
"/var/run/vineyard/vineyard-config.yaml" ,
+
]
+
)
+
):
+
logger . info (
+
'No vineyard socket or endpoint is specified, '
+
'try to launch a standalone one.'
+
)
+
try_init ()
+
return Client ( * args , ** kwargs )
+
+
+def put (
+ value : Any ,
+ builder : Optional [ BuilderContext ] = None ,
+ persist : bool = False ,
+ name : Optional [ str ] = None ,
+ ** kwargs ,
+):
+ """
+ Connect the vineyard server by the following Environment Variables:
+
+ VINEYARD_IPC_SOCKET:
+ UNIX domain socket path to setup an IPC connection.
+ E.g. /var/run/vineyard.sock
+ VINEYARD_RPC_ENDPOINT:
+ TCP endpoint to setup an RPC connection.
+ E.g. 127.0.0.1:9600
+ VINEYARD_CONFIG:
+ Either be a path to a YAML configuration file or a path to a
+ directory containing the default config file `vineyard-config.yaml`.
+
+ The configuration file should be like:
+
+ .. code:: yaml
+
+ Vineyard:
+ IPCSocket: '/path/to/vineyard.sock'
+ RPCEndpoint: 'hostname1:port1,hostname2:port2,...'
+
+ Then put python value to vineyard.
+
+ .. code:: python
+
+ >>> os.environ['VINEYARD_IPC_SOCKET'] = '/var/run/vineyard.sock'
+ >>> arr = np.arange(8)
+ >>> arr_id = vineyard.put(arr)
+ >>> arr_id
+ 00002ec13bc81226
+
+ Parameters:
+ value:
+ The python value that will be put to vineyard. Supported python value
+ types are decided by modules that registered to vineyard. By default,
+ python value can be put to vineyard after serialized as a bytes buffer
+ using pickle.
+ builder: optional
+ When putting python value to vineyard, an optional *builder* can be
+ specified to tell vineyard how to construct the corresponding vineyard
+ :class:`Object`. If not specified, the default builder context will be
+ used to select a proper builder.
+ persist: bool, optional
+ If true, persist the object after creation.
+ name: str, optional
+ If given, the name will be automatically associated with the resulted
+ object. Note that only take effect when the object is persisted.
+ kw:
+ User-specific argument that will be passed to the builder.
+
+ Returns:
+ ObjectID: The result object id will be returned.
+ """
+
+ client = connect ()
+ return client . put ( value , builder , persist , name , ** kwargs )
+
+
+def get (
+ object_id : Optional [ ObjectID ] = None ,
+ name : Optional [ str ] = None ,
+ resolver : Optional [ ResolverContext ] = None ,
+ fetch : bool = False ,
+ ** kwargs ,
+):
+ """
+ Connect the vineyard server by the following Environment Variables:
+
+ VINEYARD_IPC_SOCKET:
+ UNIX domain socket path to setup an IPC connection.
+ E.g. /var/run/vineyard.sock
+ VINEYARD_RPC_ENDPOINT:
+ TCP endpoint to setup an RPC connection.
+ E.g. 127.0.0.1:9600
+ VINEYARD_CONFIG:
+ Either be a path to a YAML configuration file or a path to a
+ directory containing the default config file `vineyard-config.yaml`.
+
+ The configuration file should be like:
+
+ .. code:: yaml
+
+ Vineyard:
+ IPCSocket: '/path/to/vineyard.sock'
+ RPCEndpoint: 'hostname1:port1,hostname2:port2,...'
+
+ Then get vineyard object as python value.
+
+ .. code:: python
+
+ >>> os.environ['VINEYARD_IPC_SOCKET'] = '/var/run/vineyard.sock'
+ >>> arr_id = vineyard.ObjectID('00002ec13bc81226')
+ >>> arr = vineyard.get(arr_id)
+ >>> arr
+ array([0, 1, 2, 3, 4, 5, 6, 7])
+
+ Parameters:
+ object_id: ObjectID
+ The object id that will be obtained from vineyard.
+ name: ObjectID
+ The object name that will be obtained from vineyard, ignored if
+ ``object_id`` is not None.
+ resolver:
+ When retrieving vineyard object, an optional *resolver* can be specified.
+ If no resolver given, the default resolver context will be used.
+ fetch:
+ Whether to trigger a migration when the target object is located on
+ remote instances.
+ kw:
+ User-specific argument that will be passed to the builder.
+
+ Returns:
+ A python object that return by the resolver, by resolving an vineyard object.
+ """
+
+ client = connect ()
+ return client . get ( object_id , name , resolver , fetch , ** kwargs )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/core/builder.html b/_modules/vineyard/core/builder.html
new file mode 100644
index 0000000000..21715cc793
--- /dev/null
+++ b/_modules/vineyard/core/builder.html
@@ -0,0 +1,663 @@
+
+
+
+
+
+
+
+ vineyard.core.builder - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.core.builder
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import contextlib
+import copy
+import inspect
+import threading
+import warnings
+from typing import Any
+from typing import Callable
+from typing import Dict
+from typing import Generator
+from typing import Optional
+
+from vineyard._C import IPCClient
+from vineyard._C import Object
+from vineyard._C import ObjectID
+from vineyard._C import ObjectMeta
+from vineyard._C import RPCClient
+
+
+[docs] class BuilderContext :
+
def __init__ ( self , parent_context : Optional [ "BuilderContext" ] = None ):
+
self . _factory = dict ()
+
if parent_context is not None :
+
self . _parent_context = parent_context
+
else :
+
self . _parent_context = self
+
+
def __str__ ( self ) -> str :
+
return str ( self . _factory )
+
+
@property
+
def parent_context ( self ) -> "BuilderContext" :
+
return self . _parent_context
+
+
[docs] def register ( self , type_id : type , builder : Callable ):
+
"""Register a Python type to the builder context.
+
+
Parameters
+
----------
+
type_id: Python type
+
Like `int`, or `numpy.ndarray`
+
+
builder: callable, e.g., a method, callable object
+
A builder translates a python object to vineyard, it accepts a Python
+
value as parameter, and returns an vineyard object as result.
+
"""
+
self . _factory [ type_id ] = builder
+
+
[docs] def run ( self , client , value , ** kw ):
+
"""Follows the MRO to find the proper builder for given python value.
+
+
Here "Follows the MRO" implies:
+
+
- If the type of python value has been found in the context, the registered
+
builder will be used.
+
+
- If not, it follows the MRO chain from down to top to find a registered
+
Python type and used the associated builder.
+
+
- When the traversal reaches the :code:`object` type, since there's a default
+
builder that serialization the python value, the parameter will be serialized
+
and be put into a blob.
+
"""
+
+
# if the python value comes from a vineyard object, we choose to just reuse it.
+
+
# N.B.: don't do that.
+
#
+
# we still construct meta, and optimize the duplicate copy in blob builder
+
#
+
# base = getattr(value, '__vineyard_ref', None)
+
# if base:
+
# return base.meta
+
+
for ty in type ( value ) . __mro__ :
+
if ty in self . _factory :
+
builder_func_sig = inspect . getfullargspec ( self . _factory [ ty ])
+
if (
+
'builder' in builder_func_sig . args
+
or builder_func_sig . varkw is not None
+
):
+
kw [ 'builder' ] = self
+
return self . _factory [ ty ]( client , value , ** kw )
+
raise RuntimeError ( 'Unknown type to build as vineyard object' )
+
+
def __call__ ( self , client , value , ** kw ):
+
return self . run ( client , value , ** kw )
+
+
def extend ( self , builders = None ):
+
builder = BuilderContext ( self )
+
builder . _factory = copy . copy ( # pylint: disable=unused-private-member
+
self . _factory
+
)
+
if builders :
+
builder . _factory . update ( builders )
+
return builder
+
+
+default_builder_context = BuilderContext ()
+
+_builder_context_local = threading . local ()
+_builder_context_local . default_builder = default_builder_context
+
+
+[docs] def get_current_builders () -> BuilderContext :
+
'''Obtain the current builder context.'''
+
default_builder = getattr ( _builder_context_local , 'default_builder' , None )
+
if not default_builder :
+
default_builder = default_builder_context . extend ()
+
return default_builder
+
+
+[docs] @contextlib . contextmanager
+
def builder_context (
+
builders : Optional [ Dict [ type , Callable ]] = None ,
+
base : Optional [ BuilderContext ] = None ,
+
) -> Generator [ BuilderContext , Any , Any ]:
+
"""Open a new context for register builders, without populating outside global
+
environment.
+
+
See Also:
+
resolver_context
+
driver_context
+
"""
+
current_builder = get_current_builders ()
+
try :
+
builders = builders or dict ()
+
base = base or current_builder
+
local_builder = base . extend ( builders )
+
_builder_context_local . default_builder = local_builder
+
yield local_builder
+
finally :
+
_builder_context_local . default_builder = current_builder
+
+
+def put (
+ client ,
+ value : Any ,
+ builder : Optional [ BuilderContext ] = None ,
+ persist : bool = False ,
+ name : Optional [ str ] = None ,
+ ** kwargs
+):
+ """Put python value to vineyard.
+
+ .. code:: python
+
+ >>> arr = np.arange(8)
+ >>> arr_id = client.put(arr)
+ >>> arr_id
+ 00002ec13bc81226
+
+ Parameters:
+ client: IPCClient or RPCClient
+ The vineyard client to use.
+ value:
+ The python value that will be put to vineyard. Supported python value
+ types are decided by modules that registered to vineyard. By default,
+ python value can be put to vineyard after serialized as a bytes buffer
+ using pickle.
+ builder: optional
+ When putting python value to vineyard, an optional *builder* can be
+ specified to tell vineyard how to construct the corresponding vineyard
+ :class:`Object`. If not specified, the default builder context will be
+ used to select a proper builder.
+ persist: bool, optional
+ If true, persist the object after creation.
+ name: str, optional
+ If given, the name will be automatically associated with the resulted
+ object. Note that only take effect when the object is persisted.
+ kw:
+ User-specific argument that will be passed to the builder.
+
+ Returns:
+ ObjectID: The result object id will be returned.
+ """
+ if builder is not None :
+ return builder ( client , value , ** kwargs )
+
+ meta = get_current_builders () . run ( client , value , ** kwargs )
+
+ # the builders is expected to return an :class:`ObjectMeta`, or an
+ # :class:`Object` (in the `bytes_builder` and `memoryview` builder).
+ if isinstance ( meta , ( ObjectMeta , Object )):
+ r = meta . id
+ else :
+ r = meta # None or ObjectID
+
+ if isinstance ( r , ObjectID ):
+ if persist :
+ client . persist ( r )
+ if name is not None :
+ if persist :
+ client . put_name ( r , name )
+ else :
+ warnings . warn (
+ "The object is not persisted, the name won't be associated." ,
+ UserWarning ,
+ )
+ return r
+
+
+setattr ( IPCClient , 'put' , put )
+setattr ( RPCClient , 'put' , put )
+
+__all__ = [
+ 'default_builder_context' ,
+ 'builder_context' ,
+ 'get_current_builders' ,
+]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/core/client.html b/_modules/vineyard/core/client.html
new file mode 100644
index 0000000000..08fc3b06e3
--- /dev/null
+++ b/_modules/vineyard/core/client.html
@@ -0,0 +1,1265 @@
+
+
+
+
+
+
+
+ vineyard.core.client - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.core.client
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import contextlib
+import os
+import warnings
+from concurrent.futures import ThreadPoolExecutor
+from concurrent.futures import as_completed
+from typing import Any
+from typing import Dict
+from typing import List
+from typing import Optional
+from typing import Tuple
+from typing import Union
+
+from vineyard import envvars
+from vineyard._C import Blob
+from vineyard._C import BlobBuilder
+from vineyard._C import IPCClient
+from vineyard._C import NotEnoughMemoryException
+from vineyard._C import Object
+from vineyard._C import ObjectID
+from vineyard._C import ObjectMeta
+from vineyard._C import RemoteBlob
+from vineyard._C import RemoteBlobBuilder
+from vineyard._C import RPCClient
+from vineyard._C import VineyardException
+from vineyard._C import _connect
+from vineyard.core.builder import BuilderContext
+from vineyard.core.builder import put
+from vineyard.core.resolver import ResolverContext
+from vineyard.core.resolver import get
+
+
+def _apply_docstring ( func ):
+ def _apply ( fn ):
+ fn . __doc__ = func . __doc__
+ return fn
+
+ return _apply
+
+
+def _parse_configuration ( config ) -> Tuple [ Optional [ str ], Optional [ str ]]:
+ '''Parse vineyard IPC socket and RPC endpoints from configuration.
+
+ Parameters:
+ config: Path to a YAML configuration file or a directory containing
+ the default config file `vineyard-config.yaml`. If you define
+ the directory of vineyard config, the
+ `/directory/vineyard-config.yaml` and
+ `/directory/vineyard/vineyard-config.yaml` will be parsed.
+
+ Returns:
+ (socket, endpoints): IPC socket path and RPC endpoints.
+ '''
+ if not config :
+ return None , None
+
+ try :
+ import yaml # pylint: disable=import-outside-toplevel
+ except ImportError :
+ return None , None
+
+ if os . path . isdir ( config ):
+ config_options = [ 'vineyard-config.yaml' , 'vineyard/vineyard-config.yaml' ]
+ for config_option in config_options :
+ config_path = os . path . join ( config , config_option )
+ if os . path . isfile ( config_path ):
+ config = config_path
+ break
+ if not os . path . isfile ( config ):
+ return None , None
+
+ try :
+ with open ( config , 'r' , encoding = 'utf-8' ) as f :
+ vineyard_config = yaml . safe_load ( f ) . get ( 'Vineyard' , {})
+ except : # noqa: E722, pylint: disable=bare-except
+ return None , None
+
+ ipc_socket = vineyard_config . get ( 'IPCSocket' , None )
+ rpc_endpoint = vineyard_config . get ( 'RPCEndpoint' , None )
+
+ if ipc_socket :
+ if not os . path . isabs ( ipc_socket ):
+ base_dir = os . path . dirname ( config ) if os . path . isfile ( config ) else config
+ ipc_socket = os . path . join ( base_dir , ipc_socket )
+
+ if not os . path . exists ( ipc_socket ):
+ ipc_socket = None
+
+ return ipc_socket , rpc_endpoint
+
+
+def _is_blob ( object_id : ObjectID ):
+ """_is_blob_
+
+ Args:
+ object_id (ObjectID): ObjectID to check if it is a blob
+
+ Returns:
+ bool: True if the object_id is a blob, False otherwise
+ """
+ return int ( object_id ) & 0x8000000000000000
+
+
+def _traverse_blobs ( meta : ObjectMeta , blobs = None ):
+ """_traverse_blobs_
+
+ Recursively traverses ObjectMeta to find and accumulate blob IDs by instance_id.
+
+ Args:
+ meta (ObjectMeta): ObjectMeta to traverse for blobs.
+ blobs (dict, optional): Accumulator for blobs organized by instance_id.
+
+ Returns:
+ dict: A dictionary of blobs organized by instance_id.
+ """
+
+ if blobs is None :
+ blobs = {}
+
+ def add_blob ( instance_id , blob_id ):
+ if instance_id not in blobs :
+ blobs [ instance_id ] = []
+ blobs [ instance_id ] . append ( blob_id )
+
+ if _is_blob ( meta . id ):
+ add_blob ( meta . instance_id , meta . id )
+ else :
+ for _ , v in meta . items ():
+ if isinstance ( v , ObjectMeta ):
+ if _is_blob ( v . id ):
+ add_blob ( v . instance_id , v . id )
+ else :
+ _traverse_blobs ( v , blobs )
+
+ return blobs
+
+
+[docs] class Client :
+
"""Client is responsible for managing IPC and RPC clients for Vineyard
+
and provides a high-level interface to fetch objects from the Vineyard cluster.
+
"""
+
+
def __init__ (
+
self ,
+
socket : str = None ,
+
port : Union [ int , str ] = None ,
+
# move host after port to make sure unnamed (host, port) works
+
host : str = None ,
+
endpoint : Tuple [ str , Union [ str , int ]] = None ,
+
session : int = None ,
+
username : str = None ,
+
password : str = None ,
+
config : str = None ,
+
):
+
"""Connects to the vineyard IPC socket and RPC socket.
+
+
- For the IPC Client, the argument `socket` takes precedence over the
+
environment variable `VINEYARD_IPC_SOCKET`, which in turn takes precedence
+
over the `IPCSocket` field in the config file."
+
- For the RPC Client, the argument `endpoint` takes precedence over the
+
argument `host` and `port`, which in turn takes precedence over the
+
environment variable `VINEYARD_RPC_ENDPOINT`, which further takes precedence
+
over the `RPCEndpoint` field in the config file.
+
+
The `connect()` API can be used in following ways:
+
+
- `connect()` without any arguments, which will try to connect to the vineyard
+
by resolving endpoints from the environment variables.
+
- `connect('/path/to/vineyard.sock')`, which will try to establish an IPC
+
connection.
+
- `connect('hostname:port')`, which will try to establish an RPC connection.
+
- `connect('hostname', port)`, which will try to establish an RPC connection.
+
- `connect(endpoint=('hostname', port))`, which will try to establish an RPC
+
connection.
+
- `connect(config='/path/to/vineyard-config.yaml')`, which will try to
+
resolve the IPC socket and RPC endpoints from the configuration file.
+
+
Parameters:
+
socket: Optional, the path to the IPC socket, or RPC endpoints of format
+
`host:port`.
+
port: Optional, the port of the RPC endpoint.
+
host: Optional, the host of the RPC endpoint.
+
endpoint: Optional, the RPC endpoint of format `host:port`.
+
session: Optional, the session id to connect.
+
username: Optional, the required username of vineyardd when authentication
+
is enabled.
+
password: Optional, the required password of vineyardd when authentication
+
is enabled.
+
config: Optional, can either be a path to a YAML configuration file or
+
a path to a directory containing the default config file
+
`vineyard-config.yaml`. Also, the environment variable
+
`VINEYARD_CONFIG` can be used to specify the
+
path to the configuration file. If not defined, the default
+
config file `/var/run/vineyard-config.yaml` or
+
`/var/run/vineyard/vineyard-config.yaml`
+
+
The content of the configuration file should has the following content:
+
+
.. code:: yaml
+
+
Vineyard:
+
IPCSocket: '/path/to/vineyard.sock'
+
RPCEndpoint: 'hostname1:port1,hostname2:port2,...'
+
"""
+
self . _ipc_client : IPCClient = None
+
self . _rpc_client : RPCClient = None
+
+
kwargs = {}
+
if session is not None :
+
kwargs [ 'session' ] = session
+
if username is not None :
+
kwargs [ 'username' ] = username
+
if password is not None :
+
kwargs [ 'password' ] = password
+
+
if socket is not None and port is not None and host is None :
+
socket , host = None , socket
+
+
hosts , ports = [], []
+
if not socket :
+
socket = os . getenv ( 'VINEYARD_IPC_SOCKET' , None )
+
if not endpoint and not ( host and port ):
+
endpoint = os . getenv ( 'VINEYARD_RPC_ENDPOINT' , None )
+
if not config :
+
config = os . getenv ( 'VINEYARD_CONFIG' , '/var/run' )
+
if endpoint :
+
if not isinstance ( endpoint , ( tuple , list )):
+
for ep in endpoint . split ( ',' ):
+
h , p = [ e . strip () for e in ep . split ( ':' )]
+
hosts . append ( h )
+
ports . append ( p )
+
else :
+
h , p = endpoint
+
hosts = [ h ]
+
ports = [ p ]
+
+
if host and port :
+
hosts . append ( host )
+
ports . append ( port )
+
+
if config and (( not socket ) or ( not ( hosts and ports ))):
+
ipc_socket , rpc_endpoint = _parse_configuration ( config )
+
if ipc_socket and not socket :
+
socket = ipc_socket
+
if rpc_endpoint and not ( hosts and ports ):
+
for ep in rpc_endpoint . split ( ',' ):
+
h , p = [ e . strip () for e in ep . split ( ':' )]
+
hosts . append ( h )
+
ports . append ( p )
+
+
if socket :
+
self . _ipc_client = _connect ( socket , ** kwargs )
+
for host , port in zip ( hosts , ports ):
+
try :
+
self . _rpc_client = _connect ( host , port , ** kwargs )
+
break
+
except VineyardException :
+
continue
+
+
self . _spread = False
+
self . _compression = True
+
if self . _ipc_client is None and self . _rpc_client is None :
+
raise ConnectionError (
+
"Failed to connect to vineyard via both IPC and RPC connection. "
+
"Arguments, environment variables `VINEYARD_IPC_SOCKET` "
+
"and `VINEYARD_RPC_ENDPOINT`, as well as the configuration file, "
+
"are all unavailable."
+
)
+
+
@property
+
def compression ( self ) -> bool :
+
'''Whether the compression is enabled for underlying RPC client.'''
+
if self . _rpc_client :
+
return self . _rpc_client . compression
+
return self . _compression
+
+
@compression . setter
+
def compression ( self , value : bool = True ):
+
if self . _rpc_client :
+
self . _rpc_client . compression = value
+
self . _compression = value
+
+
@property
+
def spread ( self ) -> bool :
+
'''Whether the spread is enabled for underlying RPC client.'''
+
return self . _spread
+
+
@spread . setter
+
def spread ( self , value : bool = False ):
+
self . _spread = value
+
+
@property
+
def ipc_client ( self ) -> IPCClient :
+
assert self . _ipc_client is not None , "IPC client is not available."
+
return self . _ipc_client
+
+
@property
+
def rpc_client ( self ) -> RPCClient :
+
assert self . _rpc_client is not None , "RPC client is not available."
+
return self . _rpc_client
+
+
def has_ipc_client ( self ):
+
return self . _ipc_client is not None
+
+
def has_rpc_client ( self ):
+
return self . _rpc_client is not None
+
+
def default_client ( self ) -> Union [ IPCClient , RPCClient ]:
+
return self . _ipc_client if self . _ipc_client else self . _rpc_client
+
+
# The following functions are wrappers of the corresponding functions in the
+
# ClientBase class.
+
+
+
+
[docs] @_apply_docstring ( IPCClient . delete )
+
def delete (
+
self ,
+
object : Union [ ObjectID , Object , ObjectMeta , List [ ObjectID ]],
+
force : bool = False ,
+
deep : bool = True ,
+
memory_trim : bool = False ,
+
) -> None :
+
return self . default_client () . delete ( object , force , deep , memory_trim )
+
+
@_apply_docstring ( IPCClient . create_stream )
+
def create_stream ( self , id : ObjectID ) -> None :
+
return self . default_client () . create_stream ( id )
+
+
@_apply_docstring ( IPCClient . open_stream )
+
def open_stream ( self , id : ObjectID , mode : str ) -> None :
+
return self . default_client () . open_stream ( id , mode )
+
+
@_apply_docstring ( IPCClient . push_chunk )
+
def push_chunk ( self , stream_id : ObjectID , chunk : ObjectID ) -> None :
+
return self . default_client () . push_chunk ( stream_id , chunk )
+
+
@_apply_docstring ( IPCClient . next_chunk_id )
+
def next_chunk_id ( self , stream_id : ObjectID ) -> ObjectID :
+
return self . default_client () . next_chunk_id ( stream_id )
+
+
@_apply_docstring ( IPCClient . next_chunk_meta )
+
def next_chunk_meta ( self , stream_id : ObjectID ) -> ObjectMeta :
+
return self . default_client () . next_chunk_meta ( stream_id )
+
+
@_apply_docstring ( IPCClient . next_chunk )
+
def next_chunk ( self , stream_id : ObjectID ) -> Object :
+
return self . default_client () . next_chunk ( stream_id )
+
+
@_apply_docstring ( IPCClient . stop_stream )
+
def stop_stream ( self , stream_id : ObjectID , failed : bool ) -> None :
+
return self . default_client () . stop_stream ( stream_id , failed )
+
+
@_apply_docstring ( IPCClient . drop_stream )
+
def drop_stream ( self , stream_id : ObjectID ) -> None :
+
return self . default_client () . drop_stream ( stream_id )
+
+
[docs] @_apply_docstring ( IPCClient . persist )
+
def persist ( self , object : Union [ ObjectID , Object , ObjectMeta ]) -> None :
+
return self . default_client () . persist ( object )
+
+
[docs] @_apply_docstring ( IPCClient . exists )
+
def exists ( self , object : ObjectID ) -> bool :
+
return self . default_client () . exists ( object )
+
+
[docs] @_apply_docstring ( IPCClient . shallow_copy )
+
def shallow_copy (
+
self , object_id : ObjectID , extra_metadata : dict = None
+
) -> ObjectID :
+
if extra_metadata :
+
return self . default_client () . shallow_copy ( object_id , extra_metadata )
+
return self . default_client () . shallow_copy ( object_id )
+
+
[docs] @_apply_docstring ( IPCClient . list_names )
+
def list_names (
+
self , pattern : str , regex : bool = False , limit : int = 5
+
) -> List [ str ]:
+
return self . default_client () . list_names ( pattern , regex , limit )
+
+
[docs] @_apply_docstring ( IPCClient . put_name )
+
def put_name ( self , object : Union [ Object , ObjectMeta , ObjectID ], name : str ) -> None :
+
return self . default_client () . put_name ( object , name )
+
+
[docs] @_apply_docstring ( IPCClient . get_name )
+
def get_name ( self , name : str , wait : bool = False ) -> ObjectID :
+
return self . default_client () . get_name ( name , wait )
+
+
[docs] @_apply_docstring ( IPCClient . drop_name )
+
def drop_name ( self , name : str ) -> None :
+
return self . default_client () . drop_name ( name )
+
+
+
+
@_apply_docstring ( IPCClient . migrate )
+
def migrate ( self , object_id : ObjectID ) -> ObjectID :
+
return self . default_client () . migrate ( object_id )
+
+
[docs] @_apply_docstring ( IPCClient . clear )
+
def clear ( self ) -> None :
+
return self . default_client () . clear ()
+
+
[docs] @_apply_docstring ( IPCClient . memory_trim )
+
def memory_trim ( self ) -> bool :
+
return self . default_client () . memory_trim ()
+
+
@_apply_docstring ( IPCClient . label )
+
def label (
+
self ,
+
object_id : ObjectID ,
+
key_or_labels : Union [ str , Dict [ str , str ]],
+
value : str = None ,
+
) -> None :
+
if isinstance ( key_or_labels , dict ) and value is None :
+
return self . default_client () . label ( object_id , key_or_labels )
+
else :
+
return self . default_client () . label ( object_id , key_or_labels , value )
+
+
@_apply_docstring ( IPCClient . evict )
+
def evict ( self , objects : List [ ObjectID ]) -> None :
+
return self . default_client () . evict ( objects )
+
+
@_apply_docstring ( IPCClient . load )
+
def load ( self , objects : List [ ObjectID ], pin : bool = False ) -> None :
+
return self . default_client () . load ( objects , pin )
+
+
@_apply_docstring ( IPCClient . unpin )
+
def unpin ( self , objects : List [ ObjectID ]) -> None :
+
return self . default_client () . unpin ( objects )
+
+
[docs] @_apply_docstring ( IPCClient . reset )
+
def reset ( self ) -> None :
+
if self . _ipc_client :
+
self . _ipc_client . reset ()
+
if self . _rpc_client :
+
self . _rpc_client . reset ()
+
+
@property
+
@_apply_docstring ( IPCClient . connected )
+
def connected ( self ):
+
return self . default_client () . connected
+
+
@property
+
@_apply_docstring ( IPCClient . instance_id )
+
def instance_id ( self ):
+
return self . default_client () . instance_id
+
+
@property
+
@_apply_docstring ( IPCClient . meta )
+
def meta ( self ):
+
return self . default_client () . meta
+
+
@property
+
@_apply_docstring ( IPCClient . status )
+
def status ( self ):
+
return self . default_client () . status
+
+
@_apply_docstring ( IPCClient . debug )
+
def debug ( self , debug : dict ):
+
return self . default_client () . debug ( debug )
+
+
@property
+
@_apply_docstring ( IPCClient . ipc_socket )
+
def ipc_socket ( self ):
+
return self . default_client () . ipc_socket
+
+
@property
+
@_apply_docstring ( IPCClient . rpc_endpoint )
+
def rpc_endpoint ( self ):
+
if self . _rpc_client :
+
return self . _rpc_client . rpc_endpoint
+
return self . default_client () . rpc_endpoint
+
+
@property
+
@_apply_docstring ( IPCClient . is_ipc )
+
def is_ipc ( self ):
+
return self . default_client () . is_ipc
+
+
@property
+
@_apply_docstring ( IPCClient . is_rpc )
+
def is_rpc ( self ):
+
return self . default_client () . is_rpc
+
+
@property
+
@_apply_docstring ( IPCClient . version )
+
def version ( self ):
+
return self . default_client () . version
+
+
# The following functions are wrappers of the corresponding functions in the
+
# IPCClient and RPCClient classes.
+
+
[docs] @_apply_docstring ( IPCClient . create_blob )
+
def create_blob (
+
self , size : Union [ int , List [ int ]]
+
) -> Union [ BlobBuilder , List [ BlobBuilder ]]:
+
return self . ipc_client . create_blob ( size )
+
+
[docs] @_apply_docstring ( IPCClient . create_empty_blob )
+
def create_empty_blob ( self ) -> BlobBuilder :
+
return self . ipc_client . create_empty_blob ()
+
+
[docs] @_apply_docstring ( IPCClient . get_blob )
+
def get_blob ( self , object_id : ObjectID , unsafe : bool = False ) -> Blob :
+
return self . ipc_client . get_blob ( object_id , unsafe )
+
+
[docs] @_apply_docstring ( IPCClient . get_blobs )
+
def get_blobs ( self , object_ids : List [ ObjectID ], unsafe : bool = False ) -> List [ Blob ]:
+
return self . ipc_client . get_blobs ( object_ids , unsafe )
+
+
[docs] @_apply_docstring ( RPCClient . create_remote_blob )
+
def create_remote_blob (
+
self , blob_builder : Union [ RemoteBlobBuilder , List [ RemoteBlobBuilder ]]
+
) -> Union [ ObjectMeta , List [ ObjectMeta ]]:
+
return self . rpc_client . create_remote_blob ( blob_builder )
+
+
[docs] @_apply_docstring ( RPCClient . get_remote_blob )
+
def get_remote_blob ( self , object_id : ObjectID , unsafe : bool = False ) -> RemoteBlob :
+
return self . rpc_client . get_remote_blob ( object_id , unsafe )
+
+
[docs] @_apply_docstring ( RPCClient . get_remote_blobs )
+
def get_remote_blobs (
+
self , object_ids : List [ ObjectID ], unsafe : bool = False
+
) -> List [ RemoteBlob ]:
+
return self . rpc_client . get_remote_blobs ( object_ids , unsafe )
+
+
[docs] @_apply_docstring ( IPCClient . get_object )
+
def get_object (
+
self , object_id : ObjectID , sync_remote : bool = True , fetch : bool = False
+
) -> Object :
+
"""
+
Fetches the object associated with the given object_id from Vineyard.
+
The IPC client is preferred if it's available, otherwise the RPC client
+
"""
+
return self . _fetch_object (
+
object_id , sync_remote = sync_remote , enable_migrate = fetch
+
)
+
+
[docs] @_apply_docstring ( IPCClient . get_objects )
+
def get_objects (
+
self , object_ids : List [ ObjectID ], sync_remote : bool = True
+
) -> List [ Object ]:
+
objects = []
+
for object_id in object_ids :
+
objects . append ( self . get_object ( object_id , sync_remote ))
+
return objects
+
+
+
+
+
+
[docs] @_apply_docstring ( IPCClient . list_objects )
+
def list_objects (
+
self , pattern : str , regex : bool = False , limit : int = 5
+
) -> List [ ObjectID ]:
+
return self . default_client () . list_objects ( pattern , regex , limit )
+
+
+
+
@_apply_docstring ( IPCClient . new_buffer_chunk )
+
def new_buffer_chunk ( self , stream : ObjectID , size : int ) -> memoryview :
+
return self . ipc_client . new_buffer_chunk ( stream , size )
+
+
@_apply_docstring ( IPCClient . next_buffer_chunk )
+
def next_buffer_chunk ( self , stream : ObjectID ) -> memoryview :
+
return self . ipc_client . next_buffer_chunk ( stream )
+
+
[docs] @_apply_docstring ( IPCClient . allocated_size )
+
def allocated_size ( self , object_id : Union [ Object , ObjectID ]) -> int :
+
return self . ipc_client . allocated_size ( object_id )
+
+
[docs] @_apply_docstring ( IPCClient . is_shared_memory )
+
def is_shared_memory ( self , pointer : int ) -> bool :
+
return self . ipc_client . is_shared_memory ( pointer )
+
+
[docs] @_apply_docstring ( IPCClient . find_shared_memory )
+
def find_shared_memory ( self , pointer : int ) -> ObjectID :
+
return self . ipc_client . find_shared_memory ( pointer )
+
+
@property
+
@_apply_docstring ( RPCClient . remote_instance_id )
+
def remote_instance_id ( self ) -> int :
+
return self . rpc_client . remote_instance_id
+
+
[docs] @_apply_docstring ( IPCClient . close )
+
def close ( self ) -> None :
+
if self . _ipc_client :
+
self . _ipc_client . close ()
+
if self . _rpc_client :
+
self . _rpc_client . close ()
+
+
@_apply_docstring ( IPCClient . fork )
+
def fork ( self ) -> 'Client' :
+
if self . _ipc_client :
+
self . _ipc_client = self . _ipc_client . fork ()
+
if self . _rpc_client :
+
self . _rpc_client = self . _rpc_client . fork ()
+
return self
+
+
def _fetch_object (
+
self , object_id : ObjectID , enable_migrate : bool , sync_remote : bool = True
+
) -> Object :
+
meta = self . get_meta ( object_id , sync_remote = sync_remote )
+
+
if self . has_ipc_client () and enable_migrate :
+
# no need to sync remote metadata as the metadata is already fetched
+
return self . _ipc_client . get_object ( object_id , fetch = True , sync_remote = False )
+
+
blobs = _traverse_blobs ( meta )
+
+
# If the object is local, return it directly
+
if blobs . keys () == { self . instance_id }:
+
return Object . from_ ( meta )
+
+
cluster_info = self . default_client () . meta
+
meta . force_local ()
+
meta . _client = None
+
+
with ThreadPoolExecutor () as executor :
+
futures = {
+
executor . submit (
+
self . _fetch_blobs_from_instance ,
+
cluster_info ,
+
instance_id ,
+
blobs [ instance_id ],
+
self . compression ,
+
)
+
for instance_id in blobs
+
if instance_id != self . instance_id
+
}
+
+
for future in as_completed ( futures ):
+
fetched_blobs = future . result ()
+
for blob in fetched_blobs :
+
meta . add_remote_blob ( blob )
+
+
return Object . from_ ( meta )
+
+
def _fetch_blobs_from_instance (
+
self , cluster_info , instance_id , blob_ids , compression
+
) -> Object :
+
"""Fetches all blobs from a given instance id in the Vineyard cluster.
+
+
Args:
+
cluster_info (Dict): The cluster information of the Vineyard cluster.
+
instance_id (int): The instance id to fetch blobs from.
+
blob_ids (List): The list of blob ids to fetch.
+
compression (bool): Whether to enable compression for RPC Client.
+
+
Returns:
+
RemoteBlob(List): The list of fetched remote blobs.
+
"""
+
instance_status = cluster_info . get ( instance_id )
+
+
if instance_status is None or instance_status [ 'rpc_endpoint' ] is None :
+
raise RuntimeError (
+
"The rpc endpoint of the vineyard instance "
+
f " { instance_id } is not available."
+
)
+
+
if self . has_rpc_client () and self . remote_instance_id == instance_id :
+
remote_client = self . _rpc_client
+
else :
+
host , port = instance_status [ 'rpc_endpoint' ] . split ( ':' )
+
try :
+
with envvars ( 'VINEYARD_RPC_SKIP_RETRY' , '1' ):
+
remote_client = _connect ( host , port )
+
remote_client . compression = compression
+
except Exception as exec :
+
raise RuntimeError (
+
f "Failed to connect to the vineyard instance { instance_id } "
+
f "at { host } : { port } ."
+
) from exec
+
+
return remote_client . get_remote_blobs ( blob_ids )
+
+
def _connect_and_get_memory ( self , instance_id , rpc_endpoint ):
+
host , port = rpc_endpoint . split ( ':' )
+
try :
+
new_client = _connect ( host , port )
+
current_available_memory = (
+
new_client . status . memory_limit - new_client . status . memory_usage
+
)
+
return instance_id , current_available_memory
+
except Exception :
+
return instance_id , float ( '-inf' )
+
+
def _find_the_most_available_memory_instance ( self ) -> int :
+
"""
+
Find the vineyard instance with the most available memory.
+
+
Returns:
+
int: The instance id with the most available memory.
+
if only have one instance, return -1
+
"""
+
futures = []
+
cluster_info = self . default_client () . meta
+
with ThreadPoolExecutor () as executor :
+
for instance_id , status in cluster_info . items ():
+
if not (
+
status [ 'ipc_socket' ] == self . ipc_socket
+
and status [ 'rpc_endpoint' ] == self . rpc_endpoint
+
):
+
futures . append (
+
executor . submit (
+
self . _connect_and_get_memory ,
+
instance_id ,
+
status [ 'rpc_endpoint' ],
+
)
+
)
+
+
instance_id_with_most_available_memory = - 1
+
available_memory = float ( '-inf' )
+
+
for future in as_completed ( futures ):
+
instance_id , current_available_memory = future . result ()
+
if current_available_memory > available_memory :
+
instance_id_with_most_available_memory = instance_id
+
available_memory = current_available_memory
+
+
return instance_id_with_most_available_memory
+
+
[docs] @_apply_docstring ( get )
+
def get (
+
self ,
+
object_id : Optional [ ObjectID ] = None ,
+
name : Optional [ str ] = None ,
+
resolver : Optional [ ResolverContext ] = None ,
+
fetch : bool = False ,
+
** kwargs ,
+
):
+
return get ( self , object_id , name , resolver , fetch , ** kwargs )
+
+
[docs] @_apply_docstring ( put )
+
def put (
+
self ,
+
value : Any ,
+
builder : Optional [ BuilderContext ] = None ,
+
persist : bool = False ,
+
name : Optional [ str ] = None ,
+
** kwargs ,
+
):
+
try :
+
return put ( self , value , builder , persist , name , ** kwargs )
+
except NotEnoughMemoryException as exec :
+
with envvars (
+
{ 'VINEYARD_RPC_SKIP_RETRY' : '1' , 'VINEYARD_IPC_SKIP_RETRY' : '1' }
+
):
+
instance_id = self . _find_the_most_available_memory_instance ()
+
previous_compression_state = self . compression
+
if instance_id == - 1 :
+
warnings . warn ( "No other vineyard instance available" )
+
raise exec
+
else :
+
meta = self . default_client () . meta
+
warnings . warn (
+
f "Put object to the vineyard instance { instance_id } "
+
"with the most available memory."
+
)
+
# connect to the instance with the most available memory
+
self . _ipc_client = None
+
if os . path . exists ( meta [ instance_id ][ 'ipc_socket' ]):
+
self . _ipc_client = _connect ( meta [ instance_id ][ 'ipc_socket' ])
+
# avoid the case the vineyard instance is restarted
+
if self . _ipc_client . instance_id != instance_id :
+
self . _ipc_client = None
+
host , port = meta [ instance_id ][ 'rpc_endpoint' ] . split ( ':' )
+
self . _rpc_client = _connect ( host , port )
+
self . compression = previous_compression_state
+
return put ( self , value , builder , persist , name , ** kwargs )
+
+
[docs] @contextlib . contextmanager
+
def with_compression ( self , enabled : bool = True ):
+
"""Disable compression for the following put operations."""
+
compression = self . compression
+
self . compression = enabled
+
yield
+
self . compression = compression
+
+
[docs] @contextlib . contextmanager
+
def with_spread ( self , enabled : bool = True ):
+
"""Enable spread for the following put operations."""
+
tmp_spread = self . _spread
+
self . spread = enabled
+
yield
+
self . spread = tmp_spread
+
+
+__all__ = [ 'Client' ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/core/driver.html b/_modules/vineyard/core/driver.html
new file mode 100644
index 0000000000..f452a0ae05
--- /dev/null
+++ b/_modules/vineyard/core/driver.html
@@ -0,0 +1,603 @@
+
+
+
+
+
+
+
+ vineyard.core.driver - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.core.driver
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import contextlib
+import copy
+import functools
+import threading
+
+from sortedcontainers import SortedDict
+
+from vineyard.core.utils import find_most_precise_match
+
+
+[docs] class DriverContext :
+
def __init__ ( self ):
+
self . _factory = SortedDict ( dict )
+
+
def __str__ ( self ) -> str :
+
return str ( self . _factory )
+
+
def register ( self , typename_prefix , meth , func ):
+
if typename_prefix not in self . _factory :
+
self . _factory [ typename_prefix ] = dict ()
+
self . _factory [ typename_prefix ][ meth ] = func
+
+
def resolve ( self , obj , typename ):
+
prefix , methods = find_most_precise_match ( typename , self . _factory )
+
if prefix :
+
for meth , func in methods . items ():
+
# if shouldn't failed, since it has already been wrapped in during
+
# resolving
+
setattr ( obj , meth , functools . partial ( func , obj ))
+
return obj
+
+
def __call__ ( self , obj , typename ):
+
return self . resolve ( obj , typename )
+
+
def extend ( self , drivers = None ):
+
driver = DriverContext ()
+
driver . _factory . update ((( k , copy . copy ( v )) for k , v in self . _factory . items ()))
+
if drivers :
+
for ty , methods in drivers . items ():
+
if ty not in self . _factory :
+
driver . _factory [ ty ] = dict ()
+
driver . _factory [ ty ] . update ( methods )
+
return driver
+
+
+default_driver_context = DriverContext ()
+
+_driver_context_local = threading . local ()
+_driver_context_local . default_driver = default_driver_context
+
+
+[docs] def get_current_drivers ():
+
'''Obtain current driver context.'''
+
default_driver = getattr ( _driver_context_local , 'default_driver' , None )
+
if not default_driver :
+
default_driver = default_driver_context . extend ()
+
return default_driver
+
+
+[docs] @contextlib . contextmanager
+
def driver_context ( drivers = None , base = None ):
+
"""Open a new context for register drivers, without populting outside global
+
environment.
+
+
See Also:
+
builder_context
+
resolver_context
+
"""
+
current_driver = get_current_drivers ()
+
try :
+
drivers = drivers or dict ()
+
base = base or current_driver
+
local_driver = base . extend ( drivers )
+
_driver_context_local . default_driver = local_driver
+
yield local_driver
+
finally :
+
_driver_context_local . default_driver = current_driver
+
+
+def register_builtin_drivers ( ctx ):
+ assert isinstance ( ctx , DriverContext )
+
+ # TODO
+ # there's no builtin drivers yet.
+
+
+def registerize ( func ):
+ """Registerize a method, add a `_factory` attribute and a `register`
+ interface to a method.
+
+ multiple-level register is automatically supported, users can
+
+ >>> open.register(local_io_adaptor)
+ >>> open.register(oss_io_adaptor)
+
+ OR
+
+ >>> open.register('file', local_io_adaptor)
+ >>> open.register('odps', odps_io_adaptor)
+
+ OR
+
+ >>> open.register('file', 'csv', local_csv_reader)
+ >>> open.register('file', 'tsv', local_tsv_reader)
+ """
+
+ @functools . wraps ( func )
+ def wrap ( * args , ** kwargs ):
+ return func ( * args , ** kwargs )
+
+ setattr ( wrap , '_factory' , None )
+
+ def register ( * args ):
+ if len ( args ) == 1 :
+ if wrap . _factory is None :
+ wrap . _factory = []
+ if not isinstance ( wrap . _factory , list ):
+ raise RuntimeError (
+ 'Invalid arguments: inconsistent with existing registerations'
+ )
+ wrap . _factory . append ( args [ 0 ])
+ else :
+ if wrap . _factory is None :
+ wrap . _factory = {}
+ if not isinstance ( wrap . _factory , dict ):
+ raise RuntimeError (
+ 'Invalid arguments: inconsistent with existing registerations'
+ )
+ root = wrap . _factory
+ for arg in args [: - 2 ]:
+ if arg not in root :
+ root [ arg ] = dict ()
+ root = root [ arg ]
+ if args [ - 2 ] not in root :
+ root [ args [ - 2 ]] = list ()
+ root [ args [ - 2 ]] . append ( args [ - 1 ])
+
+ setattr ( wrap , 'register' , register )
+
+ return wrap
+
+
+__all__ = [
+ 'default_driver_context' ,
+ 'register_builtin_drivers' ,
+ 'driver_context' ,
+ 'get_current_drivers' ,
+ 'registerize' ,
+]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/core/resolver.html b/_modules/vineyard/core/resolver.html
new file mode 100644
index 0000000000..7b341d9ecd
--- /dev/null
+++ b/_modules/vineyard/core/resolver.html
@@ -0,0 +1,685 @@
+
+
+
+
+
+
+
+ vineyard.core.resolver - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.core.resolver
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import contextlib
+import inspect
+import threading
+from typing import Any
+from typing import Callable
+from typing import Dict
+from typing import Generator
+from typing import Optional
+
+from sortedcontainers import SortedDict
+
+from vineyard._C import IPCClient
+from vineyard._C import Object
+from vineyard._C import ObjectID
+from vineyard._C import RPCClient
+from vineyard.core.utils import find_most_precise_match
+
+
+[docs] class ResolverContext :
+
def __init__ ( self , parent_context : Optional [ "ResolverContext" ] = None ):
+
self . _factory = SortedDict ()
+
if parent_context is not None :
+
self . _parent_context = parent_context
+
else :
+
self . _parent_context = self
+
+
def __str__ ( self ) -> str :
+
return str ( self . _factory )
+
+
def __repr__ ( self ) -> str :
+
return repr ( self . _factory )
+
+
@property
+
def parent_context ( self ) -> "ResolverContext" :
+
return self . _parent_context
+
+
def register ( self , typename_prefix : str , resolver : Callable ):
+
self . _factory [ typename_prefix ] = resolver
+
+
def run ( self , obj : Any , ** kw ):
+
typename = obj . meta . typename
+
prefix , resolver = find_most_precise_match ( typename , self . _factory )
+
vineyard_client = kw . pop ( '__vineyard_client' , None )
+
if prefix :
+
resolver_func_sig = inspect . getfullargspec ( resolver )
+
if resolver_func_sig . varkw is not None :
+
value = resolver ( obj , resolver = self , ** kw )
+
else :
+
try :
+
# don't pass the `**kw`.
+
if 'resolver' in resolver_func_sig . args :
+
value = resolver ( obj , resolver = self )
+
else :
+
value = resolver ( obj )
+
except Exception as e :
+
raise RuntimeError ( # pylint: disable=raise-missing-from
+
'Unable to construct the object using resolver: '
+
'typename is %s , resolver is %s ' % ( obj . meta . typename , resolver )
+
) from e
+
if value is None :
+
# if the obj has been resolved by pybind types, and there's no proper
+
# resolver, it shouldn't be an error
+
if type ( obj ) is not Object : # pylint: disable=unidiomatic-typecheck
+
return obj
+
+
# we might `client.put(None)`
+
return None
+
+
# associate a reference to the base C++ object
+
try :
+
setattr ( value , '__vineyard_ref' , obj )
+
setattr ( value , '__vineyard_client' , vineyard_client )
+
+
# register methods
+
from vineyard.core.driver import get_current_drivers
+
+
get_current_drivers () . resolve ( value , obj . typename )
+
except AttributeError :
+
pass
+
+
return value
+
# keep it as it is
+
return obj
+
+
def __call__ ( self , obj , ** kw ):
+
return self . run ( obj , ** kw )
+
+
def extend ( self , resolvers = None ):
+
resolver = ResolverContext ( self )
+
resolver . _factory = ( # pylint: disable=unused-private-member
+
self . _factory . copy ()
+
)
+
if resolvers :
+
resolver . _factory . update ( resolvers )
+
return resolver
+
+
+default_resolver_context = ResolverContext ()
+
+_resolver_context_local = threading . local ()
+_resolver_context_local . default_resolver = default_resolver_context
+
+
+[docs] def get_current_resolvers () -> ResolverContext :
+
'''Obtain current resolver context.'''
+
default_resolver = getattr ( _resolver_context_local , 'default_resolver' , None )
+
if not default_resolver :
+
default_resolver = default_resolver_context . extend ()
+
return default_resolver
+
+
+[docs] @contextlib . contextmanager
+
def resolver_context (
+
resolvers : Optional [ Dict [ str , Callable ]] = None ,
+
base : Optional [ ResolverContext ] = None ,
+
) -> Generator [ ResolverContext , Any , Any ]:
+
"""Open a new context for register resolvers, without populating outside
+
the global environment.
+
+
The :code:`resolver_context` can be useful when users have more than
+
more resolver for a certain type, e.g., the :code:`vineyard::Tensor`
+
object can be resolved as :code:`numpy.ndarray` or :code:`xgboost::DMatrix`.
+
+
We could have
+
+
.. code:: python
+
+
def numpy_resolver(obj):
+
...
+
+
default_resolver_context.register('vineyard::Tensor', numpy_resolver)
+
+
and
+
+
.. code:: python
+
+
def xgboost_resolver(obj):
+
...
+
+
default_resolver_context.register('vineyard::Tensor', xgboost_resolver)
+
+
Obviously there's a conflict, and the stackable :code:`resolver_context` could
+
help there,
+
+
.. code:: python
+
+
with resolver_context({'vineyard::Tensor', xgboost_resolver}):
+
...
+
+
Assuming the default context resolves :code:`vineyard::Tensor` to
+
:code:`numpy.ndarray`, inside the :code:`with resolver_context` the
+
:code:`vineyard::Tensor` will be resolved to :code:`xgboost::DMatrix`,
+
and after exiting the context the global environment will be restored
+
back as default.
+
+
The :code:`with resolver_context` is nestable as well.
+
+
See Also:
+
builder_context
+
driver_context
+
"""
+
current_resolver = get_current_resolvers ()
+
try :
+
resolvers = resolvers or dict ()
+
base = base or current_resolver
+
local_resolver = base . extend ( resolvers )
+
_resolver_context_local . default_resolver = local_resolver
+
yield local_resolver
+
finally :
+
_resolver_context_local . default_resolver = current_resolver
+
+
+def get (
+ client ,
+ object_id : Optional [ ObjectID ] = None ,
+ name : Optional [ str ] = None ,
+ resolver : Optional [ ResolverContext ] = None ,
+ fetch : bool = False ,
+ ** kwargs
+):
+ """Get vineyard object as python value.
+
+ .. code:: python
+
+ >>> arr_id = vineyard.ObjectID('00002ec13bc81226')
+ >>> arr = client.get(arr_id)
+ >>> arr
+ array([0, 1, 2, 3, 4, 5, 6, 7])
+
+ Parameters:
+ client: IPCClient or RPCClient
+ The vineyard client to use.
+ object_id: ObjectID
+ The object id that will be obtained from vineyard.
+ name: ObjectID
+ The object name that will be obtained from vineyard, ignored if
+ ``object_id`` is not None.
+ resolver:
+ When retrieving vineyard object, an optional *resolver* can be specified.
+ If no resolver given, the default resolver context will be used.
+ fetch:
+ Whether to trigger a migration when the target object is located on
+ remote instances.
+ kw:
+ User-specific argument that will be passed to the builder.
+
+ Returns:
+ A python object that return by the resolver, by resolving an vineyard object.
+ """
+ # wrap object_id
+ if object_id is not None :
+ if isinstance ( object_id , ( int , str )):
+ object_id = ObjectID ( object_id )
+ elif name is not None :
+ object_id = client . get_name ( name )
+
+ obj = client . get_object ( object_id , fetch = fetch )
+
+ if resolver is None :
+ resolver = get_current_resolvers ()
+ return resolver ( obj , __vineyard_client = client , ** kwargs )
+
+
+setattr ( IPCClient , 'get' , get )
+setattr ( RPCClient , 'get' , get )
+
+__all__ = [
+ 'default_resolver_context' ,
+ 'resolver_context' ,
+ 'get_current_resolvers' ,
+]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/csi.html b/_modules/vineyard/csi.html
new file mode 100644
index 0000000000..f529dcaafa
--- /dev/null
+++ b/_modules/vineyard/csi.html
@@ -0,0 +1,527 @@
+
+
+
+
+
+
+
+ vineyard.csi - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.csi
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import os
+from typing import Any
+
+import vineyard
+
+
+def _find_vineyard_socket ( path ):
+ current_dir = path
+ while current_dir != "/" :
+ socket_path = os . path . join ( current_dir , "vineyard.sock" )
+ if os . path . exists ( socket_path ):
+ return socket_path
+ current_dir = os . path . dirname ( current_dir )
+ return None
+
+
+[docs] def write (
+
value : Any ,
+
path : str ,
+
):
+
"""
+
Write python value to vineyard.
+
Notice, the API is only used for CSI driver.
+
+
Parameters:
+
path: str
+
The path that represents a vineyard object.
+
+
.. code:: python
+
+
>>> arr = np.arange(8)
+
>>> vineyard.write(arr)
+
"""
+
socket_path = _find_vineyard_socket ( path )
+
+
if socket_path is None :
+
raise FileNotFoundError (
+
f "The given path is not generated by vineyard CSI driver: { path } "
+
)
+
+
client = vineyard . connect ( socket_path )
+
client . put ( value , persist = True , name = path )
+
+
+[docs] def read (
+
path : str ,
+
):
+
"""
+
Read vineyard object from path, and return python value.
+
Notice, the API is only used for CSI driver.
+
+
Parameters:
+
path: str
+
The path that represents a vineyard object.
+
+
.. code:: python
+
+
>>> arr = vineyard.read('/a/b/c/d/f')
+
>>> arr
+
array([0, 1, 2, 3, 4, 5, 6, 7])
+
+
Returns:
+
A python object that return by the resolver, by resolving an vineyard object.
+
"""
+
socket_path = _find_vineyard_socket ( path )
+
+
if socket_path is None :
+
raise FileNotFoundError (
+
f "The given path is not generated by vineyard CSI driver: { path } "
+
)
+
+
client = vineyard . connect ( socket_path )
+
return client . get ( name = path )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/deploy/distributed.html b/_modules/vineyard/deploy/distributed.html
new file mode 100644
index 0000000000..9225855517
--- /dev/null
+++ b/_modules/vineyard/deploy/distributed.html
@@ -0,0 +1,577 @@
+
+
+
+
+
+
+
+ vineyard.deploy.distributed - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.deploy.distributed
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import contextlib
+import logging
+import subprocess
+import sys
+import textwrap
+import time
+
+import pkg_resources
+
+from vineyard.deploy.utils import ssh_base_cmd
+from vineyard.deploy.utils import start_etcd
+
+logger = logging . getLogger ( 'vineyard' )
+
+
+[docs] @contextlib . contextmanager
+
def start_vineyardd (
+
hosts = None ,
+
etcd_endpoints = None ,
+
vineyardd_path = None ,
+
size = '' ,
+
socket = '/var/run/vineyard.sock' ,
+
rpc_socket_port = 9600 ,
+
debug = False ,
+
):
+
"""Launch a local vineyard cluster in a distributed fashion.
+
+
Parameters:
+
hosts: list of str
+
A list of machines to launch vineyard server.
+
etcd_endpoint: str
+
Launching vineyard using specified etcd endpoints. If not specified,
+
vineyard will launch its own etcd instance.
+
vineyardd_path: str
+
Location of vineyard server program. If not specified, vineyard will
+
use its own bundled vineyardd binary.
+
size: int
+
The memory size limit for vineyard's shared memory. The memory size
+
can be a plain integer or as a fixed-point number using one of these
+
suffixes:
+
+
.. code::
+
+
E, P, T, G, M, K.
+
+
You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki.
+
Defaults to "", means not limited.
+
+
For example, the following represent roughly the same value:
+
+
.. code::
+
+
128974848, 129k, 129M, 123Mi, 1G, 10Gi, ...
+
socket: str
+
The UNIX domain socket socket path that vineyard server will listen on.
+
rpc_socket_port: int
+
The port that vineyard will use to privode RPC service.
+
debug: bool
+
Whether print debug logs.
+
"""
+
if vineyardd_path is None :
+
vineyardd_path = pkg_resources . resource_filename ( 'vineyard' , 'vineyardd' )
+
+
if hosts is None :
+
hosts = [ 'localhost' ]
+
+
if etcd_endpoints is None :
+
etcd_ctx = start_etcd ( host = hosts [ 0 ])
+
_etcd_proc , etcd_endpoints = etcd_ctx . __enter__ () # pylint: disable=no-member
+
else :
+
etcd_ctx = None
+
+
env = dict ()
+
if debug :
+
env [ 'GLOG_v' ] = 11
+
+
command = [
+
vineyardd_path ,
+
'--deployment' ,
+
'distributed' ,
+
'--size' ,
+
str ( size ),
+
'--socket' ,
+
socket ,
+
'--rpc_socket_port' ,
+
str ( rpc_socket_port ),
+
'--etcd_endpoint' ,
+
etcd_endpoints ,
+
]
+
+
procs = []
+
try :
+
for host in hosts :
+
proc = subprocess . Popen (
+
ssh_base_cmd ( host ) + command ,
+
env = env ,
+
stdout = subprocess . PIPE ,
+
stderr = sys . __stderr__ ,
+
universal_newlines = True ,
+
encoding = 'utf-8' ,
+
)
+
procs . append ( proc )
+
time . sleep ( 1 )
+
for proc in procs :
+
rc = proc . poll ()
+
if rc is not None :
+
err = textwrap . indent ( proc . stdout . read (), ' ' * 4 )
+
raise RuntimeError (
+
'vineyardd exited unexpectedly with '
+
'code %d : error is: \n %s ' % ( rc , err )
+
)
+
yield procs , socket , etcd_endpoints
+
finally :
+
logger . info ( 'Distributed vineyardd being killed' )
+
for proc in procs :
+
if proc . poll () is None :
+
logger . info ( 'killing the vineyardd' )
+
proc . kill ()
+
if etcd_ctx is not None :
+
etcd_ctx . __exit__ ( None , None , None ) # pylint: disable=no-member
+
+
+__all__ = [ 'start_vineyardd' ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/deploy/kubernetes.html b/_modules/vineyard/deploy/kubernetes.html
new file mode 100644
index 0000000000..2fd1ddbd0c
--- /dev/null
+++ b/_modules/vineyard/deploy/kubernetes.html
@@ -0,0 +1,721 @@
+
+
+
+
+
+
+
+ vineyard.deploy.kubernetes - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.deploy.kubernetes
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import logging
+import os
+import re
+import tempfile
+import time
+
+try :
+ import kubernetes
+except ImportError :
+ kubernetes = None
+
+from vineyard.deploy.etcd import start_etcd_k8s
+from vineyard.deploy.utils import ensure_kubernetes_namespace
+
+logger = logging . getLogger ( 'vineyard' )
+
+
+[docs] def start_vineyardd (
+
namespace = 'vineyard' ,
+
size = '512Mi' ,
+
socket = '/var/run/vineyard.sock' ,
+
rpc_socket_port = 9600 ,
+
vineyard_image = 'vineyardcloudnative/vineyardd:latest' ,
+
vineyard_image_pull_policy = 'IfNotPresent' ,
+
vineyard_image_pull_secrets = None ,
+
k8s_client = None ,
+
):
+
"""Launch a vineyard cluster on kubernetes.
+
+
Parameters:
+
namespace: str
+
namespace in kubernetes
+
size: int
+
The memory size limit for vineyard's shared memory. The memory size
+
can be a plain integer or as a fixed-point number using one of these
+
suffixes:
+
+
.. code::
+
+
E, P, T, G, M, K.
+
+
You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki.
+
+
For example, the following represent roughly the same value:
+
+
.. code::
+
+
128974848, 129k, 129M, 123Mi, 1G, 10Gi, ...
+
socket: str
+
The UNIX domain socket socket path that vineyard server will listen on.
+
rpc_socket_port: int
+
The port that vineyard will use to provide RPC service.
+
k8s_client: kubernetes.client.api.ApiClient
+
A kubernetes client. If not specified, vineyard will try to resolve the
+
kubernetes configuration from current context.
+
vineyard_image: str
+
The docker image of vineyardd to launch the daemonset.
+
vineyard_image_pull_policy: str
+
The docker image pull policy of vineyardd.
+
vineyard_image_pull_secrets: str
+
The docker image pull secrets of vineyardd.
+
+
Returns:
+
A list of created kubernetes resources during the deploying process. The
+
resources can be later release using :meth:`delete_kubernetes_objects`.
+
+
See Also:
+
vineyard.deploy.kubernetes.delete_kubernetes_objects
+
"""
+
if kubernetes is None :
+
raise RuntimeError ( 'Please install the package python "kubernetes" first' )
+
+
if k8s_client is None :
+
kubernetes . config . load_kube_config ()
+
k8s_client = kubernetes . client . ApiClient ()
+
+
created_objects = []
+
ensure_kubernetes_namespace ( namespace , k8s_client = k8s_client )
+
created_objects . extend ( start_etcd_k8s ( namespace , k8s_client = k8s_client ))
+
+
with open (
+
os . path . join ( os . path . dirname ( __file__ ), "vineyard.yaml.tpl" ),
+
'r' ,
+
encoding = 'utf-8' ,
+
) as fp :
+
formatter = {
+
'Namespace' : namespace ,
+
'Size' : size ,
+
'Socket' : socket ,
+
'Port' : rpc_socket_port ,
+
'Image' : vineyard_image ,
+
'ImagePullPolicy' : vineyard_image_pull_policy ,
+
'ImagePullSecrets' : (
+
vineyard_image_pull_secrets if vineyard_image_pull_secrets else 'none' ,
+
),
+
}
+
definitions = fp . read () . format ( ** formatter )
+
+
with tempfile . NamedTemporaryFile (
+
mode = 'w' , encoding = 'utf-8' , delete = False
+
) as rendered :
+
rendered . write ( definitions )
+
rendered . flush ()
+
rendered . close ()
+
+
with open ( rendered . name , 'r' , encoding = 'utf-8' ) as fp :
+
logger . debug ( fp . read ())
+
+
created_objects . extend (
+
kubernetes . utils . create_from_yaml (
+
k8s_client , rendered . name , namespace = namespace
+
)
+
)
+
return created_objects
+
+
+def recursive_flatten ( targets ):
+ """Flatten the given maybe nested list as a 1-level list."""
+
+ def _recursive_flatten_impl ( destination , targets ):
+ if isinstance ( targets , ( list , tuple )):
+ for target in targets :
+ _recursive_flatten_impl ( destination , target )
+ else :
+ destination . append ( targets )
+
+ destination = []
+ _recursive_flatten_impl ( destination , targets )
+ return destination
+
+
+[docs] def delete_kubernetes_objects (
+
targets , k8s_client = None , verbose = False , wait = False , timeout_seconds = 60 , ** kwargs
+
):
+
"""Delete the given kubernetes resources.
+
+
Parameters:
+
target: List
+
List of Kubernetes objects
+
k8s_client:
+
The kubernetes client. If not specified, vineyard will try to resolve
+
the kubernetes configuration from current context.
+
verbose: bool
+
Whether to print the deletion logs.
+
wait: bool
+
Whether to wait for the deletion to complete.
+
timeout_seconds: int
+
The timeout in seconds for waiting for the deletion to complete.
+
+
See Also:
+
vineyard.deploy.kubernetes.start_vineyardd
+
vineyard.deploy.kubernetes.delete_kubernetes_object
+
"""
+
for target in recursive_flatten ( targets ):
+
delete_kubernetes_object (
+
target ,
+
k8s_client ,
+
verbose = verbose ,
+
wait = wait ,
+
timeout_seconds = timeout_seconds ,
+
** kwargs
+
)
+
+
+def delete_kubernetes_object (
+ target , k8s_client = None , verbose = False , wait = False , timeout_seconds = 60 , ** kwargs
+):
+ """Delete the given kubernetes resource.
+
+ Parameters:
+ target: object
+ The Kubernetes objects that will be deleted.
+ k8s_client:
+ The kubernetes client. If not specified, vineyard will try to resolve
+ the kubernetes configuration from current context.
+ verbose: bool
+ If True, print confirmation from the delete action. Defaults to False.
+ wait: bool
+ Whether to wait for the deletion to complete. Defaults to False.
+ timeout_seconds: int
+ The timeout in seconds for waiting for the deletion to complete. Defaults
+ to 60.
+
+ Returns:
+ Status: Return status for calls kubernetes delete method.
+
+ See Also:
+ vineyard.deploy.kubernetes.start_vineyardd
+ vineyard.deploy.kubernetes.delete_kubernetes_objects
+ """
+ if isinstance ( target , ( list , tuple )):
+ return delete_kubernetes_objects (
+ target , k8s_client , verbose = verbose , wait = wait , ** kwargs
+ )
+
+ if kubernetes is None :
+ raise RuntimeError ( 'Please install the package python "kubernetes" first' )
+
+ if k8s_client is None :
+ kubernetes . config . load_kube_config ()
+ k8s_client = kubernetes . client . ApiClient ()
+
+ group , _ , version = target . api_version . partition ( "/" )
+ if version == "" :
+ version = group
+ group = "core"
+ # Take care for the case e.g. api_type is "apiextensions.k8s.io"
+ # Only replace the last instance
+ group = "" . join ( group . rsplit ( ".k8s.io" , 1 ))
+ # convert group name from DNS subdomain format to
+ # python class name convention
+ group = "" . join ( word . capitalize () for word in group . split ( "." ))
+ fcn_to_call = " {0}{1} Api" . format ( group , version . capitalize ())
+ k8s_api = getattr ( kubernetes . client , fcn_to_call )(
+ k8s_client
+ ) # pylint: disable=not-callable
+
+ kind = target . kind
+ kind = re . sub ( "(.)([A-Z][a-z]+)" , r "\1_\2" , kind )
+ kind = re . sub ( "([a-z0-9])([A-Z])" , r "\1_\2" , kind ) . lower ()
+
+ try :
+ # Expect the user to create namespaced objects more often
+ kwargs [ "name" ] = target . metadata . name
+ if hasattr ( k8s_api , "delete_namespaced_ {0} " . format ( kind )):
+ # Decide which namespace we are going to put the object in, if any
+ kwargs [ "namespace" ] = target . metadata . namespace
+ resp = getattr ( k8s_api , "delete_namespaced_ {0} " . format ( kind ))( ** kwargs )
+ else :
+ kwargs . pop ( "namespace" , None )
+ resp = getattr ( k8s_api , "delete_ {0} " . format ( kind ))( ** kwargs )
+ except kubernetes . client . rest . ApiException :
+ # Object already deleted.
+ return None
+ else :
+ # Waiting for delete
+ if wait :
+ start_time = time . time ()
+ if hasattr ( k8s_api , "read_namespaced_ {0} " . format ( kind )):
+ while True :
+ try :
+ getattr ( k8s_api , "read_namespaced_ {0} " . format ( kind ))( ** kwargs )
+ except kubernetes . client . rest . ApiException as ex :
+ if ex . status != 404 :
+ logger . exception (
+ "Deleting %s %s failed" , kind , target . metadata . name
+ )
+ break
+ else :
+ time . sleep ( 1 )
+ if time . time () - start_time > timeout_seconds :
+ logger . info (
+ "Deleting %s / %s timeout" , kind , target . metadata . name
+ )
+ if verbose :
+ msg = " {0} / {1} deleted." . format ( kind , target . metadata . name )
+ if hasattr ( resp , "status" ):
+ msg += " status=' {0} '" . format ( str ( resp . status ))
+ logger . info ( msg )
+ return resp
+
+
+__all__ = [
+ 'start_vineyardd' ,
+ 'delete_kubernetes_object' ,
+ 'delete_kubernetes_objects' ,
+]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/deploy/local.html b/_modules/vineyard/deploy/local.html
new file mode 100644
index 0000000000..0677184245
--- /dev/null
+++ b/_modules/vineyard/deploy/local.html
@@ -0,0 +1,702 @@
+
+
+
+
+
+
+
+ vineyard.deploy.local - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.deploy.local
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import atexit
+import contextlib
+import logging
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+import textwrap
+import time
+from typing import Generator
+from typing import Optional
+from typing import Tuple
+
+from vineyard.deploy.etcd import start_etcd
+from vineyard.deploy.utils import check_socket
+from vineyard.deploy.utils import find_vineyardd_path
+
+logger = logging . getLogger ( 'vineyard' )
+
+
+[docs] @contextlib . contextmanager
+
def start_vineyardd (
+
meta : Optional [ str ] = 'etcd' ,
+
etcd_endpoints : Optional [ str ] = None ,
+
etcd_prefix : Optional [ str ] = None ,
+
vineyardd_path : Optional [ str ] = None ,
+
size : Optional [ str ] = '' ,
+
socket : Optional [ str ] = None ,
+
rpc : Optional [ str ] = True ,
+
rpc_socket_port : Optional [ str ] = 9600 ,
+
debug = False ,
+
) -> Generator [ Tuple [ subprocess . Popen , str , str ], None , None ]:
+
"""Launch a local vineyard cluster.
+
+
Parameters:
+
meta: str, optional.
+
Metadata backend, can be "etcd", "redis" and "local". Defaults to
+
"etcd".
+
etcd_endpoint: str
+
Launching vineyard using specified etcd endpoints. If not specified,
+
vineyard will launch its own etcd instance.
+
etcd_prefix: str
+
Specify a common prefix to establish a local vineyard cluster.
+
vineyardd_path: str
+
Location of vineyard server program. If not specified, vineyard will
+
use its own bundled vineyardd binary.
+
size: int
+
The memory size limit for vineyard's shared memory. The memory size
+
can be a plain integer or as a fixed-point number using one of these
+
suffixes:
+
+
.. code::
+
+
E, P, T, G, M, K.
+
+
You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki.
+
Defaults to "", means not limited.
+
+
For example, the following represent roughly the same value:
+
+
.. code::
+
+
128974848, 129k, 129M, 123Mi, 1G, 10Gi, ...
+
socket: str
+
The UNIX domain socket socket path that vineyard server will listen on.
+
Default is None.
+
+
When the socket parameter is None, a random path under temporary directory
+
will be generated and used.
+
rpc_socket_port: int
+
The port that vineyard will use to provided RPC service.
+
debug: bool
+
Whether print debug logs.
+
+
Returns:
+
(proc, socket):
+
Yields a tuple with the subprocess as the first element and the UNIX-domain
+
IPC socket as the second element.
+
"""
+
+
if not vineyardd_path :
+
vineyardd_path = find_vineyardd_path ()
+
+
if not vineyardd_path :
+
raise RuntimeError ( 'Unable to find the "vineyardd" executable' )
+
+
if socket is None :
+
socketfp = tempfile . NamedTemporaryFile (
+
delete = True , prefix = 'vineyard-' , suffix = '.sock'
+
)
+
socket = socketfp . name
+
socketfp . close ()
+
+
command = [
+
vineyardd_path ,
+
'--deployment' ,
+
'local' ,
+
'--size' ,
+
str ( size ),
+
'--socket' ,
+
socket ,
+
'--rpc' if rpc else '--norpc' ,
+
'--rpc_socket_port' ,
+
str ( rpc_socket_port ),
+
'--meta' ,
+
meta ,
+
]
+
+
if meta == 'etcd' :
+
if etcd_endpoints is None :
+
etcd_ctx = start_etcd ()
+
(
+
_etcd_proc ,
+
etcd_endpoints ,
+
) = etcd_ctx . __enter__ () # pylint: disable=no-member
+
else :
+
etcd_ctx = None
+
command . extend (( '--etcd_endpoint' , etcd_endpoints ))
+
if etcd_prefix is not None :
+
command . extend (( '--etcd_prefix' , etcd_prefix ))
+
else :
+
etcd_ctx = None
+
+
env = os . environ . copy ()
+
if debug :
+
env [ 'GLOG_v' ] = '11'
+
+
proc = None
+
try :
+
proc = subprocess . Popen (
+
command ,
+
env = env ,
+
stdout = subprocess . PIPE ,
+
stderr = sys . __stderr__ ,
+
universal_newlines = True ,
+
encoding = 'utf-8' ,
+
)
+
# wait for vineyardd ready: check the rpc port and ipc sockets
+
rc = proc . poll ()
+
while rc is None :
+
if check_socket ( socket ) and (
+
( not rpc ) or check_socket (( '0.0.0.0' , rpc_socket_port ))
+
):
+
break
+
time . sleep ( 1 )
+
rc = proc . poll ()
+
+
if rc is not None :
+
err = textwrap . indent ( proc . stdout . read (), ' ' * 4 )
+
raise RuntimeError (
+
'vineyardd exited unexpectedly '
+
'with code %d , error is: \n %s ' % ( rc , err )
+
)
+
+
logger . debug ( 'vineyardd is ready.............' )
+
yield proc , socket , etcd_endpoints
+
finally :
+
logger . debug ( 'Local vineyardd being killed' )
+
if proc is not None and proc . poll () is None :
+
proc . terminate ()
+
proc . wait ()
+
try :
+
shutil . rmtree ( socket )
+
except Exception : # pylint: disable=broad-except
+
pass
+
if etcd_ctx is not None :
+
etcd_ctx . __exit__ ( None , None , None ) # pylint: disable=no-member
+
+
+__default_instance_contexts = {}
+
+
+def try_init () -> str :
+ """
+ Launching a local vineyardd instance and get a client as easy as possible.
+
+ In a clean environment, simply use:
+
+ .. code:: python
+
+ vineyard.try_init()
+
+ It will launch a local vineyardd and return a connected client to the
+ vineyardd.
+
+ It will also setup the environment variable :code:`VINEYARD_IPC_SOCKET`.
+
+ The init method can only be called once in a process, to get the established
+ sockets or clients later in the process, use :code:`get_current_socket` or
+ :code:`connect()` respectively.
+ """
+ assert not __default_instance_contexts
+
+ if 'VINEYARD_IPC_SOCKET' in os . environ :
+ raise ValueError (
+ "VINEYARD_IPC_SOCKET has already been set: %s , which "
+ "means there might be a vineyard daemon already running "
+ "locally" % os . environ [ 'VINEYARD_IPC_SOCKET' ]
+ )
+
+ ctx = start_vineyardd ( meta = 'local' , rpc = False )
+ _ , ipc_socket , etcd_endpoints = ctx . __enter__ () # pylint: disable=no-member
+ __default_instance_contexts [ ipc_socket ] = ctx
+
+ # populate the environment variable
+ os . environ [ 'VINEYARD_IPC_SOCKET' ] = ipc_socket
+ return get_current_socket ()
+
+
+[docs] def get_current_socket () -> str :
+
"""
+
Get current vineyard UNIX-domain socket established by :code:`vineyard.try_init()`.
+
+
Raises:
+
ValueError if vineyard is not initialized.
+
"""
+
if not __default_instance_contexts :
+
raise ValueError (
+
'Vineyard has not been initialized, '
+
'use vineyard.try_init() to launch vineyard instances'
+
)
+
sockets = list ( __default_instance_contexts . keys ())
+
if sockets :
+
return sockets [ 0 ]
+
raise RuntimeError ( "Vineyard has not been initialized" )
+
+
+def shutdown ():
+ """
+ Shutdown the vineyardd instances launched by previous :code:`vineyard.try_init()`.
+ """
+ global __default_instance_contexts
+ if __default_instance_contexts :
+ for ipc_socket in reversed ( __default_instance_contexts . keys ()):
+ __default_instance_contexts [ ipc_socket ] . __exit__ ( None , None , None )
+ # NB. don't pop pre-existing env if we not launch
+ os . environ . pop ( 'VINEYARD_IPC_SOCKET' , None )
+ __default_instance_contexts = {}
+
+
+@atexit . register
+def __shutdown_handler ():
+ with contextlib . suppress ( Exception ):
+ shutdown ()
+
+
+__all__ = [ 'start_vineyardd' , 'try_init' , 'shutdown' ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/io/byte.html b/_modules/vineyard/io/byte.html
new file mode 100644
index 0000000000..bf8d642e67
--- /dev/null
+++ b/_modules/vineyard/io/byte.html
@@ -0,0 +1,611 @@
+
+
+
+
+
+
+
+ vineyard.io.byte - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.io.byte
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+''' This module exposes support for ByteStream, that use can used like:
+
+.. code:: python
+
+ # create a builder, then seal it as stream
+ >>> stream = ByteStream.new(client)
+ >>> stream
+ ByteStream <o0001e09ddd98fd70>
+
+ # use write to put chunks
+ >>> writer = stream.open_writer(client)
+ >>> chunk = reader.next(1024)
+ >>> chunk
+ <memory at 0x136ca2ac0>
+ >>> len(chunk)
+ 1024
+ >>> chunk.readonly
+ False
+ >>> vineyard.memory_copy(chunk, src=b'abcde', offset=0)
+
+ # mark the stream as finished
+ >>> writer.finish()
+
+ # open a reader
+ >>> reader = stream.open_reader(client)
+ >>> chunk = reader.next()
+ >>> chunk
+ <memory at 0x136d207c0>
+ >>> len(chunk)
+ 1234
+ >>> chunk.readonly
+ True
+ >>> bytes(chunk[:10])
+ b'abcde\x00\x00\x00\x00\x00'
+
+ # the reader reaches the end of the stream
+ >>> chunk = reader.next()
+ ---------------------------------------------------------------------------
+ StreamDrainedException Traceback (most recent call last)
+ ~/libvineyard/python/vineyard/io/byte.py in next(self)
+ 108
+ --> 109 def next(self) -> memoryview:
+ 110 try:
+
+ StreamDrainedException: Stream drain: Stream drained: no more chunks
+
+ The above exception was the direct cause of the following exception:
+
+ StopIteration Traceback (most recent call last)
+ <ipython-input-11-d8809de11870> in <module>
+ ----> 1 chunk = reader.next()
+
+ ~/libvineyard/python/vineyard/io/byte.py in next(self)
+ 109 def next(self) -> memoryview:
+ 110 try:
+ --> 111 return self._client.next_buffer_chunk(self._stream)
+ 112 except StreamDrainedException as e:
+ 113 raise StopIteration('No more chunks') from e
+
+ StopIteration: No more chunks
+'''
+
+import json
+from io import BytesIO
+from typing import Dict
+
+from vineyard._C import ObjectID
+from vineyard._C import ObjectMeta
+from vineyard._C import StreamDrainedException
+from vineyard._C import memory_copy
+from vineyard.io.stream import BaseStream
+
+
+[docs] class ByteStream ( BaseStream ):
+
def __init__ ( self , meta : ObjectMeta , params : Dict = None ):
+
super () . __init__ ( meta )
+
self . _params = params
+
+
@property
+
def params ( self ):
+
return self . _params
+
+
@staticmethod
+
def new ( client , params : Dict = None , meta : ObjectMeta = None ) -> "ByteStream" :
+
if meta is None :
+
meta = ObjectMeta ()
+
meta [ 'typename' ] = 'vineyard::ByteStream'
+
if params is None :
+
params = dict ()
+
meta [ 'params_' ] = params
+
meta = client . create_metadata ( meta )
+
client . create_stream ( meta . id )
+
return ByteStream ( meta , params )
+
+
class Reader ( BaseStream . Reader ):
+
def __init__ ( self , client , stream : ObjectID ):
+
super () . __init__ ( client , stream )
+
+
def next ( self ) -> memoryview :
+
try :
+
return self . _client . next_buffer_chunk ( self . _stream )
+
except StreamDrainedException as e :
+
raise StopIteration ( 'No more chunks' ) from e
+
+
class Writer ( BaseStream . Writer ):
+
def __init__ ( self , client , stream : ObjectID ):
+
super () . __init__ ( client , stream )
+
+
self . _buffer_size_limit = 1024 * 1024 * 256
+
self . _buffer = BytesIO ()
+
+
@property
+
def buffer_size_limit ( self ):
+
return self . _buffer_size_limit
+
+
@buffer_size_limit . setter
+
def buffer_size_limit ( self , value : int ):
+
self . _buffer_size_limit = value
+
+
def next ( self , size : int ) -> memoryview :
+
return self . _client . new_buffer_chunk ( self . _stream , size )
+
+
def write ( self , data : bytes ):
+
self . _buffer . write ( data )
+
self . _try_flush_buffer ()
+
+
def _try_flush_buffer ( self , force = False ):
+
view = self . _buffer . getbuffer ()
+
if len ( view ) >= self . _buffer_size_limit or ( force and len ( view ) > 0 ):
+
if len ( view ) > 0 :
+
chunk = self . next ( len ( view ))
+
memory_copy ( chunk , view )
+
self . _buffer = BytesIO ()
+
+
def finish ( self ):
+
self . _try_flush_buffer ( True )
+
return self . _client . stop_stream ( self . _stream , False )
+
+
def _open_new_reader ( self , client ):
+
return ByteStream . Reader ( client , self . id )
+
+
def _open_new_writer ( self , client ):
+
return ByteStream . Writer ( client , self . id )
+
+
+def byte_stream_resolver ( obj ):
+ meta = obj . meta
+ if 'params_' in meta :
+ params = json . loads ( meta [ 'params_' ])
+ else :
+ params = dict
+ return ByteStream ( obj . meta , params )
+
+
+def register_byte_stream_types ( _builder_ctx , resolver_ctx ):
+ if resolver_ctx is not None :
+ resolver_ctx . register ( 'vineyard::ByteStream' , byte_stream_resolver )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/io/dataframe.html b/_modules/vineyard/io/dataframe.html
new file mode 100644
index 0000000000..4cd7e7bc4a
--- /dev/null
+++ b/_modules/vineyard/io/dataframe.html
@@ -0,0 +1,609 @@
+
+
+
+
+
+
+
+ vineyard.io.dataframe - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.io.dataframe
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+''' This module exposes support for DataframeStream, that use can used like:
+
+.. code:: python
+
+ # create a builder, then seal it as stream
+ >>> stream = DataframeStream.new(client)
+ >>> stream = builder.seal(client)
+ >>> stream
+ DataframeStream <o0001e09ddd98fd70>
+
+ # use write to put chunks
+ >>> writer = stream.open_writer(client)
+ >>> writer.write_table(
+ pa.Table.from_pandas(
+ pd.DataFrame({"x": [1,2,3], "y": [4,5,6]})))
+
+ # mark the stream as finished
+ >>> writer.finish()
+
+ # open a reader
+ >>> reader = stream.open_reader(client)
+ >>> batch = reader.next()
+ >>> batch
+ pyarrow.RecordBatch
+ x: int64
+ y: int64
+
+ # the reader reaches the end of the stream
+ >>> batch = reader.next()
+ ---------------------------------------------------------------------------
+ StreamDrainedException Traceback (most recent call last)
+ ~/libvineyard/python/vineyard/io/dataframe.py in next(self)
+ 97 try:
+ ---> 98 buffer = self._client.next_buffer_chunk(self._stream)
+ 99 with pa.ipc.open_stream(buffer) as reader:
+
+ StreamDrainedException: Stream drain: Stream drained: no more chunks
+
+ The above exception was the direct cause of the following exception:
+
+ StopIteration Traceback (most recent call last)
+ <ipython-input-11-10f09bf65f8a> in <module>
+ ----> 1 batch = reader.next()
+
+ ~/libvineyard/python/vineyard/io/dataframe.py in next(self)
+ 100 return reader.read_next_batch()
+ 101 except StreamDrainedException as e:
+ --> 102 raise StopIteration('No more chunks') from e
+ 103
+ 104 def __str__(self) -> str:
+
+ StopIteration: No more chunks
+'''
+
+import contextlib
+import json
+from io import BytesIO
+from typing import Dict
+
+import pyarrow as pa
+import pyarrow.ipc # pylint: disable=unused-import
+
+from vineyard._C import ObjectID
+from vineyard._C import ObjectMeta
+from vineyard._C import StreamDrainedException
+from vineyard._C import memory_copy
+from vineyard.io.stream import BaseStream
+
+
+[docs] class DataframeStream ( BaseStream ):
+
def __init__ ( self , meta : ObjectMeta , params : Dict = None ):
+
super () . __init__ ( meta )
+
self . _params = params
+
+
@property
+
def params ( self ):
+
return self . _params
+
+
@staticmethod
+
def new ( client , params : Dict = None , meta : ObjectMeta = None ) -> "DataframeStream" :
+
if meta is None :
+
meta = ObjectMeta ()
+
meta [ 'typename' ] = 'vineyard::DataframeStream'
+
if params is None :
+
params = dict ()
+
meta [ 'params_' ] = params
+
meta = client . create_metadata ( meta )
+
client . create_stream ( meta . id )
+
return DataframeStream ( meta , params )
+
+
class Reader ( BaseStream . Reader ):
+
def __init__ ( self , client , stream : ObjectID ):
+
super () . __init__ ( client , stream )
+
+
def next ( self ) -> pa . RecordBatch :
+
try :
+
buffer = self . _client . next_buffer_chunk ( self . _stream )
+
with pa . ipc . open_stream ( buffer ) as reader :
+
return reader . read_next_batch ()
+
except StreamDrainedException as e :
+
raise StopIteration ( 'No more chunks' ) from e
+
+
def read_table ( self ) -> pa . Table :
+
batches = []
+
while True :
+
try :
+
batches . append ( self . next ())
+
except StopIteration :
+
break
+
return pa . Table . from_batches ( batches )
+
+
class Writer ( BaseStream . Writer ):
+
def __init__ ( self , client , stream : ObjectID ):
+
super () . __init__ ( client , stream )
+
+
self . _buffer = BytesIO ()
+
+
def next ( self , size : int ) -> memoryview :
+
return self . _client . new_buffer_chunk ( self . _stream , size )
+
+
def write ( self , batch : pa . RecordBatch ):
+
sink = BytesIO ()
+
with pa . ipc . new_stream ( sink , batch . schema ) as writer :
+
writer . write ( batch )
+
view = sink . getbuffer ()
+
if len ( view ) > 0 :
+
buffer = self . next ( len ( view ))
+
memory_copy ( buffer , view )
+
+
def write_table ( self , table : pa . Table ):
+
for batch in table . to_batches ():
+
self . write ( batch )
+
+
def finish ( self ):
+
return self . _client . stop_stream ( self . _stream , False )
+
+
def _open_new_reader ( self , client ):
+
return DataframeStream . Reader ( client , self . id )
+
+
def _open_new_writer ( self , client ):
+
return DataframeStream . Writer ( client , self . id )
+
+
+def dataframe_stream_resolver ( obj ):
+ meta = obj . meta
+ if 'params_' in meta :
+ params = json . loads ( meta [ 'params_' ])
+ else :
+ params = dict
+ return DataframeStream ( obj . meta , params )
+
+
+def register_dataframe_stream_types ( _builder_ctx , resolver_ctx ):
+ if resolver_ctx is not None :
+ resolver_ctx . register ( 'vineyard::DataframeStream' , dataframe_stream_resolver )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/io/recordbatch.html b/_modules/vineyard/io/recordbatch.html
new file mode 100644
index 0000000000..7e9fc06ac5
--- /dev/null
+++ b/_modules/vineyard/io/recordbatch.html
@@ -0,0 +1,515 @@
+
+
+
+
+
+
+
+ vineyard.io.recordbatch - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.io.recordbatch
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+''' This module exposes support for RecordBatchStream.
+'''
+
+import contextlib
+import json
+from typing import Any
+from typing import Dict
+from typing import Optional
+
+from vineyard._C import ObjectMeta
+from vineyard.core import context
+from vineyard.io.stream import BaseStream
+
+
+[docs] class RecordBatchStream ( BaseStream ):
+
def __init__ ( self , meta : ObjectMeta , params : Optional [ Dict [ str , Any ]] = None ):
+
super () . __init__ ( meta )
+
self . _params = params
+
+
@property
+
def params ( self ):
+
return self . _params
+
+
@staticmethod
+
def new (
+
client ,
+
params : Optional [ Dict [ str , Any ]] = None ,
+
meta : Optional [ ObjectMeta ] = None ,
+
) -> "RecordBatchStream" :
+
if meta is None :
+
meta = ObjectMeta ()
+
meta [ 'typename' ] = 'vineyard::RecordBatchStream'
+
if params is None :
+
params = dict ()
+
meta [ 'params_' ] = params
+
meta = client . create_metadata ( meta )
+
client . create_stream ( meta . id )
+
return RecordBatchStream ( meta , params )
+
+
+def recordbatch_stream_resolver ( obj , resolver ): # pylint: disable=unused-argument
+ meta = obj . meta
+ if 'params_' in meta :
+ params = json . loads ( meta [ 'params_' ])
+ else :
+ params = dict
+ return RecordBatchStream ( meta , params )
+
+
+def register_recordbatch_stream_types ( _builder_ctx , resolver_ctx ):
+ if resolver_ctx is not None :
+ resolver_ctx . register (
+ 'vineyard::RecordBatchStream' , recordbatch_stream_resolver
+ )
+
+
+@contextlib . contextmanager
+def recordbatch_stream_context ():
+ with context () as ( builder_ctx , resolver_ctx ):
+ register_recordbatch_stream_types ( builder_ctx , resolver_ctx )
+ yield builder_ctx , resolver_ctx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/io/stream.html b/_modules/vineyard/io/stream.html
new file mode 100644
index 0000000000..1a35f9d826
--- /dev/null
+++ b/_modules/vineyard/io/stream.html
@@ -0,0 +1,892 @@
+
+
+
+
+
+
+
+ vineyard.io.stream - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.io.stream
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import json
+import logging
+import traceback
+from typing import Callable
+from typing import Dict
+from typing import List
+from typing import Optional
+from urllib.parse import urlparse
+
+from vineyard._C import ObjectID
+from vineyard._C import ObjectMeta
+from vineyard._C import StreamDrainedException
+from vineyard.core.driver import registerize
+from vineyard.core.resolver import resolver_context
+
+logger = logging . getLogger ( 'vineyard' )
+
+
+[docs] @registerize
+
def read (
+
path ,
+
* args ,
+
handlers = None ,
+
accumulate = False ,
+
chunk_hook : Optional [ Callable ] = None ,
+
** kwargs
+
):
+
"""Open a path and read it as a single stream.
+
+
Parameters
+
----------
+
path: str
+
Path to read, the last reader registered for the scheme of
+
the path will be used.
+
handlers: list, optional
+
If handlers is not None, launched worker processes will be
+
emplaced into the list for further customized job lifecycle
+
management. Default is None.
+
accumulate: bool, optional
+
If :code:`accumulate` is True, it will return a data frame,
+
rather than dataframe stream. Default is False.
+
chunk_hook: callable, optional
+
If the read/write target is a global dataframe (e.g., csv,
+
orc, parquet, etc.), the hook will be called for each chunk
+
to be read or write (usually a :code:`pyarrow.RecordBatch`).
+
The hook should return a :code:`pyarrow.RecordBatch` object
+
and should be stateless as the invoke order is not guaranteed.
+
E.g.,
+
+
.. code:: python
+
+
def exchange_column(batch):
+
import pyarrow as pa
+
+
columns = batch.columns
+
first = columns[0]
+
second = columns[1]
+
columns = [second, first] + columns[2:]
+
return pa.RecordBatch.from_arrays(columns, schema=batch.schema)
+
+
vineyard_ipc_socket: str
+
The local or remote vineyard's IPC socket location that the
+
remote readers will use to establish connections with the
+
vineyard server.
+
vineyard_endpoint: str, optional
+
An optional address of vineyard's RPC socket, which will be
+
used for retrieving server's information on the client side.
+
If not provided, the `vineyard_ipc_socket` will be used, or
+
it will tries to discovery vineyard's IPC or RPC endpoints
+
from environment variables.
+
"""
+
parsed = urlparse ( path )
+
if read . _factory and read . _factory . get ( parsed . scheme ):
+
errors = []
+
for reader in read . _factory [ parsed . scheme ][:: - 1 ]:
+
try :
+
proc_kwargs = kwargs . copy ()
+
r = reader (
+
path ,
+
proc_kwargs . pop ( 'vineyard_ipc_socket' ),
+
* args ,
+
handlers = handlers ,
+
accumulate = accumulate ,
+
chunk_hook = chunk_hook ,
+
** proc_kwargs
+
)
+
if r is not None :
+
return r
+
except Exception : # pylint: disable=broad-except
+
errors . append ( ' %s : %s ' % ( reader . __name__ , traceback . format_exc ()))
+
raise RuntimeError (
+
'Unable to find a proper IO driver for %s , potential causes are: \n %s '
+
% ( path , ' \n ' . join ( errors ))
+
)
+
else :
+
raise ValueError ( "No IO driver registered for %s " % path )
+
+
+[docs] @registerize
+
def write (
+
path , stream , * args , handlers = None , chunk_hook : Optional [ Callable ] = None , ** kwargs
+
):
+
"""Write the stream to a given path.
+
+
Parameters
+
----------
+
path: str
+
Path to write, the last writer registered for the scheme of the path
+
will be used.
+
stream: vineyard stream
+
Stream that produces the data to write.
+
handlers: list, optional
+
If handlers is not None, launched worker processes will be
+
emplaced into the list for further customized job lifecycle
+
management. Default is None.
+
chunk_hook: callable, optional
+
If the read/write target is a global dataframe (e.g., csv,
+
orc, parquet, etc.), the hook will be called for each chunk
+
to be read or write (usually a :code:`pyarrow.RecordBatch`).
+
The hook should return a :code:`pyarrow.RecordBatch` object
+
and should be stateless as the invoke order is not guaranteed.
+
E.g.,
+
+
.. code:: python
+
+
def exchange_column(batch):
+
import pyarrow as pa
+
+
columns = batch.columns
+
first = columns[0]
+
second = columns[1]
+
columns = [second, first] + columns[2:]
+
return pa.RecordBatch.from_arrays(columns, schema=batch.schema)
+
+
vineyard_ipc_socket: str
+
The local or remote vineyard's IPC socket location that the remote
+
readers will use to establish connections with the vineyard server.
+
vineyard_endpoint: str, optional
+
An optional address of vineyard's RPC socket, which will be used for
+
retrieving server's information on the client side. If not provided,
+
the `vineyard_ipc_socket` will be used, or it will tries to discovery
+
vineyard's IPC or RPC endpoints from environment variables.
+
"""
+
parsed = urlparse ( path )
+
if write . _factory and write . _factory . get ( parsed . scheme ):
+
errors = []
+
for writer in write . _factory [ parsed . scheme ][:: - 1 ]:
+
try :
+
proc_kwargs = kwargs . copy ()
+
writer (
+
path ,
+
stream ,
+
proc_kwargs . pop ( 'vineyard_ipc_socket' ),
+
* args ,
+
handlers = handlers ,
+
chunk_hook = chunk_hook ,
+
** proc_kwargs
+
)
+
except Exception : # pylint: disable=broad-except
+
exc = traceback . format_exc ()
+
errors . append ( ' %s : %s ' % ( writer . __name__ , exc ))
+
if 'StreamFailedException: Stream failed' in exc :
+
# if the source stream has already failed, we should
+
# fail immediately and don't try other drivers.
+
break
+
continue
+
else :
+
return
+
raise RuntimeError (
+
'Unable to find a proper IO driver for %s , potential causes are: \n %s '
+
% ( path , ' \n ' . join ( errors ))
+
)
+
else :
+
raise ValueError ( "No IO driver registered for %s " % path )
+
+
+[docs] def open (
+
path ,
+
* args ,
+
mode = 'r' ,
+
handlers = None ,
+
chunk_hook : Optional [ Callable ] = None ,
+
** kwargs
+
):
+
"""Open a path as a reader or writer, depends on the parameter :code:`mode`.
+
If :code:`mode` is :code:`r`, it will open a stream for read, and open a
+
stream for write when :code:`mode` is :code:`w`.
+
+
Parameters
+
----------
+
path: str
+
Path to open.
+
mode: char
+
Mode about how to open the path, :code:`r` is for read and :code:`w` for write.
+
handlers:
+
A dict that will be filled with a :code:`handler` that contains the process
+
handler of the underlying read/write process that can be joined using
+
:code:`join` to capture the possible errors during the I/O proceeding.
+
chunk_hook: callable, optional
+
If the read/write target is a global dataframe (e.g., csv,
+
orc, parquet, etc.), the hook will be called for each chunk
+
to be read or write (usually a :code:`pyarrow.RecordBatch`).
+
The hook should return a :code:`pyarrow.RecordBatch` object
+
and should be stateless as the invoke order is not guaranteed.
+
E.g.,
+
+
.. code:: python
+
+
def exchange_column(batch):
+
import pyarrow as pa
+
+
columns = batch.columns
+
first = columns[0]
+
second = columns[1]
+
columns = [second, first] + columns[2:]
+
return pa.RecordBatch.from_arrays(columns, schema=batch.schema)
+
+
vineyard_ipc_socket: str
+
Vineyard's IPC socket location.
+
vineyard_endpoint: str
+
Vineyard's RPC socket address.
+
+
See Also
+
--------
+
vineyard.io.read
+
vineyard.io.write
+
"""
+
parsed = urlparse ( path )
+
if not parsed . scheme :
+
path = 'file://' + path
+
+
if mode == 'r' :
+
return read ( path , * args , handlers = handlers , chunk_hook = chunk_hook , ** kwargs )
+
+
if mode == 'w' :
+
return write ( path , * args , handlers = handlers , chunk_hook = chunk_hook , ** kwargs )
+
+
raise RuntimeError ( 'Opening %s with mode %s is not supported' % ( path , mode ))
+
+
+class BaseStream :
+ class Reader :
+ def __init__ ( self , client , stream : ObjectID , resolver = None ):
+ self . _client = client
+ self . _stream = stream
+ self . _resolver = resolver
+ self . _client . open_stream ( stream , 'r' )
+
+ def next ( self ) -> object :
+ try :
+ chunk = self . _client . next_chunk ( self . _stream )
+ except StreamDrainedException as e :
+ raise StopIteration ( 'No more chunks' ) from e
+
+ if self . _resolver is not None :
+ return self . _resolver ( chunk )
+ else :
+ with resolver_context () as ctx :
+ return ctx . run ( chunk )
+
+ def next_metadata ( self ) -> ObjectMeta :
+ try :
+ return self . _client . next_chunk_meta ( self . _stream )
+ except StreamDrainedException as e :
+ raise StopIteration ( 'No more chunks' ) from e
+
+ def __str__ ( self ) -> str :
+ return repr ( self )
+
+ def __repr__ ( self ) -> str :
+ return ' %s of Stream < %r >' % ( self . __class__ , self . _stream )
+
+ class Writer :
+ def __init__ ( self , client , stream : ObjectID ):
+ self . _client = client
+ self . _stream = stream
+ self . _client . open_stream ( stream , 'w' )
+
+ def next ( self , size : int ) -> memoryview :
+ return self . _client . new_buffer_chunk ( self . _stream , size )
+
+ def append ( self , chunk : ObjectID ):
+ return self . _client . push_chunk ( self . _stream , chunk )
+
+ def fail ( self ):
+ return self . _client . stop_stream ( self . _stream , True )
+
+ def finish ( self ):
+ return self . _client . stop_stream ( self . _stream , False )
+
+ def __str__ ( self ) -> str :
+ return repr ( self )
+
+ def __repr__ ( self ) -> str :
+ return ' %s of Stream < %r >' % ( self . __class__ , self . _stream )
+
+ def __init__ ( self , meta : ObjectMeta , resolver = None ):
+ self . _meta = meta
+ self . _stream = meta . id
+ self . _resolver = resolver
+
+ self . _reader = None
+ self . _writer = None
+
+ @property
+ def id ( self ) -> ObjectID :
+ return self . _stream
+
+ @property
+ def meta ( self ) -> ObjectMeta :
+ return self . _meta
+
+ @property
+ def reader ( self ) -> "BaseStream.Reader" :
+ return self . open_reader ()
+
+ def __str__ ( self ) -> str :
+ return repr ( self )
+
+ def __repr__ ( self ) -> str :
+ return ' %s < %r >' % ( self . __class__ . __name__ , self . _stream )
+
+ def _open_new_reader ( self , client ) -> "BaseStream.Reader" :
+ '''Always open a new reader.'''
+ return BaseStream . Reader ( client , self . id , self . _resolver )
+
+ def open_reader ( self , client = None ) -> "BaseStream.Reader" :
+ if self . _reader is None :
+ if client is None :
+ client = self . _meta . _client
+ self . _reader = self . _open_new_reader ( client )
+ return self . _reader
+
+ @property
+ def writer ( self ) -> "BaseStream.Writer" :
+ return self . open_writer ()
+
+ def _open_new_writer ( self , client ) -> "BaseStream.Writer" :
+ return BaseStream . Writer ( client , self . id )
+
+ def open_writer ( self , client = None ) -> "BaseStream.Writer" :
+ if self . _writer is None :
+ if client is None :
+ client = self . _meta . _client
+ self . _writer = self . _open_new_writer ( client )
+ return self . _writer
+
+ def drop ( self , client = None ):
+ if client is None :
+ client = self . _meta . _client
+ if hasattr ( client , 'drop_stream' ):
+ client . drop_stream ( self . id )
+
+
+class StreamCollection :
+ """A stream collection is a set of stream, where each element is a stream, or,
+ another stream collection.
+ """
+
+ KEY_OF_STREAMS = '__streams'
+ KEY_OF_PATH = '__path'
+ KEY_OF_GLOBAL = '__global'
+ KEY_OF_OPTIONS = '__options'
+
+ def __init__ ( self , meta : ObjectMeta , streams : List [ ObjectID ]):
+ self . _meta = meta
+ self . _streams = streams
+ if StreamCollection . KEY_OF_GLOBAL in self . _meta :
+ self . _global = self . _meta [ StreamCollection . KEY_OF_GLOBAL ]
+ else :
+ self . _global = False
+
+ @staticmethod
+ def new (
+ client , metadata : Dict , streams : List [ ObjectID ], meta : ObjectMeta = None
+ ) -> "StreamCollection" :
+ if meta is None :
+ meta = ObjectMeta ()
+ meta [ 'typename' ] = 'vineyard::StreamCollection'
+ for k , v in metadata . items ():
+ if k not in [
+ 'id' ,
+ 'signature' ,
+ 'instance_id' ,
+ 'transient' ,
+ 'global' ,
+ 'typename' ,
+ ]:
+ meta [ k ] = v
+ meta [ StreamCollection . KEY_OF_STREAMS ] = [ int ( s ) for s in streams ]
+ meta = client . create_metadata ( meta )
+ return StreamCollection ( meta , streams )
+
+ @property
+ def id ( self ):
+ return self . meta . id
+
+ @property
+ def meta ( self ):
+ return self . _meta
+
+ @property
+ def isglobal ( self ):
+ return self . _global
+
+ @property
+ def streams ( self ):
+ return self . _streams
+
+ def __repr__ ( self ) -> str :
+ return "StreamCollection: %s [ %s ]" % (
+ repr ( self . id ),
+ [ repr ( s ) for s in self . streams ],
+ )
+
+ def __str__ ( self ) -> str :
+ return repr ( self )
+
+
+def stream_collection_resolver ( obj ):
+ meta = obj . meta
+ streams = json . loads ( meta [ StreamCollection . KEY_OF_STREAMS ])
+ return StreamCollection ( meta , [ ObjectID ( s ) for s in streams ])
+
+
+def register_stream_collection_types ( _builder_ctx , resolver_ctx ):
+ if resolver_ctx is not None :
+ resolver_ctx . register ( 'vineyard::StreamCollection' , stream_collection_resolver )
+
+
+__all__ = [
+ 'open' ,
+ 'read' ,
+ 'write' ,
+ 'BaseStream' ,
+ 'StreamCollection' ,
+ 'register_stream_collection_types' ,
+]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_modules/vineyard/shared_memory/shared_memory.html b/_modules/vineyard/shared_memory/shared_memory.html
new file mode 100644
index 0000000000..fe39e207fc
--- /dev/null
+++ b/_modules/vineyard/shared_memory/shared_memory.html
@@ -0,0 +1,813 @@
+
+
+
+
+
+
+
+ vineyard.shared_memory.shared_memory - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+ Source code for vineyard.shared_memory.shared_memory
+#! /usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright 2020-2023 Alibaba Group Holding Limited.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+'''
+The shared_memory module provides similar interface like multiprocessing.shared_memory
+for direct access shared memory backed by vineyard across processes.
+
+The API is kept consistent with multiprocessing.shared_memory but the semantics is
+slightly different. For vineyard, to make the shared memory visible for other process,
+a explicitly ``seal`` or ``close`` operation is needed.
+
+Refer to the documentation of multiprocessing.shared_memory for details.
+'''
+
+# pylint: skip-file
+
+try :
+ import multiprocessing.shared_memory as shm
+except ImportError :
+ # multiprocessing.shared_memory is available since Python 3.8, we use the slim
+ # library for earlier version of Python.
+ #
+ # see also github #327.
+ import shared_memory as shm
+
+import struct
+import warnings
+
+from vineyard._C import ObjectID
+
+
+[docs] class SharedMemory :
+
def __init__ ( self , vineyard_client , name = None , create = False , size = 0 ):
+
"""Create or obtain a shared memory block that backed by vineyard.
+
+
Parameters
+
----------
+
vineyard_client:
+
The vineyard IPC or RPC client.
+
name:
+
The vineyard ObjectID, could be vineyard.ObjectID, int or stringified
+
ObjectID.
+
create:
+
Whether to create a new shared memory block or just obtain existing one.
+
size:
+
Size of the shared memory block.
+
+
See Also
+
--------
+
multiprocessing.shared_memory.SharedMemory
+
"""
+
if not size >= 0 :
+
raise ValueError ( "'size' must be a positive integer" )
+
if create :
+
if size == 0 :
+
raise ValueError (
+
"'size' must be a positive number " "different from zero"
+
)
+
if name is not None :
+
raise ValueError ( "'name' can only be None if create=True" )
+
else :
+
if size != 0 :
+
warnings . warn (
+
"'size' will take no effect if create=False" ,
+
)
+
if name is None :
+
raise ValueError ( "'name' cannot be None if create=False" )
+
+
self . _name = None
+
self . _size = None
+
self . _buf = None
+
self . _blob , self . _blob_builder = None , None
+
self . _vineyard_client = vineyard_client
+
+
if create :
+
self . _blob_builder = vineyard_client . create_blob ( size )
+
self . _name = self . _blob_builder . id
+
self . _size = size
+
self . _buf = memoryview ( self . _blob_builder )
+
else :
+
self . _blob = vineyard_client . get_object ( ObjectID ( name ))
+
self . _name = self . _blob . id
+
self . _size = self . _blob . size
+
self . _buf = memoryview ( self . _blob )
+
+
def __del__ ( self ):
+
try :
+
self . close ()
+
except Exception :
+
pass
+
+
def __reduce__ ( self ):
+
return (
+
self . __class__ ,
+
(
+
self . name ,
+
False ,
+
self . size ,
+
),
+
)
+
+
def __repr__ ( self ):
+
return f ' { self . __class__ . __name__ } ( { self . name !r} , size= { self . size } )'
+
+
@property
+
def buf ( self ):
+
"A memoryview of contents of the shared memory block."
+
return self . _buf
+
+
@property
+
def name ( self ):
+
"Unique name that identifies the shared memory block."
+
return repr ( self . _name )
+
+
@property
+
def size ( self ):
+
"Size in bytes."
+
return self . _size
+
+
[docs] def freeze ( self ):
+
"Seal the shared memory to make it visible for other processes."
+
if self . _blob_builder :
+
self . _blob = self . _blob_builder . seal ( self . _vineyard_client )
+
self . _blob_builder = None
+
return self
+
+
def close ( self ):
+
self . freeze ()
+
+
[docs] def unlink ( self ):
+
"""Requests that the underlying shared memory block be destroyed."""
+
if self . _blob :
+
self . _vineyard_client . delete ( self . _blob . id )
+
self . _blob = None
+
else :
+
self . _blob_builder . abort ( self . _vineyard_client )
+
self . _blob_builder = None
+
self . _buf = None
+
+
+_encoding = "utf8"
+
+
+[docs] class ShareableList ( shm . ShareableList ):
+
"""
+
Pattern for a mutable list-like object shareable via a shared
+
memory block. It differs from the built-in list type in that these
+
lists can not change their overall length (i.e. no append, insert,
+
etc.)
+
+
Because values are packed into a memoryview as bytes, the struct
+
packing format for any storable value must require no more than 8
+
characters to describe its format.
+
+
The ShareableList in vineyard differs slightly with its equivalent
+
in the multiprocessing.shared_memory.ShareableList, as it becomes
+
immutable after obtaining from the vineyard backend.
+
+
See Also
+
--------
+
multiprocessing.shared_memory.ShareableList
+
"""
+
+
# note that the implementation of ``__init__`` entirely comes from
+
# multiprocessing.shared_memory.
+
#
+
# and note that
+
#
+
# https://github.com/python/cpython/commit/c8f1715283ec51822fb37a702bf253cbac1af276
+
#
+
# has made a set of changes to the ``ShareableList`` code.
+
#
+
def __init__ ( self , vineyard_client , sequence = None , * , name = None ):
+
if name is None or sequence is not None :
+
if name is not None :
+
warnings . warn (
+
"'name' will take no effect as we are going to "
+
"create a ShareableList" ,
+
)
+
+
sequence = sequence or ()
+
_formats = [
+
(
+
self . _types_mapping [ type ( item )]
+
if not isinstance ( item , ( str , bytes )) # noqa: E131
+
else self . _types_mapping [ type ( item )]
+
% (
+
self . _alignment * ( len ( item ) // self . _alignment + 1 ),
+
) # noqa: E131
+
)
+
for item in sequence
+
]
+
self . _list_len = len ( _formats )
+
assert sum ( len ( fmt ) <= 8 for fmt in _formats ) == self . _list_len
+
offset = 0
+
# The offsets of each list element into the shared memory's
+
# data area (0 meaning the start of the data area, not the start
+
# of the shared memory area).
+
self . _allocated_offsets = [ 0 ]
+
for fmt in _formats :
+
offset += self . _alignment if fmt [ - 1 ] != "s" else int ( fmt [: - 1 ])
+
self . _allocated_offsets . append ( offset )
+
_recreation_codes = [
+
self . _extract_recreation_code ( item ) for item in sequence
+
]
+
requested_size = struct . calcsize (
+
"q"
+
+ self . _format_size_metainfo
+
+ "" . join ( _formats )
+
+ self . _format_packing_metainfo
+
+ self . _format_back_transform_codes
+
)
+
+
self . shm = SharedMemory ( vineyard_client , create = True , size = requested_size )
+
else :
+
self . shm = SharedMemory ( vineyard_client , name )
+
+
if sequence is not None :
+
_enc = _encoding
+
struct . pack_into (
+
"q" + self . _format_size_metainfo ,
+
self . shm . buf ,
+
0 ,
+
self . _list_len ,
+
* ( self . _allocated_offsets ),
+
)
+
struct . pack_into (
+
"" . join ( _formats ),
+
self . shm . buf ,
+
self . _offset_data_start ,
+
* ( v . encode ( _enc ) if isinstance ( v , str ) else v for v in sequence ),
+
)
+
struct . pack_into (
+
self . _format_packing_metainfo ,
+
self . shm . buf ,
+
self . _offset_packing_formats ,
+
* ( v . encode ( _enc ) for v in _formats ),
+
)
+
struct . pack_into (
+
self . _format_back_transform_codes ,
+
self . shm . buf ,
+
self . _offset_back_transform_codes ,
+
* ( _recreation_codes ),
+
)
+
+
else :
+
self . _list_len = len ( self ) # Obtains size from offset 0 in buffer.
+
self . _allocated_offsets = list (
+
struct . unpack_from ( self . _format_size_metainfo , self . shm . buf , 1 * 8 )
+
)
+
+
def _get_back_transform ( self , position ):
+
"Gets the back transformation function for a single value."
+
+
if ( position >= self . _list_len ) or ( self . _list_len < 0 ):
+
raise IndexError ( "Requested position out of range." )
+
+
transform_code = struct . unpack_from (
+
"b" , self . shm . buf , self . _offset_back_transform_codes + position
+
)[ 0 ]
+
transform_function = self . _back_transforms_mapping [ transform_code ]
+
+
return transform_function
+
+
def _set_packing_format_and_transform ( self , position , fmt_as_str , value ):
+
"""Sets the packing format and back transformation code for a
+
single value in the list at the specified position."""
+
+
if ( position >= self . _list_len ) or ( self . _list_len < 0 ):
+
raise IndexError ( "Requested position out of range." )
+
+
struct . pack_into (
+
"8s" ,
+
self . shm . buf ,
+
self . _offset_packing_formats + position * 8 ,
+
fmt_as_str . encode ( _encoding ),
+
)
+
+
transform_code = self . _extract_recreation_code ( value )
+
struct . pack_into (
+
"b" ,
+
self . shm . buf ,
+
self . _offset_back_transform_codes + position ,
+
transform_code ,
+
)
+
+
def __getitem__ ( self , position ):
+
position = position if position >= 0 else position + self . _list_len
+
try :
+
offset = self . _offset_data_start + self . _allocated_offsets [ position ]
+
( v ,) = struct . unpack_from (
+
self . _get_packing_format ( position ), self . shm . buf , offset
+
)
+
except IndexError :
+
raise IndexError ( "index out of range" )
+
+
back_transform = self . _get_back_transform ( position )
+
v = back_transform ( v )
+
+
return v
+
+
def __setitem__ ( self , position , value ):
+
position = position if position >= 0 else position + self . _list_len
+
try :
+
item_offset = self . _allocated_offsets [ position ]
+
offset = self . _offset_data_start + item_offset
+
current_format = self . _get_packing_format ( position )
+
except IndexError :
+
raise IndexError ( "assignment index out of range" )
+
+
if not isinstance ( value , ( str , bytes )):
+
new_format = self . _types_mapping [ type ( value )]
+
encoded_value = value
+
else :
+
allocated_length = self . _allocated_offsets [ position + 1 ] - item_offset
+
+
encoded_value = value . encode ( _encoding ) if isinstance ( value , str ) else value
+
if len ( encoded_value ) > allocated_length :
+
raise ValueError ( "bytes/str item exceeds available storage" )
+
if current_format [ - 1 ] == "s" :
+
new_format = current_format
+
else :
+
new_format = self . _types_mapping [ str ] % ( allocated_length ,)
+
+
self . _set_packing_format_and_transform ( position , new_format , value )
+
struct . pack_into ( new_format , self . shm . buf , offset , encoded_value )
+
+
@property
+
def _format_size_metainfo ( self ):
+
"The struct packing format used for the items' storage offsets."
+
return "q" * ( self . _list_len + 1 )
+
+
@property
+
def _format_packing_metainfo ( self ):
+
"The struct packing format used for the items' packing formats."
+
return "8s" * self . _list_len
+
+
@property
+
def _format_back_transform_codes ( self ):
+
"The struct packing format used for the items' back transforms."
+
return "b" * self . _list_len
+
+
@property
+
def _offset_data_start ( self ):
+
# - 8 bytes for the list length
+
# - (N + 1) * 8 bytes for the element offsets
+
return ( self . _list_len + 2 ) * 8
+
+
@property
+
def _offset_packing_formats ( self ):
+
return self . _offset_data_start + self . _allocated_offsets [ - 1 ]
+
+
@property
+
def _offset_back_transform_codes ( self ):
+
return self . _offset_packing_formats + self . _list_len * 8
+
+
[docs] def freeze ( self ):
+
'''Make the shareable list immutable and visible for other vineyard clients.'''
+
self . shm . freeze ()
+
+
+__all__ = [ 'SharedMemory' , 'ShareableList' ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_panels_static/panels-bootstrap.5fd3999ee7762ccc51105388f4a9d115.css b/_panels_static/panels-bootstrap.5fd3999ee7762ccc51105388f4a9d115.css
new file mode 100644
index 0000000000..1b057df2f2
--- /dev/null
+++ b/_panels_static/panels-bootstrap.5fd3999ee7762ccc51105388f4a9d115.css
@@ -0,0 +1 @@
+.badge{border-radius:.25rem;display:inline-block;font-size:75%;font-weight:700;line-height:1;padding:.25em .4em;text-align:center;vertical-align:baseline;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{border-radius:10rem;padding-left:.6em;padding-right:.6em}.badge-primary{background-color:#007bff;color:#fff}.badge-primary[href]:focus,.badge-primary[href]:hover{background-color:#0062cc;color:#fff;text-decoration:none}.badge-secondary{background-color:#6c757d;color:#fff}.badge-secondary[href]:focus,.badge-secondary[href]:hover{background-color:#545b62;color:#fff;text-decoration:none}.badge-success{background-color:#28a745;color:#fff}.badge-success[href]:focus,.badge-success[href]:hover{background-color:#1e7e34;color:#fff;text-decoration:none}.badge-info{background-color:#17a2b8;color:#fff}.badge-info[href]:focus,.badge-info[href]:hover{background-color:#117a8b;color:#fff;text-decoration:none}.badge-warning{background-color:#ffc107;color:#212529}.badge-warning[href]:focus,.badge-warning[href]:hover{background-color:#d39e00;color:#212529;text-decoration:none}.badge-danger{background-color:#dc3545;color:#fff}.badge-danger[href]:focus,.badge-danger[href]:hover{background-color:#bd2130;color:#fff;text-decoration:none}.badge-light{background-color:#f8f9fa;color:#212529}.badge-light[href]:focus,.badge-light[href]:hover{background-color:#dae0e5;color:#212529;text-decoration:none}.badge-dark{background-color:#343a40;color:#fff}.badge-dark[href]:focus,.badge-dark[href]:hover{background-color:#1d2124;color:#fff;text-decoration:none}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;color:#212529;cursor:pointer;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;transition:color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:middle}.btn:hover{color:#212529;text-decoration:none}.btn:visited{color:#212529}.btn.focus,.btn:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.25);outline:0}.btn.disabled,.btn:disabled{opacity:.65}@media (prefers-reduced-motion: reduce){.btn{transition:none}}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{background-color:#007bff;border-color:#007bff;color:#fff}.btn-primary:visited{color:#fff}.btn-primary:hover{background-color:#0069d9;border-color:#0062cc;color:#fff}.btn-primary.focus,.btn-primary:focus{background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(0,123,255,0.5);color:#fff}.btn-primary.disabled,.btn-primary:disabled{background-color:#007bff;border-color:#007bff;color:#fff}.btn-primary.active:not(:disabled):not(.disabled),.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{background-color:#0062cc;border-color:#005cbf;color:#fff}.btn-primary.active:not(:disabled):not(.disabled):focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-secondary{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-secondary:visited{color:#fff}.btn-secondary:hover{background-color:#5a6268;border-color:#545b62;color:#fff}.btn-secondary.focus,.btn-secondary:focus{background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(108,117,125,0.5);color:#fff}.btn-secondary.disabled,.btn-secondary:disabled{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-secondary.active:not(:disabled):not(.disabled),.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{background-color:#545b62;border-color:#4e555b;color:#fff}.btn-secondary.active:not(:disabled):not(.disabled):focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-success{background-color:#28a745;border-color:#28a745;color:#fff}.btn-success:visited{color:#fff}.btn-success:hover{background-color:#218838;border-color:#1e7e34;color:#fff}.btn-success.focus,.btn-success:focus{background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(40,167,69,0.5);color:#fff}.btn-success.disabled,.btn-success:disabled{background-color:#28a745;border-color:#28a745;color:#fff}.btn-success.active:not(:disabled):not(.disabled),.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{background-color:#1e7e34;border-color:#1c7430;color:#fff}.btn-success.active:not(:disabled):not(.disabled):focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-info{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-info:visited{color:#fff}.btn-info:hover{background-color:#138496;border-color:#117a8b;color:#fff}.btn-info.focus,.btn-info:focus{background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(23,162,184,0.5);color:#fff}.btn-info.disabled,.btn-info:disabled{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-info.active:not(:disabled):not(.disabled),.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{background-color:#117a8b;border-color:#10707f;color:#fff}.btn-info.active:not(:disabled):not(.disabled):focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-warning{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-warning:visited{color:#212529}.btn-warning:hover{background-color:#e0a800;border-color:#d39e00;color:#212529}.btn-warning.focus,.btn-warning:focus{background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(255,193,7,0.5);color:#212529}.btn-warning.disabled,.btn-warning:disabled{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-warning.active:not(:disabled):not(.disabled),.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{background-color:#d39e00;border-color:#c69500;color:#212529}.btn-warning.active:not(:disabled):not(.disabled):focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-danger{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-danger:visited{color:#fff}.btn-danger:hover{background-color:#c82333;border-color:#bd2130;color:#fff}.btn-danger.focus,.btn-danger:focus{background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(220,53,69,0.5);color:#fff}.btn-danger.disabled,.btn-danger:disabled{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-danger.active:not(:disabled):not(.disabled),.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{background-color:#bd2130;border-color:#b21f2d;color:#fff}.btn-danger.active:not(:disabled):not(.disabled):focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-light{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-light:visited{color:#212529}.btn-light:hover{background-color:#e2e6ea;border-color:#dae0e5;color:#212529}.btn-light.focus,.btn-light:focus{background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(248,249,250,0.5);color:#212529}.btn-light.disabled,.btn-light:disabled{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-light.active:not(:disabled):not(.disabled),.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{background-color:#dae0e5;border-color:#d3d9df;color:#212529}.btn-light.active:not(:disabled):not(.disabled):focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-dark{background-color:#343a40;border-color:#343a40;color:#fff}.btn-dark:visited{color:#fff}.btn-dark:hover{background-color:#23272b;border-color:#1d2124;color:#fff}.btn-dark.focus,.btn-dark:focus{background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(52,58,64,0.5);color:#fff}.btn-dark.disabled,.btn-dark:disabled{background-color:#343a40;border-color:#343a40;color:#fff}.btn-dark.active:not(:disabled):not(.disabled),.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{background-color:#1d2124;border-color:#171a1d;color:#fff}.btn-dark.active:not(:disabled):not(.disabled):focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-primary{border-color:#007bff;color:#007bff}.btn-outline-primary:visited{color:#007bff}.btn-outline-primary:hover{background-color:#007bff;border-color:#007bff;color:#fff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{background-color:transparent;color:#007bff}.btn-outline-primary.active:not(:disabled):not(.disabled),.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{background-color:#007bff;border-color:#007bff;color:#fff}.btn-outline-primary.active:not(:disabled):not(.disabled):focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-secondary{border-color:#6c757d;color:#6c757d}.btn-outline-secondary:visited{color:#6c757d}.btn-outline-secondary:hover{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{background-color:transparent;color:#6c757d}.btn-outline-secondary.active:not(:disabled):not(.disabled),.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-outline-secondary.active:not(:disabled):not(.disabled):focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-success{border-color:#28a745;color:#28a745}.btn-outline-success:visited{color:#28a745}.btn-outline-success:hover{background-color:#28a745;border-color:#28a745;color:#fff}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{background-color:transparent;color:#28a745}.btn-outline-success.active:not(:disabled):not(.disabled),.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{background-color:#28a745;border-color:#28a745;color:#fff}.btn-outline-success.active:not(:disabled):not(.disabled):focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-info{border-color:#17a2b8;color:#17a2b8}.btn-outline-info:visited{color:#17a2b8}.btn-outline-info:hover{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{background-color:transparent;color:#17a2b8}.btn-outline-info.active:not(:disabled):not(.disabled),.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-outline-info.active:not(:disabled):not(.disabled):focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-warning{border-color:#ffc107;color:#ffc107}.btn-outline-warning:visited{color:#ffc107}.btn-outline-warning:hover{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{background-color:transparent;color:#ffc107}.btn-outline-warning.active:not(:disabled):not(.disabled),.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-outline-warning.active:not(:disabled):not(.disabled):focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-danger{border-color:#dc3545;color:#dc3545}.btn-outline-danger:visited{color:#dc3545}.btn-outline-danger:hover{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{background-color:transparent;color:#dc3545}.btn-outline-danger.active:not(:disabled):not(.disabled),.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-outline-danger.active:not(:disabled):not(.disabled):focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-light{border-color:#f8f9fa;color:#f8f9fa}.btn-outline-light:visited{color:#f8f9fa}.btn-outline-light:hover{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{background-color:transparent;color:#f8f9fa}.btn-outline-light.active:not(:disabled):not(.disabled),.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-outline-light.active:not(:disabled):not(.disabled):focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-dark{border-color:#343a40;color:#343a40}.btn-outline-dark:visited{color:#343a40}.btn-outline-dark:hover{background-color:#343a40;border-color:#343a40;color:#fff}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{background-color:transparent;color:#343a40}.btn-outline-dark.active:not(:disabled):not(.disabled),.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{background-color:#343a40;border-color:#343a40;color:#fff}.btn-outline-dark.active:not(:disabled):not(.disabled):focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-link{color:#007bff;font-weight:400;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{box-shadow:none;text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{border-radius:.3rem;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.btn-group-sm>.btn,.btn-sm{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input.btn-block[type=button],input.btn-block[type=reset],input.btn-block[type=submit]{width:100%}.stretched-link::after{background-color:rgba(0,0,0,0);bottom:0;content:'';left:0;pointer-events:auto;position:absolute;right:0;top:0;z-index:1}.text-wrap{white-space:normal !important}.card{background-clip:border-box;background-color:#fff;border:1px solid rgba(0,0,0,0.125);border-radius:.25rem;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.card>hr{margin-left:0;margin-right:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-bottom:0;margin-top:-.375rem}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{background-color:rgba(0,0,0,0.03);border-bottom:1px solid rgba(0,0,0,0.125);margin-bottom:0;padding:.75rem 1.25rem}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{background-color:rgba(0,0,0,0.03);border-top:1px solid rgba(0,0,0,0.125);padding:.75rem 1.25rem}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{border-bottom:0;margin-bottom:-.75rem;margin-left:-.625rem;margin-right:-.625rem}.card-header-pills{margin-left:-.625rem;margin-right:-.625rem}.card-img-overlay{bottom:0;left:0;padding:1.25rem;position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px)}.w-100{width:100% !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.bg-primary{background-color:#007bff !important}button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc !important}a.bg-primary:focus,a.bg-primary:hover{background-color:#0062cc !important}a.text-primary:focus,a.text-primary:hover{color:#121416 !important}.bg-secondary{background-color:#6c757d !important}button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62 !important}a.bg-secondary:focus,a.bg-secondary:hover{background-color:#545b62 !important}a.text-secondary:focus,a.text-secondary:hover{color:#121416 !important}.bg-success{background-color:#28a745 !important}button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34 !important}a.bg-success:focus,a.bg-success:hover{background-color:#1e7e34 !important}a.text-success:focus,a.text-success:hover{color:#121416 !important}.bg-info{background-color:#17a2b8 !important}button.bg-info:focus,button.bg-info:hover{background-color:#117a8b !important}a.bg-info:focus,a.bg-info:hover{background-color:#117a8b !important}a.text-info:focus,a.text-info:hover{color:#121416 !important}.bg-warning{background-color:#ffc107 !important}button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00 !important}a.bg-warning:focus,a.bg-warning:hover{background-color:#d39e00 !important}a.text-warning:focus,a.text-warning:hover{color:#121416 !important}.bg-danger{background-color:#dc3545 !important}button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130 !important}a.bg-danger:focus,a.bg-danger:hover{background-color:#bd2130 !important}a.text-danger:focus,a.text-danger:hover{color:#121416 !important}.bg-light{background-color:#f8f9fa !important}button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5 !important}a.bg-light:focus,a.bg-light:hover{background-color:#dae0e5 !important}a.text-light:focus,a.text-light:hover{color:#121416 !important}.bg-dark{background-color:#343a40 !important}button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124 !important}a.bg-dark:focus,a.bg-dark:hover{background-color:#1d2124 !important}a.text-dark:focus,a.text-dark:hover{color:#121416 !important}.bg-white{background-color:#fff !important}button.bg-white:focus,button.bg-white:hover{background-color:#e6e6e6 !important}a.bg-white:focus,a.bg-white:hover{background-color:#e6e6e6 !important}a.text-white:focus,a.text-white:hover{color:#121416 !important}.text-primary{color:#007bff !important}.text-secondary{color:#6c757d !important}.text-success{color:#28a745 !important}.text-info{color:#17a2b8 !important}.text-warning{color:#ffc107 !important}.text-danger{color:#dc3545 !important}.text-light{color:#f8f9fa !important}.text-dark{color:#343a40 !important}.text-white{color:#fff !important}.text-body{color:#212529 !important}.text-muted{color:#6c757d !important}.text-black-50{color:rgba(0,0,0,0.5) !important}.text-white-50{color:rgba(255,255,255,0.5) !important}.bg-transparent{background-color:transparent !important}.text-justify{text-align:justify !important}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.font-weight-light{font-weight:300 !important}.font-weight-lighter{font-weight:lighter !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-weight-bolder{font-weight:bolder !important}.font-italic{font-style:italic !important}.container{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container{max-width:960px}}@media (min-width: 1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width: 992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width: 1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-left:-15px;margin-right:-15px}.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{padding-left:15px;padding-right:15px;position:relative;width:100%}@media (min-width: 576px){.col-sm{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-sm-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media (min-width: 768px){.col-md{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-md-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media (min-width: 992px){.col-lg{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-lg-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media (min-width: 1200px){.col-xl{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-xl-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}.d-flex{display:-ms-flexbox !important;display:flex !important}.sphinx-bs,.sphinx-bs *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sphinx-bs p{margin-top:0}
diff --git a/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css b/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css
new file mode 100644
index 0000000000..fc14abc85d
--- /dev/null
+++ b/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css
@@ -0,0 +1 @@
+details.dropdown .summary-title{padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.dropdown:hover{cursor:pointer}details.dropdown .summary-content{cursor:default}details.dropdown summary{list-style:none;padding:1em}details.dropdown summary .octicon.no-title{vertical-align:middle}details.dropdown[open] summary .octicon.no-title{visibility:hidden}details.dropdown summary::-webkit-details-marker{display:none}details.dropdown summary:focus{outline:none}details.dropdown summary:hover .summary-up svg,details.dropdown summary:hover .summary-down svg{opacity:1}details.dropdown .summary-up svg,details.dropdown .summary-down svg{display:block;opacity:.6}details.dropdown .summary-up,details.dropdown .summary-down{pointer-events:none;position:absolute;right:1em;top:.75em}details.dropdown[open] .summary-down{visibility:hidden}details.dropdown:not([open]) .summary-up{visibility:hidden}details.dropdown.fade-in[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out;animation:panels-fade-in .5s ease-in-out}details.dropdown.fade-in-slide-down[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out}@keyframes panels-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes panels-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.octicon{display:inline-block;fill:currentColor;vertical-align:text-top}.tabbed-content{box-shadow:0 -.0625rem var(--tabs-color-overline),0 .0625rem var(--tabs-color-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.tabbed-content>:first-child{margin-top:0 !important}.tabbed-content>:last-child{margin-bottom:0 !important}.tabbed-content>.tabbed-set{margin:0}.tabbed-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.tabbed-set>input{opacity:0;position:absolute}.tabbed-set>input:checked+label{border-color:var(--tabs-color-label-active);color:var(--tabs-color-label-active)}.tabbed-set>input:checked+label+.tabbed-content{display:block}.tabbed-set>input:focus+label{outline-style:auto}.tabbed-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.tabbed-set>label{border-bottom:.125rem solid transparent;color:var(--tabs-color-label-inactive);cursor:pointer;font-size:var(--tabs-size-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .tabbed-set>label:hover{color:var(--tabs-color-label-active)}
diff --git a/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css b/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css
new file mode 100644
index 0000000000..adc6166222
--- /dev/null
+++ b/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css
@@ -0,0 +1,7 @@
+:root {
+--tabs-color-label-active: hsla(231, 99%, 66%, 1);
+--tabs-color-label-inactive: rgba(178, 206, 245, 0.62);
+--tabs-color-overline: rgb(207, 236, 238);
+--tabs-color-underline: rgb(207, 236, 238);
+--tabs-size-label: 1rem;
+}
\ No newline at end of file
diff --git a/_sources/cncf/2022-vineyard-annual.md.txt b/_sources/cncf/2022-vineyard-annual.md.txt
new file mode 100644
index 0000000000..909d49b260
--- /dev/null
+++ b/_sources/cncf/2022-vineyard-annual.md.txt
@@ -0,0 +1,149 @@
+# Vineyard 2022 Annual Review
+
+## Background
+
+[Vineyard](https://v6d.io) is an in-memory immutable data manager that provides
+**out-of-the-box high-level** abstraction and **zero-copy in-memory** sharing for
+distributed data in big data tasks, such as graph analytics, numerical computing, and
+machine learning.
+
+**Vineyard provides**:
+
+1. Efficient in-memory data management and zero-copy sharing across different systems.
+2. Out-of-the-box high-level data abstraction for distributed objects (e.g., tensors, tables,
+ graphs) and efficient polyglot support (currently including C++, Python, and Java).
+3. Built-in streaming support for data accessing and across system pipelining.
+4. An extensible driver framework and a set of efficient built-in drivers for eliminating
+ the boilerplate part in computation engines, e.g., I/O, serialization, and checkpointing.
+
+**Alignment with CNCF**:
+
+1. Vineyard builds on Kubernetes for deploying and scaling and the objects are observable
+ in Kubernetes as CRDs.
+2. Vineyard makes efficient zero-copy sharing possible for data-intensive workflows on
+ cloud-native infrastructure by a data-aware Kubernetes scheduler plugin.
+3. Vineyard adopts a immutable object design, which aligns with the immutable infrastructure
+ of the cloud-native environment.
+
+**Vineyard was accepted as a CNCF sandbox project on Apr 28th, 2021.**
+
+## DevStats
+
+> Include a link to your project’s devstats page. We will be looking for signs of consistent
+> or increasing contribution activity. Please feel free to add commentary to add colour to
+> the numbers and graphs we will see on devstats.
+
+- Stargazers and Forks
+ - [https://vineyard.devstats.cncf.io/d/3/stars-and-forks-by-repository?orgId=1&from=now-2y&to=now](https://vineyard.devstats.cncf.io/d/3/stars-and-forks-by-repository?orgId=1&from=now-2y&to=now)
+- Commits per week
+ - [https://vineyard.devstats.cncf.io/d/1/activity-repository-groups?orgId=1&var-period=w&var-repogroups=All&from=now-6M&to=now](https://vineyard.devstats.cncf.io/d/1/activity-repository-groups?orgId=1&var-period=w&var-repogroups=All&from=now-6M&to=now)
+- Contributors and Companies
+ - [https://vineyard.devstats.cncf.io/d/7/companies-contributing-in-repository-groups?orgId=1&var-period=d7&var-repogroup_name=All&from=now-1y&to=now](https://vineyard.devstats.cncf.io/d/7/companies-contributing-in-repository-groups?orgId=1&var-period=d7&var-repogroup_name=All&from=now-1y&to=now)
+
+The vineyard community has grown since the project entered the CNCF sandbox.
+
+- Number of contributors: 11 -> 26
+- Github stars: 300+ -> 600+
+- Github forks: 20+ -> 80+
+- Contributing organizations: 1 -> 12
+
+## Maintainers
+
+> How many maintainers do you have, and which organisations are they from? (Feel free
+> to link to an existing MAINTAINERS file if appropriate.)
+
+We currently have 7 maintainers and 2 committers and have [a maintainer list on Github](https://github.com/v6d-io/v6d/blob/main/MAINTAINERS.md).
+
+- **Initial maintainers**
+
+ | Name | GitHub ID | Affiliation | Email |
+ | --- | --- | --- | --- |
+ | Tao He | [sighingnow](https://github.com/sighingnow) | Alibaba | [linzhu.ht@alibaba-inc.com](mailto:linzhu.ht@alibaba-inc.com) |
+ | Xiaojian Luo | [luoxiaojian](https://github.com/luoxiaojian) | Alibaba | [lxj193371@alibaba-inc.com](mailto:lxj193371@alibaba-inc.com) |
+ | Wenyuan Yu | [wenyuanyu](https://github.com/wenyuanyu) | Alibaba | [wenyuan.ywy@alibaba-inc.com](mailto:wenyuan.ywy@alibaba-inc.com) |
+ | Weibin Zeng | [acezen](https://github.com/acezen) | Alibaba | [qiaozi.zwb@alibaba-inc.com](mailto:qiaozi.zwb@alibaba-inc.com) |
+ | Siyuan Zhang | [siyuan0322](https://github.com/siyuan0322) | Alibaba | [siyuanzhang.zsy@alibaba-inc.com](mailto:siyuanzhang.zsy@alibaba-inc.com) |
+ | Diwen Zhu | [andydiwenzhu](https://github.com/andydiwenzhu) | Alibaba | [diwen.zdw@alibaba-inc.com](mailto:diwen.zdw@alibaba-inc.com) |
+
+- **New maintainers in this year**
+
+ | Name | GitHub ID | Affiliation | Email |
+ | --- | --- | --- | --- |
+ | Ke Meng | [septicmk](https://github.com/septicmk) | Alibaba | [mengke.mk@alibaba-inc.com](mailto:mengke.mk@alibaba-inc.com) |
+
+- **New Committers in this year**
+
+ | Name | GitHub ID | Affiliation | Email |
+ | --- | --- | --- | --- |
+ | Lihong Lin | [linlih](https://github.com/linlih) | PKU | [linlh@stu.pku.edu.cn](mailto:linlh@stu.pku.edu.cn) |
+ | Pei Li | [peilii](https://github.com/peilii) | CMU | [peili.dev@gmail.com](mailto:peili.dev@gmail.com) |
+
+## Adoption
+
+> What do you know about adoption, and how has this changed since your last review / since
+> you joined Sandbox? If you can list companies that are end-users of your project, please
+> do so. (Feel free to link to an existing ADOPTERS file if appropriate.)
+
+We know several cases where vineyard has been adopted in both testing and production environments.
+
+- _GraphScope_: production stage
+ - _GraphScope_ is an open-source graph processing platform.
+ - Vineyard is used in graphscope to provide distributed shared in-memory storage for different
+ graph processing engines.
+- _weilaisudu_: transiting from testing to production stage
+ - _weilaisudu_ is the company behind the project [Mars](https://github.com/mars-project/mars),
+ a distributed scientific computing engine that provides numpy and pandas like API.
+ - Vineyard is used as the shared-memory storage for actors that do computation on chunks.
+- _ESRF_: testing stage
+ - _ESRF_ is a joint research facility situated in France, one of the biggest x-ray science
+ facilities in Europe.
+ - VIneyard is used in the BLISS software to serve as the shared storage between sensors and
+ data processing jobs.
+- _PingAn_: testing stage
+ - _PingAn_ is a large-scale fin-tech company in China.
+ - Vineyard is used in a research platform to support efficient dataset sharing and management
+ among data science researchers.
+
+We have also integrated with the apache-airflow project, which is a workflow orchestration engine
+and has been widely adopted. We have published airflow-vineyard-provider on Astronomer Registry
+and received much feedback from end-users, but we haven't tracked the actual adoption yet.
+
+## Project Goals
+
+> How has the project performed against its goals since the last review? (We won't penalize you
+> if your goals changed for good reasons.)
+
+Vineyard has successfully archived the goal of bringing value to big data analytical workflows
+on Kubernetes. We have shown the gain in an internal project which involves both ETL, graph
+computation, and machine learning jobs.
+
+Our goal hasn't changed since becoming CNCF sandbox project and we are still aiming at supporting
+a more efficient big data analytical workflow on the cloud-native infrastructure. Specifically,
+we'll keep moving towards following goals in the next year:
+
+1. Providing efficient cross-engine data sharing for data-intensive workflows in Kubernetes
+2. Integrating with projects in the cloud-native community for orchestration and scheduling
+ and integrating with more big data computing engines to improve the end-to-end efficiency.
+3. Building a new cloud-native paradigm for big data applications working together. By
+ integrating Vineyard, Kubernetes can help orchestrating data and workloads together for
+ better alignment and efficiency.
+
+We still need to do more to engage end-users to show the value-added of the vineyard project.
+
+## CNCF membership
+
+> How can the CNCF help you achieve your upcoming goals?
+
+Vineyard has incredibly benefited from CNCF since accepted as a sandbox project. We believe
+the end-users in the CNCF community are critical for Vineyard to become successful. We have
+submitted proposals for the KubeCon and CNCF Conferences in the past year but got rejected.
+We hope we could have more opportunities to introduce our project to border end-users in the
+CNCF community to increase adoption.
+
+## Incubation
+
+> Do you think that your project meets the [criteria for incubation](https://github.com/cncf/toc/blob/master/process/graduation_criteria.adoc#incubating-stage)?
+
+We think our project vineyard still needs further exploration to get border adoption in the
+production environment and we are looking forward to meeting the incubation criteria in near
+future.
diff --git a/_sources/cncf/2023-vineyard-annual.md.txt b/_sources/cncf/2023-vineyard-annual.md.txt
new file mode 100644
index 0000000000..d5c00feae2
--- /dev/null
+++ b/_sources/cncf/2023-vineyard-annual.md.txt
@@ -0,0 +1,208 @@
+# Vineyard 2023 Annual Review
+
+## Background
+
+[Vineyard](https://v6d.io) is an in-memory immutable data manager that provides
+**out-of-the-box high-level** abstraction and **zero-copy in-memory** sharing for
+distributed data in big data tasks, such as graph analytics, numerical computing, and
+machine learning. Vineyard is design to address the inefficiency of data sharing in
+big data analytical workflows on Kubernetes.
+
+**Vineyard provides**:
+
+1. Efficient in-memory data management and zero-copy sharing across different systems.
+2. Out-of-the-box high-level data abstraction for distributed objects (e.g., tensors, tables,
+ graphs, and distributed datasets) and efficient polyglot support (currently including C++,
+ Python, Go, Rust and Java).
+3. Seamless integration with Kubernetes for cluster deployment and management, workloads
+ orchestration, and observability.
+4. Out-of-the-box integration with workflow orchestration engines (including
+ [Apache Airflow](https://github.com/v6d-io/v6d/tree/main/python/vineyard/contrib/airflow),
+ [Flyte](https://github.com/v6d-io/v6d/tree/main/python/vineyard/contrib/kedro)
+ and [Kubeflow Pipelines](https://github.com/v6d-io/v6d/tree/main/k8s/examples)),
+ providing end-users with a unified and intrusive experience to leverage Vineyard in
+ their data-intensive workflows to improving performance.
+
+**Alignment with CNCF**:
+
+1. Vineyard builds on Kubernetes for deploying and scaling, and the objects are observable
+ in Kubernetes as CRDs.
+2. Vineyard makes efficient zero-copy sharing possible for data-intensive workflows on
+ cloud-native infrastructure by a data-aware Kubernetes scheduler plugin.
+3. Vineyard adopts an immutable object design, which aligns with the immutable infrastructure
+ of the cloud-native environment.
+4. Vineyard aligns with the CNCF effort on helping migrate batching system workflows to cloud
+ native environments.
+
+## Development
+
+### DevStats
+
+> Include a link to your project’s devstats page. We will be looking for signs of consistent
+> or increasing contribution activity. Please feel free to add commentary to add colour to
+> the numbers and graphs we will see on devstats.
+
+- Stargazers and Forks
+ - [https://vineyard.devstats.cncf.io/d/3/stars-and-forks-by-repository?orgId=1&from=now-2y&to=now](https://vineyard.devstats.cncf.io/d/3/stars-and-forks-by-repository?orgId=1&from=now-2y&to=now)
+- Commits per week
+ - [https://vineyard.devstats.cncf.io/d/1/activity-repository-groups?orgId=1&var-period=w&var-repogroups=All&from=now-6M&to=now](https://vineyard.devstats.cncf.io/d/1/activity-repository-groups?orgId=1&var-period=w&var-repogroups=All&from=now-6M&to=now)
+- Contributors and Companies
+ - [https://vineyard.devstats.cncf.io/d/7/companies-contributing-in-repository-groups?orgId=1&var-period=d7&var-repogroup_name=All&from=now-1y&to=now](https://vineyard.devstats.cncf.io/d/7/companies-contributing-in-repository-groups?orgId=1&var-period=d7&var-repogroup_name=All&from=now-1y&to=now)
+
+The vineyard community has grown since the project entered the CNCF sandbox.
+
+- Number of contributors: 26 -> 40
+- Github stars: 600+ -> ~750
+- Github forks: 80+ -> 110+
+
+### Highlights of new features
+
+Vineyard published 8 release (one release about per 1.5 month) since the last annual review.
+The major new features and improvements include:
+
+- Language SDKs in Rust and Go, where the Rust SDK was a collaboration with our external
+ end-user, and enabled users seamlessly and efficiently interoperating their data between
+ Python and Rust.
+- Integration with the workflow engine Kedro, and gained attention in the Kedro community.
+- Vineyard supports the [Apache Hive](https://github.com/apache/hive) data processing engine,
+ letting users can easily connect traditional data processing pipelines built with the
+ Hadoop ecosystem with emerging big-data and AI applications (e.g., applications in the
+ [PyData](https://pandas.pydata.org/community/ecosystem.html) community).
+- A initial version of CSI driver, which helped Vineyard aligned with the Kubernetes platform
+ and enables users to leverage Vineyard in their Kubeflow pipelines to optimize the data
+ sharing between steps with only minor changes to their existing source code.
+
+### Academic Research
+
+We have conducted a series of research work around Vineyard and published the paper
+_Vineyard: Optimizing Data Sharing in Data-Intensive Analytics_ in SIGMOD 2023, a top-tier
+conference in the data management community.
+
+- Wenyuan Yu, Tao He, Lei Wang, Ke Meng, Ye Cao, Diwen Zhu, Sanhong Li, Jingren Zhou.
+ Vineyard: Optimizing Data Sharing in Data-Intensive Analytics. ACM SIG Conference on
+ Management of Data (SIGMOD), industry, 2023. [https://dl.acm.org/doi/10.1145/3589780](https://dl.acm.org/doi/10.1145/3589780).
+
+## Maintainers
+
+> How many maintainers do you have, and which organisations are they from? (Feel free
+> to link to an existing MAINTAINERS file if appropriate.)
+
+We currently have 10 maintainers and 2 committers and have [a maintainer list on Github](https://github.com/v6d-io/v6d/blob/main/MAINTAINERS.md).
+
+- **Initial maintainers**
+
+ | Name | GitHub ID | Affiliation | Email |
+ | --- | --- | --- | --- |
+ | Tao He | [sighingnow](https://github.com/sighingnow) | Alibaba | [linzhu.ht@alibaba-inc.com](mailto:linzhu.ht@alibaba-inc.com) |
+ | Xiaojian Luo | [luoxiaojian](https://github.com/luoxiaojian) | Alibaba | [lxj193371@alibaba-inc.com](mailto:lxj193371@alibaba-inc.com) |
+ | Ke Meng | [septicmk](https://github.com/septicmk) | Alibaba | [mengke.mk@alibaba-inc.com](mailto:mengke.mk@alibaba-inc.com) |
+ | Wenyuan Yu | [wenyuanyu](https://github.com/wenyuanyu) | Alibaba | [wenyuan.ywy@alibaba-inc.com](mailto:wenyuan.ywy@alibaba-inc.com) |
+ | Weibin Zeng | [acezen](https://github.com/acezen) | Alibaba | [qiaozi.zwb@alibaba-inc.com](mailto:qiaozi.zwb@alibaba-inc.com) |
+ | Siyuan Zhang | [siyuan0322](https://github.com/siyuan0322) | Alibaba | [siyuanzhang.zsy@alibaba-inc.com](mailto:siyuanzhang.zsy@alibaba-inc.com) |
+ | Diwen Zhu | [andydiwenzhu](https://github.com/andydiwenzhu) | Alibaba | [diwen.zdw@alibaba-inc.com](mailto:diwen.zdw@alibaba-inc.com) |
+
+- **New maintainers in this year**
+
+ | Name | GitHub ID | Affiliation | Email |
+ | --- | --- | --- | --- |
+ | Ye Cao | [dashanji](https://github.com/dashanji) | Alibaba | [caoye.cao@alibaba-inc.com](mailto:caoye.cao@alibaba-inc.com) |
+ | Shumin Yuan | [vegetableysm](https://github.com/vegetableysm) | Alibaba | [yuanshumin.ysm@alibaba-inc.com](mailto:yuanshumin.ysm@alibaba-inc.com) |
+ | Denghao Li | [lidh15](https://github.com/lidh15) | PingAn Tech | [lidhrandom@gmail.com](mailto:lidhrandom@gmail.com) |
+
+- **New Committers in this year**
+
+ | Name | GitHub ID | Affiliation | Email |
+ | --- | --- | --- | --- |
+ | Lihong Lin | [linlih](https://github.com/linlih) | PKU | [linlh@stu.pku.edu.cn](mailto:linlh@stu.pku.edu.cn) |
+ | Pei Li | [peilii](https://github.com/peilii) | CMU | [peili.dev@gmail.com](mailto:peili.dev@gmail.com) |
+
+## Adoption
+
+> What do you know about adoption, and how has this changed since your last review / since
+> you joined Sandbox? If you can list companies that are end-users of your project, please
+> do so. (Feel free to link to an existing ADOPTERS file if appropriate.)
+
+We have tracked the following two major adoption since [our last annual review]()
+
+- _StartDT (Qidianyun)_: transiting towards production stage
+ - _StartDT_ is a startup company in China, providing a cloud-native data platform for
+ big-data analytics and machine learning applications.
+ - Vineyard is currently used in their Python-centric data processing pipelines to
+ share distributed dataframe artifacts between steps, and help build a composable
+ and efficient data processing platform to end-users.
+
+ Vineyard has passed their eager-evaluation, and they are working on building their
+ distributed data processing platform on top of Vineyard.
+
+- _PingAn Tech_: production stage
+ - _PingAn_ is a large-scale fin-tech company in China.
+ - Vineyard is used in their data science platform to support efficient dataset sharing and
+ management among data science researchers.
+
+ The status of Vineyard in their platform has been transited from testing to production
+ stage, and one of their engineers has become a maintainer of the Vineyard project.
+
+Besides these two major companies, since our last annual review, we have also noticed some other
+questions about using Vineyard in machine learning inference scenarios, but we haven't tracked
+the actual adoption yet.
+
+## Project Goals
+
+> How has the project performed against its goals since the last review? (We won't penalize you
+> if your goals changed for good reasons.)
+
+Vineyard has successfully archived the goals about easing the getting started process for
+end-users from three aspects:
+
+1. Out-of-the-box integration with data processing systems, especially Spark and Hive,
+ the most popular data processing engines in the big data community;
+2. Data processing pipeline orchestration: providing non-intrusive interfaces to help users
+ migrate their existing data processing pipelines to Vineyard on Kubernetes and finally
+ benefit from the efficient data sharing;
+3. Seamless inter-operability with other systems in the cloud-native environments: we invest
+ a lot of effort in the Vineyard operator to help use deploy vineyard along with their
+ workloads in a non-intrusive, declarative way and has tested the functionality with
+ _GraphScope_ in end-users production environments.
+
+Besides, Vineyard has successfully attracted new end-users from the big data community to
+adopt Vineyard in their own data processing platform, and the feedback from the Kedro
+community is also positive.
+
+> What are the current goals of the project? For example, are you working on major new features? Or are you concentrating on adoption or documentation?
+
+Our current goals are mainly focused on the attracting more end-user to adopt Vineyard in
+their scenarios from different domains. Specifically, we are keeping moving towards the
+following goals in the next year:
+
+1. Optimizing our current Kubeflow integration and find more opportunities to evaluate
+ and deploy Vineyard in production machine learning applications;
+2. Publish our integration with the big data processing systems to their end-user
+ community and gather feedback for further improvements;
+3. Seeking more opportunities to evaluate Vineyard in the emerging LLM applications,
+ for both data preprocessing, training, and inference serving to see if Vineyard
+ can bring added value to these applications as where the data cost is usually high;
+4. Getting engaged with the Batch System WG in CNCF to seek opportunities about
+ further collaboration with other projects in CNCF.
+
+## CNCF membership
+
+> How can the CNCF help you achieve your upcoming goals?
+
+Vineyard has incredibly benefited from CNCF since accepted as a sandbox project. We believe
+the end-users in the CNCF community are critical for Vineyard to become successful. With
+the help of CNCF service desk, we have successfully built a new website for Vineyard, which
+is more friendly to end-users. We are also working on components like CSI driver and hope
+that could make the inter-operation with other projects in the CNCF community easier.
+
+We will host a _Project Kiosk_ in this KubeCon China and hope to get more feedback from the
+community, and hope to get more feedback from the community. Furthermore, we hope we could have
+more opportunities to introduce our project to border end-users in the CNCF community to
+increase adoption.
+
+## Incubation
+
+> Do you think that your project meets the [criteria for incubation](https://github.com/cncf/toc/blob/master/process/graduation_criteria.adoc#incubating-stage)?
+
+We think our project vineyard still needs further exploration to get border adoption in the
+end-user's production deployment and gather more feedback, and we are looking forward to
+meeting the incubation criteria in the near future.
diff --git a/_sources/docs.rst.txt b/_sources/docs.rst.txt
new file mode 100644
index 0000000000..3f68441758
--- /dev/null
+++ b/_sources/docs.rst.txt
@@ -0,0 +1,265 @@
+.. vineyard documentation master file, created by
+ sphinx-quickstart on Tue Aug 27 10:19:05 2019.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+.. meta::
+ :description: Vineyard (v6d), a CNCF sandbox project, is an in-memory immutable data manager
+ that provides **out-of-the-box high-level** abstraction and **zero-copy in-memory** sharing for
+ distributed data in big data tasks, such as graph analytics (e.g., `GraphScope`_), numerical
+ computing (e.g., `Mars`_), and machine learning.
+ :keywords: distributed-systems, distributed, shared-memory, graph-analytics, in-memory-storage,
+ big-data-analytics, distributed-comp
+
+.. figure:: images/vineyard-logo-rect.png
+ :width: 397
+ :alt: Vineyard: an in-memory immutable data manager
+ :target: https://v6d.io
+
+ *an in-memory immutable data manager*
+
+|PyPI| |FAQ| |Discussion| |Slack| |License| |ACM DL|
+
+Why bother?
+-----------
+
+Sharing intermediate data between systems in modern big data and AI workflows
+can be challenging, often causing significant bottlenecks in such jobs. Let's
+consider the following fraud detection pipeline:
+
+.. figure:: images/fraud-detection-job.jpg
+ :width: 75%
+ :alt: A real-life fraud detection job
+
+ A real-life fraud detection job
+
+From the pipeline, we observed:
+
+1. Users usually prefer to program with dedicated computing systems for different tasks in the
+ same applications, such as SQL and Python.
+
+ **Integrating a new computing system into production environments demands high technical
+ effort to align with existing production environments in terms of I/O, failover, etc.**
+
+2. Data could be polymorphic. Non-relational data, such as tensors, dataframes (in Pandas) and
+ graphs/networks (in `GraphScope`_) are becoming increasingly prevalent. Tables and SQL may
+ not be the best way to store, exchange, or process them.
+
+ **Transforming the data back and forth between different systems as "tables" could
+ result in a significant overhead.**
+
+3. Saving/loading the data to/from the external storage requires numerous memory copies and
+ incurs high IO costs.
+
+What is Vineyard?
+-----------------
+
+Vineyard (v6d) is an **in-memory immutable data manager** that offers **out-of-the-box high-level**
+abstraction and **zero-copy sharing** for distributed data in big data tasks, such as
+graph analytics (e.g., `GraphScope`_), numerical computing (e.g., `Mars`_), and machine learning.
+
+Features
+^^^^^^^^
+
+Efficient data sharing
+~~~~~~~~~~~~~~~~~~~~~~
+
+Vineyard shares immutable data across different systems using shared memory without extra overheads,
+eliminating the overhead of serialization/deserialization and IO when exchanging immutable
+data between systems.
+
+Out-of-the-box data abstraction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Vineyard defines a metadata-payload separated data model to capture the payload commonalities and
+method commonalities between sharable objects in different programming languages and different
+computing systems in a unified way.
+
+The :ref:`VCDL` (Vineyard Component Description Language) is specifically designed to annotate
+sharable members and methods, enabling automatic generation of boilerplate code for minimal
+integration effort.
+
+Pluggable I/O routines
+~~~~~~~~~~~~~~~~~~~~~~
+
+In many big data analytical tasks, a substantial portion of the workload consists of boilerplate
+routines that are unrelated to the core computation. These routines include various IO adapters,
+data partition strategies, and migration jobs. Due to different data structure abstractions across
+systems, these routines are often not easily reusable, leading to increased complexity and redundancy.
+
+Vineyard provides common manipulation routines for immutable data as drivers, which extend
+the capabilities of data structures by registering appropriate drivers. This enables out-of-the-box
+reuse of boilerplate components across diverse computation jobs.
+
+Data orchestration on Kubernetes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Vineyard provides efficient distributed data sharing in cloud-native environments by embracing
+cloud-native big data processing. Kubernetes helps Vineyard leverage the scale-in/out and
+scheduling abilities of Kubernetes.
+
+Use cases
+^^^^^^^^^
+
+.. panels::
+ :header: text-center
+ :container: container-lg pb-4
+ :column: col-lg-4 col-md-4 col-sm-4 col-xs-12 p-2
+ :body: text-center
+
+ .. link-button:: #
+ :type: url
+ :text: Object manager
+ :classes: btn-block stretched-link
+
+ Put and get arbitrary objects using Vineyard, in a zero-copy way!
+
+ ---
+
+ .. link-button:: #
+ :type: url
+ :text: Cross-system sharing
+ :classes: btn-block stretched-link
+
+ Share large objects across computing systems.
+
+ ---
+
+ .. link-button:: #
+ :type: url
+ :text: Data orchestration
+ :classes: btn-block stretched-link
+
+ Vineyard coordinates the flow of objects and jobs on Kubernetes based on data-aware scheduling.
+
+Get started now!
+----------------
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: notes/getting-started
+ :type: ref
+ :text: User Guides
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Get started with Vineyard.
+
+ ---
+
+ .. link-button:: notes/cloud-native/deploy-kubernetes
+ :type: ref
+ :text: Deploy on Kubernetes
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Deploy Vineyard on Kubernetes and accelerate big-data analytical workflows on cloud-native
+ infrastructures.
+
+ ---
+
+ .. link-button:: tutorials/tutorials
+ :type: ref
+ :text: Tutorials
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Explore use cases and tutorials where Vineyard can bring added value.
+
+ ---
+
+ .. link-button:: notes/developers
+ :type: ref
+ :text: Getting Involved
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Get involved and become part of the Vineyard community.
+
+ ---
+
+ .. link-button:: notes/developers/faq
+ :type: ref
+ :text: FAQ
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Frequently asked questions and discussions during the adoption of Vineyard.
+
+Read the Paper
+--------------
+
+- Wenyuan Yu, Tao He, Lei Wang, Ke Meng, Ye Cao, Diwen Zhu, Sanhong Li, Jingren Zhou.
+ `Vineyard: Optimizing Data Sharing in Data-Intensive Analytics `_.
+ ACM SIG Conference on Management of Data (SIGMOD), industry, 2023. |ACM DL|.
+
+Vineyard is a `CNCF sandbox project`_ and is made successful by its community.
+
+.. image:: https://v6d.io/_static/cncf-color.svg
+ :width: 400
+ :alt: Vineyard is a CNCF sandbox project
+
+.. toctree::
+ :maxdepth: 1
+ :caption: User Guides
+ :hidden:
+
+ notes/getting-started.rst
+ notes/architecture.rst
+ notes/key-concepts.rst
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Cloud-Native
+ :hidden:
+
+ notes/cloud-native/deploy-kubernetes.rst
+ notes/cloud-native/vineyard-operator.rst
+ Command-line tool
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Tutorials
+ :hidden:
+
+ tutorials/data-processing.rst
+ tutorials/kubernetes.rst
+ tutorials/extending.rst
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Integration
+ :hidden:
+
+ notes/integration-bigdata.rst
+ notes/integration-orchestration.rst
+
+.. toctree::
+ :maxdepth: 2
+ :caption: API Reference
+ :hidden:
+
+ notes/references.rst
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Developer Guides
+ :hidden:
+
+ notes/developers.rst
+ notes/developers/faq.rst
+
+.. _Mars: https://github.com/mars-project/mars
+.. _GraphScope: https://github.com/alibaba/GraphScope
+.. _CNCF sandbox project: https://www.cncf.io/sandbox-projects/
+
+.. |PyPI| image:: https://img.shields.io/pypi/v/vineyard?color=blue
+ :target: https://pypi.org/project/vineyard
+.. |FAQ| image:: https://img.shields.io/badge/-FAQ-blue?logo=Read%20The%20Docs
+ :target: https://v6d.io/notes/faq.html
+.. |Discussion| image:: https://img.shields.io/badge/Discuss-Ask%20Questions-blue?logo=GitHub
+ :target: https://github.com/v6d-io/v6d/discussions
+.. |Slack| image:: https://img.shields.io/badge/Slack-Join%20%23vineyard-purple?logo=Slack
+ :target: https://slack.cncf.io/
+.. |License| image:: https://img.shields.io/github/license/v6d-io/v6d
+ :target: https://github.com/v6d-io/v6d/blob/main/LICENSE
+
+.. |ACM DL| image:: https://img.shields.io/badge/ACM%20DL-10.1145%2F3589780-blue
+ :target: https://dl.acm.org/doi/10.1145/3589780
diff --git a/_sources/notes/architecture.rst.txt b/_sources/notes/architecture.rst.txt
new file mode 100644
index 0000000000..fa52021ca3
--- /dev/null
+++ b/_sources/notes/architecture.rst.txt
@@ -0,0 +1,182 @@
+.. _architecture-of-vineyard:
+
+Architecture
+============
+
+Overview
+--------
+
+The following figure illustrates the architecture of Vineyard.
+
+.. figure:: ../images/vineyard_arch.jpg
+ :width: 75%
+ :alt: Architecture of Vineyard
+
+ Architecture of Vineyard
+
+Server side
+^^^^^^^^^^^
+
+On the server (daemon) side (i.e., the aforementioned Vineyard instance), there are
+three primary components:
+
+1. The **shared memory** is the memory space in Vineyard that is shared with Vineyard
+ clients via the UNIX domain socket through memory mapping.
+
+ As previously mentioned, the partitions of the distributed data reside in the
+ shared memory of the corresponding Vineyard instance in the cluster.
+
+2. The **metadata manager** is responsible for managing the metadata of the data stored
+ in Vineyard.
+
+ The metadata manager maintains the metadata (structures, layouts, and properties) of
+ the data to provide high-level abstractions (e.g., graphs, tensors, dataframes).
+ The metadata managers in a Vineyard cluster communicate with each other through
+ the backend key-value store, such as etcd server, to ensure the consistency of the
+ distributed data stored in Vineyard.
+
+3. The **IPC/RPC servers** manage the IPC/RPC connections from Vineyard
+ clients for data sharing.
+
+ Specifically, the client can retrieve both metadata and data partitions stored in
+ Vineyard via IPC and RPC connections. However, when both connection types are available,
+ IPC connections are prioritized due to the greater efficiency of memory mapping for data
+ sharing.
+
+.. _client-side:
+
+Client side
+^^^^^^^^^^^
+
+On the client side, the core component is the **Vineyard client**. The client side
+includes both low-level APIs for accessing Vineyard instances in a precise
+manner and high-level APIs for data structure sharing, manipulation, and
+routine reuse (e.g., I/O drivers). More specifically,
+
+1. The **IPC client** communicates with *local* Vineyard instances by connecting
+ to the UNIX domain socket.
+
+ The IPC client is used to establish an IPC connection between the Vineyard server and
+ the client, enabling memory-sharing (by :code:`mmap` and transferring the file descriptor)
+ between the Vineyard server and the computing engines.
+
+2. The **RPC client** communicates with *remote* Vineyard instances by connecting
+ to the TCP port that the Vineyard daemon is bound to.
+
+ Unlike the IPC client, the RPC client doesn't allow memory sharing between processes
+ and is less efficient in that regard. However, it is still useful for retrieving both
+ metadata and payloads from the Vineyard cluster via TCP or RDMA.
+
+3. The **builders and resolvers** for out-of-the-box high-level data abstractions
+ offer a convenient way for applications to consume objects in Vineyard and
+ produce result objects into Vineyard.
+
+ The builders and resolvers adopt an extensible design where users can register
+ their own builders and resolvers for their newly defined data types, as well as
+ new builders and resolvers that build ad-hoc engine-specific data structures
+ as Vineyard objects and wrap Vineyard objects as engine-specific data types
+ at a low cost.
+
+ The builders, resolvers, and the registry are part of the language-specific
+ SDKs of Vineyard. Currently, Python and C++ are officially supported, and the Rust
+ and Go SDKs are under heavy development.
+
+4. The **pluggable drivers** assign specific functionalities to certain types of data
+ in Vineyard.
+
+ In particular, I/O drivers synchronize with external storages such as databases and file
+ systems to read data into and write data from Vineyard, while partition and
+ re-partition drivers reorganize the distributed graphs stored in Vineyard to
+ balance the workload.
+
+ .. note::
+
+ The drivers typically employ the low-level APIs for precise operations.
+
+5. **Object migration** is the mechanism implemented on the client side to
+ migrate objects between Vineyard instances in a cluster. Object migration
+ is usually needed when the computing engines cannot be scheduled to co-locate
+ with the data required by the jobs.
+
+ Object migration is implemented on the client side as a process pair where the
+ sender and receiver are both connected to (different) Vineyard instances and
+ communicate with each other using TCP to move objects between Vineyard instances.
+ We don't put the object migration on the server side to decouple the functionalities
+ and allow users to register a more efficient object migration implemented on
+ their own deployment infrastructures, e.g.,leveraging RDMA and other high-performance
+ network technologies.
+
+Core features
+-------------
+
+Zero-cost in-memory data sharing
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Vineyard provides zero-cost data sharing through memory-mapping, as data objects
+in Vineyard are immutable. When an object is created, we allocate blobs in
+Vineyard to store the data payload. On the other hand, when retrieving the object,
+we map the blob from the Vineyard instance into the application process using
+inter-process memory mapping techniques, ensuring that no memory copy is involved
+in sharing the data payload.
+
+Distributed data sharing in big data tasks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+By examining the practices of big data tasks such as numeric computing, machine learning,
+and graph analysis, we have identified four key properties of the data involved:
+
++ Distributed and each partitioned fragment usually fits into memory;
++ Immutable, i.e., never modified after creation;
++ With complex structure, e.g., graph in CSR format;
++ Required to share between different computation systems and programming languages.
+
+Vineyard is designed to address these challenges with:
+
++ Composable design for Vineyard objects;
++ Immutable zero-cost in-memory data sharing via memory mapping;
++ Out-of-the-box high-level data abstraction for complex data structures;
++ Extensible design for builder/resolver/driver, enabling flexible cross-system and
+ cross-language data sharing.
+
+In general, Vineyard's design choices are fully determined by addressing
+the difficulties in handling large-scale distributed data in practice.
+
+Out-of-the-box high-level data abstraction
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Vineyard objects are stored with structures and high-level abstractions.
+For instance, a graph with CSR format in Vineyard stores the index along with
+the vertices and edges, enabling operations like edge iteration based on the
+index. This means users don't have to implement the index-building
+function and edge iterators themselves, which is often required in
+existing big data practices.
+
+Convenient data integration
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The extensible design of builder/resolver/driver allows for convenient extension
+of existing Vineyard objects to different programming languages. Moreover,
+with codegen tools in Vineyard, users can easily transplant their
+data structures into Vineyard with only a few annotations.
+
+Data orchestration in a Python notebook
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Using Vineyard as the common data orchestration engine throughout the end-to-end
+big data processing, users can hold large-scale distributed data as variables
+of Vineyard objects in Python. As long as the computation modules
+involved provide Python APIs, users can write down the entire processing
+pipeline in a Python notebook. By running the Python script, users can
+manage trillions of data and different computation systems in the background
+distributedly across the cluster.
+
+Non-goals and limitations
+-------------------------
+
+*NO* mutable objects
+^^^^^^^^^^^^^^^^^^^^
+
+Once a Vineyard object is created and sealed in the Vineyard instance, it
+becomes immutable and can NOT be modified anymore. Thus, Vineyard is not
+suitable for use as a data cache to store mutable data that changes
+rapidly along the processing pipeline.
diff --git a/_sources/notes/cloud-native/deploy-kubernetes.rst.txt b/_sources/notes/cloud-native/deploy-kubernetes.rst.txt
new file mode 100644
index 0000000000..4df37b2bec
--- /dev/null
+++ b/_sources/notes/cloud-native/deploy-kubernetes.rst.txt
@@ -0,0 +1,209 @@
+.. _deploy-on-kubernetes:
+
+Deploy on Kubernetes
+====================
+
+Vineyard is managed by the :ref:`vineyard-operator` on Kubernetes.
+
+Quick start
+-----------
+
+If you want to install vineyard cluster quickly, you can
+use the following command.
+
+Install `vineyardctl`_ as follows.
+
+.. code:: bash
+
+ pip3 install vineyard
+
+Use the vineyardctl to install vineyard cluster.
+
+.. code:: bash
+
+ python3 -m vineyard.ctl deploy vineyard-cluster --create-namespace
+
+Also, you could follow the next guide to install vineyard cluster steps
+by steps.
+
+Install vineyard-operator
+-------------------------
+
+There are two recommended methods for installing the vineyard operator: using Helm (preferred) or
+installing directly from the source code.
+
+.. note::
+
+ Prior to installing the vineyard operator, ensure that you have a Kubernetes cluster and kubectl
+ installed. In this guide, we will use `kind`_ to create a cluster.
+
+
+Option #1: Install from helm chart (recommended)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: bash
+
+ $ helm repo add vineyard https://vineyard.oss-ap-southeast-1.aliyuncs.com/charts/
+ $ helm repo update
+ $ helm install vineyard-operator vineyard/vineyard-operator \
+ --namespace vineyard-system \
+ --create-namespace
+
+Wait for the vineyard operator until ready.
+
+Option #2: Install form source code
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+1. Clone the vineyard repo:
+
+ .. code:: bash
+
+ $ git clone https://github.com/v6d-io/v6d.git
+
+2. Build the vineyard operator's Docker image:
+
+ .. code:: bash
+
+ $ cd k8s
+ $ make -C k8s docker-build
+
+ .. caution::
+
+ With `kind`_, you need to first import the image into the kind cluster:
+
+ .. code:: bash
+
+ $ kind load docker-image vineyardcloudnative/vineyard-operator:latest
+
+3. Next, deploy the vineyard operator:
+
+ .. code:: bash
+
+ $ make -C k8s deploy
+
+Wait vineyard-operator ready
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Once the operator is installed, its deployment can be checked using :code:`kubectl`:
+
+.. code:: bash
+
+ $ kubectl get all -n vineyard-system
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ NAME READY STATUS RESTARTS AGE
+ pod/vineyard-controller-manager-5c6f4bc454-8xm8q 2/2 Running 0 62m
+
+ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+ service/vineyard-controller-manager-metrics-service ClusterIP 10.96.240.173 8443/TCP 62m
+ service/vineyard-webhook-service ClusterIP 10.96.41.132 443/TCP 62m
+
+ NAME READY UP-TO-DATE AVAILABLE AGE
+ deployment.apps/vineyard-controller-manager 1/1 1 1 62m
+
+ NAME DESIRED CURRENT READY AGE
+ replicaset.apps/vineyard-controller-manager-5c6f4bc454 1 1 1 62m
+
+Create vineyard cluster
+-----------------------
+
+Once the vineyard operator becomes ready, you can create a vineyard cluster by creating a
+:code:`Vineyardd` `CRD`_. The following is an example of creating a vineyard cluster with 3 daemon
+replicas:
+
+.. code:: yaml
+
+ $ cat < 2379/TCP 48s
+ service/etcd0 ClusterIP 10.96.128.87 2379/TCP,2380/TCP 48s
+ service/etcd1 ClusterIP 10.96.72.116 2379/TCP,2380/TCP 48s
+ service/etcd2 ClusterIP 10.96.99.182 2379/TCP,2380/TCP 48s
+ service/vineyard-controller-manager-metrics-service ClusterIP 10.96.240.173 8443/TCP 72s
+ service/vineyard-webhook-service ClusterIP 10.96.41.132 443/TCP 72s
+ service/vineyardd-sample-rpc ClusterIP 10.96.102.183 9600/TCP 48s
+
+ NAME READY UP-TO-DATE AVAILABLE AGE
+ deployment.apps/vineyard-controller-manager 1/1 1 1 72s
+ deployment.apps/vineyardd-sample 3/3 3 3 48s
+
+ NAME DESIRED CURRENT READY AGE
+ replicaset.apps/vineyard-controller-manager-5c6f4bc454 1 1 1 72s
+ replicaset.apps/vineyardd-sample-5cc797668f 3 3 3 48s
+
+References
+----------
+
+In addition to deploying and managing the vineyard cluster, the operator plays a crucial role in scheduling
+workloads on vineyard. This optimizes data sharing between tasks in workflows and triggers necessary data
+movement or transformation tasks. Detailed references and examples can be found in :code:`vineyard-operator`.
+
+To simplify interactions with vineyard on Kubernetes, we offer a command-line tool, :code:`vineyardctl`, which
+automates much of the boilerplate configuration required when deploying workflows with vineyard on Kubernetes.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: ./vineyard-operator
+ :type: ref
+ :text: Vineyard operator
+ :classes: btn-block stretched-link text-left
+ ^^^^^^^^^^^^
+ Vineyard operator manages vineyard cluster and orchestrates shared objects on Kubernetes.
+
+ ---
+
+ .. link-button:: ./vineyardctl
+ :type: ref
+ :text: vineyardctl
+ :classes: btn-block stretched-link text-left
+ ^^^^^^^^^^^^
+ :code:`vineyardctl` is the command-line tool for working with the Vineyard Operator.
+
+.. _vineyardctl: https://github.com/v6d-io/v6d/blob/main/k8s/cmd/README.md
+.. _kind: https://kind.sigs.k8s.io
+.. _CRD: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions
diff --git a/_sources/notes/cloud-native/vineyard-operator.rst.txt b/_sources/notes/cloud-native/vineyard-operator.rst.txt
new file mode 100644
index 0000000000..4a4cabf58a
--- /dev/null
+++ b/_sources/notes/cloud-native/vineyard-operator.rst.txt
@@ -0,0 +1,1403 @@
+.. _vineyard-operator:
+
+Vineyard Operator
+=================
+
+Architecture
+------------
+
+The following figure demonstrates the architecture of vineyard operator.
+
+.. figure:: ../../images/vineyard_operator_arch.png
+ :width: 75%
+ :alt: Architecture of vineyard operator
+
+ Architecture of vineyard operator
+
+.. contents:: Table of Contents
+ :depth: 2
+ :local:
+ :class: this-will-duplicate-information-and-it-is-still-useful-here
+
+Create a vineyard Cluster
+-------------------------
+
+After successfully installing the vineyard operator (refer to :ref:`deploy-on-kubernetes`
+for installation details), you can effortlessly create a vineyard cluster by utilizing
+the :code:`Vineyardd` CRD. The following example demonstrates the creation of a vineyard
+cluster with 3 daemon replicas:
+
+.. note::
+
+ The namespace of the vineyard cluster must be the same as the namespace of the
+ vineyard operator, as the vineyard cluster will use the vineyard operator's
+ service account.
+
+.. code:: yaml
+
+ $ cat < 2379/TCP 48s
+ service/etcd0 ClusterIP 10.96.128.87 2379/TCP,2380/TCP 48s
+ service/etcd1 ClusterIP 10.96.72.116 2379/TCP,2380/TCP 48s
+ service/etcd2 ClusterIP 10.96.99.182 2379/TCP,2380/TCP 48s
+ service/vineyard-controller-manager-metrics-service ClusterIP 10.96.240.173 8443/TCP 72s
+ service/vineyard-webhook-service ClusterIP 10.96.41.132 443/TCP 72s
+ service/vineyardd-sample-rpc ClusterIP 10.96.102.183 9600/TCP 48s
+
+ NAME READY UP-TO-DATE AVAILABLE AGE
+ deployment.apps/vineyard-controller-manager 1/1 1 1 72s
+ deployment.apps/vineyardd-sample 3/3 3 3 48s
+
+ NAME DESIRED CURRENT READY AGE
+ replicaset.apps/vineyard-controller-manager-5c6f4bc454 1 1 1 72s
+ replicaset.apps/vineyardd-sample-5cc797668f 3 3 3 48s
+
+Also, if you want to use the custom vineyard socket path and mount something like /dev to the
+vineyard container, you could use the following YAML file:
+
+.. code:: yaml
+
+ $ cat <`_.
+
+Installing vineyard as sidecar
+------------------------------
+
+Vineyard can be seamlessly integrated as a sidecar container within a pod. We offer the `Sidecar`
+Custom Resource Definition (CRD) for configuring and managing the sidecar container. The `Sidecar`
+CRD shares many similarities with the `Vineyardd` CRD, and all available configurations can be found
+in the `Sidecar CRD <../references/crds.md#sidecar>`_.
+
+Besides, We provide some labels and annotations to help users to use the sidecar in vineyard operator.
+The following are all labels that we provide:
+
+.. list-table:: Sidecar Configurations
+ :widths: 25 15 60
+ :header-rows: 1
+
+ * - Name
+ - Yaml Fields
+ - Description
+
+ * - "sidecar.v6d.io/enabled"
+ - labels
+ - Enable the sidecar.
+
+ * - "sidecar.v6d.io/name"
+ - annotations
+ - The name of sidecar cr. If the name is `default`, the default sidecar cr will be created.
+
+There are two methods to install vineyard as a sidecar:
+
+- Utilize the **default sidecar configuration**. Users should add two annotations,
+ **sidecar.v6d.io/enabled: true** and **sidecar.v6d.io/name: default**, to their app's YAML.
+ This will create a default sidecar Custom Resource (CR) for observation.
+
+- Employ the **custom sidecar configuration**. Users must first create a custom sidecar CR,
+ such as `sidecar-demo`, and then add two annotations, **sidecar.v6d.io/enabled: true** and
+ **sidecar.v6d.io/name: sidecar-demo**, to their app's YAML.
+
+The following example demonstrates how to install vineyard as a sidecar container within a
+pod. First, install the vineyard operator according to the previous steps, and then create
+a namespace with the specific label `sidecar-injection: enabled` to enable the sidecar.
+
+.. code:: bash
+
+ $ kubectl create namespace vineyard-job
+ $ kubectl label namespace vineyard-job sidecar-injection=enabled
+
+
+Next, use the following YAML to inject the default sidecar into the pod.
+
+.. note::
+
+ Please configure the command field of your app container to be in the format
+ **["/bin/sh" or "/bin/bash", "-c", (your app command)]**. After injecting the vineyard
+ sidecar, the command field will be modified to **["/bin/sh" or "/bin/bash", "-c",
+ while [ ! -e /var/run/vineyard.sock ]; do sleep 1; done;" + (your app command)]** to
+ ensure that the vineyard sidecar is ready before the app container starts.
+
+.. code:: yaml
+
+ $ cat <`_.
+
+
+In general, the GlobalObjects are created as intermediate objects when deploying
+users' applications. You could get them as follows.
+
+.. code:: bash
+
+ $ kubectl get globalobjects -A
+ NAMESPACE NAME ID NAME SIGNATURE TYPENAME
+ vineyard-system o001bcbcea406acd0 o001bcbcea406acd0 s001bcbcea4069f60 vineyard::GlobalDataFrame
+ vineyard-system o001bcc19dbfc9c34 o001bcc19dbfc9c34 s001bcc19dbfc8d7a vineyard::GlobalDataFrame
+
+LocalObject
+^^^^^^^^^^^
+
+The **LocalObject** custom resource definition (CRD) declaratively defines the local object
+in a Kubernetes cluster, and you can find all configurations in the `LocalObject CRD
+<../references/crds.md#localobject>`_.
+
+The LocalObjects are also intermediate objects just like the GlobalObjects, and you could
+get them as follows.
+
+.. code:: bash
+
+ $ kubectl get localobjects -A
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ NAMESPACE NAME ID NAME SIGNATURE TYPENAME INSTANCE HOSTNAME
+ vineyard-system o001bcbce202ab390 o001bcbce202ab390 s001bcbce202aa6f6 vineyard::DataFrame 0 kind-worker2
+ vineyard-system o001bcbce21d273e4 o001bcbce21d273e4 s001bcbce21d269c2 vineyard::DataFrame 1 kind-worker
+ vineyard-system o001bcbce24606f6a o001bcbce24606f6a s001bcbce246067fc vineyard::DataFrame 2 kind-worker3
+
+Vineyard Scheduler
+------------------
+
+The Vineyard operator includes a scheduler plugin designed to efficiently schedule workloads
+on Vineyard by placing them as close as possible to their input data, thereby reducing data
+migration costs. The Vineyard scheduler plugin is developed based on the `Kubernetes Scheduling
+Framework`_, and its overall scheduling strategy can be summarized as follows:
+
+- All Vineyard workloads can only be deployed on nodes where the Vineyard daemon server is
+ present.
+- If a workload does not depend on any other workload, it will be scheduled using a
+ **round-robin** approach. For example, if a workload has 3 replicas and there are 3 nodes
+ with Vineyard daemon servers, the first replica will be scheduled on the first node, the
+ second replica on the second node, and so on.
+- If a workload depends on other workloads, it will be scheduled using a **best-effort** policy.
+ Assuming a workload produces N chunks during its lifecycle, and there are M nodes with
+ Vineyard daemon servers, the best-effort policy will attempt to make the next workload
+ consume :code:`M/N`: chunks. For instance, imagine a workload produces 12 chunks with the
+ following distribution:
+
+ .. code::
+
+ node1: 0-8
+ node2: 9-11
+ node3: 12
+
+ The next workload has 3 replicas, and the best-effort policy will schedule it as follows:
+
+ .. code::
+
+ replica1 -> node1 (consume 0-3 chunks)
+ replica2 -> node1 (consume 4-7 chunks)
+ replica3 -> node2 (consume 9-11 chunks, the other chunks will be migrated to the node)
+
+Utilizing the Vineyard Scheduler
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Vineyard scheduler is integrated into the Vineyard operator and deployed alongside it.
+This scheduler plugin relies on specific annotations and labels to provide necessary input
+information. The required configurations are listed below in a clear and comprehensive manner:
+
+.. admonition:: Scheduler Plugin Configurations
+ :class: admonition-details
+
+ .. list-table::
+ :widths: 25 15 60
+ :header-rows: 1
+
+ * - Name
+ - Yaml Fields
+ - Description
+
+ * - "scheduling.k8s.v6d.io/required"
+ - annotations
+ - All jobs required by the job. If there are
+ more than two tasks, use the concatenator ','
+ to concatenate them into a string.
+ E.g. `job1,job2,job3`.
+ If there is no required jobs, set `none`.
+
+ * - "scheduling.k8s.v6d.io/vineyardd"
+ - labels
+ - The name or namespaced name of vineyardd. e.g.,
+ `vineyard-sample` or
+ `vineyard-system/vineyard-sample`.
+
+ * - "scheduling.k8s.v6d.io/job ""
+ - labels
+ - The job name.
+
+ * - "schedulerName"
+ - spec
+ - The vineyard scheduler's name, and the
+ default value is `vineyard-scheduler`.
+
+In this section, we will demonstrate a comprehensive example of utilizing the Vineyard
+scheduler. To begin, ensure that the Vineyard operator and Vineyard daemon server are
+installed by following the steps outlined earlier. Then, proceed to deploy `workflow-job1`_
+as shown below.
+
+.. code:: bash
+
+ $ kubectl create ns vineyard-job
+
+.. code:: yaml
+
+ $ cat < 1 kind-worker2
+ o001c8729e4590626 o001c8729e4590626 s001c8729e458f47a vineyard::Tensor 2 kind-worker3
+
+ # when a job is scheduled, the scheduler will create a configmap to record the globalobject id
+ # that the next job will consume.
+ $ kubectl get configmap v6d-workflow-demo-job1 -n vineyard-job -o yaml
+ apiVersion: v1
+ data:
+ kind-worker3: o001c8729e4590626
+ v6d-workflow-demo-job1: o001c8729e49e06b8
+ kind: ConfigMap
+ ...
+
+Then deploy the `workflow-job2`_ as follows.
+
+.. code:: yaml
+
+ $ cat <`_ to get more details.
+
+The Operation Custom Resource (CR) is created by the vineyard scheduler while scheduling vineyard jobs.
+You can retrieve the created Operation CRs as follows:
+
+.. code:: bash
+
+ $ kubectl get operation -A
+ NAMESPACE NAME OPERATION TYPE STATE
+ vineyard-job dask-repartition-job2-bbf596bf4-985vc repartition dask
+
+Currently, the vineyard operator includes three pluggable drivers: `checkpoint`, `assembly`, and
+`repartition`. The following sections provide a brief introduction to each of these drivers.
+
+Checkpoint
+^^^^^^^^^^
+
+Vineyard currently supports two types of checkpoint drivers:
+
+1. Active checkpoint - **Serialization**: Users can store data in temporary or persistent storage
+ for checkpoint purposes using the API (`vineyard.io.serialize/deserialize`). *Note* that the
+ serialization process is triggered by the user within the application image, and the volume is
+ also created by the user. Therefore, it is not managed by the vineyard operator.
+
+2. Passive checkpoint - **Spill**: Vineyard now supports spilling data from memory to storage
+ when the data size exceeds the available memory capacity. There are two watermarks for memory
+ spilling: the low watermark and the high watermark. When the data size surpasses the high watermark,
+ vineyardd will spill the excess data to storage until it reaches the low watermark.
+
+Triggering a checkpoint job
+"""""""""""""""""""""""""""
+
+Now, the checkpoint driver (**Spill**) is configured within the `vineyardd` Custom Resource
+Definition (CRD). To create a default vineyardd daemon server with the spill mechanism enabled,
+use the following YAML file:
+
+.. note::
+
+ The spill mechanism supports temporary storage (`HostPath`_) and persistent storage
+ (`PersistentVolume`_)
+
+.. code:: yaml
+
+ $ cat <`_
+for more details.
+
+After data backup, you can create a Recover CR to restore a certain vineyard backup data.
+Please refer the `Recover CRD <../references/crds.md#recover>`_ for more details.
+
+Next, we will show how to use the failover mechanism in vineyard operator. Assuming that
+we have a vineyard cluster that contains some objects, then we create a backup cr to back
+up the data. The following is the yaml file of the backup:
+
+.. note::
+
+ Please make sure you have installed the vineyard operator and vineyardd before
+ running the following yaml file.
+
+.. code:: yaml
+
+ $ cat < operation -> job2.
+
+```
+vineyardctl create operation [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl create](#vineyardctl-create) - Create a vineyard jobs on kubernetes
+
+### Examples
+
+```shell
+ # create a local assembly operation between job1 and job2
+ vineyardctl create operation --name assembly \
+ --type local \
+ --require job1 \
+ --target job2 \
+ --timeoutSeconds 600
+
+ # create a distributed assembly operation between job1 and job2
+ vineyardctl create operation --name assembly \
+ --type distributed \
+ --require job1 \
+ --target job2 \
+ --timeoutSeconds 600
+
+ # create a dask repartition operation between job1 and job2
+ vineyardctl create operation --name repartition \
+ --type dask \
+ --require job1 \
+ --target job2 \
+ --timeoutSeconds 600
+```
+
+### Options
+
+```
+ -h, --help help for operation
+ --kind string the kind of operation, including "assembly" and "repartition"
+ --name string the name of operation
+ --require string the job that need an operation to be executed
+ --target string the job that need to be executed before this operation
+ --timeoutSeconds int the timeout seconds of operation (default 600)
+ --type string the type of operation: for assembly, it can be "local" or "distributed"; for repartition, it can be "dask"
+```
+
+## `vineyardctl create recover`
+
+Create a recover cr to recover the current vineyard cluster on kubernetes
+
+### Synopsis
+
+Recover the current vineyard cluster on kubernetes. You could
+recover all objects from a backup of vineyard cluster. Usually,
+the recover crd should be created in the same namespace of
+the backup job.
+
+Notice, the command is used to create a recover cr for the
+vineyard operator and you must deploy the vineyard operator
+and vineyard cluster before using it.
+
+```
+vineyardctl create recover [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl create](#vineyardctl-create) - Create a vineyard jobs on kubernetes
+
+### Examples
+
+```shell
+ # create a recover cr for a backup job in the same namespace
+ vineyardctl create recover --backup-name vineyardd-sample -n vineyard-system
+```
+
+### Options
+
+```
+ --backup-name string the name of backup job (default "vineyard-backup")
+ -h, --help help for recover
+ --recover-name string the name of recover job (default "vineyard-recover")
+```
+
+## `vineyardctl csi`
+
+Start the vineyard csi driver
+
+```
+vineyardctl csi [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+
+### Examples
+
+```shell
+ # start the csi with the specific endpoint and node id
+ vineyardctl csi --endpoint=unix:///csi/csi.sock --nodeid=csinode1
+```
+
+### Options
+
+```
+ -f, --endpoint string the endpoint of vineyard csi driver
+ -h, --help help for csi
+ --nodeid string the node id of vineyard csi driver
+ --state-file-path string the path of state file (default "/csi/state")
+```
+
+## `vineyardctl delete`
+
+Delete the vineyard components from kubernetes
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+* [vineyardctl delete backup](#vineyardctl-delete-backup) - Delete the backup job on kubernetes
+* [vineyardctl delete csidriver](#vineyardctl-delete-csidriver) - Delete the vineyard csi driver on kubernetes
+* [vineyardctl delete operation](#vineyardctl-delete-operation) - Delete the operation from kubernetes
+* [vineyardctl delete operator](#vineyardctl-delete-operator) - Delete the vineyard operator from kubernetes
+* [vineyardctl delete recover](#vineyardctl-delete-recover) - Delete the recover job from kubernetes
+* [vineyardctl delete vineyard-cluster](#vineyardctl-delete-vineyard-cluster) - Delete the vineyard cluster from kubernetes
+* [vineyardctl delete vineyard-deployment](#vineyardctl-delete-vineyard-deployment) - delete vineyard-deployment will delete the vineyard deployment without vineyard operator
+* [vineyardctl delete vineyardd](#vineyardctl-delete-vineyardd) - Delete the vineyardd cluster from kubernetes
+
+### Examples
+
+```shell
+ # delete the default vineyard cluster on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config delete
+
+ # delete the default vineyard operator on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config delete operator
+
+ # delete the default vineyardd on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config delete vineyardd
+```
+
+### Options
+
+```
+ -h, --help help for delete
+```
+
+## `vineyardctl delete backup`
+
+Delete the backup job on kubernetes
+
+### Synopsis
+
+Delete the backup job on kubernetes.
+
+```
+vineyardctl delete backup [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the default backup job
+ vineyardctl delete backup
+```
+
+### Options
+
+```
+ --backup-name string the name of backup job (default "vineyard-backup")
+ -h, --help help for backup
+```
+
+## `vineyardctl delete csidriver`
+
+Delete the vineyard csi driver on kubernetes
+
+```
+vineyardctl delete csidriver [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the csi driver named "csidriver-test"
+ vineyardctl delete csidriver --name csidriver-test
+```
+
+### Options
+
+```
+ -h, --help help for csidriver
+ --name string The name of the csi driver cr. (default "csidriver-sample")
+```
+
+## `vineyardctl delete operation`
+
+Delete the operation from kubernetes
+
+```
+vineyardctl delete operation [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the operation named "assembly-test" in the "vineyard-system" namespace
+ vineyardctl delete operation --name assembly-test
+```
+
+### Options
+
+```
+ -h, --help help for operation
+ --name string the name of operation
+```
+
+## `vineyardctl delete operator`
+
+Delete the vineyard operator from kubernetes
+
+```
+vineyardctl delete operator [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the default vineyard operator in the vineyard-system namespace
+ vineyardctl delete operator
+
+ # delete the vineyard operator in a specific namespace
+ vineyardctl delete operator -n
+```
+
+### Options
+
+```
+ -h, --help help for operator
+```
+
+## `vineyardctl delete recover`
+
+Delete the recover job from kubernetes
+
+```
+vineyardctl delete recover [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the default recover job on kubernetes
+ vineyardctl delete recover
+```
+
+### Options
+
+```
+ -h, --help help for recover
+ --recover-name string the name of recover job (default "vineyard-recover")
+```
+
+## `vineyardctl delete vineyard-cluster`
+
+Delete the vineyard cluster from kubernetes
+
+```
+vineyardctl delete vineyard-cluster [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the default vineyard cluster on kubernetes
+ vineyardctl delete vineyard-cluster
+```
+
+### Options
+
+```
+ -h, --help help for vineyard-cluster
+```
+
+## `vineyardctl delete vineyard-deployment`
+
+delete vineyard-deployment will delete the vineyard deployment without vineyard operator
+
+```
+vineyardctl delete vineyard-deployment [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the default vineyard deployment in the vineyard-system namespace
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config delete vineyard-deployment
+
+ # delete the vineyard deployment with specific name in the vineyard-system namespace
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config delete vineyard-deployment \
+ --name vineyardd-0
+```
+
+### Options
+
+```
+ -h, --help help for vineyard-deployment
+ --name string the name of vineyardd (default "vineyardd-sample")
+```
+
+## `vineyardctl delete vineyardd`
+
+Delete the vineyardd cluster from kubernetes
+
+```
+vineyardctl delete vineyardd [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl delete](#vineyardctl-delete) - Delete the vineyard components from kubernetes
+
+### Examples
+
+```shell
+ # delete the default vineyardd cluster(vineyardd-sample) in the default namespace
+ vineyardctl delete vineyardd
+
+ # delete the specific vineyardd cluster in the vineyard-system namespace
+ vineyardctl -n vineyard-system delete vineyardd --name vineyardd-test
+```
+
+### Options
+
+```
+ -h, --help help for vineyardd
+ --name string the name of vineyardd (default "vineyardd-sample")
+```
+
+## `vineyardctl deploy`
+
+Deploy the vineyard components on kubernetes
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+* [vineyardctl deploy backup-job](#vineyardctl-deploy-backup-job) - Deploy a backup job of vineyard cluster on kubernetes
+* [vineyardctl deploy csidriver](#vineyardctl-deploy-csidriver) - Deploy the vineyard csi driver on kubernetes
+* [vineyardctl deploy operator](#vineyardctl-deploy-operator) - Deploy the vineyard operator on kubernetes
+* [vineyardctl deploy recover-job](#vineyardctl-deploy-recover-job) - Deploy a recover job to recover a backup of current vineyard cluster on kubernetes
+* [vineyardctl deploy vineyard-cluster](#vineyardctl-deploy-vineyard-cluster) - Deploy the vineyard cluster from kubernetes
+* [vineyardctl deploy vineyard-deployment](#vineyardctl-deploy-vineyard-deployment) - DeployVineyardDeployment builds and deploy the yaml file of vineyardd without vineyard operator
+* [vineyardctl deploy vineyardd](#vineyardctl-deploy-vineyardd) - Deploy the vineyardd on kubernetes
+
+### Examples
+
+```shell
+ # deploy the default vineyard cluster on kubernetes
+ vineyardctl --kubeconfig $HOME/.kube/config deploy vineyard-cluster
+
+ # deploy the vineyard operator on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy operator
+
+ # deploy the vineyardd on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy vineyardd
+
+ # deploy the vineyard csi driver on kubernetes
+ vineyardctl deploy csidriver --name vineyard-csi-sample \
+ --clusters vineyard-system/vineyardd-sample,default/vineyardd-sample
+```
+
+### Options
+
+```
+ -h, --help help for deploy
+```
+
+## `vineyardctl deploy backup-job`
+
+Deploy a backup job of vineyard cluster on kubernetes
+
+### Synopsis
+
+Deploy the backup job for the vineyard cluster on kubernetes,
+which will backup all objects of the current vineyard cluster
+quickly. For persistent storage, you could specify the pv spec
+and pv spec and the related pv and pvc will be created automatically.
+Also, you could also specify the existing pv and pvc name to use
+
+```
+vineyardctl deploy backup-job [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl deploy](#vineyardctl-deploy) - Deploy the vineyard components on kubernetes
+
+### Examples
+
+```shell
+ # deploy a backup job for all vineyard objects of the vineyard
+ # cluster on kubernetes and you could define the pv and pvc
+ # spec from json string as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --path /var/vineyard/dump \
+ --pv-pvc-spec '{
+ "pv-spec": {
+ "capacity": {
+ "storage": "1Gi"
+ },
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "storageClassName": "manual",
+ "hostPath": {
+ "path": "/var/vineyard/dump"
+ }
+ },
+ "pvc-spec": {
+ "storageClassName": "manual",
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "1Gi"
+ }
+ }
+ }
+ }'
+
+ # deploy a backup job for the vineyard cluster on kubernetes
+ # you could define the pv and pvc spec from yaml string as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --path /var/vineyard/dump \
+ --pv-pvc-spec \
+ '
+ pv-spec:
+ capacity:
+ storage: 1Gi
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: manual
+ hostPath:
+ path: "/var/vineyard/dump"
+ pvc-spec:
+ storageClassName: manual
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ '
+
+ # deploy a backup job for specific vineyard objects of the vineyard
+ # cluster on kubernetes.
+ cat pv-pvc.json | vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --objectIDs "o000018d29207fd01,o000018d80d264010" \
+ --path /var/vineyard/dump
+
+ # Assume you have already deployed a pvc named "pvc-sample", you
+ # could use them as the backend storage for the backup job as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --path /var/vineyard/dump \
+ --pvc-name pvc-sample
+
+ # The namespace to deploy the backup and recover job must be the same
+ # as the vineyard cluster namespace.
+ # Assume the vineyard cluster is deployed in the namespace "test", you
+ # could deploy the backup job as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace test \
+ --namespace test \
+ --path /var/vineyard/dump \
+ --pvc-name pvc-sample
+```
+
+### Options
+
+```
+ --backup-name string the name of backup job (default "vineyard-backup")
+ -h, --help help for backup-job
+ --objectIDs strings the specific objects to be backed up
+ --path string the path of the backup data
+ --pv-pvc-spec string the PersistentVolume and PersistentVolumeClaim of the backup data
+ --pvc-name string the name of an existing PersistentVolumeClaim
+ --vineyard-deployment-name string the name of vineyard deployment
+ --vineyard-deployment-namespace string the namespace of vineyard deployment
+```
+
+## `vineyardctl deploy csidriver`
+
+Deploy the vineyard csi driver on kubernetes
+
+### Synopsis
+
+Deploy the Vineyard CSI Driver on kubernetes.
+The CR is a cluster-scoped resource, and can only be created once.
+
+```
+vineyardctl deploy csidriver [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl deploy](#vineyardctl-deploy) - Deploy the vineyard components on kubernetes
+
+### Examples
+
+```shell
+ # deploy the Vineyard CSI Driver named vineyard-csi-sample on kubernetes
+ # Notice, the clusters are built as {vineyard-deployment-namespace}/{vineyard-deployment-name}
+ # and sperated by comma, e.g. vineyard-system/vineyardd-sample, default/vineyardd-sample
+ # They must be created before deploying the Vineyard CSI Driver.
+ vineyardctl deploy csidriver --name vineyard-csi-sample \
+ --clusters vineyard-system/vineyardd-sample,default/vineyardd-sample
+```
+
+### Options
+
+```
+ --attacherImage string The image of csi attacher. (default "registry.k8s.io/sig-storage/csi-attacher:v4.0.0")
+ --clusters strings The list of vineyard clusters.
+ --enableToleration Enable toleration for vineyard csi driver.
+ -h, --help help for csidriver
+ -i, --image string The image of vineyard csi driver. (default "vineyardcloudnative/vineyard-operator")
+ --imagePullPolicy string The image pull policy of vineyard csi driver. (default "IfNotPresent")
+ --livenessProbeImage string The image of livenessProbe. (default "registry.k8s.io/sig-storage/livenessprobe:v2.8.0")
+ --name string The name of the csi driver cr. (default "csidriver-sample")
+ --nodeRegistrarImage string The image of csi nodeRegistrar. (default "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.6.0")
+ --provisionerImage string The image of csi provisioner. (default "registry.k8s.io/sig-storage/csi-provisioner:v3.3.0")
+ --sidecar.enableTopology Enable topology for the csi driver.
+ --sidecar.imagePullPolicy string The image pull policy of all sidecar containers. (default "Always")
+ -s, --storageClassName string The name of storage class. (default "vineyard-csi")
+ -m, --volumeBindingMode string The volume binding mode of the storage class. (default "WaitForFirstConsumer")
+```
+
+## `vineyardctl deploy operator`
+
+Deploy the vineyard operator on kubernetes
+
+### Synopsis
+
+Deploy the vineyard operator on kubernetes.
+
+```
+vineyardctl deploy operator [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl deploy](#vineyardctl-deploy) - Deploy the vineyard components on kubernetes
+
+### Examples
+
+```shell
+ # deploy the vineyard operator on the 'vineyard-system' namespace
+ vineyardctl deploy operator
+
+ # deploy the vineyard operator on the existing namespace
+ vineyardctl deploy operator -n my-custom-namespace
+
+ # deploy the vineyard operator on the new namespace
+ vineyardctl deploy operator -n a-new-namespace-name --create-namespace
+```
+
+### Options
+
+```
+ -h, --help help for operator
+```
+
+## `vineyardctl deploy recover-job`
+
+Deploy a recover job to recover a backup of current vineyard cluster on kubernetes
+
+### Synopsis
+
+Deploy the recover job for vineyard cluster on kubernetes, which
+will recover all objects from a backup of vineyard cluster. Usually,
+the recover job should be created in the same namespace of
+the backup job.
+
+```
+vineyardctl deploy recover-job [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl deploy](#vineyardctl-deploy) - Deploy the vineyard components on kubernetes
+
+### Examples
+
+```shell
+ # Deploy a recover job for the vineyard deployment in the same namespace.
+ # After the recover job finished, the command will create a kubernetes
+ # configmap named [recover-name]+"-mapping-table" that contains the
+ # mapping table from the old vineyard objects to the new ones.
+ #
+ # If you create the recover job as follows, you can get the mapping table via
+ # "kubectl get configmap vineyard-recover-mapping-table -n vineyard-system -o yaml"
+ # the left column is the old object id, and the right column is the new object id.
+ vineyardctl deploy recover-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --recover-path /var/vineyard/dump \
+ --pvc-name vineyard-backup
+```
+
+### Options
+
+```
+ -h, --help help for recover-job
+ --pvc-name string the name of an existing PersistentVolumeClaim
+ --recover-name string the name of recover job (default "vineyard-recover")
+ --recover-path string the path of recover job
+ --vineyard-deployment-name string the name of vineyard deployment
+ --vineyard-deployment-namespace string the namespace of vineyard deployment
+```
+
+## `vineyardctl deploy vineyard-cluster`
+
+Deploy the vineyard cluster from kubernetes
+
+```
+vineyardctl deploy vineyard-cluster [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl deploy](#vineyardctl-deploy) - Deploy the vineyard components on kubernetes
+
+### Examples
+
+```shell
+ # deploy the default vineyard cluster on kubernetes
+ vineyardctl deploy vineyard-cluster
+```
+
+### Options
+
+```
+ -h, --help help for vineyard-cluster
+```
+
+## `vineyardctl deploy vineyard-deployment`
+
+DeployVineyardDeployment builds and deploy the yaml file of vineyardd without vineyard operator
+
+### Synopsis
+
+Builds and deploy the yaml file of vineyardd the vineyardd
+without vineyard operator. You could deploy a customized
+vineyardd from stdin or file.
+
+```
+vineyardctl deploy vineyard-deployment [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl deploy](#vineyardctl-deploy) - Deploy the vineyard components on kubernetes
+
+### Examples
+
+```shell
+ # deploy the default vineyard deployment on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config \
+ deploy vineyard-deployment
+
+ # deploy the vineyard deployment with customized image
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config \
+ deploy vineyard-deployment --image vineyardcloudnative/vineyardd:v0.12.2
+```
+
+### Options
+
+```
+ --etcd.replicas int the number of etcd replicas in a vineyard cluster (default 1)
+ -f, --file string the path of vineyardd
+ -h, --help help for vineyard-deployment
+ --name string the name of vineyardd (default "vineyardd-sample")
+ --owner-references string The owner reference of all vineyard deployment resources
+ --pluginImage.backupImage string the backup image of vineyardd (default "ghcr.io/v6d-io/v6d/backup-job")
+ --pluginImage.daskRepartitionImage string the dask repartition image of vineyardd workflow (default "ghcr.io/v6d-io/v6d/dask-repartition")
+ --pluginImage.distributedAssemblyImage string the distributed image of vineyard workflow (default "ghcr.io/v6d-io/v6d/distributed-assembly")
+ --pluginImage.localAssemblyImage string the local assembly image of vineyardd workflow (default "ghcr.io/v6d-io/v6d/local-assembly")
+ --pluginImage.recoverImage string the recover image of vineyardd (default "ghcr.io/v6d-io/v6d/recover-job")
+ --replicas int the number of vineyardd replicas (default 3)
+ --securityContext string the json string of security context of vineyardd
+ --vineyardd.cpu string the cpu requests and limits of vineyard container
+ --vineyardd.envs strings The environment variables of vineyardd
+ --vineyardd.image string the image of vineyardd (default "vineyardcloudnative/vineyardd:latest")
+ --vineyardd.imagePullPolicy string the imagePullPolicy of vineyardd (default "IfNotPresent")
+ --vineyardd.memory string the memory requests and limits of vineyard container
+ --vineyardd.metric.enable enable metrics of vineyardd
+ --vineyardd.metric.image string the metic image of vineyardd (default "vineyardcloudnative/vineyard-grok-exporter:latest")
+ --vineyardd.metric.imagePullPolicy string the imagePullPolicy of the metric image (default "IfNotPresent")
+ --vineyardd.reserve_memory Reserving enough physical memory pages for vineyardd
+ --vineyardd.service.port int the service port of vineyard service (default 9600)
+ --vineyardd.service.type string the service type of vineyard service (default "ClusterIP")
+ --vineyardd.size string The size of vineyardd. You can use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki. Defaults "", means not limited
+ --vineyardd.socket string The directory on host for the IPC socket file. The namespace and name will be replaced with your vineyard config (default "/var/run/vineyard-kubernetes/{{.Namespace}}/{{.Name}}")
+ --vineyardd.spill.config string If you want to enable the spill mechanism, please set the name of spill config
+ --vineyardd.spill.path string The path of spill config
+ --vineyardd.spill.pv-pvc-spec string the json string of the persistent volume and persistent volume claim
+ --vineyardd.spill.spillLowerRate string The low watermark of spilling memory (default "0.3")
+ --vineyardd.spill.spillUpperRate string The high watermark of spilling memory (default "0.8")
+ --vineyardd.streamThreshold int memory threshold of streams (percentage of total memory) (default 80)
+ --vineyardd.syncCRDs enable metrics of vineyardd (default true)
+ --vineyardd.volume.mountPath string Set the mount path for the pvc
+ --vineyardd.volume.pvcname string Set the pvc name for storing the vineyard objects persistently
+ --volume string the json string of vineyardd volume
+ --volumeMount string the json string of vineyardd volume mount
+```
+
+## `vineyardctl deploy vineyardd`
+
+Deploy the vineyardd on kubernetes
+
+### Synopsis
+
+Deploy the vineyardd on kubernetes. You could deploy a
+customized vineyardd from stdin or file.
+
+```
+vineyardctl deploy vineyardd [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl deploy](#vineyardctl-deploy) - Deploy the vineyard components on kubernetes
+
+### Examples
+
+```shell
+ # deploy the default vineyard on kubernetes
+ # wait for the vineyardd to be ready(default option)
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy vineyardd
+
+ # not to wait for the vineyardd to be ready
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy vineyardd \
+ --wait=false
+
+ # deploy the vineyardd from a yaml file
+ vineyardctl --kubeconfig $HOME/.kube/config deploy vineyardd --file vineyardd.yaml
+
+ # deploy the vineyardd with customized image
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy vineyardd \
+ --image vineyardd:v0.12.2
+
+ # deploy the vineyardd with spill mechanism on persistent storage from json string
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy vineyardd \
+ --vineyardd.spill.config spill-path \
+ --vineyardd.spill.path /var/vineyard/spill \
+ --vineyardd.spill.pv-pvc-spec '{
+ "pv-spec": {
+ "capacity": {
+ "storage": "1Gi"
+ },
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "storageClassName": "manual",
+ "hostPath": {
+ "path": "/var/vineyard/spill"
+ }
+ },
+ "pvc-spec": {
+ "storageClassName": "manual",
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "512Mi"
+ }
+ }
+ }
+ }'
+
+ # deploy the vineyardd with spill mechanism on persistent storage from yaml string
+ vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy vineyardd \
+ --vineyardd.spill.config spill-path \
+ --vineyardd.spill.path /var/vineyard/spill \
+ --vineyardd.spill.pv-pvc-spec \
+ '
+ pv-spec:
+ capacity:
+ storage: 1Gi
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: manual
+ hostPath:
+ path: "/var/vineyard/spill"
+ pvc-spec:
+ storageClassName: manual
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 512Mi
+ '
+
+# deploy the vineyardd with spill mechanism on persistent storage from json file
+ # also you could use the yaml file
+ cat pv-pvc.json | vineyardctl -n vineyard-system --kubeconfig $HOME/.kube/config deploy vineyardd \
+ --vineyardd.spill.config spill-path \
+ --vineyardd.spill.path /var/vineyard/spill \
+ -
+```
+
+### Options
+
+```
+ --etcd.replicas int the number of etcd replicas in a vineyard cluster (default 1)
+ -f, --file string the path of vineyardd
+ -h, --help help for vineyardd
+ --name string the name of vineyardd (default "vineyardd-sample")
+ --pluginImage.backupImage string the backup image of vineyardd (default "ghcr.io/v6d-io/v6d/backup-job")
+ --pluginImage.daskRepartitionImage string the dask repartition image of vineyardd workflow (default "ghcr.io/v6d-io/v6d/dask-repartition")
+ --pluginImage.distributedAssemblyImage string the distributed image of vineyard workflow (default "ghcr.io/v6d-io/v6d/distributed-assembly")
+ --pluginImage.localAssemblyImage string the local assembly image of vineyardd workflow (default "ghcr.io/v6d-io/v6d/local-assembly")
+ --pluginImage.recoverImage string the recover image of vineyardd (default "ghcr.io/v6d-io/v6d/recover-job")
+ --replicas int the number of vineyardd replicas (default 3)
+ --securityContext string the json string of security context of vineyardd
+ --vineyardd.cpu string the cpu requests and limits of vineyard container
+ --vineyardd.envs strings The environment variables of vineyardd
+ --vineyardd.image string the image of vineyardd (default "vineyardcloudnative/vineyardd:latest")
+ --vineyardd.imagePullPolicy string the imagePullPolicy of vineyardd (default "IfNotPresent")
+ --vineyardd.memory string the memory requests and limits of vineyard container
+ --vineyardd.metric.enable enable metrics of vineyardd
+ --vineyardd.metric.image string the metic image of vineyardd (default "vineyardcloudnative/vineyard-grok-exporter:latest")
+ --vineyardd.metric.imagePullPolicy string the imagePullPolicy of the metric image (default "IfNotPresent")
+ --vineyardd.reserve_memory Reserving enough physical memory pages for vineyardd
+ --vineyardd.service.port int the service port of vineyard service (default 9600)
+ --vineyardd.service.type string the service type of vineyard service (default "ClusterIP")
+ --vineyardd.size string The size of vineyardd. You can use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki. Defaults "", means not limited
+ --vineyardd.socket string The directory on host for the IPC socket file. The namespace and name will be replaced with your vineyard config (default "/var/run/vineyard-kubernetes/{{.Namespace}}/{{.Name}}")
+ --vineyardd.spill.config string If you want to enable the spill mechanism, please set the name of spill config
+ --vineyardd.spill.path string The path of spill config
+ --vineyardd.spill.pv-pvc-spec string the json string of the persistent volume and persistent volume claim
+ --vineyardd.spill.spillLowerRate string The low watermark of spilling memory (default "0.3")
+ --vineyardd.spill.spillUpperRate string The high watermark of spilling memory (default "0.8")
+ --vineyardd.streamThreshold int memory threshold of streams (percentage of total memory) (default 80)
+ --vineyardd.syncCRDs enable metrics of vineyardd (default true)
+ --vineyardd.volume.mountPath string Set the mount path for the pvc
+ --vineyardd.volume.pvcname string Set the pvc name for storing the vineyard objects persistently
+ --volume string the json string of vineyardd volume
+ --volumeMount string the json string of vineyardd volume mount
+```
+
+## `vineyardctl get`
+
+Get vineyard object, metadata, blob or cluster-info
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+* [vineyardctl get blob](#vineyardctl-get-blob) - Get vineyard blob
+* [vineyardctl get cluster-info](#vineyardctl-get-cluster-info) - Get vineyard cluster info
+* [vineyardctl get metadata](#vineyardctl-get-metadata) - Get vineyard metadata
+* [vineyardctl get object](#vineyardctl-get-object) - Get vineyard object
+
+### Examples
+
+```shell
+ # Connect the vineyardd deployment with IPC client
+ # Get the cluster info and output as table
+ vineyardctl get cluster-info --deployment-name vineyardd-sample -n vineyard-system
+```
+
+### Options
+
+```
+ -h, --help help for get
+```
+
+## `vineyardctl get blob`
+
+Get vineyard blob
+
+### Synopsis
+
+Get vineyard blob and only support IPC socket.
+If you don't specify the ipc socket every time, you can set it as the
+environment variable VINEYARD_IPC_SOCKET.
+
+```
+vineyardctl get blob [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl get](#vineyardctl-get) - Get vineyard object, metadata, blob or cluster-info
+
+### Examples
+
+```shell
+ # Get vineyard blob with the given vineyard object_id and the ipc socket
+ vineyardctl get blob --object_id xxxxxxxx --ipc-socket /var/run/vineyard.sock
+
+ # Get vineyard blob with the given vineyard object_id and the ipc socket
+ # and set the unsafe to be true
+ vineyardctl get blob --object_id xxxxxxxx --unsafe --ipc-socket /var/run/vineyard.sock
+
+ # If you set the environment variable VINEYARD_IPC_SOCKET
+ # you can use the following command to get vineyard blob
+ vineyardctl get blob --object_id xxxxxxxx
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for blob
+ --ipc-socket string vineyard IPC socket path
+ --object_id string The object id to get
+ --port int the port of vineyard deployment (default 9600)
+ --rpc-socket string vineyard RPC socket path
+ --syncRemote If the target object is a remote object,code_remote=True will force a meta synchronization on the vineyard server.
+ --unsafe unsafe means getting the blob even the blob is not sealed yet.Default is False.
+```
+
+## `vineyardctl get cluster-info`
+
+Get vineyard cluster info
+
+### Synopsis
+
+Get vineyard cluster info, including
+the instanceId, hostName, node name and so on.
+
+```
+vineyardctl get cluster-info [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl get](#vineyardctl-get) - Get vineyard object, metadata, blob or cluster-info
+
+### Examples
+
+```shell
+ # Get the cluster info of vineyard deployment and output as table
+ vineyardctl get cluster-info --deployment-name vineyardd-sample -n vineyard-system
+
+ # Get the cluster info of vineyard deployment and output as json
+ vineyardctl get cluster-info --deployment-name vineyardd-sample -n vineyard-system -o json
+
+ # Get the cluster info via IPC socket
+ vineyardctl get cluster-info --ipc-socket /var/run/vineyard.sock
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for cluster-info
+ --ipc-socket string vineyard IPC socket path
+ --port int the port of vineyard deployment (default 9600)
+ --rpc-socket string vineyard RPC socket path
+```
+
+## `vineyardctl get metadata`
+
+Get vineyard metadata
+
+### Synopsis
+
+Get vineyard metadata and support IPC socket,
+RPC socket and vineyard deployment. If you don't specify the ipc socket or rpc socket
+every time, you can set it as the environment variable VINEYARD_IPC_SOCKET or
+VINEYARD_RPC_SOCKET.
+
+```
+vineyardctl get metadata [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl get](#vineyardctl-get) - Get vineyard object, metadata, blob or cluster-info
+
+### Examples
+
+```shell
+ # Get vineyard metadata with the given vineyard object_id and the ipc socket
+ vineyardctl get metadata --object_id xxxxxxxx --ipc-socket /var/run/vineyard.sock
+
+ # Get vineyard metadata with the given vineyard object_id and the ipc socket
+ # and set the syncRemote to be true
+ vineyardctl get metadata --object_id xxxxxxxx --syncRemote --ipc-socket /var/run/vineyard.sock
+
+ # Get vineyard metadata with the given vineyard object_id and the rpc socket
+ vineyardctl get metadata --object_id xxxxxxxx --rpc-socket 127.0.0.1:9600
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for metadata
+ --ipc-socket string vineyard IPC socket path
+ --object_id string The object id to get
+ --port int the port of vineyard deployment (default 9600)
+ --rpc-socket string vineyard RPC socket path
+ --syncRemote If the target object is a remote object,code_remote=True will force a meta synchronization on the vineyard server.
+ --unsafe unsafe means getting the blob even the blob is not sealed yet.Default is False.
+```
+
+## `vineyardctl get object`
+
+Get vineyard object
+
+### Synopsis
+
+Get vineyard object and support IPC socket,
+RPC socket and vineyard deployment. If you don't specify the ipc socket or rpc socket
+every time, you can set it as the environment variable VINEYARD_IPC_SOCKET or
+VINEYARD_RPC_SOCKET.
+
+```
+vineyardctl get object [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl get](#vineyardctl-get) - Get vineyard object, metadata, blob or cluster-info
+
+### Examples
+
+```shell
+ # Get vineyard object with the given vineyard object_id and the ipc socket
+ vineyardctl get object --object_id xxxxxxxx --ipc-socket /var/run/vineyard.sock
+
+ # Get vineyard object with the given vineyard object_id and the rpc socket
+ vineyardctl get object --object_id xxxxxxxx --rpc-socket 127.0.0.1:9600
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for object
+ --ipc-socket string vineyard IPC socket path
+ --object_id string The object id to get
+ --port int the port of vineyard deployment (default 9600)
+ --rpc-socket string vineyard RPC socket path
+ --syncRemote If the target object is a remote object,code_remote=True will force a meta synchronization on the vineyard server.
+ --unsafe unsafe means getting the blob even the blob is not sealed yet.Default is False.
+```
+
+## `vineyardctl inject`
+
+Inject the vineyard sidecar container into a workload
+
+### Synopsis
+
+Inject the vineyard sidecar container into a workload. You can
+input a workload yaml or a workload json and then get the injected
+workload and some etcd manifests from the output. The workload can
+be a pod or a deployment or a statefulset, etc.
+
+The output is a set of manifests that includes the injected workload,
+the rpc service, the etcd service and the etcd cluster(e.g. several
+pods and services).
+
+If you have a pod yaml:
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: python
+spec:
+ containers:
+ - name: python
+ image: python:3.10
+ command: ["python", "-c", "import time; time.sleep(100000)"]
+```
+Then, you can use the following command to inject the vineyard sidecar
+
+$ vineyardctl inject -f pod.yaml
+
+After running the command, the output is as follows:
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ labels:
+ app.vineyard.io/name: vineyard-sidecar
+ app.vineyard.io/role: etcd
+ etcd_node: vineyard-sidecar-etcd-0
+ name: vineyard-sidecar-etcd-0
+ namespace: null
+ ownerReferences: []
+spec:
+ containers:
+ - command:
+ - etcd
+ - --name
+ - vineyard-sidecar-etcd-0
+ - --initial-advertise-peer-urls
+ - http://vineyard-sidecar-etcd-0:2380
+ - --advertise-client-urls
+ - http://vineyard-sidecar-etcd-0:2379
+ - --listen-peer-urls
+ - http://0.0.0.0:2380
+ - --listen-client-urls
+ - http://0.0.0.0:2379
+ - --initial-cluster
+ - vineyard-sidecar-etcd-0=http://vineyard-sidecar-etcd-0:2380
+ - --initial-cluster-state
+ - new
+ image: vineyardcloudnative/vineyardd:latest
+ name: etcd
+ ports:
+ - containerPort: 2379
+ name: client
+ protocol: TCP
+ - containerPort: 2380
+ name: server
+ protocol: TCP
+ restartPolicy: Always
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ etcd_node: vineyard-sidecar-etcd-0
+ name: vineyard-sidecar-etcd-0
+ namespace: null
+ ownerReferences: []
+spec:
+ ports:
+ - name: client
+ port: 2379
+ protocol: TCP
+ targetPort: 2379
+ - name: server
+ port: 2380
+ protocol: TCP
+ targetPort: 2380
+ selector:
+ app.vineyard.io/role: etcd
+ etcd_node: vineyard-sidecar-etcd-0
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: vineyard-sidecar-etcd-service
+ namespace: null
+ ownerReferences: []
+spec:
+ ports:
+ - name: etcd-for-vineyard-port
+ port: 2379
+ protocol: TCP
+ targetPort: 2379
+ selector:
+ app.vineyard.io/name: vineyard-sidecar
+ app.vineyard.io/role: etcd
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app.vineyard.io/name: vineyard-sidecar
+ name: vineyard-sidecar-rpc
+ namespace: null
+ ownerReferences: []
+spec:
+ ports:
+ - name: vineyard-rpc
+ port: 9600
+ protocol: TCP
+ selector:
+ app.vineyard.io/name: vineyard-sidecar
+ app.vineyard.io/role: vineyardd
+ type: ClusterIP
+---
+apiVersion: v1
+kind: Pod
+metadata:
+ creationTimestamp: null
+ labels:
+ app.vineyard.io/name: vineyard-sidecar
+ app.vineyard.io/role: vineyardd
+ name: python
+ ownerReferences: []
+spec:
+ containers:
+ - command:
+ - python
+ - -c
+ - while [ ! -e /var/run/vineyard.sock ]; do sleep 1; done;import time; time.sleep(100000)
+ env:
+ - name: VINEYARD_IPC_SOCKET
+ value: /var/run/vineyard.sock
+ image: python:3.10
+ name: python
+ resources: {}
+ volumeMounts:
+ - mountPath: /var/run
+ name: vineyard-socket
+ - command:
+ - /bin/bash
+ - -c
+ - |
+ /usr/local/bin/vineyardd --sync_crds true --socket /var/run/vineyard.sock --size \
+ --stream_threshold 80 --etcd_cmd etcd --etcd_prefix /vineyard --etcd_endpoint http://vineyard-sidecar-etcd-service:2379
+ env:
+ - name: VINEYARDD_UID
+ value: null
+ - name: VINEYARDD_NAME
+ value: vineyard-sidecar
+ - name: VINEYARDD_NAMESPACE
+ value: null
+ image: vineyardcloudnative/vineyardd:latest
+ imagePullPolicy: IfNotPresent
+ name: vineyard-sidecar
+ ports:
+ - containerPort: 9600
+ name: vineyard-rpc
+ protocol: TCP
+ resources:
+ limits: null
+ requests: null
+ securityContext: {}
+ volumeMounts:
+ - mountPath: /var/run
+ name: vineyard-socket
+ volumes:
+ - emptyDir: {}
+ name: vineyard-socket
+status: {}
+```
+
+Next, we will introduce a simple example to show the injection with
+the apply-resources flag.
+
+Assume you have the following workload yaml:
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: nginx-deployment
+ # Notice, you must set the namespace here
+ namespace: vineyard-job
+spec:
+ selector:
+ matchLabels:
+ app: nginx
+ template:
+ metadata:
+ labels:
+ app: nginx
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:1.14.2
+ ports:
+ - containerPort: 80
+```
+
+Then, you can use the following command to inject the vineyard sidecar
+which means that all resources will be created during the injection except
+the workload itself. The workload should be created by users.
+
+$ vineyardctl inject -f workload.yaml --apply-resources
+
+After running the command, the main output(removed some unnecessary fields)
+is as follows:
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: null
+ name: nginx-deployment
+ namespace: vineyard-job
+spec:
+ selector:
+ matchLabels:
+ app: nginx
+template:
+ metadata:
+ labels:
+ app: nginx
+ # the default sidecar name is vineyard-sidecar
+ app.vineyard.io/name: vineyard-sidecar
+ spec:
+ containers:
+ - command: null
+ image: nginx:1.14.2
+ name: nginx
+ ports:
+ - containerPort: 80
+ volumeMounts:
+ - mountPath: /var/run
+ name: vineyard-socket
+ - command:
+ - /bin/bash
+ - -c
+ - |
+ /usr/local/bin/vineyardd --sync_crds true --socket /var/run/vineyard.sock \
+ --stream_threshold 80 --etcd_cmd etcd --etcd_prefix /vineyard \
+ --etcd_endpoint http://vineyard-sidecar-etcd-service:2379
+ env:
+ - name: VINEYARDD_UID
+ value: null
+ - name: VINEYARDD_NAME
+ value: vineyard-sidecar
+ - name: VINEYARDD_NAMESPACE
+ value: vineyard-job
+ image: vineyardcloudnative/vineyardd:latest
+ imagePullPolicy: IfNotPresent
+ name: vineyard-sidecar
+ ports:
+ - containerPort: 9600
+ name: vineyard-rpc
+ protocol: TCP
+ volumeMounts:
+ - mountPath: /var/run
+ name: vineyard-socket
+ volumes:
+ - emptyDir: {}
+ name: vineyard-socket
+```
+
+The sidecar template can be accessed from the following link:
+https://github.com/v6d-io/v6d/blob/main/k8s/pkg/templates/sidecar/injection-template.yaml
+also you can get some inspiration from the doc link:
+https://v6d.io/notes/cloud-native/vineyard-operator.html#installing-vineyard-as-sidecar
+
+```
+vineyardctl inject [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+* [vineyardctl inject argo-workflow](#vineyardctl-inject-argo-workflow) - Inject the vineyard volumes into the argo workflow
+
+### Examples
+
+```shell
+ # use json format to output the injected workload
+ # notice that the output is a json string of all manifests
+ # it looks like:
+ # {
+ # "workload": "workload json string",
+ # "rpc_service": "rpc service json string",
+ # "etcd_service": "etcd service json string",
+ # "etcd_internal_service": [
+ # "etcd internal service json string 1",
+ # "etcd internal service json string 2",
+ # "etcd internal service json string 3"
+ # ],
+ # "etcd_pod": [
+ # "etcd pod json string 1",
+ # "etcd pod json string 2",
+ # "etcd pod json string 3"
+ # ]
+ # }
+ vineyardctl inject -f workload.yaml -o json
+
+ # inject the default vineyard sidecar container into a workload
+ # output all injected manifests and then deploy them
+ vineyardctl inject -f workload.yaml | kubectl apply -f -
+
+ # if you only want to get the injected workload yaml rather than
+ # all manifests that includes the etcd cluster and the rpc service,
+ # you can enable the apply-resources and then the manifests will be
+ # created during the injection, finally you will get the injected
+ # workload yaml
+ vineyardctl inject -f workload.yaml --apply-resources
+```
+
+### Options
+
+```
+ --apply-resources Whether to apply the resources including the etcd cluster and the rpc service if you enable this flag, the etcd cluster and the rpc service will be created during the injection
+ --etcd-replicas int The number of etcd replicas (default 1)
+ -f, --file string The yaml of workload
+ -h, --help help for inject
+ --name string The name of sidecar (default "vineyard-sidecar")
+ -o, --output string The output format of the command, support yaml and json (default "yaml")
+ --owner-references string The owner reference of all injectied resources
+ --resource string The resource of workload
+ --securityContext string the json string of security context of vineyard sidecar container
+ --sidecar.cpu string the cpu requests and limits of vineyard container
+ --sidecar.envs strings The environment variables of vineyardd
+ --sidecar.image string the image of vineyardd (default "vineyardcloudnative/vineyardd:latest")
+ --sidecar.imagePullPolicy string the imagePullPolicy of vineyardd (default "IfNotPresent")
+ --sidecar.memory string the memory requests and limits of vineyard container
+ --sidecar.metric.enable enable metrics of vineyardd
+ --sidecar.metric.image string the metic image of vineyardd (default "vineyardcloudnative/vineyard-grok-exporter:latest")
+ --sidecar.metric.imagePullPolicy string the imagePullPolicy of the metric image (default "IfNotPresent")
+ --sidecar.reserve_memory Reserving enough physical memory pages for vineyardd
+ --sidecar.service.port int the service port of vineyard service (default 9600)
+ --sidecar.service.type string the service type of vineyard service (default "ClusterIP")
+ --sidecar.size string The size of vineyardd. You can use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki. Defaults "", means not limited
+ --sidecar.socket string The directory on host for the IPC socket file. The namespace and name will be replaced with your vineyard config (default "/var/run/vineyard-kubernetes/{{.Namespace}}/{{.Name}}")
+ --sidecar.spill.config string If you want to enable the spill mechanism, please set the name of spill config
+ --sidecar.spill.path string The path of spill config
+ --sidecar.spill.pv-pvc-spec string the json string of the persistent volume and persistent volume claim
+ --sidecar.spill.spillLowerRate string The low watermark of spilling memory (default "0.3")
+ --sidecar.spill.spillUpperRate string The high watermark of spilling memory (default "0.8")
+ --sidecar.streamThreshold int memory threshold of streams (percentage of total memory) (default 80)
+ --sidecar.syncCRDs enable metrics of vineyardd (default true)
+ --sidecar.volume.mountPath string Set the mount path for the pvc
+ --sidecar.volume.pvcname string Set the pvc name for storing the vineyard objects persistently
+ --volume string the json string of vineyard sidecar container volume
+ --volumeMount string the json string of vineyard sidecar container volume mount
+```
+
+## `vineyardctl inject argo-workflow`
+
+Inject the vineyard volumes into the argo workflow
+
+### Synopsis
+
+Inject the vineyard volumes into the argo workflow DAGs. You can input
+the workflow manifest file and the injected manifest file with
+vineyard volume will be output to the file with the suffix
+"_with_vineyard", such as "workflow_with_vineyard.yaml".
+
+Suppose the workflow manifest named "workflow.yaml" is as follows:
+
+```yaml
+apiVersion: argoproj.io/v1alpha1
+kind: Workflow
+metadata:
+ generateName: mlops-
+spec:
+ entrypoint: dag
+ templates:
+ - name: producer
+ container:
+ image: producer:latest
+ command: [python]
+ args: ["/producer.py"]
+ - name: consumer
+ container:
+ image: consumer:latest
+ command: [python]
+ args: ["/consumer.py"]
+ - name: dag
+ dag:
+ tasks:
+ - name: producer
+ template: producer
+ - name: consumer
+ template: consumer
+ dependencies:
+ - producer
+```
+
+Assume the 'producer' and 'consumer' task all need to use vineyard
+volume, you can inject the vineyard volume into the workflow manifest
+with the following command:
+
+$ vineyardctl inject argo-workflow -f workflow.yaml \
+ --templates="producer,consumer" \
+ --vineyard-cluster="vineyard-system/vineyardd-sample" \
+ --mount-path="/vineyard/data" \
+ --dag="dag" \
+ --tasks="producer,consumer" \
+ --output-as-file
+
+The injected manifest will be output to the file named "workflow_with_vineyard.yaml".
+
+$ cat workflow_with_vineyard.yaml
+
+```yaml
+apiVersion: argoproj.io/v1alpha1
+kind: Workflow
+metadata:
+ generateName: mlops-
+spec:
+ entrypoint: dag
+ templates:
+ - name: producer
+ container:
+ image: producer:latest
+ command: [python]
+ args: ["/producer.py"]
+ ################## Injected #################
+ volumeMounts:
+ - name: vineyard-objects
+ mountPath: /vineyard/data
+ #############################################
+ ######################## Injected #######################
+ volumes:
+ - name: vineyard-objects
+ persistentVolumeClaim:
+ claimName: '{{inputs.parameters.vineyard-objects-name}}'
+ #########################################################
+ ############## Injected #############
+ inputs:
+ parameters:
+ - {name: vineyard-objects-name}
+ #####################################
+ - name: consumer
+ container:
+ image: consumer:latest
+ command: [python]
+ args: ["/consumer.py"]
+ ################## Injected #################
+ volumeMounts:
+ - name: vineyard-objects
+ mountPath: /vineyard/data
+ #############################################
+ ######################## Injected #######################
+ volumes:
+ - name: vineyard-objects
+ persistentVolumeClaim:
+ claimName: '{{inputs.parameters.vineyard-objects-name}}'
+ #########################################################
+ ############## Injected #############
+ inputs:
+ parameters:
+ - {name: vineyard-objects-name}
+ #####################################
+ - name: dag
+ dag:
+ tasks:
+ - name: producer
+ template: producer
+ arguments:
+ parameters:
+ ################################# Injected ################################
+ - name: vineyard-objects-name
+ value: '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ###########################################################################
+ dependencies:
+ ########### Injected ##########
+ - vineyard-objects
+ ###############################
+ - name: consumer
+ template: consumer
+ arguments:
+ parameters:
+ ################################# Injected ################################
+ - name: vineyard-objects-name
+ value: '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ###########################################################################
+ dependencies:
+ - producer
+ ########### Injected ##########
+ - vineyard-objects
+ ###############################
+ ########## Injected #########
+ - name: vineyard-objects
+ template: vineyard-objects
+ #############################
+############################# Injected ##########################
+ - name: vineyard-objects
+ resource:
+ action: create
+ setOwnerReference: true
+ manifest: |
+ apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: '{{workflow.name}}-vineyard-objects-pvc'
+ spec:
+ accessModes:
+ - ReadWriteMany
+ resources:
+ requests:
+ storage: 1Mi
+ storageClassName: vineyard-system.vineyardd-sample.csi
+ outputs:
+ parameters:
+ - name: vineyard-objects-name
+ valueFrom:
+ jsonPath: '{.metadata.name}'
+##############################################################
+```
+Suppose your workflow YAML only has a single template as follows.
+$ cat workflow.yaml
+
+```yaml
+apiVersion: argoproj.io/v1alpha1
+kind: Workflow
+metadata:
+ generateName: mlops-
+spec:
+ entrypoint: dag
+ templates:
+ - name: MLops
+ inputs:
+ parameters:
+ - name: functions
+ container:
+ imagePullPolicy: IfNotPresent
+ image: mlops-benchmark:latest
+ command: [python]
+ args: ["-m", "{{inputs.parameters.functions}}"]
+ - name: dag
+ dag:
+ tasks:
+ - name: producer
+ template: MLops
+ arguments:
+ parameters:
+ - name: functions
+ value: producer.py
+ - name: consumer
+ template: MLops
+ dependencies:
+ - producer
+ arguments:
+ parameters:
+ - name: functions
+ value: consumer.py
+```
+Suppose only the 'consumer' task need to use vineyard volume,
+you can inject the vineyard volume into the workflow manifest
+with the following command:
+$ vineyardctl inject argo-workflow -f workflow.yaml \
+ --templates="MLops" \
+ --vineyard-cluster="vineyard-system/vineyardd-sample" \
+ --mount-path="/vineyard/data" \
+ --dag="dag" \
+ --tasks="consumer"
+
+Then the injected manifest will be as follows:
+
+```yaml
+apiVersion: argoproj.io/v1alpha1
+kind: Workflow
+metadata:
+ generateName: mlops-
+spec:
+ entrypoint: dag
+ templates:
+ - container:
+ args:
+ - -m
+ - '{{inputs.parameters.functions}}'
+ command:
+ - python
+ image: mlops-benchmark:latest
+ imagePullPolicy: IfNotPresent
+ ############# Injected ############
+ volumeMounts:
+ - name: vineyard-objects
+ mountPath: /vineyard/data
+ ###################################
+ inputs:
+ parameters:
+ - name: functions
+ ############# Injected ############
+ - name: vineyard-objects-name
+ ###################################
+ name: MLops
+ ######################### Injected ########################
+ volumes:
+ - name: vineyard-objects
+ persistentVolumeClaim:
+ claimName: '{{inputs.parameters.vineyard-objects-name}}'
+ ###########################################################
+ - dag:
+ tasks:
+ - arguments:
+ parameters:
+ - name: functions
+ value: producer.py
+ ################################# Injected #################################
+ - name: vineyard-objects-name
+ value: '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ############################################################################
+ dependencies:
+ ##### Injected #####
+ - vineyard-objects
+ ####################
+ name: producer
+ template: MLops
+ - arguments:
+ parameters:
+ - name: functions
+ value: consumer.py
+ ################################# Injected #################################
+ - name: vineyard-objects-name
+ value: '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ############################################################################
+ dependencies:
+ - producer
+ ##### Injected #####
+ - vineyard-objects
+ ####################
+ name: consumer
+ template: MLops
+ ########### Injected ###########
+ - name: vineyard-objects
+ template: vineyard-objects
+ ################################
+ name: dag
+ ################################# Injected #################################
+ - name: vineyard-objects
+ outputs:
+ parameters:
+ - name: vineyard-objects-name
+ valueFrom:
+ jsonPath: '{.metadata.name}'
+ resource:
+ action: create
+ manifest: |-
+ apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: '{{workflow.name}}-vineyard-objects-pvc'
+ spec:
+ accessModes:
+ - ReadWriteMany
+ resources:
+ requests:
+ storage: 1Mi
+ storageClassName: vineyard-system.vineyardd-sample.csi
+ setOwnerReference: true
+ ############################################################################
+```
+
+```
+vineyardctl inject argo-workflow [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl inject](#vineyardctl-inject) - Inject the vineyard sidecar container into a workload
+
+### Examples
+
+```shell
+ # Inject the vineyard volumes into the argo workflow
+ $ vineyardctl inject argo-workflow -f workflow.yaml \
+ --templates="preprocess-data,train-data" \
+ --vineyard-cluster="vineyard-system/vineyardd-sample" \
+ --mount-path="/vineyard/data" \
+ --dag="dag" \
+ --tasks="preprocess-data,train-data"
+
+ # Suppose you only have a single template in the workflow
+ # you could set only one template name in the --templates flag
+ $ vineyardctl inject argo-workflow -f workflow.yaml \
+--templates="mlops" \
+ --vineyard-cluster="vineyard-system/vineyardd-sample" \
+ --mount-path="/vineyard/data" \
+ --dag="dag" \
+ --tasks="preprocess-data,test-data"
+```
+
+### Options
+
+```
+ --dag string The name of dag which will be injected with vineyard volumes
+ -f, --file string The file name of argo workflow
+ -h, --help help for argo-workflow
+ --mount-path string The mount path of vineyard volumes
+ --output-as-file Whether to output the injected workflow as a file, default is falseThe output file name will add a suffix '_with_vineyard' to the original file name
+ --tasks strings The set of task names under the dag
+ -t, --templates strings The name of workflow template which will be injected with vineyard volumes
+ --vineyard-cluster string The name of vineyard cluster which the argo workflow will use
+```
+
+## `vineyardctl ls`
+
+List vineyard objects, metadatas or blobs
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+* [vineyardctl ls blobs](#vineyardctl-ls-blobs) - List vineyard blobs
+* [vineyardctl ls metadatas](#vineyardctl-ls-metadatas) - List vineyard metadatas
+* [vineyardctl ls objects](#vineyardctl-ls-objects) - List vineyard objects
+
+### Examples
+
+```shell
+ # Connect the vineyardd server with IPC client
+ # List the vineyard objects no more than 10
+ vineyardctl ls objects --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List the vineyard blobs no more than 10
+ vineyardctl ls blobs --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List the vineyard objects with the specified pattern
+ vineyardctl ls objects --pattern "vineyard::Tensor<.*>" --regex --ipc-socket /var/run/vineyard.sock
+
+ # Connect the vineyardd server with RPC client
+ # List the vineyard metadatas no more than 1000
+ vineyardctl ls metadatas --rpc-socket 127.0.0.1:9600 --limit 1000
+
+ # Connect the vineyard deployment with PRC client
+ # List the vineyard objects no more than 1000
+ vineyardctl ls objects --deployment-name vineyardd-sample -n vineyard-system
+```
+
+### Options
+
+```
+ -h, --help help for ls
+```
+
+## `vineyardctl ls blobs`
+
+List vineyard blobs
+
+### Synopsis
+
+List vineyard blobs and only support IPC socket.
+If you don't specify the ipc socket every time, you can set it as the
+environment variable VINEYARD_IPC_SOCKET.
+
+```
+vineyardctl ls blobs [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl ls](#vineyardctl-ls) - List vineyard objects, metadatas or blobs
+
+### Examples
+
+```shell
+ # List no more than 10 vineyard blobs
+ vineyardctl ls blobs --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List no more than 1000 vineyard blobs
+ vineyardctl ls blobs --ipc-socket /var/run/vineyard.sock --limit 1000
+
+ # List vineyard blobs with the name matching
+ vineyardctl ls blobs --pattern "vineyard::Tensor<.*>" --regex --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard blobs with the regex pattern
+ vineyardctl ls blobs --pattern "*DataFrame*" --ipc-socket /var/run/vineyard.sock
+
+ # If you set the environment variable VINEYARD_IPC_SOCKET
+ # you can use the following command to list vineyard blobs
+ vineyardctl ls blobs --limit 1000
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for blobs
+ --ipc-socket string vineyard IPC socket path
+ -l, --limit int maximum number of objects to return (default 5)
+ --port int the port of vineyard deployment (default 9600)
+ --rpc-socket string vineyard RPC socket path
+```
+
+## `vineyardctl ls metadatas`
+
+List vineyard metadatas
+
+### Synopsis
+
+List vineyard metadatas and support IPC socket,
+RPC socket and vineyard deployment. If you don't specify the ipc socket or rpc socket
+every time, you can set it as the environment variable VINEYARD_IPC_SOCKET or
+VINEYARD_RPC_SOCKET.
+
+```
+vineyardctl ls metadatas [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl ls](#vineyardctl-ls) - List vineyard objects, metadatas or blobs
+
+### Examples
+
+```shell
+ # List no more than 10 vineyard metadatas
+ vineyardctl ls metadatas --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List no more than 1000 vineyard metadatas
+ vineyardctl ls metadatas --rpc-socket 127.0.0.1:9600 --limit 1000
+
+ # List vineyard metadatas with the name matching the regex pattern
+ vineyardctl ls metadatas --pattern "vineyard::Blob" --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard metadatas of the vineyard deployment
+ vineyardctl ls metadatas --deployment-name vineyardd-sample -n vineyard-system --limit 1000
+
+ # List vineyard metadatas sorted by the instance id
+ vineyardctl ls metadatas --sorted-key instance_id --limit 1000 --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard metadatas sorted by the type and print the output as json format
+ vineyardctl ls metadatas --sorted-key type --limit 1000 --format json --ipc-socket /var/run/vineyard.sock
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for metadatas
+ --ipc-socket string vineyard IPC socket path
+ -l, --limit int maximum number of objects to return (default 5)
+ -p, --pattern string string that will be matched against the object’s typenames (default "*")
+ --port int the port of vineyard deployment (default 9600)
+ -r, --regex regex pattern to match the object’s typenames
+ --rpc-socket string vineyard RPC socket path
+ -k, --sorted-key string key to sort the objects, support:
+ - id: object id, the default value.
+ - typename: object typename, e.g. tensor, dataframe, etc.
+ - type: object type, e.g. global, local, etc.
+ - instance_id: object instance id. (default "id")
+```
+
+## `vineyardctl ls objects`
+
+List vineyard objects
+
+### Synopsis
+
+List vineyard objects and support IPC socket,
+RPC socket and vineyard deployment. If you don't specify the ipc socket or rpc socket
+every time, you can set it as the environment variable VINEYARD_IPC_SOCKET or
+VINEYARD_RPC_SOCKET.
+
+```
+vineyardctl ls objects [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl ls](#vineyardctl-ls) - List vineyard objects, metadatas or blobs
+
+### Examples
+
+```shell
+ # List no more than 10 vineyard objects
+ vineyardctl ls objects --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List any vineyard objects and no more than 1000 objects
+ vineyardctl ls objects --pattern "*" --ipc-socket /var/run/vineyard.sock --limit 1000
+
+ # List vineyard objects with the name matching the regex pattern
+ vineyardctl ls objects --pattern "vineyard::Tensor<.*>" --regex --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard objects and output as json format
+ vineyardctl ls objects --format json --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard objects sorted by the typename
+ vineyardctl ls objects --sorted-key typename --limit 1000 --ipc-socket /var/run/vineyard.sock
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for objects
+ --ipc-socket string vineyard IPC socket path
+ -l, --limit int maximum number of objects to return (default 5)
+ -p, --pattern string string that will be matched against the object’s typenames (default "*")
+ --port int the port of vineyard deployment (default 9600)
+ -r, --regex regex pattern to match the object’s typenames
+ --rpc-socket string vineyard RPC socket path
+ -k, --sorted-key string key to sort the objects, support:
+ - id: object id, the default value.
+ - typename: object typename, e.g. tensor, dataframe, etc.
+ - type: object type, e.g. global, local, etc.
+ - instance_id: object instance id. (default "id")
+```
+
+## `vineyardctl manager`
+
+Start the manager of vineyard operator
+
+```
+vineyardctl manager [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+
+### Examples
+
+```shell
+ # start the manager of vineyard operator with default configuration
+ # (Enable the controller, webhooks and scheduler)
+ vineyardctl manager
+
+ # start the manager of vineyard operator without webhooks
+ vineyardctl manager --enable-webhook=false
+
+ # start the manager of vineyard operator without scheduler
+ vineyardctl manager --enable-scheduler=false
+
+ # only start the controller
+ vineyardctl manager --enable-webhook=false --enable-scheduler=false
+```
+
+### Options
+
+```
+ --enable-scheduler Enable scheduler for controller manager. (default true)
+ --enable-webhook Enable webhook for controller manager. (default true)
+ --health-probe-bind-address string The address the probe endpoint binds to. (default ":8081")
+ -h, --help help for manager
+ --leader-elect Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.
+ --metrics-bind-address string The address the metric endpoint binds to. (default "127.0.0.1:8080")
+ --scheduler-config-file string The location of scheduler plugin's configuration file. (default "/etc/kubernetes/scheduler.yaml")
+ --webhook-cert-dir string The directory to store the generated certificates. (default "/etc/webhook/certs")
+```
+
+## `vineyardctl put`
+
+Put basic data type into vineyard
+
+### Synopsis
+
+Put basic data type into vineyard and only support IPC socket.
+It receives the flag --value as string and will print object id if succeed.
+If you don't specify the ipc socket every time, you can set it as the
+environment variable VINEYARD_IPC_SOCKET.
+
+```
+vineyardctl put [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+
+### Examples
+
+```shell
+ # put value into vineyard with the given ipc socket
+ vineyardctl put --value 12345 --ipc-socket /var/run/vineyard.sock
+ vineyardctl put --value hello,world --ipc-socket /var/run/vineyard.sock
+
+ # If you set the environment variable VINEYARD_IPC_SOCKET
+ # you can use the following command to get vineyard blob
+ vineyardctl put --value 12345
+```
+
+### Options
+
+```
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for put
+ --ipc-socket string vineyard IPC socket path
+ --port int the port of vineyard deployment (default 9600)
+ --rpc-socket string vineyard RPC socket path
+ --value string vineyard blob value
+```
+
+## `vineyardctl schedule`
+
+Schedule a workload or a workflow to existing vineyard cluster.
+
+**SEE ALSO**
+
+* [vineyardctl](#vineyardctl) - vineyardctl is the command-line tool for interact with the Vineyard Operator.
+* [vineyardctl schedule workflow](#vineyardctl-schedule-workflow) - Schedule a workflow based on the vineyard cluster
+* [vineyardctl schedule workload](#vineyardctl-schedule-workload) - Schedule the workload to a vineyard cluster
+
+### Examples
+
+```shell
+ # Schedule a workload to a vineyard cluster
+ # it will add PodAffinity to the workload
+ vineyardctl schedule workload --resource '{kubernetes workload json string}'
+
+ # schedule a workflow to the vineyard cluster
+ # it will use the best-effort scheduling strategy
+ vineyardctl schedule workflow --file workflow.yaml
+```
+
+### Options
+
+```
+ -h, --help help for schedule
+```
+
+## `vineyardctl schedule workflow`
+
+Schedule a workflow based on the vineyard cluster
+
+### Synopsis
+
+Schedule a workflow based on the vineyard cluster.
+It will apply the workflow to kubernetes cluster and deploy the workload
+of the workflow on the vineyard cluster with the best-fit strategy.
+
+```
+vineyardctl schedule workflow [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl schedule](#vineyardctl-schedule) - Schedule a workload or a workflow to existing vineyard cluster.
+
+### Examples
+
+```shell
+ # schedule a workflow to the vineyard cluster with the best-fit strategy
+ vineyardctl schedule workflow --file workflow.yaml
+
+ # schedule a workflow without CRD installed
+ # Notice, it only works for the workflow built by pods
+ vineyardctl schedule workflow --file pod-workflow.yaml --without-crd
+```
+
+### Options
+
+```
+ -f, --file string the path of workflow file
+ -h, --help help for workflow
+ --without-crd whether the CRD(especially for GlobalObject and LocalObject) is installed
+```
+
+## `vineyardctl schedule workload`
+
+Schedule the workload to a vineyard cluster
+
+### Synopsis
+
+Schedule the workload to a vineyard cluster.
+It will add the podAffinity to the workload so that the workload
+will be scheduled to the vineyard cluster. Besides, if the workload
+does not have the socket volumeMount and volume, it will add one.
+
+Assume you have the following workload yaml:
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: python-client
+ # Notice, you must set the namespace here
+ namespace: vineyard-job
+spec:
+ selector:
+ matchLabels:
+ app: python
+ template:
+ metadata:
+ labels:
+ app: python
+ spec:
+ containers:
+ - name: python
+ image: python:3.10
+ command: ["python", "-c", "import time; time.sleep(100000)"]
+```
+
+Then you can run the following command to add the podAffinity and socket volume
+to the workload yaml:
+
+$ vineyard schedule workload -f workload.yaml -o yaml
+
+After that, you will get the following workload yaml:
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ creationTimestamp: null
+ name: python-client
+ namespace: vineyard-job
+spec:
+ selector:
+ matchLabels:
+ app: python
+ strategy: {}
+ template:
+ metadata:
+ creationTimestamp: null
+ labels:
+ app: python
+ spec:
+ affinity:
+ podAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ - labelSelector:
+ matchExpressions:
+ - key: app.kubernetes.io/instance
+ operator: In
+ values:
+ - vineyard-system-vineyardd-sample
+ namespaces:
+ - vineyard-system
+ topologyKey: kubernetes.io/hostname
+
+ containers:
+ - command:
+ - python
+ - -c
+ - import time; time.sleep(100000)
+ env:
+ - name: VINEYARD_IPC_SOCKET
+ value: /var/run/vineyard.sock
+ image: python:3.10
+ name: python
+ resources: {}
+ volumeMounts:
+ - mountPath: /var/run
+ name: vineyard-socket
+ volumes:
+ - hostPath:
+ path: /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+ name: vineyard-socket
+```
+
+```
+vineyardctl schedule workload [flags]
+```
+
+**SEE ALSO**
+
+* [vineyardctl schedule](#vineyardctl-schedule) - Schedule a workload or a workflow to existing vineyard cluster.
+
+### Examples
+
+```shell
+ # Add the podAffinity to the workload yaml
+ vineyardctl schedule workload -f workload.yaml \
+ --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-system
+
+ # Add the podAffinity to the workload for the specific vineyard cluster
+ vineyardctl schedule workload --resource '{
+ "apiVersion": "apps/v1",
+ "kind": "Deployment",
+ "metadata": {
+ "name": "web-server"
+ },
+ "spec": {
+ "selector": {
+ "matchLabels": {
+ "app": "web-store"
+ }
+ },
+ "replicas": 3,
+ "template": {
+ "metadata": {
+ "labels": {
+ "app": "web-store"
+ }
+ },
+ "spec": {
+ "affinity": {
+ "podAntiAffinity": {
+ "requiredDuringSchedulingIgnoredDuringExecution": [
+ {
+ "labelSelector": {
+ "matchExpressions": [
+ {
+ "key": "app",
+ "operator": "In",
+ "values": [
+ "web-store"
+ ]
+ }
+ ]
+ },
+ "topologyKey": "kubernetes.io/hostname"
+ }
+ ]
+ },
+ "podAffinity": {
+ "requiredDuringSchedulingIgnoredDuringExecution": [
+ {
+ "labelSelector": {
+ "matchExpressions": [
+ {
+ "key": "app",
+ "operator": "In",
+ "values": [
+ "store"
+ ]
+ }
+ ]
+ },
+ "topologyKey": "kubernetes.io/hostname"
+ }
+ ]
+ }
+ },
+ "containers": [
+ {
+ "name": "web-app",
+ "image": "nginx:1.16-alpine"
+ }
+ ]
+ }
+ }
+ }
+ }' \
+ --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-system
+```
+
+### Options
+
+```
+ -f, --file string the file path of workload
+ -h, --help help for workload
+ -o, --output string the output format for vineyardctl schedule workload command (default "json")
+ --resource string the json string of kubernetes workload
+ --vineyardd-name string the namespace of vineyard cluster (default "vineyardd-sample")
+ --vineyardd-namespace string the namespace of vineyard cluster (default "vineyard-system")
+```
diff --git a/_sources/notes/developers.rst.txt b/_sources/notes/developers.rst.txt
new file mode 100644
index 0000000000..67c45449bd
--- /dev/null
+++ b/_sources/notes/developers.rst.txt
@@ -0,0 +1,82 @@
+Getting Involved
+----------------
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ developers/build-from-source.rst
+ developers/contributing.rst
+ developers/troubleshooting.rst
+ developers/roadmap.rst
+
+Vineyard is an open-source project that was accepted into the CNCF sandbox in April 2021.
+It has been successfully developed and maintained by the open-source community. We are
+committed to engaging community members to help us improve Vineyard. You will find our
+community welcoming and responsive by joining our Github discussions or Slack channel:
+
+.. panels::
+ :container: container-lg pb-4
+ :column: col-lg-4 col-md-4 col-sm-4 col-xs-12 p-2
+ :body: text-center
+
+ .. link-button:: https://github.com/v6d-io/v6d/discussions
+ :type: url
+ :text: Github Discussions
+ :classes: btn-block stretched-link
+
+ :fa:`github`
+
+ ---
+
+ .. link-button:: http://slack.cncf.io
+ :type: url
+ :text: Slack
+ :classes: btn-block stretched-link
+
+ :fa:`slack`
+
+To modify the Vineyard source code, you will need to set up the development environment
+and build the project from source. Follow the instructions below:
+
+.. panels::
+ :container: container-lg pb-4
+ :column: col-lg-6 col-md-6 col-sm-6 col-xs-12 p-2
+ :body: text-center card-body-less-padding
+
+ .. link-button:: developers/build-from-source
+ :type: ref
+ :text: Building from source
+ :classes: btn-block stretched-link
+
+If you encounter any issues during your journey with Vineyard, you may find solutions in:
+
+.. panels::
+ :container: container-lg pb-4
+ :column: col-lg-4 col-md-4 col-sm-4 col-xs-12 p-2
+ :body: text-center card-body-less-padding
+
+ .. link-button:: developers/troubleshooting
+ :type: ref
+ :text: Troubleshooting
+ :classes: btn-block stretched-link
+
+ ---
+
+ .. link-button:: https://github.com/v6d-io/v6d/issues
+ :type: url
+ :text: Github Issues
+ :classes: btn-block stretched-link
+
+We also have a public roadmap that outlines our future goals and highlights our ongoing efforts:
+
+.. panels::
+ :container: container-lg pb-4
+ :column: col-lg-4 col-md-4 col-sm-4 col-xs-12 p-2
+ :body: text-center card-body-less-padding
+
+ .. link-button:: developers/roadmap
+ :type: ref
+ :text: Our Roadmap
+ :classes: btn-block stretched-link
diff --git a/_sources/notes/developers/build-from-source.rst.txt b/_sources/notes/developers/build-from-source.rst.txt
new file mode 100644
index 0000000000..030515f9bc
--- /dev/null
+++ b/_sources/notes/developers/build-from-source.rst.txt
@@ -0,0 +1,169 @@
+Building from source
+====================
+
+Install vineyard
+----------------
+
+Vineyard is distributed as a `python package `_
+and can be easily installed with :code:`pip`:
+
+.. code:: shell
+
+ pip3 install vineyard
+
+Install etcd
+------------
+
+Vineyard is based on `etcd `_, please refer the `doc `_ to install it.
+
+Install from source
+-------------------
+
+Vineyard is open source on Github: `https://github.com/v6d-io/v6d `_.
+You can obtain the source code using ``git``:
+
+.. code:: console
+
+ git clone https://github.com/v6d-io/v6d
+ cd v6d
+ git submodule update --init
+
+Prepare dependencies
+^^^^^^^^^^^^^^^^^^^^
+
+Vineyard can be built and deployed on common Unix-like systems. Vineyard has been
+fully tests with C++ compilers that supports C++ 14.
+
+Dependencies
+~~~~~~~~~~~~
+
+Vineyard requires the following software as dependencies to build and run:
+
++ apache-arrow >= 3.0.0
++ gflags
++ glog
++ boost
++ mpi, for the graph data structure module
+
+If you want to build the vineyard server, the following additional libraries are needed:
+
++ protobuf
++ grpc
+
+And the following python packages are required:
+
++ libclang
+
+ Can be installed using pip
+
+ .. code:: shell
+
+ pip3 install libclang
+
+Install on Ubuntu (or Debian)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Vineyard has been fully tested on Ubuntu 20.04. The dependencies can be installed by
+
+.. code:: shell
+
+ apt-get install -y ca-certificates \
+ cmake \
+ doxygen \
+ libboost-all-dev \
+ libcurl4-openssl-dev \
+ libgflags-dev \
+ libgoogle-glog-dev \
+ libgrpc-dev \
+ libgrpc++-dev \
+ libmpich-dev \
+ libprotobuf-dev \
+ libssl-dev \
+ libunwind-dev \
+ libz-dev \
+ protobuf-compiler-grpc \
+ python3-pip \
+ wget
+
+Then install the apache-arrow (see also `https://arrow.apache.org/install `_):
+
+.. code:: shell
+
+ wget https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb \
+ -O /tmp/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb
+ apt install -y -V /tmp/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb
+ apt update -y
+ apt install -y libarrow-dev
+
+Dependencies on MacOS
+~~~~~~~~~~~~~~~~~~~~~
+
+Vineyard has been tested on MacOS as well, the dependencies can be installed using :code:`brew`:
+
+.. code:: shell
+
+ brew install apache-arrow boost gflags glog grpc protobuf llvm mpich openssl zlib autoconf
+
+Building vineyard
+^^^^^^^^^^^^^^^^^
+
+After the required dependencies are installed, you do an out-of-source build using **CMake**:
+
+.. tip::
+
+ We recommend to use the brew installed LLVM as the compiler for building vineyard on MacOS,
+ which can be accomplished by setting the environment variable :code:`CC` and :code:`CXX`:
+
+ .. code::
+
+ export CC=$(brew --prefix llvm)/bin/clang
+ export CXX=$(brew --prefix llvm)/bin/clang++
+
+.. code:: shell
+
+ mkdir build
+ cd build
+ cmake ..
+ make -j$(nproc)
+ sudo make install # optionally
+
+You will see vineyard server binary under the ``bin`` directory, and static or shared linked
+libraries will be placed under the ``lib-shared`` folder.
+
+Building python wheels
+^^^^^^^^^^^^^^^^^^^^^^
+
+After building the vineyard library successfully, you can package an install wheel distribution by
+
+.. code:: shell
+
+ python3 setup.py bdist_wheel
+
+
+Building the documentation
+--------------------------
+
+Vineyard documentation is organized and generated by sphinx. There are other packages that
+help us build the documentation, which can be easily installed using ``pip``:
+
+.. code:: shell
+
+ pip3 install -r requirements.txt -r requirements-dev.txt
+
+Once installed, you could go to the `docs/` directory and build the documentation by
+
+.. code:: shell
+
+ cd docs/ # skip if you are already there
+ make html
+
+Building on various platforms
+-----------------------------
+
+Vineyard is continuously tested on various platforms and you may find building and installation steps
+from our CI:
+
+- `Ubuntu `_
+- `MacOS `_
+- `CentOS `_
+- `Arch Linux `_
diff --git a/_sources/notes/developers/contributing.rst.txt b/_sources/notes/developers/contributing.rst.txt
new file mode 100644
index 0000000000..fe48147cb8
--- /dev/null
+++ b/_sources/notes/developers/contributing.rst.txt
@@ -0,0 +1,4 @@
+.. This file is just a placeholder to refer the top-level CONTRIBUTING.rst
+ to sphinx doc workspace.
+
+.. include:: ../../../CONTRIBUTING.rst
diff --git a/_sources/notes/developers/faq.rst.txt b/_sources/notes/developers/faq.rst.txt
new file mode 100644
index 0000000000..a3ea573285
--- /dev/null
+++ b/_sources/notes/developers/faq.rst.txt
@@ -0,0 +1,124 @@
+Frequently Asked Questions
+==========================
+
+This *FAQ* page compiles questions frequently asked by our end users to provide
+informative and concise answers. If the following sections do not address your
+concerns, please feel free to `open an issue`_ or `post it to discussions`_.
+
+1. *What are the objects in vineyard?*
+
+ A global object is composed of multiple local objects distributed across the cluster,
+ with each local object stored in a single vineyard daemon (ensuring that a local object
+ can always fit into the memory of a single machine).
+
+ These local objects represent partitions of the global object (e.g., partitioned dataframes
+ within a large dataframe, graph fragments within a vast graph). Generally, a global object
+ serves as an abstraction for the input or output of a parallel-processing workload, while
+ a local object corresponds to the input or output of an individual worker within that workload.
+
+2. *Can multiple readers access the same data simultaneously in vineyard?*
+
+ Absolutely. Vineyard stores objects as **immutable** entities, which are shared
+ among readers' processes through memory mapping. This ensures safe and concurrent
+ access to objects by multiple readers without any conflicts.
+
+3. *How can I launch a cluster with multiple vineyardd instances?*
+
+ A vineyard daemon server represents a single vineyard instance within a vineyard cluster. To
+ initiate a vineyard cluster, simply start the ``vineyardd`` process on all the
+ machines within the cluster, ensuring that these vineyard instances can register with
+ the same ``etcd_endpoint``. The default value for ``etcd_endpoint`` is
+ ``http://127.0.0.1:2379``, and if the etcd servers are not already running on the cluster,
+ ``vineyard`` will automatically launch the ``etcd_endpoint``.
+
+ For additional parameter settings, refer to the help documentation by running
+ ``python3 -m vineyard --help``.
+
+4. *Is Kubernetes a necessity for vineyard?*
+
+ No, Kubernetes is not a necessity for vineyard. However, deploying vineyard on Kubernetes
+ allows users to benefit from the flexible resource management offered by cloud-native
+ deployments for their application workloads. Additionally, the scheduler plugin assists
+ in co-locating worker pods with the data for improved data-work alignment.
+
+5. *How does vineyard achieve IPC and memory sharing (i.e., zero-copy sharing) on Kubernetes?*
+
+ Inter-process memory sharing can be challenging in Kubernetes, but it is achievable. When
+ deployed on Kubernetes, vineyard exposes its UNIX-domain socket as a :code:`PersistentVolume`.
+ This volume can be mounted into the job's pod, allowing the socket to be used for IPC
+ connections to the vineyard daemon. Memory sharing is accomplished by mounting a volume of
+ medium :code:`Memory` into both the vineyard daemon's pod and the job's pod.
+
+6. *How does vineyard's stream differ from similar systems, such as Kafka?*
+
+ Vineyard's stream is an abstraction of a sequence of objects, where each object typically
+ represents a small portion of the entire object (e.g., a mini-batch of a tensor). This
+ abstraction is designed to support cross-engine pipelining between consecutive workers in
+ a data analytics pipeline (e.g., a dataframe engine generating training data while the
+ subsequent machine learning engine consumes the data and trains the model simultaneously).
+
+ The primary distinction between vineyard's stream and traditional stream frameworks like
+ Kafka is that data in vineyard's stream is still abstracted as (high-level) objects and
+ can be consumed in a zero-copy manner, similar to normal objects in vineyard. In contrast,
+ Kafka is designed for stream processing applications and abstracts data as (low-level)
+ messages. Utilizing Kafka in the aforementioned scenario would still incur (de)serialization
+ and memory copy costs.
+
+7. *Does vineyard support accessing remote objects?*
+
+ Yes, vineyard's RPC client can access the metadata of an object, regardless of whether
+ the object is local or remote. This capability enables users and internal operators to
+ examine essential information (e.g., chunk axis, size) about an object, assisting in
+ decision-making processes related to object management (e.g., determining the need for
+ repartitioning, planning the next workload). With this capability, the `vineyard client`_
+ connects to the Vineyard daemon that stores the object's payloads, retrieves these payloads,
+ and assembles the objects locally.
+
+8. *How does migration work in vineyard? Is it automatically triggered?*
+
+ Consider a scenario where workload *A* produces a global object *O*, and the subsequent
+ workload *B* consumes *O* as input. In a Kubernetes cluster with multiple hosts (e.g.,
+ *h1*, *h2*, *h3*, *h4*), if *A* has two worker pods on *h1* and *h2*, the local objects
+ (i.e., *O1* and *O2*) of *O* are stored on *h1* and *h2*, respectively.
+
+ If the two worker pods of *B* (i.e., *B1* and *B2*) are placed on *h1* and *h3*, *B1*
+ can access *O1* locally via memory mapping. However, *B2* (on *h3*) cannot access *O2*
+ since it resides on *h2*. In this situation, a utility program distributed with vineyard
+ in the :code:`initContainer` of *B2* triggers the migration of *O2* from *h2* to *h3*,
+ enabling pod *B2* to access *O2* locally.
+
+ Although data migration incurs a cost, the scheduler plugin has been developed to
+ prioritize *h2* when launching *B2*, minimizing the need for migration whenever possible.
+
+9. *What's the minimal Kubernetes version requirement for vineyard operator?*
+
+ At present, we only test the vineyard operator based on Kubernetes 1.24.0.
+ So we highly recommend using Kubernetes 1.24.0 or above.
+
+10. *Why the vineyard operator can't be deployed on Kubernetes?*
+
+ If you use the helm to deploy the vineyard operator, you may find the vineyard operator
+ can't be deployed successfully after a long time. In this case, you should check whether
+ the command contains the flag `--wait`. If so, you should remove the flag `--wait` and
+ try to install the operator again.
+
+11. *How to connect to the vineyard cluster deployed by the vineyard operator?*
+
+ There are two ways to connect to the vineyard cluster deployed by the vineyard operator:
+
+ - `Through IPC`. Create a pod with the specific labels so that the pod can be scheduled
+ to the node where the vineyard cluster is deployed.
+
+ - `Through RPC`. Connect to the vineyard cluster through the RPC service exposed by the
+ vineyard operator. You could refer to the `guide`_ for more details.
+
+12. *Is there a way to install the vineyard cluster on Kubernetes quickly?*
+
+ To reduce the complexity of the installation, we provide a `command line tool`_
+ to install the vineyard cluster on Kubernetes quickly.
+
+.. _open an issue: https://github.com/v6d-io/v6d/issues/new
+.. _post it to discussions: https://github.com/v6d-io/v6d/discussions/new
+.. _guide: ../../tutorials/kubernetes/using-vineyard-operator.rst
+.. _command line tool: ../../notes/cloud-native/vineyardctl.md
+.. _vineyard client: ../../notes/references/python-api.html#vineyard.Client
\ No newline at end of file
diff --git a/_sources/notes/developers/roadmap.rst.txt b/_sources/notes/developers/roadmap.rst.txt
new file mode 100644
index 0000000000..1d7f9b63a2
--- /dev/null
+++ b/_sources/notes/developers/roadmap.rst.txt
@@ -0,0 +1,126 @@
+Roadmap
+=======
+
+Vineyard aims to serve as an open-source in-memory immutable data manager. We
+cut a major release once a year, a minor release for about every two months,
+and a patch release every one or two weeks.
+
+The roadmap for major vineyard releases are listed as follows:
+
+v0.8.0
+------
+
+Vineyard *v0.8.0* will deliver the first implementation of the following
+important features and will be hopefully release in the later Aug, 2022:
+
+- Filesystem view of vineyard objects: vineyard objects can be accessed like
+ files on a filesystem in a high-performance fashion. Such a feature would
+ greatly ease the integration of computing processes with vineyard.
+- Copy-on-realloc and data lineage: the mutation support would be extended
+ from blobs to general objects with a carefully concurrency-control design.
+- Transparent object spilling: objects in vineyard can be spilled to disk
+ when they are too large to fit in memory.
+- Sharing GPU memory between processes of different compute engines: we are
+ working on shared memory on devices to enable boarder applications that
+ can benefit from the shared vineyard store, especially for deep learning
+ frameworks and GNN frameworks.
+
+v0.7.0
+------
+
+Vineyard *v0.7.0* will be released in later July, 2022. Vineyard v0.7.0 will
+introduces the following experimental features to ease the integration of
+various kinds of workloads with Vineyard:
+
+- Limited mutation support on blobs: starts from vineyard *v0.7.0*, unsealed
+ blobs can be get by other clients with an :code:`unsafe` flag to ease the
+ integration of some online storage engines.
+- Limited support for remote data accessing using the RPC client: vineyard
+ *v0.7.0* will bring the feature about creating and accessing remote blobs
+ using the RPC client. It would be greatly helpful for some specific deployment
+ and the cost of remote data sourcing to vineyard is tolerable.
+
+v0.6.0
+------
+
+We plan to release the *v0.6.0* version before tne end of June, 2022. The *v0.6.0*
+release will include the following enhancement:
+
+- Better compatibility on various platforms (e.g., CentOS and ArchLinux), and process
+ platform-specific features like `LD_LIBRARY_PATH` and `libunwind` dependency
+ carefully.
+- Ensure the backwards compatibility with various third-party integrations, e.g.,
+ apache-airflow.
+- Vineyard v0.6.0 will be available from `homebrew `_.
+
+v0.5.0
+------
+
+We plan to release the first preliminary version for the Rust SDK and Go SDK
+in vineyard *v0.5.0*, that is expected to be delivered in later May, 2022.
+
+In vineyard *v0.5.0*, we will investigate the opportunity about code generation
+based on the metadata of vineyard objects, i.e., we could generate the data
+structure definition based on the structure of metadata in runtime (for Python)
+and in compile time (even maybe in runtime) for C++ and Rust.
+
+The integration with Kubernetes (especially the CSI part) will be another key
+improvement for *v0.5.0*.
+
+Further details about release for *v0.5.0* will be added later.
+
+v0.4.0
+------
+
+The release of vineyard *v0.4.0*, will be hopefully released before April, 2022, will
+be a follow-up bugfix releases after *v0.3.0*. The version *v0.4.0* makes the
+kubernetes related components better.
+
++ Improve the robustness of the scheduler plugin.
++ Refine the definition of CRDs.
++ Distribute the vineyard operator to artifact hub as a chart, to make it available for more users.
+
+v0.3.0
+------
+
+We plan to release *v0.3.0* by the end of 2021. vineyard *v0.3.0* will be the first major
+stable releases with fully kubernetes support, which will include:
+
++ A stable CRD definition for ``LocalObject`` and ``GlobalObject`` to represents vineyard objects
+ as kubernetes resources.
++ A full-features scheduler plugin for kubernetes, as well as a custom controller that manages
+ objects (custom resources) in vineyard cluster.
++ A refined version of Helm integration.
++ Application-aware far memory will be included in v0.3.0 as an experimental feature.
+
+v0.2.0
+------
+
+Vineyard *v0.2.0* will address the issue about Python ecosystem compatibility, I/O, and
+the kubernetes integration. Vineyard v0.2.0 will take about half of a year with several bugfix
+release to testing the design and APIs to reach a stable stable state.
+
++ Vineyard *v0.2.0* will support any *filesystem-spec*-compatible data source/sink as well as file
+ format.
++ Vineyard *v0.2.0* will support Python ecosystem (especially numpy and pandas) better.
++ Vineyard *v0.2.0* will include basic Helm integration for deploying on Kubernetes as a ``DaemonSet``.
++ A prototype of scheduler plugin to do data locality scheduling will be included into vineyard v0.2.0
+ to demonstrates the capability about co-scheduling job and data in kubernetes brought by vineyard.
++ Match the criterion of CNCF sandbox project.
+
+v0.1.0
+------
+
+Vineyard *v0.1.0* is the first release after open source. This version includes:
+
++ Complete functionality for both server and client.
++ Complete Python SDK.
++ User-friendly package distribution on pypi (for python SDK) and on dockerhub (for vineyardd server).
+
+Release Notes
+-------------
+
+For more details about what changes happened for every version, please refer to
+our `releases notes`_ as well.
+
+.. _releases notes: https://github.com/v6d-io/v6d/releases
diff --git a/_sources/notes/developers/troubleshooting.rst.txt b/_sources/notes/developers/troubleshooting.rst.txt
new file mode 100644
index 0000000000..68abee637d
--- /dev/null
+++ b/_sources/notes/developers/troubleshooting.rst.txt
@@ -0,0 +1,49 @@
+Troubleshooting
+===============
+
+This page provides guidance for addressing common issues that may arise when
+working with Vineyard.
+
+.. Installation Errors
+.. -------------------
+
+Vineyard Fails to Start
+-----------------------
+
+1. Improper Etcd Configuration
+
+ If you encounter the following error when sending requests to Vineyard:
+
+ .. code::
+
+ Etcd error: etcdserver: too many operations in txn request, error code: 3
+
+ This indicates that your Etcd configuration is not set up correctly and does not support
+ more than 128 operations within a single transaction. To resolve this issue, check your Etcd
+ startup parameters and increase the :code:`--max-txn-ops` value, for example, to :code:`102400`.
+
+2. bind: Permission Denied Error When Launching vineyardd
+
+ The Vineyard server uses a UNIX-domain socket for IPC connections and memory sharing with clients.
+ By default, the UNIX-domain socket is located at :code:`/var/run/vineyard.sock`, which typically
+ requires root permission.
+
+ To launch vineyardd, you can either:
+
+ + Run the :code:`vineyardd` command with :code:`sudo`,
+ + Or, specify a different location for the UNIX-domain socket that does not require root permission
+ using the :code:`--socket` command line argument, e.g.,
+ .. code:: bash
+
+ python3 -m vineyard --socket=/tmp/vineyard.sock
+
+Vineyard Issues on Kubernetes
+-----------------------------
+
+1. Etcd Pod Resource Limitations in Kubernetes Deployment
+
+ We have observed that etcd performance may degrade when a Vineyard client persists a large
+ object, particularly in Kubernetes deployments where the CPU cores of the etcd pod are limited by
+ cgroups. In such cases, users should increase the CPU resources allocated to the etcd pod. For
+ more information on etcd tuning, please refer to the `Hardware recommendations
+ `_ section in the etcd documentation.
diff --git a/_sources/notes/getting-started.rst.txt b/_sources/notes/getting-started.rst.txt
new file mode 100644
index 0000000000..a1b117337d
--- /dev/null
+++ b/_sources/notes/getting-started.rst.txt
@@ -0,0 +1,236 @@
+Getting Started
+===============
+
+.. _getting-started:
+
+Installing vineyard
+-------------------
+
+Vineyard is distributed as a `Python package`_ and can be effortlessly installed using :code:`pip`:
+
+.. code:: console
+
+ $ pip3 install vineyard
+
+Launching vineyard server
+-------------------------
+
+.. code:: console
+
+ $ python3 -m vineyard
+
+A vineyard daemon server will be launched with default settings. By default, :code:`/var/run/vineyard.sock`
+will be used by vineyardd to listen for incoming IPC connections.
+
+To stop the running vineyardd instance, simply press :code:`Ctrl-C` in the terminal.
+
+.. tip::
+
+ If you encounter errors like ``cannot launch vineyardd on '/var/run/vineyard.sock':
+ Permission denied,``, it means **you don't have the permission** to create a UNIX-domain
+ socket at :code:`/var/run/vineyard.sock`. You can either:
+
+ - Run vineyard as root, using ``sudo``:
+
+ .. code:: console
+
+ $ sudo -E python3 -m vineyard
+
+ - Or, change the socket path to a writable location with the ``--socket`` command
+ line option:
+
+ .. code:: console
+
+ $ python3 -m vineyard --socket /tmp/vineyard.sock
+
+Connecting to vineyard
+----------------------
+
+Once launched, you can call :code:`vineyard.connect` with the socket name to initiate a vineyard client
+from Python:
+
+.. code:: python
+
+ >>> import vineyard
+ >>> client = vineyard.connect('/var/run/vineyard.sock')
+
+Storing and Retrieving Python Objects
+-------------------------------------
+
+Vineyard is designed as an in-memory object store and offers two high-level APIs :code:`put` and
+:code:`get` for creating and accessing shared objects, enabling seamless interoperability with the Python
+ecosystem. The former returns a :code:`vineyard.ObjectID` upon success, which can be used
+to retrieve shared objects from vineyard using the latter.
+
+In the following example, we use :code:`client.put()` to build a vineyard object from the numpy
+ndarray ``arr``, which returns the ``object_id`` - a unique identifier in vineyard representing
+the object. Given the ``object_id``, we can obtain a shared-memory object from vineyard with the
+:code:`client.get()` method.
+
+.. code:: python
+
+ >>> import numpy as np
+ >>>
+ >>> object_id = client.put(np.random.rand(2, 4))
+ >>> object_id
+ o0015c78883eddf1c
+ >>>
+ >>> shared_array = client.get(object_id)
+ >>> shared_array
+ ndarray([[0.39736989, 0.38047846, 0.01948815, 0.38332264],
+ [0.61671189, 0.48903213, 0.03875045, 0.5873005 ]])
+
+.. note::
+
+ :code:`shared_array` does not allocate extra memory in the Python process; instead, it shares memory
+ with the vineyard server via `mmap`_ in a zero-copy process.
+
+The sharable objects can be complex and nested. Like numpy ndarray, the pandas dataframe ``df`` can
+be seamlessly stored in vineyard and retrieved with the ``.put()`` and ``.get()`` methods as follows:
+
+.. code:: python
+
+ >>> import pandas as pd
+ >>>
+ >>> df = pd.DataFrame({'u': [0, 0, 1, 2, 2, 3],
+ >>> 'v': [1, 2, 3, 3, 4, 4],
+ >>> 'weight': [1.5, 3.2, 4.7, 0.3, 0.8, 2.5]})
+ >>> object_id = client.put(df)
+ >>>
+ >>> shared_dataframe = client.get(object_id)
+ >>> shared_dataframe
+ u v weight
+ 0 0 1 1.5
+ 1 0 2 3.2
+ 2 1 3 4.7
+ 3 2 3 0.3
+ 4 2 4 0.8
+ 5 3 4 2.5
+
+Under the hood, vineyard implements a builder/resolver mechanism to represent arbitrary
+data structures as *vineyard objects* and resolve them back to native values in the corresponding
+programming languages and computing systems. See also :ref:`divein-driver-label` for more information.
+
+Sharing objects between tasks
+-----------------------------
+
+Vineyard is designed for sharing intermediate data between tasks. The following example
+demonstrates how a dataframe can be passed between two **processes** using vineyard, namely
+the producer and consumer in the example below:
+
+.. code:: python
+
+ import multiprocessing as mp
+ import vineyard
+
+ import numpy as np
+ import pandas as pd
+
+ socket = '/var/run/vineyard.sock'
+
+ def produce(name):
+ client = vineyard.connect(socket)
+ client.put(pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')),
+ persist=True, name=name)
+
+ def consume(name):
+ client = vineyard.connect(socket)
+ print(client.get(name=name).sum())
+
+ if __name__ == '__main__':
+ name = 'dataset'
+
+ producer = mp.Process(target=produce, args=(name,))
+ producer.start()
+ consumer = mp.Process(target=consume, args=(name,))
+ consumer.start()
+
+ producer.join()
+ consumer.join()
+
+Running the code above, you should see the following output:
+
+.. code:: text
+
+ A -4.529080
+ B -2.969152
+ C -7.067356
+ D 4.003676
+ dtype: float64
+
+Next steps
+----------
+
+Beyond the core functionality of sharing objects between tasks, vineyard also provides:
+
+- Distributed objects and stream abstraction over immutable chunks;
+- An IDL (:ref:`vcdl`) that helps integrate vineyard with other systems at minimal cost;
+- A mechanism of pluggable drivers for various tasks that serve as the glue
+ between the core compute engine and the external world, e.g., data sources, data
+ sinks;
+- Integration with Kubernetes for sharing between tasks in workflows deployed
+ on cloud-native infrastructures.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: architecture
+ :type: ref
+ :text: Architecture
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Overview of vineyard.
+
+Learn more about vineyard's key concepts from the following user guides:
+
+.. panels::
+ :header: text-center
+ :container: container-lg pb-4
+ :column: col-lg-4 col-md-4 col-sm-4 col-xs-12 p-2
+ :body: text-center
+
+ .. link-button:: key-concepts/objects
+ :type: ref
+ :text: Vineyard Objects
+ :classes: btn-block stretched-link
+
+ Explore the design of the object model in vineyard.
+
+ ---
+
+ .. link-button:: key-concepts/vcdl
+ :type: ref
+ :text: VCDL
+ :classes: btn-block stretched-link
+
+ Discover how vineyard integrates with other computing systems.
+
+ ---
+
+ .. link-button:: key-concepts/io-drivers
+ :type: ref
+ :text: I/O Drivers
+ :classes: btn-block stretched-link
+
+ Understand the design and implementation of pluggable routines for I/O, repartition,
+ migration, and more.
+
+Vineyard is a natural fit for cloud-native computing, where it can be deployed and
+managed by the *vineyard operator*, providing data-aware scheduling for data analytical
+workflows to achieve efficient data sharing on Kubernetes. More details about vineyard
+on Kubernetes can be found here:
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: cloud-native/deploy-kubernetes
+ :type: ref
+ :text: Kubernetes
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Deploy vineyard on Kubernetes and accelerate your big-data workflows.
+
+.. _Python package: https://pypi.org/project/vineyard
+.. _mmap: https://man7.org/linux/man-pages/man2/mmap.2.html
diff --git a/_sources/notes/integration-bigdata.rst.txt b/_sources/notes/integration-bigdata.rst.txt
new file mode 100644
index 0000000000..e9382f784a
--- /dev/null
+++ b/_sources/notes/integration-bigdata.rst.txt
@@ -0,0 +1,34 @@
+Big-data on Vineyard
+====================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ integration/dask.rst
+ integration/ml.rst
+
+Vineyard serves as a powerful data-sharing engine, seamlessly integrating with
+a variety of big-data computing platforms. This includes machine learning
+frameworks and the distributed data processing engine, Dask.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: integration/ml
+ :type: ref
+ :text: Machine Learning
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Executing machine learning workflows on top of vineyard.
+
+ ---
+
+ .. link-button:: integration/dask
+ :type: ref
+ :text: Dask
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Using vineyard as the data source / sink of dask computations.
diff --git a/_sources/notes/integration-orchestration.rst.txt b/_sources/notes/integration-orchestration.rst.txt
new file mode 100644
index 0000000000..9b354750ad
--- /dev/null
+++ b/_sources/notes/integration-orchestration.rst.txt
@@ -0,0 +1,46 @@
+Workflow orchestration
+======================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ integration/airflow.rst
+ integration/kedro.md
+
+Vineyard seamlessly integrates with the workflow orchestration engines, e.g.,
+Apache Airflow and Kedro, enabling users to effortlessly incorporate Vineyard
+into their workflows for enhanced performance.
+
+Moreover, the Airflow integration empowers users to work with large Python objects
+featuring complex data types (e.g., :code:`pandas.DataFrame`) at minimal cost, while
+eliminating the need for cumbersome :code:`pickle.dump/loads` operations.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: integration/airflow
+ :type: ref
+ :text: Airflow
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Airflow uses vineyard as the XCom backend to efficiently handle complex data in Python.
+
+The Kedro integration enables users to easily share large data objects across
+nodes in a pipeline and eliminates the high cost of (de)serialization and I/O
+compared with alternatives like AWS S3 or Minio, without the need to modify
+the pipeline code intrusively, and provides seamless user experience when scaling
+pipelines to Kubernetes.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: integration/kedro
+ :type: ref
+ :text: Kedro
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Kedro uses vineyard as a `DataSet` implementation for efficient intermediate data sharing.
diff --git a/_sources/notes/integration/airflow.rst.txt b/_sources/notes/integration/airflow.rst.txt
new file mode 100644
index 0000000000..11d0163507
--- /dev/null
+++ b/_sources/notes/integration/airflow.rst.txt
@@ -0,0 +1,227 @@
+Airflow on Vineyard
+===================
+
+Big data analytical pipelines often involve various types of workloads, each
+requiring a dedicated computing system to complete the task. Intermediate
+data flows between tasks in the pipeline, and the additional cost of transferring data
+accounts for a significant portion of the end-to-end performance in real-world deployments,
+making optimization a challenging task.
+
+Integrating Vineyard with Airflow presents opportunities to alleviate this problem.
+
+Introducing Airflow
+-------------------
+
+Airflow is a platform that enables users to programmatically author, schedule, and
+monitor workflows. Users organize tasks in a Directed Acyclic Graph (DAG), and the
+Airflow scheduler executes the tasks on workflows while adhering to the specified
+dependencies.
+
+Consider the following ETL workflow as an example [1]_,
+
+.. code:: python
+
+ @dag(schedule_interval=None, start_date=days_ago(2), tags=['example'])
+ def tutorial_taskflow_api_etl():
+ @task()
+ def extract():
+ data_string = '{"1001": 301.27, "1002": 433.21, "1003": 502.22}'
+
+ order_data_dict = json.loads(data_string)
+ return order_data_dict
+
+ @task(multiple_outputs=True)
+ def transform(order_data_dict: dict):
+ return {"total_order_value": total_order_value}
+
+ @task()
+ def load(total_order_value: float):
+ print(f"Total order value is: {total_order_value:.2f}")
+
+ order_data = extract()
+ order_summary = transform(order_data)
+
+
+ tutorial_etl_dag = tutorial_taskflow_api_etl()
+
+It forms the following DAG, including three individual tasks as the nodes, and
+runs the tasks sequentially based on their data This forms a DAG, including
+three individual tasks as nodes, and edges between nodes that describe the
+data dependency relations. The Airflow scheduler runs the tasks sequentially
+based on their data dependencies.dependencies. Airflow ETL Workflow
+
+Airflow on Vineyard
+-------------------
+
+The Rationale for Airflow on Vineyard
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Airflow excels at defining and orchestrating complex workflows. However, managing
+data flow within the pipeline remains a challenge. Airflow relies on database
+backends such as SQLite, MySQL, and PostgreSQL to store intermediate data between
+tasks. In real-world scenarios, large-scale data, such as large tensors, dataframes,
+and distributed graphs, cannot fit into these databases. As a result, external
+storage systems like HDFS and S3 are used to store intermediate data, with only
+an identifier stored in the database.
+
+Utilizing external storage systems to share intermediate data among tasks in big
+data analytical pipelines incurs performance costs due to data copying,
+serialization/deserialization, and network data transfer.
+
+Vineyard is designed to efficiently share intermediate in-memory data for big data
+analytical pipelines, making it a natural fit for workloads on Airflow.
+
+How Vineyard Enhances Airflow
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Airflow allows users to register an external **XCom** backend, which is precisely
+what Vineyard is designed for.
+
+Vineyard serves as an *XCom* backend for Airflow workers, enabling the transfer of
+large-scale data objects between tasks without relying on Airflow's database backend
+or external storage systems like HDFS. The Vineyard XCom backend also handles object
+migration when the required inputs are not located where the task is scheduled to
+execute.
+
+Vineyard's XCom backend achieves its functionality by injecting hooks into the
+processes of saving values to the backend and fetching values from the backend,
+as described below:
+
+.. code:: python
+
+ class VineyardXCom(BaseXCom):
+
+ @staticmethod
+ def serialize_value(value: Any):
+ """ Store the value to vineyard server, and serialized the result
+ Object ID to save it into the backend database later.
+ """
+
+ @staticmethod
+ def deserialize_value(result: "XCom") -> Any:
+ """ Obtain the Object ID after deserialization, and fetching the
+ underlying value from vineyard.
+
+ This value is resolved from vineyard objects in a zero-copy
+ fashion.
+ """
+
+
+Addressing Distributed Deployment Challenges
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Airflow supports parallel task execution across multiple workers to efficiently
+process complex workflows. In a distributed deployment (using the `CeleryExecutor`),
+tasks sharing intermediate data might be scheduled on different workers, necessitating
+remote data access.
+
+Vineyard seamlessly handles object migration for various data types. In the XCom backend,
+when the IPC client encounters remote objects, it triggers a migration action to move
+the objects to the local worker, ensuring input data is readily available before task
+execution.
+
+This transparent object migration simplifies complex data operations and movement,
+allowing data scientists to focus on computational logic when developing big data
+applications on Airflow.
+
+Running Vineyard + Airflow
+--------------------------
+
+Users can try Airflow provider for Vineyard by the following steps:
+
+1. Install required packages:
+
+ .. code:: bash
+
+ pip3 install airflow-provider-vineyard
+
+2. Configure Vineyard locally
+
+ The vineyard server can be easier launched locally with the following command:
+
+ .. code:: bash
+
+ python -m vineyard --socket=/tmp/vineyard.sock
+
+ See also our documentation about `launching vineyard`_.
+
+3. Configure Airflow to use the vineyard XCom backend by specifying the environment
+ variable
+
+ .. code:: bash
+
+ export AIRFLOW__CORE__XCOM_BACKEND=vineyard.contrib.airflow.xcom.VineyardXCom
+
+ and configure the location of UNIX-domain IPC socket for vineyard client by
+
+ .. code:: bash
+
+ export AIRFLOW__VINEYARD__IPC_SOCKET=/tmp/vineyard.sock
+
+ or
+
+ .. code:: bash
+
+ export VINEYARD_IPC_SOCKET=/tmp/vineyard.sock
+
+4. Launching your airflow scheduler and workers, and run the following DAG as example,
+
+ .. code:: python
+
+ import numpy as np
+ import pandas as pd
+
+ from airflow.decorators import dag, task
+ from airflow.utils.dates import days_ago
+
+ default_args = {
+ 'owner': 'airflow',
+ }
+
+ @dag(default_args=default_args, schedule_interval=None, start_date=days_ago(2), tags=['example'])
+ def taskflow_etl_pandas():
+ @task()
+ def extract():
+ order_data_dict = pd.DataFrame({
+ 'a': np.random.rand(100000),
+ 'b': np.random.rand(100000),
+ })
+ return order_data_dict
+
+ @task(multiple_outputs=True)
+ def transform(order_data_dict: dict):
+ return {"total_order_value": order_data_dict["a"].sum()}
+
+ @task()
+ def load(total_order_value: float):
+ print(f"Total order value is: {total_order_value:.2f}")
+
+ order_data = extract()
+ order_summary = transform(order_data)
+ load(order_summary["total_order_value"])
+
+ taskflow_etl_pandas_dag = taskflow_etl_pandas()
+
+In the example above, the `extract` and `transform` tasks share a `pandas.DataFrame` as
+intermediate data. This presents a challenge, as the DataFrame cannot be pickled, and when
+dealing with large data, it cannot fit into the backend databases of Airflow.
+
+This example is adapted from the Airflow documentation. For more information, refer to the
+`Tutorial on the Taskflow API`_.
+
+Further Ahead
+-------------
+
+The Airflow provider for Vineyard, currently in its experimental stage, demonstrates
+significant potential for efficiently and flexibly sharing large-scale intermediate data
+in big data analytical workflows within Airflow.
+
+The Airflow community is actively working to enhance support for modern big data and AI
+applications. We believe that the integration of Vineyard, Airflow, and other cloud-native
+infrastructures can provide a more effective and efficient solution for data scientists.
+
+
+.. [1] See: https://airflow.apache.org/docs/apache-airflow/stable/tutorial_taskflow_api.html
+
+.. _launching vineyard: https://v6d.io/notes/getting-started.html#starting-vineyard-server
+.. _Tutorial on the Taskflow API: https://airflow.apache.org/docs/apache-airflow/stable/tutorial_taskflow_api.html
diff --git a/_sources/notes/integration/dask.rst.txt b/_sources/notes/integration/dask.rst.txt
new file mode 100644
index 0000000000..628d1906a8
--- /dev/null
+++ b/_sources/notes/integration/dask.rst.txt
@@ -0,0 +1,150 @@
+Dask on Vineyard
+================
+
+The integration with Dask enables dask.array and dask.dataframe to be seamlessly persisted in
+and retrieved from Vineyard. In the following sections, we demonstrate how Vineyard simplifies
+the implementation of an example that utilizes Dask for data preprocessing and TensorFlow for
+distributed learning, as previously showcased in the blog_.
+
+The Deployment
+--------------
+
+.. image:: ../../images/dask-tf.jpg
+ :alt: Dask Tensorflow Workflow
+
+As illustrated in the figure above, we employ two machines for the distributed tasks for
+demonstration purposes. The Vineyard daemon processes are launched on both machines, along
+with the Dask workers. The Dask scheduler is initiated on the first machine, where we also
+run the Dask preprocessing program in the first step, as the Dask scheduler manages the
+distribution of computation tasks among its workers.
+
+In the second step, we execute the training program on both machines with different **TF_CONFIG**
+settings. For details on configuring the setup, please refer to the `documentation`_.
+
+Preprocessing in Dask
+---------------------
+
+In this step, we load the mnist data and duplicate it to simulate the parallel processing as same as the blog_.
+
+.. code:: python
+
+ from vineyard.core.builder import builder_context
+ from vineyard.contrib.dask.dask import dask_context
+
+ def dask_preprocess(dask_scheduler):
+ def get_mnist():
+ (x_train, y_train), _ = tf.keras.datasets.mnist.load_data()
+ # The `x` arrays are in uint8 and have values in the [0, 255] range.
+ # You need to convert them to float64 with values in the [0, 1] range.
+ x_train = x_train / np.float64(255)
+ y_train = y_train.astype(np.int64)
+ return pd.DataFrame({'x': list(x_train), 'y': y_train})
+
+ with dask_context():
+ datasets = [delayed(get_mnist)() for i in range(20)]
+ dfs = [dd.from_delayed(ds) for ds in datasets]
+ gdf = dd.concat(dfs)
+ gdf_id = vineyard.connect().put(gdf, dask_scheduler=dask_scheduler)
+
+ return gdf_id
+
+Here the returned **gdf_id** is the ObjectID of a **vineyard::GlobalDataFrame**
+which consists of 20 partitions (10 partitions on each machine).
+
+Training in Tensorflow
+----------------------
+
+In this step, we use the preprocessed data **gdf_id** to train a model distributedly
+in keras of Tensorflow.
+
+.. code:: python
+
+ from vineyard.contrib.ml.tensorflow import register_tf_types
+ from vineyard.core.resolver import resolver_context
+
+ def mnist_dataset(gdf_id, batch_size):
+ with resolver_context() as resolver:
+ # register the resolver for tensorflow Dataset to the resolver_context
+ register_tf_types(None, resolver)
+ train_datasets = vineyard.connect().get(gdf_id, data='x', label='y')
+ train_datasets = train_datasets.repeat().batch(batch_size)
+
+ options = tf.data.Options()
+ options.experimental_distribute.auto_shard_policy = tf.data.experimental.AutoShardPolicy.OFF
+ train_datasets_no_auto_shard = train_datasets.with_options(options)
+ return train_datasets_no_auto_shard
+
+ def build_and_compile_cnn_model():
+ model = tf.keras.Sequential([
+ tf.keras.layers.InputLayer(input_shape=(28, 28)),
+ tf.keras.layers.Reshape(target_shape=(28, 28, 1)),
+ tf.keras.layers.Conv2D(32, 3, activation='relu'),
+ tf.keras.layers.Flatten(),
+ tf.keras.layers.Dense(128, activation='relu'),
+ tf.keras.layers.Dense(10)
+ ])
+ model.compile(
+ loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
+ optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
+ metrics=['accuracy'])
+ return model
+
+ def train(gdf_id):
+ per_worker_batch_size = 64
+ strategy = tf.distribute.MultiWorkerMirroredStrategy()
+ train_dataset = mnist_dataset(gdf_id, per_worker_batch_size)
+
+ with strategy.scope():
+ multi_worker_model = mnist.build_and_compile_cnn_model()
+
+ multi_worker_model.fit(train_dataset, epochs=3, steps_per_epoch=70)
+
+To utilize the preprocessed data, we first register the resolvers capable of resolving a
+**vineyard::GlobalDataFrame** distributed across multiple workers within the resolver_context.
+Subsequently, we can directly obtain the **tf.data.Dataset** from Vineyard using the **get**
+method.
+
+.. note::
+
+ It is essential to specify the column names for the data and label, as they were set in
+ the previous step.
+
+Transfer Learning
+-----------------
+
+In this section, we demonstrate how the dask-vineyard integration can be effectively utilized
+in transfer learning scenarios. Transfer learning is a technique where a pre-trained deep
+learning model is used to compute features for downstream models. Storing these features in
+memory is advantageous, as it eliminates the need to recompute features or incur significant
+I/O costs by repeatedly reading them from disk. We will refer to the featurization_ example
+and use the tf_flowers_ dataset as a **dask.array**. We will employ the pre-trained **ResNet50**
+model to generate features and subsequently store them in Vineyard. The resulting global
+tensor in Vineyard will consist of 8 partitions, each containing 400 data slots.
+
+.. code:: python
+
+ def get_images(idx, num):
+ paths = list(Path("flower_photos").rglob("*.jpg"))[idx::num]
+ data = []
+ for p in paths:
+ with open(p,'rb') as f:
+ img = Image.open(io.BytesIO(f.read())).resize([224, 224])
+ arr = preprocess_input(img_to_array(img))
+ data.append(arr)
+ return np.array(data)
+
+ def featurize(v, block_id=None):
+ model = ResNet50(include_top=False)
+ preds = model.predict(np.stack(v))
+ return preds.reshape(400, 100352)
+
+ imgs = [da.from_delayed(delayed(get_images)(i,8), shape=(400, 244, 244, 3), dtype='float') for i in range(8)]
+ imgs = da.concatenate(imgs, axis=0)
+ res = imgs.map_blocks(featurize, chunks=(400,100352), drop_axis=[2,3], dtype=float)
+ global_tensor_id = vineyard.connect().put(res, dask_scheduler=dask_scheduler)
+
+
+.. _documentation: https://www.tensorflow.org/tutorials/distribute/multi_worker_with_keras
+.. _blog: http://matthewrocklin.com/blog/work/2017/02/11/dask-tensorflow
+.. _featurization: https://docs.databricks.com/_static/notebooks/deep-learning/deep-learning-transfer-learning-keras.html
+.. _tf_flowers: https://www.tensorflow.org/datasets/catalog/tf_flowers
diff --git a/_sources/notes/integration/kedro.md.txt b/_sources/notes/integration/kedro.md.txt
new file mode 100644
index 0000000000..c0cb65e339
--- /dev/null
+++ b/_sources/notes/integration/kedro.md.txt
@@ -0,0 +1,270 @@
+Kedro Vineyard Plugin
+=====================
+
+The Kedro vineyard plugin contains components (e.g., `DataSet` and `Runner`)
+to share intermediate data among nodes in Kedro pipelines using vineyard.
+
+Kedro on Vineyard
+-----------------
+
+Vineyard works as the *DataSet* provider for kedro workers to allow transferring
+large-scale data objects between tasks that cannot be efficiently serialized and
+is not suitable for `pickle`, without involving external storage systems like
+AWS S3 (or Minio as an alternative). The Kedro vineyard plugin handles object migration
+as well when the required inputs are not located where the task is scheduled to execute.
+
+Requirements
+------------
+
+The following packages are needed to run Kedro on vineyard,
+
+- kedro >= 0.18
+- vineyard >= 0.14.5
+
+Configuration
+-------------
+
+1. Install required packages:
+
+ pip3 install vineyard-kedro
+
+2. Configure Vineyard locally
+
+ The vineyard server can be easier launched locally with the following command:
+
+ python3 -m vineyard --socket=/tmp/vineyard.sock
+
+ See also our documentation about [Launching Vineyard][1].
+
+3. Configure the environment variable to tell Kedro vineyard plugin how to connect to the
+ vineyardd server:
+
+ export VINEYARD_IPC_SOCKET=/tmp/vineyard.sock
+
+Usage
+-----
+
+After installing the dependencies and preparing the vineyard server, you can execute the
+Kedro workflows as usual and benefits from vineyard for intermediate data sharing.
+
+We take the [Iris example][2] as an example,
+
+```bash
+$ kedro new --starter=pandas-iris
+```
+
+The nodes in this pipeline look like
+
+```python
+def split_data(
+ data: pd.DataFrame, parameters: Dict[str, Any]
+) -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series, pd.Series]:
+ data_train = data.sample(
+ frac=parameters["train_fraction"], random_state=parameters["random_state"]
+ )
+ data_test = data.drop(data_train.index)
+
+ X_train = data_train.drop(columns=parameters["target_column"])
+ X_test = data_test.drop(columns=parameters["target_column"])
+ y_train = data_train[parameters["target_column"]]
+ y_test = data_test[parameters["target_column"]]
+
+ return X_train, X_test, y_train, y_test
+
+
+def make_predictions(
+ X_train: pd.DataFrame, X_test: pd.DataFrame, y_train: pd.Series
+) -> pd.Series:
+ X_train_numpy = X_train.to_numpy()
+ X_test_numpy = X_test.to_numpy()
+
+ squared_distances = np.sum(
+ (X_train_numpy[:, None, :] - X_test_numpy[None, :, :]) ** 2, axis=-1
+ )
+ nearest_neighbour = squared_distances.argmin(axis=0)
+ y_pred = y_train.iloc[nearest_neighbour]
+ y_pred.index = X_test.index
+
+ return y_pred
+```
+
+You can see that the intermediate data between `split_data` and `make_predictions` is some pandas
+dataframes and series.
+
+Try running the pipeline without vineyard,
+
+```bash
+$ cd iris
+$ kedro run
+[05/25/23 11:38:56] INFO Kedro project iris session.py:355
+[05/25/23 11:38:57] INFO Loading data from 'example_iris_data' (CSVDataSet)... data_catalog.py:343
+ INFO Loading data from 'parameters' (MemoryDataSet)... data_catalog.py:343
+ INFO Running node: split: split_data([example_iris_data,parameters]) -> [X_train,X_test,y_train,y_test] node.py:329
+ INFO Saving data to 'X_train' (MemoryDataSet)... data_catalog.py:382
+ INFO Saving data to 'X_test' (MemoryDataSet)... data_catalog.py:382
+ INFO Saving data to 'y_train' (MemoryDataSet)... data_catalog.py:382
+ INFO Saving data to 'y_test' (MemoryDataSet)... data_catalog.py:382
+ INFO Completed 1 out of 3 tasks sequential_runner.py:85
+ INFO Loading data from 'X_train' (MemoryDataSet)... data_catalog.py:343
+ INFO Loading data from 'X_test' (MemoryDataSet)... data_catalog.py:343
+ INFO Loading data from 'y_train' (MemoryDataSet)... data_catalog.py:343
+ INFO Running node: make_predictions: make_predictions([X_train,X_test,y_train]) -> [y_pred] node.py:329
+...
+```
+
+You can see that the intermediate data is shared with memory. When kedro is deploy to a cluster, e.g.,
+to [argo workflow][3], the `MemoryDataSet` is not applicable anymore and you will need to setup the
+AWS S3 or Minio service and sharing those intermediate data as CSV files.
+
+```yaml
+X_train:
+ type: pandas.CSVDataSet
+ filepath: s3://testing/data/02_intermediate/X_train.csv
+ credentials: minio
+
+X_test:
+ type: pandas.CSVDataSet
+ filepath: s3://testing/data/02_intermediate/X_test.csv
+ credentials: minio
+
+y_train:
+ type: pandas.CSVDataSet
+ filepath: s3://testing/data/02_intermediate/y_train.csv
+ credentials: minio
+```
+
+It might be inefficient for pickling pandas dataframes when data become larger. With the kedro
+vineyard plugin, you can run the pipeline with vineyard as the intermediate data medium by
+
+```bash
+$ kedro run --runner vineyard.contrib.kedro.runner.SequentialRunner
+[05/25/23 11:45:34] INFO Kedro project iris session.py:355
+ INFO Loading data from 'example_iris_data' (CSVDataSet)... data_catalog.py:343
+ INFO Loading data from 'parameters' (MemoryDataSet)... data_catalog.py:343
+ INFO Running node: split: split_data([example_iris_data,parameters]) -> [X_train,X_test,y_train,y_test] node.py:329
+ INFO Saving data to 'X_train' (VineyardDataSet)... data_catalog.py:382
+ INFO Saving data to 'X_test' (VineyardDataSet)... data_catalog.py:382
+ INFO Saving data to 'y_train' (VineyardDataSet)... data_catalog.py:382
+ INFO Saving data to 'y_test' (VineyardDataSet)... data_catalog.py:382
+ INFO Loading data from 'X_train' (VineyardDataSet)... data_catalog.py:343
+ INFO Loading data from 'X_test' (VineyardDataSet)... data_catalog.py:343
+ INFO Loading data from 'y_train' (VineyardDataSet)... data_catalog.py:343
+ INFO Running node: make_predictions: make_predictions([X_train,X_test,y_train]) -> [y_pred] node.py:329
+...
+```
+
+Without any modification to your pipeline code, you can see that the intermediate data is shared
+with vineyard using the `VineyardDataSet` and no longer suffers from the overhead of (de)serialization
+and the I/O cost between external AWS S3 or Minio services.
+
+Like `kedro catalog create`, the Kedro vineyard plugin provides a command-line interface to generate
+the catalog configuration for given pipeline, which will rewrite the unspecified intermediate data
+to `VineyardDataSet`, e.g.,
+
+```bash
+$ kedro vineyard catalog create -p __default__
+```
+
+You will get
+
+```yaml
+X_test:
+ ds_name: X_test
+ type: vineyard.contrib.kedro.io.dataset.VineyardDataSet
+X_train:
+ ds_name: X_train
+ type: vineyard.contrib.kedro.io.dataset.VineyardDataSet
+y_pred:
+ ds_name: y_pred
+ type: vineyard.contrib.kedro.io.dataset.VineyardDataSet
+y_test:
+ ds_name: y_test
+ type: vineyard.contrib.kedro.io.dataset.VineyardDataSet
+y_train:
+ ds_name: y_train
+ type: vineyard.contrib.kedro.io.dataset.VineyardDataSet
+```
+
+Deploy to Kubernetes
+--------------------
+
+When the pipeline scales to Kubernetes, the interaction with the Kedro vineyard plugin is
+still simple and non-intrusive. The plugin provides tools to prepare the docker image and
+generate Argo workflow specification file for the Kedro pipeline. Next, we'll demonstrate
+how to deploy pipelines to Kubernetes while leverage Vineyard for efficient intermediate
+sharing between tasks step-by-step.
+
+1. Prepare the vineyard cluster (see also [Deploy on Kubernetes][5]):
+
+ ```bash
+ # export your kubeconfig path here
+ $ export KUBECONFIG=/path/to/your/kubeconfig
+
+ # install the vineyard operator
+ $ go run k8s/cmd/main.go deploy vineyard-cluster --create-namespace
+ ```
+
+2. Install the argo server:
+
+ ```bash
+ # install the argo server
+ $ kubectl create namespace argo
+ $ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.4.8/install.yaml
+ ```
+
+3. Generate the iris demo project from the official template:
+
+ ```bash
+ $ kedro new --starter=pandas-iris
+ ```
+
+4. Build the Docker image for this iris demo project:
+
+ ```bash
+ # walk to the iris demo root directory
+ $ cd iris
+ $ kedro vineyard docker build
+ ```
+
+ A Docker image named `iris` will be built successfully. The docker image
+ need to be pushed to your image registry, or loaded to the kind/minikube cluster, to be
+ available in Kubernetes.
+
+ ```bash
+ $ docker images | grep iris
+ iris latest 3c92da8241c6 About a minute ago 690MB
+ ```
+
+5. Next, generate the Argo workflow YAML file from the iris demo project:
+
+ ```bash
+ $ kedro vineyard argo generate -i iris
+
+ # check the generated Argo workflow YAML file, you can see the Argo workflow YAML file named `iris.yaml`
+ # is generated successfully.
+ $ ls -l argo-iris.yml
+ -rw-rw-r-- 1 root root 3685 Jun 12 23:55 argo-iris.yml
+ ```
+
+6. Finally, submit the Argo workflow to Kubernetes:
+
+ ```bash
+ $ argo submit -n argo argo-iris.yml
+ ```
+
+ You can interact with the Argo workflow using the `argo` command-line tool, e.g.,
+
+ ```bash
+ $ argo list workflows -n argo
+ NAME STATUS AGE DURATION PRIORITY MESSAGE
+ iris-sg6qf Succeeded 18m 30s 0
+ ```
+
+We have prepared a benchmark to evaluate the performance gain brought by vineyard for data
+sharing when data scales, for more details, please refer to [this report][4].
+
+[1]: https://v6d.io/notes/getting-started.html#starting-vineyard-server
+[2]: https://docs.kedro.org/en/stable/get_started/new_project.html
+[3]: https://docs.kedro.org/en/stable/deployment/argo.html#how-to-run-your-kedro-pipeline-using-argo-workflows
+[4]: https://v6d.io/tutorials/data-processing/accelerate-data-sharing-in-kedro.html
+[5]: https://v6d.io/notes/cloud-native/deploy-kubernetes.html
diff --git a/_sources/notes/integration/ml.rst.txt b/_sources/notes/integration/ml.rst.txt
new file mode 100644
index 0000000000..16c3837439
--- /dev/null
+++ b/_sources/notes/integration/ml.rst.txt
@@ -0,0 +1,295 @@
+Machine Learning with Vineyard
+==============================
+
+
+**Vineyard-ML**: A Vineyard package that integrates Machine Learning Frameworks to Vineyard.
+
+TensorFlow
+----------
+
+Using Numpy Data
+^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> import tensorflow as tf
+ >>> from vineyard.contrib.ml import tensorflow
+ >>> dataset = tf.data.Dataset.from_tensor_slices((data, label))
+ >>> data_id = vineyard_client.put(dataset)
+ >>> vin_data = vineyard_client.get(data_id)
+
+Vineyard supports the ``tf.data.Dataset``. The ``vin_data`` will be a shared-memory object
+from the vineyard.
+
+Using Dataframe
+^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> import pandas as pd
+ >>> df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8], 'target': [1.0, 2.0, 3.0, 4.0]})
+ >>> label = df.pop('target')
+ >>> dataset = tf.data.Dataset.from_tensor_slices((dict(df), label))
+ >>> data_id = vineyard_client.put(dataset)
+ >>> vin_data = vineyard_client.get(data_id)
+
+Wrap the dataframe with ``tf.data.Dataset``. This enables the use of feature columns as a
+bridge to map from the columns in Pandas Dataframe to features in Dataset. The
+dataset should return a dictionary of column names (from the dataframe) that maps
+to column values. The dataset should only contain ``numerical data``.
+
+Using RecordBatch of Pyarrow
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code:: python
+
+ >>> import pyarrow as pa
+ >>> arrays = [pa.array([1, 2, 3, 4]), pa.array([3.0, 4.0, 5.0, 6.0]), pa.array([0, 1, 0, 1])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'f1', 'label'])
+ >>> data_id = vineyard_client.put(batch)
+ >>> vin_data = vineyard_client.get(data_id)
+
+Vineyard supports direct integration of RecordBatch. The ``vin_data`` object will
+be a TensorFlow Dataset, i.e. ``tf.data.Dataset``. Here the ``label`` row should be named as ``label``.
+
+Using Tables of Pyarrow
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> arrays = [pa.array([1, 2, 3, 4]), pa.array([3.0, 4.0, 5.0, 6.0]), pa.array([0, 1, 0, 1])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'f1', 'label'])
+ >>> batches = [batch]*3
+ >>> table = pa.Table.from_batches(batches)
+ >>> data_id = vineyard_client.put(table)
+ >>> vin_data = vineyard_client.get(data_id)
+
+Vineyard supports direct integration of Tables as well. Here, the ``vin_data``
+object will be of type TensorFlow Dataset, i.e. ``tf.data.Dataset``. Here the ``label`` row
+should be named as ``label``.
+
+
+PyTorch
+-------
+
+Using Numpy Data
+^^^^^^^^^^^^^^^^
+
+Vineyard supports ``Custom Datasets`` inherited from the PyTorch Dataset.
+
+.. code:: python
+
+ >>> import torch
+ >>> from vineyard.contrib.ml import pytorch
+ >>> data_id = vineyard_client.put(dataset, typename='Tensor')
+ >>> vin_data = vineyard_client.get(data_id)
+
+The dataset object should be an object of the type CustomDataset class which is inherited
+from ``torch.utils.data.Dataset`` class. Adding the typename as ``Tensor`` is important.
+The ``vin_data`` will be of type ``torch.utils.data.TensorDataset``.
+
+Using Dataframe
+^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8], 'c': [1.0, 2.0, 3.0, 4.0]})
+ >>> label = torch.from_numpy(df['c'].values.astype(np.float32))
+ >>> data = torch.from_numpy(df.drop('c', axis=1).values.astype(np.float32))
+ >>> dataset = torch.utils.data.TensorDataset(data, label)
+ >>> data_id = vineyard_client.put(dataset, typename='Dataframe', cols=['a', 'b', 'c'], label='c')
+ >>> vin_data = vineyard_client.get(data_id, label='c)
+
+While using the PyTorch form of the dataframe with vineyard, it is important to mention
+the typename as ``Dataframe``, a list of column names in ``cols`` and the ``label``
+name in label tag. The ``vin_data`` will be of the form ``TensorDataset`` with
+the label as mentioned with the label tag. If no value is passed to the label tag
+vineyard will consider the default value which is the value of label passed in while
+calling the ``put`` method
+
+Using RecordBatch of Pyarrow
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> import pyarrow as pa
+ >>> arrays = [pa.array([1, 2, 3, 4]), pa.array([3.0, 4.0, 5.0, 6.0]), pa.array([0, 1, 0, 1])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'f1', 'f2'])
+ >>> data_id = vineyard_client.put(batch)
+ >>> vin_data = vineyard_client.get(data_id, label='f2')
+
+The ``vin_data`` will be of the form ``TensorDataset`` with the label as mentioned
+with the label tag. In this case it is important to mention the label tag.
+
+Using Tables of Pyarrow
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> arrays = [pa.array([1, 2, 3, 4]), pa.array([3.0, 4.0, 5.0, 6.0]), pa.array([0, 1, 0, 1])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'f1', 'f2'])
+ >>> batches = [batch]*3
+ >>> table = pa.Table.from_batches(batches)
+ >>> data_id = vineyard_client.put(table)
+ >>> vin_data = vineyard_client.get(data_id, label='f2')
+
+The ``vin_data`` object will be of the form ``TensorDataset`` with the label as mentioned
+with the label tag. In this case, it is important to mention the label tag.
+
+MxNet
+-----
+
+Using Numpy Data
+^^^^^^^^^^^^^^^^
+
+Vineyard supports ``Array Datasets`` from the gluon.data of MxNet.
+
+.. code:: python
+
+ >>> import mxnet as mx
+ >>> from vineyard.contrib.ml import mxnet
+ >>> dataset = mx.gluon.data.ArrayDataset((data, label))
+ >>> data_id = vineyard_client.put(dataset, typename='Tensor')
+ >>> vin_data = vineyard_client.get(data_id)
+
+The dataset object should be an object of the type ArrayDataset from ``mxnet.gluon.data``
+class. Here, Adding the typename as ``Tensor`` is important. The ``vin_data`` will be
+of type ``mxnet.gluon.data.ArrayDataset``.
+
+Using Dataframe
+^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8], 'c': [1.0, 2.0, 3.0, 4.0]})
+ >>> label = df['c'].values.astype(np.float32)
+ >>> data = df.drop('c', axis=1).values.astype(np.float32)
+ >>> dataset = mx.gluon.data.ArrayDataset((data, label))
+ >>> data_id = vineyard_client.put(dataset, typename='Dataframe', cols=['a', 'b', 'c'], label='c')
+ >>> vin_data = vineyard_client.get(data_id, label='c)
+
+While using the MxNet form of the dataframe with vineyard, it is important to mention
+the typename as ``Dataframe``, a list of column names in ``cols`` and the ``label``
+name in label tag. The ``vin_data`` will be of the form ``ArrayDataset`` with
+the label as mentioned with the label tag. If no value is passed to the label tag
+vineyard will consider the default value which is the value of label passed in while
+calling the ``put`` method
+
+Using RecordBatch of Pyarrow
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> import pyarrow as pa
+ >>> arrays = [pa.array([1, 2, 3, 4]), pa.array([3.0, 4.0, 5.0, 6.0]), pa.array([0, 1, 0, 1])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'f1', 'f2'])
+ >>> data_id = vineyard_client.put(batch)
+ >>> vin_data = vineyard_client.get(data_id, label='f2')
+
+The ``vin_data`` will be of the form ``ArrayDataset`` with the label as mentioned
+with the label tag. In this case, it is important to mention the label tag.
+
+Using Tables of Pyarrow
+^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> arrays = [pa.array([1, 2, 3, 4]), pa.array([3.0, 4.0, 5.0, 6.0]), pa.array([0, 1, 0, 1])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'f1', 'f2'])
+ >>> batches = [batch]*3
+ >>> table = pa.Table.from_batches(batches)
+ >>> data_id = vineyard_client.put(table)
+ >>> vin_data = vineyard_client.get(data_id, label='f2')
+
+The ``vin_data`` object will be of the form ``ArrayDataset`` with the label as mentioned
+with the label tag. In this case, it is important to mention the label tag.
+
+XGBoost
+-------
+
+Vineyard supports resolving ``XGBoost::DMatrix`` from various kinds of vineyard data types.
+
+From Vineyard::Tensor
+^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> arr = np.random.rand(4, 5)
+ >>> vin_tensor_id = vineyard_client.put(arr)
+ >>> dmatrix = vineyard_client.get(vin_tensor_id)
+
+The ``dmatrix`` will be a ``DMatrix`` instance with the same shape ``(4, 5)`` resolved from the ``Vineyard::Tensor``
+object with the id ``vin_tensor_id``.
+
+From Vineyard::DataFrame
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8], 'c': [1.0, 2.0, 3.0, 4.0]})
+ >>> vin_df_id = vineyard_client.put(df)
+ >>> dmatrix = vineyard_client.get(vin_df_id, label='a')
+
+The ``dmatrix`` will be a ``DMatrix`` instance with shape of ``(4, 2)`` and ``feature_names`` of ``['b', 'c']``.
+While the label of ``dmatrix`` is the values of column ``a``.
+
+Sometimes the dataframe is a complex data structure and only ``one`` column will be used as the ``features``.
+We support this case by providing the ``data`` kwarg.
+
+.. code:: python
+
+ >>> df = pd.DataFrame({'a': [1, 2, 3, 4],
+ >>> 'b': [[5, 1.0, 4], [6, 2.0, 3], [7, 3.0, 2], [8, 9.0, 1]]})
+ >>> vin_df_id = vineyard_client.put(df)
+ >>> dmatrix = vineyard_client.get(vin_df_id, data='b', label='a')
+
+The ``dmatrix`` will have the shape of ``(4, 3)`` corresponding to the values of column ``b``.
+While the label is the values of column ``a``.
+
+From Vineyard::RecordBatch
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> import pyarrow as pa
+ >>> arrays = [pa.array([1, 2, 3, 4]), pa.array([3.0, 4.0, 5.0, 6.0]), pa.array([0, 1, 0, 1])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'f1', 'target'])
+ >>> vin_rb_id = vineyard_client.put(batch)
+ >>> dmatrix = vineyard_client.get(vin_rb_id, label='target')
+
+The ``dmatrix`` will have the shape of ``(4, 2)`` and ``feature_names`` of ``['f0', 'f1']``.
+While the label is the values of column ``target``.
+
+From Vineyard::Table
+^^^^^^^^^^^^^^^^^^^^
+
+.. code:: python
+
+ >>> arrays = [pa.array([1, 2]), pa.array([0, 1]), pa.array([0.1, 0.2])]
+ >>> batch = pa.RecordBatch.from_arrays(arrays, ['f0', 'label', 'f2'])
+ >>> batches = [batch] * 3
+ >>> table = pa.Table.from_batches(batches)
+ >>> vin_tab_id = vineyard_client.put(table)
+ >>> dmatrix = vineyard_client.get(vin_tab_id, label='label')
+
+The ``dmatrix`` will have the shape of ``(6, 2)`` and ``feature_names`` of ``['f0', 'f2']``.
+While the label is the values of column ``label``.
+
+Nvidia-DALI
+-----------
+
+Vineyard supports integration of ``Dali Pipelines``.
+
+.. code:: python
+
+ >>> from nvidia.dali import pipeline_def
+ >>> pipeline = pipe(device_id=device_id, num_threads=num_threads, batch_size=batch_size)
+ >>> pipeline.build()
+ >>> pipe_out = pipeline.run()
+ >>> data_id = vineyard_client.put(pipe_out)
+ >>> vin_pipe = vineyard_client.get(data_id)
+
+In this case, the pipe is a ``pipeline_def`` function. The data received after executing pipe.run() can
+be stored into vineyard. The Pipeline should only return two values, namely data and label. The return
+type of the data and label values should be of type ``TensorList``. The ``vin_pipe`` object will be the
+output of a simple in-built pipeline after executing the pipeline.build() and pipeline.run(). It will
+simply return two values of type Pipeline.
\ No newline at end of file
diff --git a/_sources/notes/integration/ray.rst.txt b/_sources/notes/integration/ray.rst.txt
new file mode 100644
index 0000000000..1ba5d32d40
--- /dev/null
+++ b/_sources/notes/integration/ray.rst.txt
@@ -0,0 +1,2 @@
+Ray on Vineyard
+===============
diff --git a/_sources/notes/key-concepts.rst.txt b/_sources/notes/key-concepts.rst.txt
new file mode 100644
index 0000000000..f16d5e3400
--- /dev/null
+++ b/_sources/notes/key-concepts.rst.txt
@@ -0,0 +1,77 @@
+Key Concepts
+============
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ key-concepts/objects.rst
+ key-concepts/vcdl.rst
+ key-concepts/data-accessing.rst
+ key-concepts/streams.rst
+ key-concepts/io-drivers.rst
+
+The *User Guide* section offers an in-depth understanding of vineyard's design
+and implementation. It covers detailed environment setup instructions, the
+architecture, and the core features within the vineyard engine.
+
+*Additional information on vineyard's internals will be provided soon*.
+
+.. tip::
+
+ If you are new to vineyard, we recommend starting with the
+ `Getting Started `_ page for a smoother
+ introduction.
+
+Concepts
+--------
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: key-concepts/objects
+ :type: ref
+ :text: Vineyard Objects
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ The design space of vineyard objects.
+
+ ---
+
+ .. link-button:: key-concepts/vcdl
+ :type: ref
+ :text: VCDL and Integration
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ VCDL and how to integration vineyard with computing systems.
+
+ ---
+
+ .. link-button:: key-concepts/data-accessing
+ :type: ref
+ :text: Accessing Objects in Vineyard
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ The approaches that can be used to access various kinds of objects stored in
+ vineyard.
+
+ ---
+
+ .. link-button:: key-concepts/streams
+ :type: ref
+ :text: Stream in Vineyard
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ The stream abstraction upon the immutable data sharing storage and its usages.
+
+ ---
+
+ .. link-button:: key-concepts/io-drivers
+ :type: ref
+ :text: I/O Drivers
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Design and implementation of the builtin I/O drivers that eases the integration
+ of computing engines to existing infrastructure.
diff --git a/_sources/notes/key-concepts/data-accessing.rst.txt b/_sources/notes/key-concepts/data-accessing.rst.txt
new file mode 100644
index 0000000000..51eff7744b
--- /dev/null
+++ b/_sources/notes/key-concepts/data-accessing.rst.txt
@@ -0,0 +1,317 @@
+Data Accessing
+==============
+
+Vineyard is designed to support distributed object sharing and offers both IPCClient
+and RPCClient for efficient data access. This section will guide you through various
+methods of accessing objects within vineyard. For more information on vineyard object
+basics, please refer to :ref:`metadata-and-payloads` and :ref:`distributed-objects`.
+
+IPCClient vs. RPCClient
+-----------------------
+
+As depicted in the above figure, data is partitioned across different vineyard
+instances. The concept of zero-copy sharing was explained in :ref:`architecture-of-vineyard`.
+Memory mapping is only available for clients on the same instance, while metadata
+is globally synchronized and accessible from clients connected to instances on other hosts.
+
+Vineyard provides two clients to support IPC and RPC scenarios:
+
+- IPC Client
+
+ - Can only connect to instances deployed on the same host.
+ - Offers full support for local data access. Accessing local blobs is enabled
+ by zero-copy memory mapping.
+
+- RPC Client
+
+ - Can connect to any instance with an enabled RPC endpoint.
+ - Provides limited support for remote data access. Creating and fetching remote
+ blobs incurs considerable network transfer overhead.
+
+Local vs. Remote
+^^^^^^^^^^^^^^^^
+
+Distributed shared objects are typically partitioned, with each vineyard instance managing
+some chunks of the entire object. As shown in :ref:`distributed-objects`, a :code:`GlobalTensor`
+is partitioned into three chunks, and each instance holds one chunk of type :code:`Tensor`.
+
+**From the perspective of computing engines**, distributed computing engines launch
+workers on vineyard instances. Each worker connects to the co-located local instance and
+is responsible for processing chunks in that local instance. For example, when starting a Dask
+cluster on a vineyard cluster as illustrated in the picture above, each Dask worker is responsible
+for executing computations on its local chunks. Some computing tasks require communication between
+workers, such as aggregation. In these cases, the communication is performed by the computing
+engine itself (in this case, the Dask cluster).
+
+.. tip::
+
+ We assume that the computing engines built upon vineyard are responsible for scheduling
+ tasks based on their awareness of the underlying data partitioning within the vineyard
+ cluster.
+
+ This design is well-suited for commonly-used modern computing engines,such as GraphScope,
+ Spark, Presto, Dask, Mars, and Ray.
+
+Local Objects
+-------------
+
+Creating and accessing local objects in vineyard can be easily achieved using :code:`put` and :code:`get` methods (see
+:meth:`vineyard.IPCClient.put` and :meth:`vineyard.IPCClient.get`).
+
+.. code:: python
+ :caption: Effortlessly create and access local objects using :code:`put` and :code:`get`
+
+ >>> import pandas as pd
+ >>> import vineyard
+ >>> import numpy as np
+ >>>
+ >>> vineyard_ipc_client = vineyard.connect("/tmp/vineyard.sock")
+ >>>
+ >>> df = pd.DataFrame(np.random.rand(10, 2))
+ >>>
+ >>> # put object into vineyard
+ >>> r = vineyard_ipc_client.put(df)
+ >>> r, type(r)
+ (o00053008257020f8, vineyard._C.ObjectID)
+ >>>
+ >>> # get object from vineyard using object id
+ >>> data = vineyard_ipc_client.get(r)
+ >>> data
+ 0 1
+ 0 0.534487 0.261941
+ 1 0.901056 0.441583
+ 2 0.687568 0.671564
+ ...
+
+Vineyard provides low-level APIs to operate on metadatas and raw blobs as well.
+
+Accessing metadatas
+^^^^^^^^^^^^^^^^^^^
+
+The method :meth:`vineyard.IPCClient.get_meta` can be used to inspect metadata in the
+vineyard cluster, which returns a :class:`vineyard.ObjectMeta` value:
+
+.. code:: python
+ :caption: Accessing metadata in vineyard
+
+ >>> meta = vineyard_ipc_client.get_meta(r)
+ >>> meta.id
+ o00053008257020f8
+ >>> meta.instance_id
+ 0
+ >>> meta.typename
+ 'vineyard::DataFrame'
+ >>> meta
+ {
+ "instance_id": 0,
+ "nbytes": 0,
+ "signature": 1460186430481176,
+ "transient": true,
+ "typename": "vineyard::DataFrame"
+ "__values_-value-0": {
+ "global": false,
+ "id": "o0005300822f54d1c",
+ "instance_id": 0,
+ "nbytes": 80,
+ "order_": "\"F\"",
+ "shape_": "[10]",
+ "signature": 1460186388165810,
+ "transient": true,
+ "typename": "vineyard::Tensor",
+ "value_type_": "float64",
+ "value_type_meta_": ">> import vineyard
+ >>> vineyard_ipc_client = vineyard.connect("/tmp/vineyard.sock")
+ >>>
+ >>> # mock a data
+ >>> payload = b'abcdefgh1234567890uvwxyz'
+ >>>
+ >>> # create a blob builder
+ >>> buffer_builder = vineyard_ipc_client.create_blob(len(payload))
+ >>>
+ >>> # copy the mocked data into the builder
+ >>> buffer_builder.copy(0, payload)
+ >>>
+ >>> # seal the builder then we will get a blob
+ >>> blob = buffer_builder.seal(vineyard_ipc_client)
+
+.. code:: python
+ :caption: Accessing local blobs
+
+ >>> # get the blob from vineyard using object id
+ >>> blob = vineyard_ipc_client.get_blob(blob.id)
+ >>> blob, type(blob)
+ (Object <"o800532e4ab1f2087": vineyard::Blob>, vineyard._C.Blob)
+ >>>
+ >>> # inspect the value
+ >>> bytes(memoryview(blob))
+ b'abcdefgh1234567890uvwxyz'
+
+Remote Objects
+--------------
+
+Creating and accessing remote objects in vineyard can be easily achieved using :code:`put` and :code:`get` methods (see
+:meth:`vineyard.RPCClient.put` and :meth:`vineyard.RPCClient.get`).
+
+.. code:: python
+ :caption: Effortlessly create and access remote objects using :code:`put` and :code:`get`
+
+ >>> import pandas as pd
+ >>> import vineyard
+ >>> import numpy as np
+ >>>
+ >>> vineyard_rpc_client = vineyard.connect("localhost", 9600)
+ >>>
+ >>> df = pd.DataFrame(np.random.rand(10, 2))
+ >>>
+ >>> # put object into vineyard
+ >>> r = vineyard_rpc_client.put(df)
+ >>> r, type(r)
+ (o000a45730a85f8fe, vineyard._C.ObjectID)
+ >>>
+ >>> # get object from vineyard using object id
+ >>> data = vineyard_rpc_client.get(r)
+ >>> data
+ 0 1
+ 0 0.884227 0.576031
+ 1 0.863040 0.069815
+ 2 0.297906 0.911874
+ ...
+
+The RPC client enables inspection of remote object metadata and facilitates operations on blobs
+within the remote cluster, while taking into account the associated network transfer costs.
+
+Inspecting metadata
+^^^^^^^^^^^^^^^^^^^
+
+The method :meth:`vineyard.RPCClient.get_meta` allows you to access object metadata in a similar
+manner to :meth:`vineyard.IPCClient.get_meta`, but with the added capability of connecting to a
+remote instance.
+
+.. code:: python
+ :caption: Metadata accessing using RPCClient
+
+ >>> import vineyard
+ >>> vineyard_rpc_client = vineyard.connect("localhost", 9600)
+ >>>
+ >>> # the `r` from the above "Local Objects" section
+ >>> meta = vineyard_rpc_client.get_meta(r)
+ >>> meta.id
+ o00053008257020f8
+ >>> meta.instance_id
+ 0
+ >>> meta.typename
+ 'vineyard::DataFrame'
+
+Using remote blobs
+^^^^^^^^^^^^^^^^^^
+
+However, due to the absence of memory sharing between hosts, zero-copy data sharing is not feasible when
+connecting to a vineyard instance that is not deployed on the same host as the client. Transferring data
+over the network incurs significant costs, and vineyard requires users to explicitly issue a :code:`migrate`
+command to move data from the remote instance to the local instance. For more details, please refer to
+:ref:`Object Migration in Vineyard `.
+
+For added convenience, we also provide APIs to fetch remote blobs to the local client by transferring
+payloads over the network.
+
+- :meth:`vineyard.RPCClient.create_remote_blob`: put a **filled** remote blob builder
+ :class:`vineyard.RemoteBlobBuilder` to connected remote instance.
+- :meth:`vineyard.RPCClient.get_remote_blob`: obtain a remote blob :class:`vineyard.RemoteBlob`
+ from the vineyard cluster by copying over the network.
+- :meth:`vineyard.RPCClient.get_remote_blobs`: obtain a set of remote blobs
+ :code:`List[vineyard.RemoteBlob]` from the vineyard cluster by copying over the network.
+
+.. warning::
+
+ Note that the :code:`remote` in the above APIs means the blob will be transferred using
+ TCP network. For large blobs, it implies a significant cost of time.
+
+.. code:: python
+ :caption: Creating remote blobs
+
+ >>> import vineyard
+ >>> vineyard_rpc_client = vineyard.connect("localhost", 9600)
+ >>>
+ >>> # mock a data
+ >>> payload = b'abcdefgh1234567890uvwxyz'
+ >>>
+ >>> # create an empty blob builder
+ >>> remote_buffer_builder = vineyard.RemoteBlobBuilder(len(payload))
+ >>>
+ >>> # copy the mocked data into the builder
+ >>> remote_buffer_builder.copy(0, payload)
+ >>>
+ >>> # create the remote blob using the RPCClient, with the `remote_buffer_builder` as argument
+ >>> remote_blob_meta = vineyard_rpc_client.create_remote_blob(remote_buffer_builder)
+
+.. code:: python
+ :caption: Accessing remote blobs
+
+ >>> # get the remote blob from vineyard using object id
+ >>> remote_blob = vineyard_rpc_client.get_remote_blob(remote_blob_meta.id)
+ >>> remote_blob, type(remote_blob)
+ (, vineyard._C.RemoteBlob)
+ >>>
+ >>> # inspect the value of remote blob
+ >>> bytes(memoryview(remote_blob))
+ b'abcdefgh1234567890uvwxyz'
+
+.. warning::
+
+ The APIs for creating blobs in :class:`vineyard.IPCClient` and :class:`vineyard.RPCClient`
+ have subtle differences. The :meth:`vineyard.IPCClient.create_blob` method first allocates
+ a shared memory buffer to create an empty blob builder, allowing the user to fill the buffer
+ and then seal it. In contrast, the :meth:`vineyard.RPCClient.create_remote_blob` method
+ creates a remote blob builder on-the-fly, enabling the user to fill the buffer and subsequently
+ use the client API to send the :code:`remote_buffer_builder` to the remote instance.
+
+Utilizing Distributed Objects
+-----------------------------
+
+In the illustration at the beginning of this section, we demonstrate that vineyard is capable of sharing
+distributed objects partitioned across multiple hosts. Accessing these distributed objects
+in vineyard can be achieved through two distinct approaches:
+
+- Inspecting metadata of global.
+
+ The metadata of global objects can be examined using the :class:`vineyard.RPCClient`. This allows
+ computing engines to understand the distribution of partitions of global tensors using the
+ RPCClient, and subsequently schedule jobs over those chunks based on the distribution information.
+
+ Mars employs this method to consume distributed tensors and dataframes in vineyard.
+
+ Additionally, by leveraging the metadata of global objects and the server metadata accessible
+ via :meth:`vineyard.Client.meta`, multiple RPC clients can connect to retrieve the corresponding
+ blobs from different nodes. These blobs are then assembled locally into a single object. This approach
+ is also the default method for :class:`vineyard.client`.
+
+- Accessing local partitions of global objects using the :code:`IPCClient`:
+
+ Another prevalent pattern for accessing shared global objects involves launching a worker on each
+ instance where the global object is partitioned. Then, using the :class:`vineyard.IPCClient`,
+ workers can obtain the local partitions of the global object. Each worker is responsible for
+ processing its local partitions.
+
+ This pattern is commonly utilized in many computing engines that have been integrated with
+ vineyard, such as GraphScope and Presto.
diff --git a/_sources/notes/key-concepts/io-drivers.rst.txt b/_sources/notes/key-concepts/io-drivers.rst.txt
new file mode 100644
index 0000000000..78231f3415
--- /dev/null
+++ b/_sources/notes/key-concepts/io-drivers.rst.txt
@@ -0,0 +1,37 @@
+.. _divein-driver-label:
+
+I/O Drivers
+===========
+
+As we have shown in the getting-started, the ``open`` function in vineyard can open a local
+file as a stream for consuming, and we notice that the path of the local file is headed
+with the scheme ``file://``.
+
+Actually, vineyard supports several different types of data source, e.g., ``kafka://``
+for kafka topics. The functional methods to open different data sources as vineyard
+streams are called ``drivers`` in vineyard. They are registered to ``open`` for
+specific schemes, so that when ``open`` is invoked, it will dispatch the corresponding
+driver to handle the specific data source according to the scheme of the path.
+
+The following sample code demonstrates the dispatching logic in ``open``, and the
+registration examples.
+
+.. code:: python
+
+ >>> @registerize
+ >>> def open(path, *args, **kwargs):
+ >>> scheme = urlparse(path).scheme
+
+ >>> for reader in open._factory[scheme][::-1]:
+ >>> r = reader(path, *args, **kwargs)
+ >>> if r is not None:
+ >>> return r
+ >>> raise RuntimeError('Unable to find a proper IO driver for %s' % path)
+ >>>
+ >>> # different driver functions are registered as follows
+ >>> open.register('file', local_driver)
+
+
+Most importantly, the registration design allows users to register their own drivers
+to ``registerized`` vineyard methods using ``.register``, which prevents major revisions
+on the processing code to fulfill customized computation requirements.
diff --git a/_sources/notes/key-concepts/objects.rst.txt b/_sources/notes/key-concepts/objects.rst.txt
new file mode 100644
index 0000000000..18b50ef411
--- /dev/null
+++ b/_sources/notes/key-concepts/objects.rst.txt
@@ -0,0 +1,279 @@
+.. _vineyard-objects:
+
+Objects
+=======
+
+Vineyard represents various data types as vineyard objects. It employs a
+metadata-payloads decoupled design, where an object in vineyard comprises:
+
+1. A collection of blobs containing the actual data payload;
+2. A hierarchical meta tree that describes the data's type, layout, and properties.
+
+.. _metadata-and-payloads:
+
+Object = metadata + payloads
+----------------------------
+
+There are some examples that explain the basic idea of metadata and payload that
+forms vineyard objects:
+
+- Blob: A blob is a pointer with a length that describes the size of the data,
+
+ - metadata:
+
+ - :code:`length`
+
+ - payloads:
+
+ - :code:`pointer`, the actual payload of the blob
+
+- Tensor: A tensor can be viewed as a blob that contains the actual data and several
+ metadata entries that describe the shape and type information,
+
+ - metadata:
+
+ - :code:`shape`
+ - :code:`dtype`
+ - :code:`data`, a member with type :code:`Blob`
+
+ - payloads:
+
+ - :code:`pointer` in the member :code:`data`
+
+- Dataframe: A dataframe is an ordered collection of tensors as its columns and each
+ column has a unique name,
+
+ - metadata:
+
+ - :code:`column_size`
+ - :code:`names`, a list of members with type :code:`string`
+ - :code:`columns`, a list of member with type :code:`Tensor`
+
+ - payloads:
+
+ - a set of :code:`pointer` in the member :code:`columns` (the member :code:`data` of
+ of those :code:`Tensor` s)
+
+From the example above, it is evident that objects naturally conform to a hierarchical
+model, allowing complex data objects to be composed of simpler ones. Each object
+consists of a set of blobs as the payload and a metadata tree that describes
+the semantics and organization of those blobs.
+
+.. admonition:: An example for the object metadata: a dataframe with two columns where each
+ column is a tensor.
+ :class: admonition-details
+
+ .. code:: json
+
+ {
+ "__values_-key-0": "1",
+ "__values_-key-1": "\"a\"",
+ "__values_-size": 2,
+ "__values_-value-0": {
+ "buffer_": {
+ "id": "o800527ecdf05cff9",
+ "instance_id": 39,
+ "length": 0,
+ "nbytes": 0,
+ "transient": true,
+ "typename": "vineyard::Blob"
+ },
+ "id": "o000527ecdffd95c4",
+ "instance_id": 39,
+ "nbytes": 400,
+ "partition_index_": "[]",
+ "shape_": "[100]",
+ "signature": 1451273207424436,
+ "transient": false,
+ "typename": "vineyard::Tensor",
+ "value_type_": "float"
+ },
+ "__values_-value-1": {
+ "buffer_": {
+ "id": "o800527ecdeaf1015",
+ "instance_id": 39,
+ "length": 0,
+ "nbytes": 0,
+ "transient": true,
+ "typename": "vineyard::Blob"
+ },
+ "id": "o000527ece12e4f0a",
+ "instance_id": 39,
+ "nbytes": 800,
+ "partition_index_": "[]",
+ "shape_": "[100]",
+ "signature": 1451273227452968,
+ "transient": false,
+ "typename": "vineyard::Tensor",
+ "value_type_": "double"
+ },
+ "columns_": "[\"a\",1]",
+ "id": "o000527ece15d374c",
+ "instance_id": 39,
+ "nbytes": 1200,
+ "partition_index_column_": 0,
+ "partition_index_row_": 0,
+ "row_batch_index_": 0,
+ "signature": 1451273231074538,
+ "transient": false,
+ "typename": "vineyard::DataFrame"
+ }
+
+From the above example of object metadata, it is evident that an object is composed
+of various sub-objects, forming a hierarchical data model. Each object consists of
+a set of blobs and a metadata tree that describes the semantics of those blobs.
+
+.. tip::
+
+ Without the metadata, the set of blobs would merely be a collection of memory
+ pieces without any meaningful interpretation.
+
+Refer to :ref:`using-objects-python` for a demonstration of how to put Python objects
+into vineyard and retrieve them using IPC clients.
+
+Separating metadata and payload
+-------------------------------
+
+The decoupling of data payload and data layout in vineyard offers three key advantages:
+
+1. Payloads are stored locally within each vineyard instance, while metadata is shared
+ across all instances in the cluster. This significantly reduces the overhead of maintaining
+ consistency for distributed data.
+
+2. Vineyard objects become self-descriptive, as the metadata fully determines how
+ the object should be resolved. This not only ensures semantic consistency when
+ sharing vineyard objects between different systems and programming languages,
+ but also allows users to store complex data structures with high-level abstractions, such
+ as graphs in CSR format directly in vineyard, without the need for serialization/deserialization
+ every time the object is saved or loaded.
+
+3. This design enables the exploitation of data-aware scheduling techniques. For example, when processing
+ a graph in vineyard, we can easily access the metadata tree of the graph to determine the size of each
+ partitioned fragment without accessing the actual vertices and edges. As a result,
+ we can allocate precise amounts of computational resources for each fragment, leading to overall
+ performance improvements.
+
+Vineyard employs two design choices for the metadata and methods of its objects:
+
+1. A composable design for vineyard objects, which facilitates distributed data management;
+
+2. An extensible design for object methods, enabling flexible data sharing
+ between different computation systems with minimal additional development cost.
+
+Data model
+----------
+
+Composable
+^^^^^^^^^^
+
+The composition mechanism in vineyard is based on the hierarchical tree structure of
+the metadata of its objects. The root metadata of a complex object stores references
+to the root metadata of its components. By recursively traversing these references,
+a complete metadata tree is constructed for the complex object.
+
+.. figure:: ../../images/vineyard_composable.jpg
+ :width: 75%
+ :alt: Vineyard objects are composable
+
+ Vineyard objects are composable
+
+For instance, a distributed dataframe consists of partitioned dataframe chunks, while
+a dataframe is composed of column vectors. Considering the decoupling design of payload
+and layout in vineyard objects, the blobs are stored in the corresponding vineyard
+instance's memory for each partition, and the metadata (e.g., chunk index, shape,
+column data types) are stored in the key-value store behind the metadata service.
+
+To store a distributed graph, we first save the partitioned fragments in each vineyard
+instance and share their metadata in the backend key-value store. Then, we can create
+the distributed graph by generating the root metadata containing links to the root
+metadata of the fragments in an efficient manner.
+
+.. _distributed-objects:
+
+Distributed objects
+^^^^^^^^^^^^^^^^^^^
+
+Vineyard is designed to store large objects across multiple nodes in a cluster, enabling
+user programs to seamlessly interact with these objects as a single entity. Data is
+sharded across multiple machines without replication.
+
+.. figure:: ../../images/vineyard_distributed_tensor.jpg
+ :alt: Distributed objects in vineyard
+ :width: 60%
+
+ Distributed objects in vineyard
+
+For example, consider a "Tensor" object that contains billions of columns and rows, making
+it too large to fit into a single machine. In such cases, the tensor can be split along
+the index or column axis, with each vineyard node holding a subset of chunks. Vineyard
+provides a logical view of the complete tensor, allowing distributed computation engines
+like Mars and GraphScope to process the data structure as a whole.
+.. TODO: add the collection APIs
+
+.. tip::
+
+ See also the concepts of *persistent objects* in the following subsection. Refer to
+ the following subsection for more information on the concept of *persistent objects*.
+
+Transient vs. Persistent
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+As previously mentioned, vineyard objects' metadata and payloads are managed separately
+by different components of the vineyard server. Payloads are designed to be shared with
+computing engines using local memory mapping. However, metadata may need to be inspected
+by clients connected to other vineyard instances, such as when forming a distributed object.
+In this case, the distributed object consists of a set of chunks placed on different
+vineyard instances. When retrieving the distributed objects from vineyard, computing engines
+may need to inspect the metadata of non-local pieces to understand the distribution of the
+entire dataset.
+
+This requirement implies that metadata must be globally synchronized and accessible from
+clients connected to other vineyard instances. However, global synchronization is a costly
+operation, and numerous small key-value pairs can significantly increase the burden on the
+key-value store backend of our metadata services. To address this issue, we categorize
+objects as transient or persistent.
+
+- **Transient objects** are designed for cases where the object is known not to be part of a
+ distributed object and will never need to be inspected by clients on other vineyard instances.
+ Transient objects are useful for short-lived immediate values within the progress of a
+ single computing engine.
+
+- **Persistent objects** are designed for cases where the object chunk will be used to form
+ a larger distributed object, and the metadata is needed when applications inspect the
+ distributed object. Persistent objects and distributed objects are commonly used to pass
+ intermediate data between two distributed engines.
+
+.. caution::
+
+ By default, objects are **transient**. We provide an API :code:`client.persist()` that
+ can explicitly persist the metadata of the target object to etcd, ensuring its visibility
+ by clients connected to other instances in the cluster.
+
+.. _builder-resolver:
+
+Builders and resolvers
+^^^^^^^^^^^^^^^^^^^^^^
+
+Vineyard utilizes an extensible registry mechanism to enable users to easily integrate their
+data structures into the system. This design, which includes builders, resolvers, and drivers,
+allows users to create, resolve, and share their data structures across different systems and
+paradigms. Notably, even the core data structures and drivers in Vineyard follow this design.
+
+.. note::
+
+ **What is the registry mechanism?**
+
+ The registry mechanism decouples methods from the definition of Vineyard data types. For
+ builders and resolvers, this means users can flexibly register different implementations
+ in various languages to build and resolve the same Vineyard data type. This enables data
+ sharing between different systems and paradigms and allows for native language optimizations.
+
+ For drivers, the registry mechanism permits users to flexibly plug in functionality methods
+ in different languages for Vineyard data types, providing the necessary capabilities for
+ data types during the data analysis process.
+
+ Moreover, the registered methods can be implemented and optimized according to specific
+ data analysis tasks, further enhancing efficiency.
+
+Refer to :ref:`define-python-types` and :ref:`define-cpp-types` for examples of how builders
+and resolvers are implemented in Python and C++, respectively.
diff --git a/_sources/notes/key-concepts/streams.rst.txt b/_sources/notes/key-concepts/streams.rst.txt
new file mode 100644
index 0000000000..afa663367e
--- /dev/null
+++ b/_sources/notes/key-concepts/streams.rst.txt
@@ -0,0 +1,122 @@
+.. _streams-in-vineyard:
+
+Streams in Vineyard
+===================
+
+Streams in Vineyard serve as an abstraction over the immutable data sharing storage,
+facilitating seamless pipelining between computing engines. Similar to
+`pipe `_, Vineyard's streams enable
+efficient inter-engine communication while minimizing the overhead associated with
+data serialization/deserialization and copying.
+
+A typical use case for streams in Vineyard involves one process continuously producing
+data chunks (e.g., an IO reader) while another process performs scan computations
+on the data (e.g., filtering and aggregation operations). A stream consists of a
+sequence of immutable data chunks, produced by the former engine and consumed by the
+latter engine.
+
+This section will explore the utilization of streams in Vineyard.
+
+Using streams
+-------------
+
+We first import required packages:
+
+.. code:: python
+
+ import threading
+ import time
+ from typing import List
+
+ import numpy as np
+ import pandas as pd
+
+ import vineyard
+ from vineyard.io.recordbatch import RecordBatchStream
+
+.. tip::
+
+ Vineyard has defined some built-in stream types, e.g.,
+ :class:`vineyard.io.recordbatch.RecordBatchStream`. For other stream types,
+ you could refer to :ref:`python-api-streams`.
+
+Producer and consumer
+---------------------
+
+We define a producer that generates random dataframe chunks and inserts them
+into the stream:
+
+.. code:: python
+ :caption: A producer of :code:`RecordBatchStream`
+
+ def generate_random_dataframe(dtypes, size):
+ columns = dict()
+ for k, v in dtypes.items():
+ columns[k] = np.random.random(size).astype(v)
+ return pd.DataFrame(columns)
+
+ def producer(stream: RecordBatchStream, total_chunks, dtypes, produced: List):
+ writer = stream.writer
+ for idx in range(total_chunks):
+ time.sleep(idx)
+ chunk = generate_random_dataframe(dtypes, 2) # np.random.randint(10, 100))
+ chunk_id = vineyard_client.put(chunk)
+ writer.append(chunk_id)
+ produced.append((chunk_id, chunk))
+ writer.finish()
+
+Additionally, we create a consumer that retrieves the chunks from the stream in a
+loop, continuing until it encounters a :code:`StopIteration` exception:
+
+.. code:: python
+ :caption: A consumer of :code:`RecordBatchStream`
+
+ def consumer(stream: RecordBatchStream, total_chunks, produced: List):
+ reader = stream.reader
+ index = 0
+ while True:
+ try:
+ chunk = reader.next()
+ print('reader receive chunk:', type(chunk), chunk)
+ pd.testing.assert_frame_equal(produced[index][1], chunk)
+ except StopIteration:
+ break
+ index += 1
+
+Streams between processes
+-------------------------
+
+Finally, we can test the producer and consumer using two threads:
+
+.. code:: python
+ :caption: Connect the producer and consumer threads using vineyard stream
+
+ def test_recordbatch_stream(vineyard_client, total_chunks):
+ stream = RecordBatchStream.new(vineyard_client)
+ dtypes = {
+ 'a': np.dtype('int'),
+ 'b': np.dtype('float'),
+ 'c': np.dtype('bool'),
+ }
+
+ client1 = vineyard_client.fork()
+ client2 = vineyard_client.fork()
+ stream1 = client1.get(stream.id)
+ stream2 = client2.get(stream.id)
+
+ produced = []
+
+ thread1 = threading.Thread(target=consumer, args=(stream1, total_chunks, produced))
+ thread1.start()
+
+ thread2 = threading.Thread(target=producer, args=(stream2, total_chunks, dtypes, produced))
+ thread2.start()
+
+ thread1.join()
+ thread2.join()
+
+ if __name__ == '__main__':
+ vineyard_client = vineyard.connect("/tmp/vineyard.sock")
+ test_recordbatch_stream(vineyard_client, total_chunks=10)
+
+For more detailed API about the streams, please refer to :ref:`python-api-streams`.
diff --git a/_sources/notes/key-concepts/vcdl.rst.txt b/_sources/notes/key-concepts/vcdl.rst.txt
new file mode 100644
index 0000000000..24683a28d7
--- /dev/null
+++ b/_sources/notes/key-concepts/vcdl.rst.txt
@@ -0,0 +1,40 @@
+.. _vcdl:
+
+Code Generation for Boilerplate
+===============================
+
+The process of sharing objects between engines involves two fundamental steps: defining
+the data structure and establishing the protocol to represent the data type
+as :ref:`vineyard-objects`. To alleviate the integration burden with custom data types,
+Vineyard offers an auto-generation mechanism.
+
+This mechanism, known as **VCDL**, relies on the custom annotation :code:`[[shared]]`
+applied to C++ classes.
+
+Consider the following C++ class :code:`Array` as an example:
+
+.. code:: c++
+
+ template
+ class [[vineyard]] Array {
+ public:
+ [[shared]] const T& operator[](size_t loc) const { return data()[loc]; }
+ [[shared]] size_t size() const { return size_; }
+ [[shared]] const T* data() const {
+ return reinterpret_cast(buffer_->data());
+ }
+
+ private:
+ [[shared]] size_t size_;
+ [[shared]] std::shared_ptr buffer_;
+ };
+
+- When applied to classes: the class itself is identified as a shared vineyard
+ object, and a builder and resolver (see also :ref:`builder-resolver`) are
+ automatically synthesized.
+
+- When applied to data members: the data member is treated as a metadata
+ field or a sub-member.
+
+- When applied to method members: the method member is deemed
+ cross-language sharable, and FFI wrappers are automatically synthesized.
diff --git a/_sources/notes/references.rst.txt b/_sources/notes/references.rst.txt
new file mode 100644
index 0000000000..9d3cc6650c
--- /dev/null
+++ b/_sources/notes/references.rst.txt
@@ -0,0 +1,48 @@
+API Reference
+==============
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ references/python-api.rst
+ references/cpp-api.rst
+ Kubernetes CRDs
+
+Vineyard offers a comprehensive suite of SDKs, including Python and C++ versions.
+For detailed API references, please explore the following pages:
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: references/python-api
+ :type: ref
+ :text: Python
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ API reference for vineyard Python SDK.
+
+ ---
+
+ .. link-button:: references/cpp-api
+ :type: ref
+ :text: C++
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ API reference for vineyard C++ SDK.
+
+All terms in the documentation site can use search from the following
+indexing page:
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: genindex
+ :type: ref
+ :text: API Indexes
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Term indexes for the vineyard documentation.
diff --git a/_sources/notes/references/cpp-api.rst.txt b/_sources/notes/references/cpp-api.rst.txt
new file mode 100644
index 0000000000..e13bb7e647
--- /dev/null
+++ b/_sources/notes/references/cpp-api.rst.txt
@@ -0,0 +1,146 @@
+C++ API Reference
+=================
+
+.. _cpp-api:
+
+.. default-domain:: cpp
+
+Objects
+-------
+
+.. doxygentypedef:: vineyard::ObjectID
+
+.. doxygenclass:: vineyard::Object
+ :members:
+ :protected-members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::ObjectBuilder
+ :members:
+ :protected-members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::ObjectBase
+ :members:
+ :undoc-members:
+
+Metadata
+--------
+
+.. doxygenclass:: vineyard::ObjectMeta
+ :members:
+ :protected-members:
+ :undoc-members:
+
+Vineyard Clients
+----------------
+
+.. doxygenclass:: vineyard::ClientBase
+ :members:
+ :protected-members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::Client
+ :members:
+ :protected-members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::RPCClient
+ :members:
+ :protected-members:
+ :undoc-members:
+
+Vineyard Server
+---------------
+
+.. doxygenstruct:: vineyard::InstanceStatus
+ :members:
+ :undoc-members:
+
+Blob
+----
+
+.. doxygenclass:: vineyard::Blob
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::BlobWriter
+ :members:
+ :undoc-members:
+
+Stream
+------
+
+.. doxygenclass:: vineyard::ByteStream
+ :members:
+ :undoc-members:
+
+Basic Data Types
+----------------
+
+.. doxygenclass:: vineyard::Array
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::ArrayBuilder
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::Hashmap
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::HashmapBuilder
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::Tensor
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::TensorBuilder
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::DataFrame
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::DataFrameBuilder
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::Sequence
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::SequenceBuilder
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::Scalar
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::ScalarBuilder
+ :members:
+ :undoc-members:
+
+Distributed Data Types
+----------------------
+
+.. doxygenclass:: vineyard::GlobalTensor
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::GlobalTensorBuilder
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::GlobalDataFrame
+ :members:
+ :undoc-members:
+
+.. doxygenclass:: vineyard::GlobalDataFrameBuilder
+ :members:
+ :undoc-members:
diff --git a/_sources/notes/references/crds.md.txt b/_sources/notes/references/crds.md.txt
new file mode 100644
index 0000000000..f837a5093e
--- /dev/null
+++ b/_sources/notes/references/crds.md.txt
@@ -0,0 +1,615 @@
+# API Reference
+
+## Packages
+- [k8s.v6d.io/v1alpha1](#k8sv6diov1alpha1)
+
+
+## k8s.v6d.io/v1alpha1
+
+Package v1alpha1 contains API Schema definitions for the k8s v1alpha1 API group
+
+### Resource Types
+- [Backup](#backup)
+- [BackupList](#backuplist)
+- [CSIDriver](#csidriver)
+- [CSIDriverList](#csidriverlist)
+- [GlobalObject](#globalobject)
+- [GlobalObjectList](#globalobjectlist)
+- [LocalObject](#localobject)
+- [LocalObjectList](#localobjectlist)
+- [Operation](#operation)
+- [OperationList](#operationlist)
+- [Recover](#recover)
+- [RecoverList](#recoverlist)
+- [Sidecar](#sidecar)
+- [SidecarList](#sidecarlist)
+- [Vineyardd](#vineyardd)
+- [VineyarddList](#vineyarddlist)
+
+
+
+#### Backup
+
+
+
+Backup describes a backup operation of vineyard objects, which uses the [Kubernetes PersistentVolume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) to store the backup data. Every backup operation will be binded with the name of Backup.
+
+_Appears in:_
+- [BackupList](#backuplist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `Backup`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[BackupSpec](#backupspec)_ | |
+
+
+#### BackupList
+
+
+
+BackupList contains a list of Backup
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `BackupList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[Backup](#backup) array_ | |
+
+
+#### BackupSpec
+
+
+
+BackupSpec defines the desired state of Backup
+
+_Appears in:_
+- [Backup](#backup)
+
+| Field | Description |
+| --- | --- |
+| `vineyarddName` _string_ | the name of the vineyard cluster |
+| `vineyarddNamespace` _string_ | the namespace of the vineyard cluster |
+| `objecIDs` _string array_ | the specific objects to be backed up if not specified, all objects will be backed up |
+| `backupPath` _string_ | the path of backup data |
+| `persistentVolumeSpec` _[PersistentVolumeSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#persistentvolumespec-v1-core)_ | the PersistentVolumeSpec of the backup data |
+| `persistentVolumeClaimSpec` _[PersistentVolumeClaimSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#persistentvolumeclaimspec-v1-core)_ | the PersistentVolumeClaimSpec of the backup data |
+
+
+
+
+#### CSIDriver
+
+
+
+CSIDriver is the Schema for the csidrivers API
+
+_Appears in:_
+- [CSIDriverList](#csidriverlist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `CSIDriver`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[CSIDriverSpec](#csidriverspec)_ | |
+
+
+#### CSIDriverList
+
+
+
+CSIDriverList contains a list of CSIDriver
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `CSIDriverList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[CSIDriver](#csidriver) array_ | |
+
+
+#### CSIDriverSpec
+
+
+
+CSIDriverSpec defines the desired state of CSIDriver
+
+_Appears in:_
+- [CSIDriver](#csidriver)
+
+| Field | Description |
+| --- | --- |
+| `image` _string_ | Image is the name of the csi driver image |
+| `imagePullPolicy` _string_ | ImagePullPolicy is the image pull policy of the csi driver |
+| `storageClassName` _string_ | StorageClassName is the name of the storage class |
+| `volumeBindingMode` _string_ | VolumeBindingMode is the volume binding mode of the storage class |
+| `sidecar` _[CSISidecar](#csisidecar)_ | Sidecar is the configuration for the CSI sidecar container nolint: lll |
+| `clusters` _[VineyardClusters](#vineyardclusters) array_ | Clusters are the list of vineyard clusters |
+| `enableToleration` _boolean_ | EnableToleration is the flag to enable toleration for the csi driver |
+| `enableVerboseLog` _boolean_ | EnableVerboseLog is the flag to enable verbose log for the csi driver |
+
+
+
+
+#### CSISidecar
+
+
+
+CSISidecar holds the configuration for the CSI sidecar container
+
+_Appears in:_
+- [CSIDriverSpec](#csidriverspec)
+
+| Field | Description |
+| --- | --- |
+| `provisionerImage` _string_ | ProvisionerImage is the image of the provisioner sidecar |
+| `attacherImage` _string_ | AttacherImage is the image of the attacher sidecar |
+| `nodeRegistrarImage` _string_ | NodeRegistrarImage is the image of the node registrar sidecar |
+| `livenessProbeImage` _string_ | LivenessProbeImage is the image of the liveness probe sidecar |
+| `imagePullPolicy` _string_ | ImagePullPolicy is the image pull policy of all sidecar containers |
+| `enableTopology` _boolean_ | EnableTopology is the flag to enable topology for the csi driver |
+
+
+#### GlobalObject
+
+
+
+GlobalObject describes a global object in vineyard, whose metadata will be stored in etcd.
+
+_Appears in:_
+- [GlobalObjectList](#globalobjectlist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `GlobalObject`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[GlobalObjectSpec](#globalobjectspec)_ | |
+
+
+#### GlobalObjectList
+
+
+
+GlobalObjectList contains a list of GlobalObject
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `GlobalObjectList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[GlobalObject](#globalobject) array_ | |
+
+
+#### GlobalObjectSpec
+
+
+
+GlobalObjectSpec defines the desired state of GlobalObject
+
+_Appears in:_
+- [GlobalObject](#globalobject)
+
+| Field | Description |
+| --- | --- |
+| `id` _string_ | |
+| `name` _string_ | |
+| `signature` _string_ | |
+| `typename` _string_ | |
+| `members` _string array_ | |
+| `metadata` _string_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+
+
+
+
+#### LocalObject
+
+
+
+LocalObject describes a local object in vineyard, whose metadata will only be stored in local vineyard.
+
+_Appears in:_
+- [LocalObjectList](#localobjectlist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `LocalObject`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[LocalObjectSpec](#localobjectspec)_ | |
+
+
+#### LocalObjectList
+
+
+
+LocalObjectList contains a list of LocalObject
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `LocalObjectList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[LocalObject](#localobject) array_ | |
+
+
+#### LocalObjectSpec
+
+
+
+LocalObjectSpec defines the desired state of LocalObject
+
+_Appears in:_
+- [LocalObject](#localobject)
+
+| Field | Description |
+| --- | --- |
+| `id` _string_ | |
+| `name` _string_ | |
+| `signature` _string_ | |
+| `typename` _string_ | |
+| `instance_id` _integer_ | |
+| `hostname` _string_ | |
+| `metadata` _string_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+
+
+
+
+#### MetricConfig
+
+
+
+MetricConfig holds the configuration about metric container
+
+_Appears in:_
+- [SidecarSpec](#sidecarspec)
+- [VineyarddSpec](#vineyarddspec)
+
+| Field | Description |
+| --- | --- |
+| `enable` _boolean_ | Enable metrics |
+| `image` _string_ | represent the metric's image |
+| `imagePullPolicy` _string_ | the policy about pulling image |
+
+
+#### Operation
+
+
+
+Operation describes an operation between workloads, such as assembly and repartition.
+ As for the `assembly` operation, there are several kinds of computing engines, some may not support the stream data, so we need to insert an `assembly` operation to assemble the stream data into a batch data, so that the next computing engines can process the data.
+ As for the `repartition` operation, the vineyard has integrated with the distributed computing engines, such as Dask. If you want to repartition the data to adapt the dask workers, then the `repartition` operation is essential for such scenario.
+
+_Appears in:_
+- [OperationList](#operationlist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `Operation`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[OperationSpec](#operationspec)_ | |
+
+
+#### OperationList
+
+
+
+OperationList contains a list of Operation
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `OperationList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[Operation](#operation) array_ | |
+
+
+#### OperationSpec
+
+
+
+OperationSpec defines the desired state of Operation
+
+_Appears in:_
+- [Operation](#operation)
+
+| Field | Description |
+| --- | --- |
+| `name` _string_ | the name of vineyard pluggable drivers, including assembly and repartition. |
+| `type` _string_ | the type of object, including local and distributed. |
+| `require` _string_ | the required job's name of the operation |
+| `target` _string_ | the target job's name of the operation |
+| `timeoutSeconds` _integer_ | TimeoutSeconds is the timeout of the operation. |
+
+
+
+
+#### PluginImageConfig
+
+
+
+PluginImageConfig holds all image configuration about pluggable drivers(backup, recover, local assembly, distributed assembly, repartition)
+
+_Appears in:_
+- [VineyarddSpec](#vineyarddspec)
+
+| Field | Description |
+| --- | --- |
+| `backupImage` _string_ | the image of backup operation |
+| `recoverImage` _string_ | the image of recover operation |
+| `daskRepartitionImage` _string_ | the image of dask repartition operation |
+| `localAssemblyImage` _string_ | the image of local assembly operation |
+| `distributedAssemblyImage` _string_ | the image of distributed assembly operation |
+
+
+#### Recover
+
+
+
+Recover describes a recover operation of vineyard objects, which is used to recover a specific backup operation.
+
+_Appears in:_
+- [RecoverList](#recoverlist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `Recover`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[RecoverSpec](#recoverspec)_ | |
+
+
+#### RecoverList
+
+
+
+RecoverList contains a list of Recover
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `RecoverList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[Recover](#recover) array_ | |
+
+
+#### RecoverSpec
+
+
+
+RecoverSpec defines the desired state of Recover
+
+_Appears in:_
+- [Recover](#recover)
+
+| Field | Description |
+| --- | --- |
+| `backupName` _string_ | the name of backup |
+| `backupNamespace` _string_ | the namespace of backup |
+
+
+
+
+#### ServiceConfig
+
+
+
+ServiceConfig holds all service configuration about vineyardd
+
+_Appears in:_
+- [SidecarSpec](#sidecarspec)
+- [VineyarddSpec](#vineyarddspec)
+
+| Field | Description |
+| --- | --- |
+| `type` _string_ | service type |
+| `port` _integer_ | service port |
+
+
+#### Sidecar
+
+
+
+Sidecar is used for configuring and managing the vineyard sidecar container.
+
+_Appears in:_
+- [SidecarList](#sidecarlist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `Sidecar`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[SidecarSpec](#sidecarspec)_ | |
+
+
+#### SidecarList
+
+
+
+SidecarList contains a list of Sidecar
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `SidecarList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[Sidecar](#sidecar) array_ | |
+
+
+#### SidecarSpec
+
+
+
+SidecarSpec defines the desired state of Sidecar
+
+_Appears in:_
+- [Sidecar](#sidecar)
+
+| Field | Description |
+| --- | --- |
+| `selector` _string_ | the selector of pod |
+| `replicas` _integer_ | the replicas of workload |
+| `etcdReplicas` _integer_ | EtcdReplicas describe the etcd replicas |
+| `vineyard` _[VineyardConfig](#vineyardconfig)_ | vineyard container configuration nolint: lll |
+| `metric` _[MetricConfig](#metricconfig)_ | metric container configuration |
+| `volume` _[VolumeConfig](#volumeconfig)_ | metric configurations |
+| `service` _[ServiceConfig](#serviceconfig)_ | rpc service configuration |
+| `securityContext` _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#securitycontext-v1-core)_ | SecurityContext holds the security context settings for the vineyardd container. |
+| `volumes` _[Volume](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#volume-v1-core) array_ | Volumes is the list of Kubernetes volumes that can be mounted by the vineyard container. |
+| `volumeMounts` _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#volumemount-v1-core) array_ | VolumeMounts specifies the volumes listed in ".spec.volumes" to mount into the vineyard container. |
+
+
+
+
+#### SpillConfig
+
+
+
+SpillConfig holds all configuration about spilling
+
+_Appears in:_
+- [VineyardConfig](#vineyardconfig)
+
+| Field | Description |
+| --- | --- |
+| `name` _string_ | the name of the spill config |
+| `path` _string_ | the path of spilling |
+| `spillLowerRate` _string_ | low watermark of spilling memory |
+| `spillUpperRate` _string_ | high watermark of triggering spilling |
+| `persistentVolumeSpec` _[PersistentVolumeSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#persistentvolumespec-v1-core)_ | the PersistentVolumeSpec of the spilling PV |
+| `persistentVolumeClaimSpec` _[PersistentVolumeClaimSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#persistentvolumeclaimspec-v1-core)_ | the PersistentVolumeClaimSpec of the spill file |
+
+
+#### VineyardClusters
+
+
+
+VineyardClusters contains the list of vineyard clusters
+
+_Appears in:_
+- [CSIDriverSpec](#csidriverspec)
+
+| Field | Description |
+| --- | --- |
+| `namespace` _string_ | Namespace is the namespace of the vineyard cluster |
+| `name` _string_ | Name is the name of the vineyard deployment |
+
+
+#### VineyardConfig
+
+
+
+VineyardConfig holds all configuration about vineyard container
+
+_Appears in:_
+- [SidecarSpec](#sidecarspec)
+- [VineyarddSpec](#vineyarddspec)
+
+| Field | Description |
+| --- | --- |
+| `image` _string_ | represent the vineyardd's image |
+| `imagePullPolicy` _string_ | the policy about pulling image |
+| `syncCRDs` _boolean_ | synchronize CRDs when persisting objects |
+| `socket` _string_ | The directory on host for the IPC socket file. The UNIX-domain socket will be placed as `${Socket}/vineyard.sock`. |
+| `size` _string_ | shared memory size for vineyardd |
+| `reserveMemory` _boolean_ | reserve the shared memory for vineyardd |
+| `streamThreshold` _integer_ | memory threshold of streams (percentage of total memory) |
+| `spill` _[SpillConfig](#spillconfig)_ | the configuration of spilling |
+| `env` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#envvar-v1-core) array_ | vineyard environment configuration |
+| `memory` _string_ | the memory resources of vineyard container |
+| `cpu` _string_ | the cpu resources of vineyard container |
+
+
+#### Vineyardd
+
+
+
+Vineyardd is used to deploy a vineyard cluster on kubernetes, which can simplify the configurations of the vineyard binary, the external etcd cluster and the vineyard [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/). As vineyard is bound to a specific socket on the hostpath by default, the vineyard pod cannot be deployed on the same node. Before deploying vineyardd, you should know how many nodes are available for vineyard pod to deploy on and make sure the vineyardd pod number is less than the number of available nodes.
+
+_Appears in:_
+- [VineyarddList](#vineyarddlist)
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `Vineyardd`
+| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `spec` _[VineyarddSpec](#vineyarddspec)_ | |
+
+
+#### VineyarddList
+
+
+
+VineyarddList contains a list of Vineyardd
+
+
+
+| Field | Description |
+| --- | --- |
+| `apiVersion` _string_ | `k8s.v6d.io/v1alpha1`
+| `kind` _string_ | `VineyarddList`
+| `metadata` _[ListMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#listmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
+| `items` _[Vineyardd](#vineyardd) array_ | |
+
+
+#### VineyarddSpec
+
+
+
+VineyarddSpec holds all configuration about vineyardd
+
+_Appears in:_
+- [Vineyardd](#vineyardd)
+
+| Field | Description |
+| --- | --- |
+| `replicas` _integer_ | Replicas is the number of vineyardd pods to deploy |
+| `etcdReplicas` _integer_ | EtcdReplicas describe the etcd replicas |
+| `service` _[ServiceConfig](#serviceconfig)_ | vineyardd's service |
+| `vineyard` _[VineyardConfig](#vineyardconfig)_ | vineyard container configuration nolint: lll |
+| `pluginImage` _[PluginImageConfig](#pluginimageconfig)_ | operation container configuration nolint: lll |
+| `metric` _[MetricConfig](#metricconfig)_ | metric container configuration |
+| `volume` _[VolumeConfig](#volumeconfig)_ | Volume configuration |
+| `securityContext` _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#securitycontext-v1-core)_ | SecurityContext holds the security context settings for the vineyardd container. |
+| `volumes` _[Volume](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#volume-v1-core) array_ | Volumes is the list of Kubernetes volumes that can be mounted by the vineyard deployment. |
+| `volumeMounts` _[VolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#volumemount-v1-core) array_ | VolumeMounts specifies the volumes listed in ".spec.volumes" to mount into the vineyard deployment. |
+
+
+
+
+#### VolumeConfig
+
+
+
+VolumeConfig holds all configuration about persistent volume
+
+_Appears in:_
+- [SidecarSpec](#sidecarspec)
+- [VineyarddSpec](#vineyarddspec)
+
+| Field | Description |
+| --- | --- |
+| `pvcName` _string_ | the name of pvc |
+| `mountPath` _string_ | the mount path of pv |
+
+
diff --git a/_sources/notes/references/python-api.rst.txt b/_sources/notes/references/python-api.rst.txt
new file mode 100644
index 0000000000..f45bee5771
--- /dev/null
+++ b/_sources/notes/references/python-api.rst.txt
@@ -0,0 +1,163 @@
+Python API Reference
+====================
+
+.. _python-api:
+
+.. default-domain:: py
+
+.. currentmodule:: vineyard
+
+Objects
+-------
+
+.. autoclass:: ObjectID
+ :special-members:
+ :members:
+
+.. autoclass:: Object
+ :members:
+
+.. autoclass:: ObjectBuilder
+ :members:
+
+Metadata
+--------
+
+.. autoclass:: ObjectMeta
+ :special-members:
+ :members:
+
+Vineyard client
+---------------
+
+.. autofunction:: connect
+
+.. autoclass:: Client
+ :inherited-members:
+ :members:
+
+.. autoclass:: IPCClient
+ :inherited-members:
+ :members:
+
+.. autoclass:: RPCClient
+ :inherited-members:
+ :members:
+
+Vineyard cluster
+----------------
+
+.. autoclass:: InstanceStatus
+ :special-members:
+ :members:
+
+Blob
+----
+
+.. autoclass:: Blob
+ :members:
+
+.. autoclass:: BlobBuilder
+ :members:
+
+.. autoclass:: RemoteBlob
+ :members:
+
+.. autoclass:: RemoteBlobBuilder
+ :members:
+
+Resolvers and builders
+----------------------
+
+.. autoclass:: vineyard.core.resolver.ResolverContext
+ :members:
+
+.. autofunction:: vineyard.core.resolver.get_current_resolvers
+.. autofunction:: vineyard.core.resolver.resolver_context
+
+.. autoclass:: vineyard.core.builder.BuilderContext
+ :members:
+
+.. autofunction:: vineyard.core.builder.get_current_builders
+.. autofunction:: vineyard.core.builder.builder_context
+
+.. autoclass:: vineyard.core.driver.DriverContext
+ :members:
+
+.. autofunction:: vineyard.core.driver.get_current_drivers
+.. autofunction:: vineyard.core.driver.driver_context
+
+.. _shared-memory:
+
+Shared memory
+-------------
+
+.. autoclass:: vineyard.shared_memory.SharedMemory
+ :members:
+
+.. autoclass:: vineyard.shared_memory.ShareableList
+ :members:
+
+.. _vineyard-python-deployment-api:
+
+Deployment
+----------
+
+.. autofunction:: vineyard.connect
+.. autofunction:: vineyard.get_current_socket
+.. autofunction:: vineyard.deploy.local.start_vineyardd
+.. autofunction:: vineyard.deploy.distributed.start_vineyardd
+.. autofunction:: vineyard.deploy.kubernetes.start_vineyardd
+.. autofunction:: vineyard.deploy.kubernetes.delete_kubernetes_objects
+
+I/O Drivers
+-----------
+
+.. autofunction:: vineyard.io.open
+.. autofunction:: vineyard.io.read
+.. autofunction:: vineyard.io.write
+
+.. _python-api-streams:
+
+Streams
+-------
+
+.. autoclass:: vineyard.io.byte.ByteStream
+ :members:
+
+.. autoclass:: vineyard.io.dataframe.DataframeStream
+ :members:
+
+.. autoclass:: vineyard.io.recordbatch.RecordBatchStream
+ :members:
+
+Interacting with the CSI Driver
+-------------------------------
+
+.. autofunction:: vineyard.csi.read
+.. autofunction:: vineyard.csi.write
+
+Vineyard Cli Tool
+-----------------
+
+You can also use the Python API to interact with internal
+`Vineyard Cli Tool`_.
+
+.. code-block:: bash
+
+ $ python -m vineyard.cli [options]
+
+Vineyard LLM KV Cache
+---------------------
+
+Before using the KV Cache, you need to install the ``vineyard-llm`` package.
+
+.. autoclass:: vineyard.llm.KVCache
+ :special-members:
+ :members:
+
+.. autoclass:: vineyard.llm.KVCacheConfig
+ :special-members:
+ :members:
+
+.. _Vineyard Cli Tool: https://v6d.io/notes/cloud-native/vineyardctl.html
diff --git a/_sources/tutorials/data-processing.rst.txt b/_sources/tutorials/data-processing.rst.txt
new file mode 100644
index 0000000000..2d4ecc1d75
--- /dev/null
+++ b/_sources/tutorials/data-processing.rst.txt
@@ -0,0 +1,70 @@
+
+Data processing
+===============
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ ./data-processing/using-objects-python.rst
+ ./data-processing/python-sharedmemory.rst
+ ./data-processing/distributed-learning.rst
+ ./data-processing/accelerate-data-sharing-in-kedro.rst
+ ./data-processing/gpu-memory-sharing.rst
+
+In these comprehensive case studies, we demonstrate how to seamlessly integrate vineyard's
+capabilities with existing data-intensive tasks. By incorporating vineyard into complex
+workflows involving multiple computing engines, users can experience significant
+improvements in both performance and ease of use.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: ./data-processing/using-objects-python
+ :type: ref
+ :text: Python Objects
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Effortlessly share Python objects between processes using vineyard's intuitive and efficient approach.
+
+ ---
+
+ .. link-button:: ./data-processing/python-sharedmemory
+ :type: ref
+ :text: SharedMemory in Python
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Utilize vineyard as an elegant alternative to :code:`multiprocessing.shared_memory` in Python.
+
+ ---
+
+ .. link-button:: ./data-processing/distributed-learning
+ :type: ref
+ :text: Distributed Learning
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Discover how vineyard enhances distributed machine learning training workflows by
+ seamlessly integrating with various computing engines for improved efficiency and elegance.
+
+ ---
+
+ .. link-button:: ./data-processing/accelerate-data-sharing-in-kedro
+ :type: ref
+ :text: Accelerate Data Sharing in Kedro
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Vineyard serves as the :code:`DataSet` backend for Kedro pipelines, enabling
+ efficient data sharing between tasks without intrusive code modification, even
+ when the pipeline is deployed to Kubernetes.
+
+ ---
+
+ .. link-button:: ./data-processing/gpu-memory-sharing
+ :type: ref
+ :text: GPU Memory Sharing
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Vineyard supports sharing GPU memory in zero-copy manner, enabling efficient data sharing
+ between GPU-accelerated tasks.
diff --git a/_sources/tutorials/data-processing/accelerate-data-sharing-in-kedro.rst.txt b/_sources/tutorials/data-processing/accelerate-data-sharing-in-kedro.rst.txt
new file mode 100644
index 0000000000..a3ebe5a7eb
--- /dev/null
+++ b/_sources/tutorials/data-processing/accelerate-data-sharing-in-kedro.rst.txt
@@ -0,0 +1,292 @@
+.. _accelerate-data-sharing-in-kedro:
+
+Accelerate Data Sharing in Kedro
+================================
+
+This is a tutorial that shows how Vineyard accelerate the intermediate data
+sharing between tasks in Kedro pipelines using our
+`vineyard-kedro `_ plugin, when data
+scales and the pipeline are deployed on Kubernetes.
+
+.. note::
+
+ This tutorial is based on the `Developing and Learning MLOps at Home `_ project,
+ a tutorial about orchestrating a machine learning pipeline with Kedro.
+
+Prepare the Kubernetes cluster
+------------------------------
+
+To deploy Kedro pipelines on Kubernetes, you must have a kubernetes cluster.
+
+.. tip::
+
+ If you already have a K8s cluster, just skip this section and continue
+ on deploying.
+
+We recommend `kind v0.20.0 `_ to create a multi-node
+Kubernetes cluster on your local machine as follows:
+
+.. code:: bash
+
+ $ cat <
+
+ - If you are working with Minio, you first need to expose the services
+ and then create the bucket:
+
+ - Forward minio-artifacts service:
+
+ .. code:: bash
+
+ $ kubectl port-forward service/minio -n minio-dev 9000:9000
+
+ - Install the minio client:
+
+ .. code:: bash
+
+ $ wget https://dl.min.io/client/mc/release/linux-amd64/mc
+ $ chmod +x mc
+ $ sudo mv mc /usr/local/bin
+
+ - Configure the minio client:
+
+ .. code:: bash
+
+ $ mc alias set minio http://localhost:9000
+ Enter Access Key:
+ Enter Secret Key:
+
+ - Finally, create the bucket :code:`minio-s3-benchmark-bucket`:
+
+ .. code:: bash
+
+ $ mc mb minio/minio-s3-benchmark-bucket
+ Bucket created successfully `minio/minio-s3-benchmark-bucket`.
+
+Prepare the Docker images
+-------------------------
+
+1. Vineyard has delivered `a benchmark project `_
+ to test Kedro pipelines on Vineyard and S3:
+
+ .. code:: bash
+
+ $ cd python/vineyard/contrib/kedro/benchmark/mlops
+
+2. Configure the credentials configurations of AWS S3:
+
+ .. code:: bash
+
+ $ cat conf/aws-s3/credentials.yml
+ benchmark_aws_s3:
+ client_kwargs:
+ aws_access_key_id: Your AWS/Minio Access Key ID
+ aws_secret_access_key: Your AWS/Minio Secret Access Key
+ region_name: Your AWS Region Name
+
+3. To deploy pipelines to Kubernetes, you first need to build the Docker image for the
+ benchmark project.
+
+ To show how vineyard can accelerate the data sharing along with the dataset
+ scales, Docker images for different data size will be generated:
+
+ - For running Kedro on vineyard:
+
+ .. code:: bash
+
+ $ make docker-build
+
+ You will see Docker images for different data size are generated:
+
+ .. code:: bash
+
+ $ docker images | grep mlops
+ mlops-benchmark latest fceaeb5a6688 17 seconds ago 1.07GB
+
+4. To make those images available for your Kubernetes cluster, they need to be
+ pushed to your registry (or load to kind cluster if you setup your Kubernetes
+ cluster using kind):
+
+ - Push to registry:
+
+ .. code:: bash
+
+ $ docker tag mlops-benchmark:latest /mlops-benchmark:latest
+ $ docker push /mlops-benchmark:latest
+
+ - Load to kind cluster:
+
+ .. code:: bash
+
+ $ kind load docker-image mlops-benchmark:latest
+
+Deploy the Kedro Pipelines
+--------------------------
+
+1. Deploy the Kedro pipeline with vineyard for intermediate data sharing:
+
+ .. code:: bash
+
+ $ kubectl create namespace vineyard
+ $ for multiplier in 1 10 100 500; do \
+ argo submit -n vineyard --watch argo-vineyard-benchmark.yml -p multiplier=${multiplier}; \
+ done
+
+2. Similarly, using AWS S3 or Minio for intermediate data sharing:
+
+ - Using AWS S3:
+
+ .. code:: bash
+
+ $ kubectl create namespace aws-s3
+ # create the aws secrets from your ENV
+ $ kubectl create secret generic aws-secrets -n aws-s3 \
+ --from-literal=access_key_id=$AWS_ACCESS_KEY_ID \
+ --from-literal=secret_access_key=$AWS_SECRET_ACCESS_KEY
+ $ for multiplier in 1 10 100 500 1000 2000; do \
+ argo submit -n aws-s3 --watch argo-aws-s3-benchmark.yml -p multiplier=${multiplier}; \
+ done
+
+ - Using `Cloudpickle dataset `_:
+
+ .. code:: bash
+
+ $ kubectl create namespace cloudpickle
+ # create the aws secrets from your ENV
+ $ kubectl create secret generic aws-secrets -n cloudpickle \
+ --from-literal=access_key_id=$AWS_ACCESS_KEY_ID \
+ --from-literal=secret_access_key=$AWS_SECRET_ACCESS_KEY
+ $ for multiplier in 1 10 100 500 1000 2000; do \
+ argo submit -n cloudpickle --watch argo-cloudpickle-benchmark.yml -p multiplier=${multiplier}; \
+ done
+
+ - Using Minio:
+
+ .. code:: bash
+
+ $ kubectl create namespace minio-s3
+ $ for multiplier in 1 10 100 500 1000 2000; do \
+ argo submit -n minio-s3 --watch argo-minio-s3-benchmark.yml -p multiplier=${multiplier}; \
+ done
+
+Performance
+-----------
+
+After running the benchmark above on Kubernetes, we recorded each node's execution time from the logs
+of the argo workflow and calculated the sum of all nodes as the following end-to-end execution time
+for each data scale:
+
+========== ========= ======== ============== =========
+Data Scale Vineyard Minio S3 Cloudpickle S3 AWS S3
+========== ========= ======== ============== =========
+1 4.2s 4.3s 22.5s 16.9s
+10 4.9s 5.5s 28.6s 23.3s
+100 13.2s 20.3s 64.4s 74s
+500 53.6s 84.5s 173.2s 267.9s
+1000 109.8s 164.2s 322.7s 510.6s
+2000 231.6s 335.9s 632.8s 1069.7s
+========== ========= ======== ============== =========
+
+We have the following observations from above comparison:
+
+- Vineyard can significantly accelerate the data sharing between tasks in Kedro pipelines, without the
+ need for any intrusive changes to the original Kedro pipelines;
+- When data scales, the performance of Vineyard is more impressive, as the intermediate data sharing
+ cost becomes more dominant in end-to-end execution;
+- Even compared with local Minio, Vineyard still outperforms it by a large margin, thanks to the ability
+ of Vineyard to avoid (de)serialization, file I/O and excessive memory copies.
+- When using the Cloudpickle dataset(pickle + zstd), the performance is better than AWS S3, as the dataset
+ will be compressed before uploading to S3.
diff --git a/_sources/tutorials/data-processing/distributed-learning.ipynb.txt b/_sources/tutorials/data-processing/distributed-learning.ipynb.txt
new file mode 100644
index 0000000000..dd6c41a750
--- /dev/null
+++ b/_sources/tutorials/data-processing/distributed-learning.ipynb.txt
@@ -0,0 +1,536 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Distributed Learning with Vineyard\n",
+ "==================================\n",
+ "\n",
+ "With the growth of data, distributed learning is becoming a must in real-world machine learning\n",
+ "applications, as the data size can easily exceed the memory limit of a single machine.\n",
+ "Thus, many distributed systems addressing different workloads are developed\n",
+ "and they share the same objective of extending users' single machine prototypes \n",
+ "to distributed settings with as few modifications to the code as possible.\n",
+ "\n",
+ "For example, **dask.dataframe** mimics the API of **pandas** which is the de-facto standard\n",
+ "library for single-machine structured data processing, so that users can apply their\n",
+ "pandas code for data preprocessing in the dask cluster with few modifications.\n",
+ "Similarly, **horovod** provides easy-to-use APIs for users to transfer their single-machine\n",
+ "code in machine learning frameworks (e.g., TensorFlow, PyTorch, MXNet) to the distributed settings\n",
+ "with only a few additional lines of code.\n",
+ "\n",
+ "However, when extending to distributed learning, the data sharing between libraries within the same\n",
+ "python process (e.g., pandas and tensorflow) becomes inter-process sharing between engines (e.g.,\n",
+ "dask and horovod), not to mention in the distributed fashion. Existing solutions using external\n",
+ "distributed file systems are less than optimal for the huge I/O overheads.\n",
+ "\n",
+ "Vineyard shares the same design principle with the aforementioned distributed systems, which aims to\n",
+ "provide efficient cross-engine data sharing with few modifications to the existing code.\n",
+ "Next, we demonstrate how to transfer a single-machine learning example in **keras** to\n",
+ "distributed learning with dask, horovod and Vineyard.\n",
+ "\n",
+ "An Example from Keras\n",
+ "---------------------\n",
+ "\n",
+ "This [example](https://keras.io/examples/structured_data/wide_deep_cross_networks/)\n",
+ "uses the Covertype dataset from the UCI Machine Learning Repository.\n",
+ "The task is to predict forest cover type from cartographic variables.\n",
+ "The dataset includes 506,011 instances with 12 input features:\n",
+ "10 numerical features and 2 categorical features.\n",
+ "Each instance is categorized into 1 of 7 classes.\n",
+ "\n",
+ "The solution contains three steps:\n",
+ "\n",
+ "1. preprocess the data in pandas to extract the 12 features and the label\n",
+ "2. store the preprocessed data in files\n",
+ "3. define and train the model in keras\n",
+ "\n",
+ "\n",
+ "Mapping the solution to distributed learning, we have:\n",
+ "\n",
+ "1. preprocess the data in dask.dataframe\n",
+ "2. share the preprocessed data using Vineyard\n",
+ "3. train the model in horovod.keras\n",
+ "\n",
+ "\n",
+ "We will walk through the code as follows.\n",
+ "\n",
+ "Setup\n",
+ "-------\n",
+ "\n",
+ "The distributed deployment of vineyard and dask is as follows: on each machine, we launch a vineyard daemon process to handle the local data storage on that machine; and we also launch a dask worker on that machine for the computation accordingly. In this notebook, we limit the machine number as 1 (i.e., the local machine) just for demonstration."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "import vineyard\n",
+ "import subprocess as sp\n",
+ "\n",
+ "# launch local vineyardd\n",
+ "client = vineyard.connect()\n",
+ "\n",
+ "# launch dask scheduler and worker\n",
+ "dask_scheduler = sp.Popen(['dask-scheduler', '--host', 'localhost'])\n",
+ "dask_worker = sp.Popen(['dask-worker', 'tcp://localhost:8786'])"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Preprocessing the data\n",
+ "----------------------\n",
+ "\n",
+ "To read the data, we replace\n",
+ "**pd.read_csv** by **dd.read_csv**, which will automatically\n",
+ "read the data in parallel."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "import dask.dataframe as dd\n",
+ "raw_data = dd.read_csv('covtype.data', header=None)"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Then we preprocess the data using the same code from the example,\n",
+ "except the replacement of **pd.concat** to **dd.concat** only."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "\"\"\"\n",
+ "The two categorical features in the dataset are binary-encoded.\n",
+ "We will convert this dataset representation to the typical representation, where each\n",
+ "categorical feature is represented as a single integer value.\n",
+ "\"\"\"\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')\n",
+ "\n",
+ "soil_type_values = [f\"soil_type_{idx+1}\" for idx in range(40)]\n",
+ "wilderness_area_values = [f\"area_type_{idx+1}\" for idx in range(4)]\n",
+ "\n",
+ "soil_type = raw_data.loc[:, 14:53].apply(\n",
+ " lambda x: soil_type_values[0::1][x.to_numpy().nonzero()[0][0]], axis=1\n",
+ ")\n",
+ "wilderness_area = raw_data.loc[:, 10:13].apply(\n",
+ " lambda x: wilderness_area_values[0::1][x.to_numpy().nonzero()[0][0]], axis=1\n",
+ ")\n",
+ "\n",
+ "CSV_HEADER = [\n",
+ " \"Elevation\",\n",
+ " \"Aspect\",\n",
+ " \"Slope\",\n",
+ " \"Horizontal_Distance_To_Hydrology\",\n",
+ " \"Vertical_Distance_To_Hydrology\",\n",
+ " \"Horizontal_Distance_To_Roadways\",\n",
+ " \"Hillshade_9am\",\n",
+ " \"Hillshade_Noon\",\n",
+ " \"Hillshade_3pm\",\n",
+ " \"Horizontal_Distance_To_Fire_Points\",\n",
+ " \"Wilderness_Area\",\n",
+ " \"Soil_Type\",\n",
+ " \"Cover_Type\",\n",
+ "]\n",
+ "\n",
+ "data = dd.concat(\n",
+ " [raw_data.loc[:, 0:9], wilderness_area, soil_type, raw_data.loc[:, 54]],\n",
+ " axis=1,\n",
+ " ignore_index=True,\n",
+ ")\n",
+ "data.columns = CSV_HEADER\n",
+ "\n",
+ "# Convert the target label indices into a range from 0 to 6 (there are 7 labels in total).\n",
+ "data[\"Cover_Type\"] = data[\"Cover_Type\"] - 1"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Finally, instead of saving the preprocessed data into files, we store them in Vineyard.\n"
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "import vineyard\n",
+ "from vineyard.core.builder import builder_context\n",
+ "from vineyard.contrib.dask.dask import register_dask_types\n",
+ "\n",
+ "with builder_context() as builder:\n",
+ " register_dask_types(builder, None) # register dask builders\n",
+ " gdf_id = client.put(data, dask_scheduler='tcp://localhost:8786')\n",
+ " print(gdf_id)"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "We saved the preprocessed data as a global dataframe\n",
+ "in Vineyard with the ObjectID above."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Training the model\n",
+ "------------------\n",
+ "\n",
+ "In the single machine solution from the example. A **get_dataset_from_csv** function \n",
+ "is defined to load the dataset from the files of the preprocessed data as follows:\n",
+ "```python\n",
+ "def get_dataset_from_csv(csv_file_path, batch_size, shuffle=False):\n",
+ "\n",
+ " dataset = tf.data.experimental.make_csv_dataset(\n",
+ " csv_file_path,\n",
+ " batch_size=batch_size,\n",
+ " column_names=CSV_HEADER,\n",
+ " column_defaults=COLUMN_DEFAULTS,\n",
+ " label_name=TARGET_FEATURE_NAME,\n",
+ " num_epochs=1,\n",
+ " header=True,\n",
+ " shuffle=shuffle,\n",
+ " )\n",
+ " return dataset.cache()\n",
+ "```\n",
+ "while in the training procedure, it loads the train_dataset and test_dataset\n",
+ "separately from two files as:\n",
+ "```python\n",
+ "def run_experiment(model):\n",
+ "\n",
+ " model.compile(\n",
+ " optimizer=keras.optimizers.Adam(learning_rate=learning_rate),\n",
+ " loss=keras.losses.SparseCategoricalCrossentropy(),\n",
+ " metrics=[keras.metrics.SparseCategoricalAccuracy()],\n",
+ " )\n",
+ "\n",
+ " train_dataset = get_dataset_from_csv(train_data_file, batch_size, shuffle=True)\n",
+ "\n",
+ " test_dataset = get_dataset_from_csv(test_data_file, batch_size)\n",
+ "\n",
+ " print(\"Start training the model...\")\n",
+ " history = model.fit(train_dataset, epochs=num_epochs)\n",
+ " print(\"Model training finished\")\n",
+ "\n",
+ " _, accuracy = model.evaluate(test_dataset, verbose=0)\n",
+ "\n",
+ " print(f\"Test accuracy: {round(accuracy * 100, 2)}%\")\n",
+ "```\n",
+ "In our solution, we provide a function to load dataset from the global dataframe\n",
+ "generated in the last step."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "from vineyard.core.resolver import resolver_context\n",
+ "from vineyard.contrib.ml.tensorflow import register_tf_types\n",
+ "\n",
+ "def get_dataset_from_vineyard(object_id, batch_size, shuffle=False):\n",
+ " with resolver_context() as resolver:\n",
+ " register_tf_types(None, resolver) # register tf resolvers\n",
+ " ds = vineyard.connect().get(object_id, label=TARGET_FEATURE_NAME) # specify the label column\n",
+ "\n",
+ " if shuffle:\n",
+ " ds = ds.shuffle(len(ds))\n",
+ "\n",
+ " len_test = int(len(ds) * 0.15)\n",
+ " test_dataset = ds.take(len_test).batch(batch_size)\n",
+ " train_dataset = ds.skip(len_test).batch(batch_size)\n",
+ "\n",
+ " return train_dataset, test_dataset"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "And modify the training procedure with a few lines of horovod code."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "import horovod.keras as hvd\n",
+ "\n",
+ "def run_experiment(model):\n",
+ "\n",
+ " hvd.init()\n",
+ "\n",
+ " model.compile(\n",
+ " optimizer=hvd.DistributedOptimizer(keras.optimizers.Adam(learning_rate=learning_rate)),\n",
+ " loss=keras.losses.SparseCategoricalCrossentropy(),\n",
+ " metrics=[keras.metrics.SparseCategoricalAccuracy()],\n",
+ " )\n",
+ "\n",
+ " callbacks = [\n",
+ " # Horovod: broadcast initial variable states from rank 0 to all other processes.\n",
+ " # This is necessary to ensure consistent initialization of all workers when\n",
+ " # training is started with random weights or restored from a checkpoint.\n",
+ " hvd.callbacks.BroadcastGlobalVariablesCallback(0),\n",
+ " ]\n",
+ "\n",
+ " train_dataset, test_dataset = get_dataset_from_vineyard(gdf_id, batch_size, shuffle=True)\n",
+ "\n",
+ " print(\"Start training the model...\")\n",
+ " history = model.fit(train_dataset, epochs=num_epochs, callbacks=callbacks)\n",
+ " print(\"Model training finished\")\n",
+ "\n",
+ " _, accuracy = model.evaluate(test_dataset, verbose=0)\n",
+ "\n",
+ " print(f\"Test accuracy: {round(accuracy * 100, 2)}%\")"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "All the other parts of training procedure are the same as the single machine solution."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "TARGET_FEATURE_NAME = \"Cover_Type\"\n",
+ "\n",
+ "TARGET_FEATURE_LABELS = [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]\n",
+ "\n",
+ "NUMERIC_FEATURE_NAMES = [\n",
+ " \"Aspect\",\n",
+ " \"Elevation\",\n",
+ " \"Hillshade_3pm\",\n",
+ " \"Hillshade_9am\",\n",
+ " \"Hillshade_Noon\",\n",
+ " \"Horizontal_Distance_To_Fire_Points\",\n",
+ " \"Horizontal_Distance_To_Hydrology\",\n",
+ " \"Horizontal_Distance_To_Roadways\",\n",
+ " \"Slope\",\n",
+ " \"Vertical_Distance_To_Hydrology\",\n",
+ "]\n",
+ "\n",
+ "CATEGORICAL_FEATURES_WITH_VOCABULARY = {\n",
+ " \"Soil_Type\": soil_type_values,\n",
+ " \"Wilderness_Area\": wilderness_area_values,\n",
+ "}\n",
+ "\n",
+ "CATEGORICAL_FEATURE_NAMES = list(CATEGORICAL_FEATURES_WITH_VOCABULARY.keys())\n",
+ "\n",
+ "FEATURE_NAMES = NUMERIC_FEATURE_NAMES + CATEGORICAL_FEATURE_NAMES\n",
+ "\n",
+ "NUM_CLASSES = len(TARGET_FEATURE_LABELS)\n",
+ "\n",
+ "learning_rate = 0.001\n",
+ "dropout_rate = 0.1\n",
+ "batch_size = 265\n",
+ "num_epochs = 5\n",
+ "\n",
+ "hidden_units = [32, 32]\n",
+ "\n",
+ "\"\"\"\n",
+ "## Create model inputs\n",
+ "Now, define the inputs for the models as a dictionary, where the key is the feature name,\n",
+ "and the value is a `keras.layers.Input` tensor with the corresponding feature shape\n",
+ "and data type.\n",
+ "\"\"\"\n",
+ "import tensorflow as tf\n",
+ "\n",
+ "def create_model_inputs():\n",
+ " inputs = {}\n",
+ " for feature_name in FEATURE_NAMES:\n",
+ " if feature_name in NUMERIC_FEATURE_NAMES:\n",
+ " inputs[feature_name] = layers.Input(\n",
+ " name=feature_name, shape=(), dtype=tf.float32\n",
+ " )\n",
+ " else:\n",
+ " inputs[feature_name] = layers.Input(\n",
+ " name=feature_name, shape=(), dtype=tf.string\n",
+ " )\n",
+ " return inputs\n",
+ "\n",
+ "\n",
+ "\"\"\"\n",
+ "## Encode features\n",
+ "We create two representations of our input features: sparse and dense:\n",
+ "1. In the **sparse** representation, the categorical features are encoded with one-hot\n",
+ "encoding using the `CategoryEncoding` layer. This representation can be useful for the\n",
+ "model to *memorize* particular feature values to make certain predictions.\n",
+ "2. In the **dense** representation, the categorical features are encoded with\n",
+ "low-dimensional embeddings using the `Embedding` layer. This representation helps\n",
+ "the model to *generalize* well to unseen feature combinations.\n",
+ "\"\"\"\n",
+ "\n",
+ "\n",
+ "from tensorflow.keras.layers import StringLookup\n",
+ "\n",
+ "\n",
+ "def encode_inputs(inputs, use_embedding=False):\n",
+ " encoded_features = []\n",
+ " for feature_name in inputs:\n",
+ " if feature_name in CATEGORICAL_FEATURE_NAMES:\n",
+ " vocabulary = CATEGORICAL_FEATURES_WITH_VOCABULARY[feature_name]\n",
+ " # Create a lookup to convert string values to an integer indices.\n",
+ " # Since we are not using a mask token nor expecting any out of vocabulary\n",
+ " # (oov) token, we set mask_token to None and num_oov_indices to 0.\n",
+ " lookup = StringLookup(\n",
+ " vocabulary=vocabulary,\n",
+ " mask_token=None,\n",
+ " num_oov_indices=0,\n",
+ " output_mode=\"int\" if use_embedding else \"binary\",\n",
+ " )\n",
+ " if use_embedding:\n",
+ " # Convert the string input values into integer indices.\n",
+ " encoded_feature = lookup(inputs[feature_name])\n",
+ " embedding_dims = int(math.sqrt(len(vocabulary)))\n",
+ " # Create an embedding layer with the specified dimensions.\n",
+ " embedding = layers.Embedding(\n",
+ " input_dim=len(vocabulary), output_dim=embedding_dims\n",
+ " )\n",
+ " # Convert the index values to embedding representations.\n",
+ " encoded_feature = embedding(encoded_feature)\n",
+ " else:\n",
+ " # Convert the string input values into a one hot encoding.\n",
+ " encoded_feature = lookup(tf.expand_dims(inputs[feature_name], -1))\n",
+ " else:\n",
+ " # Use the numerical features as-is.\n",
+ " encoded_feature = tf.expand_dims(inputs[feature_name], -1)\n",
+ "\n",
+ " encoded_features.append(encoded_feature)\n",
+ "\n",
+ " all_features = layers.concatenate(encoded_features)\n",
+ " return all_features\n",
+ "\n",
+ "\n",
+ "\"\"\"\n",
+ "## Experiment 1: a baseline model\n",
+ "In the first experiment, let's create a multi-layer feed-forward network,\n",
+ "where the categorical features are one-hot encoded.\n",
+ "\"\"\"\n",
+ "from tensorflow import keras\n",
+ "from tensorflow.keras import layers\n",
+ "\n",
+ "def create_baseline_model():\n",
+ " inputs = create_model_inputs()\n",
+ " features = encode_inputs(inputs)\n",
+ "\n",
+ " for units in hidden_units:\n",
+ " features = layers.Dense(units)(features)\n",
+ " features = layers.BatchNormalization()(features)\n",
+ " features = layers.ReLU()(features)\n",
+ " features = layers.Dropout(dropout_rate)(features)\n",
+ "\n",
+ " outputs = layers.Dense(units=NUM_CLASSES, activation=\"softmax\")(features)\n",
+ " model = keras.Model(inputs=inputs, outputs=outputs)\n",
+ " return model\n",
+ "\n",
+ "\n",
+ "baseline_model = create_baseline_model()"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Let's run it:"
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "run_experiment(baseline_model)"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "We clear the environments in the end."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "source": [
+ "dask_worker.terminate()\n",
+ "dask_scheduler.terminate()\n",
+ "\n",
+ "vineyard.shutdown()"
+ ],
+ "outputs": [],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Finally, we can use **horovodrun** to run the above code distributedly in a cluster for distributed learning on big datasets."
+ ],
+ "metadata": {}
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "Conclusion\n",
+ "----------\n",
+ "\n",
+ "From this example, we can see that with the help of Vineyard, users can easily extend\n",
+ "their single machine solutions to distributed learning using dedicated systems without\n",
+ "worrying about the cross-system data sharing issues."
+ ],
+ "metadata": {}
+ }
+ ],
+ "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.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/_sources/tutorials/data-processing/gpu-memory-sharing.rst.txt b/_sources/tutorials/data-processing/gpu-memory-sharing.rst.txt
new file mode 100644
index 0000000000..39ed8e06d9
--- /dev/null
+++ b/_sources/tutorials/data-processing/gpu-memory-sharing.rst.txt
@@ -0,0 +1,113 @@
+.. _gpu-memory-sharing:
+
+Sharing GPU Memory
+------------------
+
+Vineyard supports sharing both CPU memory and GPU memory between different
+processes and different compute engines. The sharing of GPU memory is archived
+by using the `CUDA IPC mechanism `_
+and provides a flexible unified memory interfaces.
+
+CUDA IPC and Unified Memory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The CUDA IPC memory handle allows GPU memory to be shared between different
+processes via IPC. In vineyard, the GPU memory is allocated by the vineyardd
+instance when :code:`CreateGPUBuffer()`, then an IPC handle is transferred to the
+client process and the GPU memory can be accessed by the client process after
+calling :code:`cudaIpcOpenMemHandle()`. For readers, the GPU memory can be accessed
+like a normal CPU shared memory object with :code:`GetGPUBuffers()`.
+
+Like `CUDA unified memory `_,
+vineyard's provides a unified memory interface which can be adapted to different
+kinds of implementation (GPU, PPU, etc.) as the abstraction to share GPU memory
+between different processes, as well as sharing memory between the host and
+device.
+
+The unified memory abstraction is able to automatically synchronize the memory
+between host and devices by leverage the RAII mechanism of C++.
+
+Example
+~~~~~~~
+
+.. note::
+
+ The GPU shared memory is still under development and the APIs may change in
+ the future.
+
+- Creating a GPU buffer:
+
+ .. code:: c++
+
+ ObjectID object_id;
+ Payload object;
+ std::shared_ptr buffer = nullptr;
+ RETURN_ON_ERROR(client.CreateGPUBuffer(data_size(), object_id, object, buffer));
+
+ CHECK(!buffer->is_cpu());
+ CHECK(buffer->is_mutable());
+
+ The result buffer's data :code:`buffer->mutable_data()` is a GPU memory pointer,
+ which can be directly passed to GPU kernels, e.g.,
+
+ .. code:: c++
+
+ printKernel<<<1, 1>>>(buffer->data());
+
+- Composing the buffer content from host code like Unified Memory:
+
+ .. code:: c++
+
+ {
+ CUDABufferMirror mirror(*buffer, false);
+ memcpy(mirror.mutable_data(), "hello world", 12);
+ }
+
+ Here the :code:`mirror`'s :code:`data()` and :code:`mutable_data()` are host memory pointers
+ allocated using the :code:`cudaHostAlloc()` API. When :code:`CUDABufferMirror` destructing,
+ the host memory will be copied back to the GPU memory automatically.
+
+ The second argument of :code:`CUDABufferMirror` indicates whether the initial memory of the
+ GPU buffer needs to be copied to the host memory. Defaults to :code:`false`.
+
+- Accessing the GPU buffer from another process:
+
+ .. code:: c++
+
+ ObjectID object_id = ...;
+ std::shared_ptr buffer = nullptr;
+ RETURN_ON_ERROR(client.GetGPUBuffer(object_id, true, buffer));
+ CHECK(!buffer->is_cpu());
+ CHECK(!buffer->is_mutable());
+
+ The result buffer's data :code:`buffer->data()` is a GPU memory pointer, which can be directly
+ passed to GPU kernels, e.g.,
+
+ .. code:: c++
+
+ printKernel<<<1, 1>>>(buffer->data());
+
+- Accessing the shared GPU buffer from CPU:
+
+ .. code:: c++
+
+ {
+ CUDABufferMirror mirror(*buffer, true);
+ printf("CPU data from GPU is: %s\n",
+ reinterpret_cast(mirror.data()));
+ }
+
+ Using the :code:`CUDABufferMirror` to access the GPU buffer from CPU, the mirror's :code:`data()`
+ is a host memory pointer allocated using the :code:`cudaHostAlloc()` API. For immutable :code:`Buffer`,
+ the second argument of :code:`CUDABufferMirror` must be :code:`true`, and the GPU memory will be
+ copied to the host memory when the mirror is constructed.
+
+- Freeing the shared GPU buffer:
+
+ .. code:: c++
+
+ ObjectID object_id = ...;
+ RETURN_ON_ERROR(client.DelData(object_id));
+
+For complete example about GPU memory sharing, please refer to
+`gpumalloc_test.cu `_
diff --git a/_sources/tutorials/data-processing/python-sharedmemory.rst.txt b/_sources/tutorials/data-processing/python-sharedmemory.rst.txt
new file mode 100644
index 0000000000..4ff434e3c7
--- /dev/null
+++ b/_sources/tutorials/data-processing/python-sharedmemory.rst.txt
@@ -0,0 +1,42 @@
+:code:`multiprocessing.shared_memory` in Python
+===============================================
+
+Vineyard offers a shared memory interface through :class:`SharedMemory` and
+:class:`ShareableList` classes, ensuring compatibility with Python's `multiprocessing.shared_memory`_.
+
+Utilize the shared memory interface as demonstrated below:
+
+.. code:: python
+
+ >>> from vineyard import shared_memory
+ >>> value = shared_memory.ShareableList(client, [b"a", "bb", 1234, 56.78, True])
+ >>> value
+ ShareableList([b'a', 'bb', 1234, 56.78, True], name='o8000000119aa10c0')
+ >>> value[4] = False
+ >>> value
+ ShareableList([b'a', 'bb', 1234, 56.78, False], name='o8000000119aa10c0')
+
+.. caution::
+
+ Please be aware that the semantics of Vineyard's :code:`shared_memory` differ slightly
+ from those of Python's multiprocessing module's :code:`shared_memory`. In Vineyard,
+ shared memory cannot be modified once it becomes visible to other clients.
+
+We have added a :code:`freeze` method to make such transformation happen:
+
+.. code:: python
+
+ >>> value.freeze()
+
+After being frozen, the shared memory (aka. the :code:`ShareableList` in this case)
+is available for other clients:
+
+.. code:: python
+
+ >>> value1 = shared_memory.ShareableList(client, name=value.shm.name)
+ >>> value1
+ ShareableList([b'a', 'bb', 1234, 56.78, False], name='o8000000119aa10c0')
+
+For more details, see :ref:`shared-memory`.
+
+.. _multiprocessing.shared_memory: https://docs.python.org/3/library/multiprocessing.shared_memory.html
diff --git a/_sources/tutorials/data-processing/using-objects-python.rst.txt b/_sources/tutorials/data-processing/using-objects-python.rst.txt
new file mode 100644
index 0000000000..4b41e053f1
--- /dev/null
+++ b/_sources/tutorials/data-processing/using-objects-python.rst.txt
@@ -0,0 +1,87 @@
+.. _using-objects-python:
+
+Sharing Python Objects with Vineyard
+------------------------------------
+
+As discussed in :ref:`vineyard-objects`, each object in Vineyard consists of two parts:
+
+1. The data payload, which is stored locally in the corresponding Vineyard instance
+2. The hierarchical metadata, which is shared across the entire Vineyard cluster
+
+Specifically, a ``Blob`` represents the unit where the data payload resides within a
+Vineyard instance. A blob object holds a segment of memory in the bulk store of the
+Vineyard instance, allowing users to save their local buffer into a blob and later
+retrieve the blob in another process using a zero-copy approach through memory mapping.
+
+.. code:: python
+
+ >>> payload = b"Hello, World!"
+ >>> blob_id = client.put(payload)
+ >>> blob = client.get_object(blob_id)
+ >>> print(blob.typename, blob.size, blob)
+
+.. code:: console
+
+ vineyard::Blob 28 Object <"o800000011cfa7040": vineyard::Blob>
+
+On the other hand, the hierarchical metadata of Vineyard objects is shared across
+the entire cluster. In the following example, for the sake of simplicity, we
+launch a Vineyard cluster consisting of two Vineyard instances on the same machine.
+However, in real-world scenarios, these Vineyard instances would be distributed
+across multiple machines within the cluster.
+
+.. code:: console
+
+ $ python3 -m vineyard --socket /var/run/vineyard.sock1
+ $ python3 -m vineyard --socket /var/run/vineyard.sock2
+
+With this setup, we can create a distributed pair of arrays in Vineyard, where
+the first array is stored in the first Vineyard instance listening to the IPC socket
+``/var/run/vineyard.sock1``, and the second array is stored in the second instance
+listening to the IPC socket ``/var/run/vineyard.sock2``.
+
+.. code:: python
+
+ >>> import numpy as np
+ >>> import vineyard
+ >>> import vineyard.data.tensor
+
+ >>> # build the first array in the first vineyard instance
+ >>> client1 = vineyard.connect('/var/run/vineyard.sock1')
+ >>> id1 = client1.put(np.zeros(8))
+ >>> # persist the object to make it visible to form the global object
+ >>> client1.persist(id1)
+
+ >>> # build the second array in the second vineyard instance
+ >>> client2 = vineyard.connect('/var/run/vineyard.sock2')
+ >>> id2 = client2.put(np.ones(4))
+ >>> # persist the object to make it visible to form the global object
+ >>> client2.persist(id2)
+
+ >>> # build the pair from client1
+ >>> obj1 = client1.get_object(id1)
+ >>> obj2 = client2.get_object(id2)
+ >>> id_pair = client1.put((obj1, obj2))
+
+ >>> # get the pair object from client2
+ >>> obj_pair = client2.get_object(id_pair)
+ >>> print(obj_pair.first.typename, obj_pair.first.size(), obj_pair.second.size())
+
+.. code:: console
+
+ vineyard::Array 8 4
+
+.. code:: console
+
+ >>> # get the pair value from client2
+ >>> value_pair = client2.get(id_pair)
+ >>> print(value_pair)
+
+.. code:: console
+
+ (None, [1, 1, 1, 1])
+
+In this example, we can access the metadata of the pair object from ``client2``
+even though it was created by ``client1``. However, we cannot retrieve the payload
+of the first element of the pair from ``client2`` because it is stored locally
+in the first Vineyard instance.
diff --git a/_sources/tutorials/extending.rst.txt b/_sources/tutorials/extending.rst.txt
new file mode 100644
index 0000000000..4eab2b7188
--- /dev/null
+++ b/_sources/tutorials/extending.rst.txt
@@ -0,0 +1,37 @@
+
+Extending vineyard
+==================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ ./extending/define-datatypes-python.rst
+ ./extending/define-datatypes-cpp.rst
+
+Vineyard offers a collection of efficient data structures tailored for data-intensive tasks,
+such as tensors, data frames, tables, and graphs. These data types can be easily extended
+to accommodate custom requirements. By registering user-defined types in the vineyard type
+registry, computing engines built on top of vineyard can instantly leverage the advantages
+provided by these custom data structures.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: ./extending/define-datatypes-python
+ :type: ref
+ :text: Define Python Types
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Craft builders and resolvers for custom Python data types.
+
+ ---
+
+ .. link-button:: ./extending/define-datatypes-cpp
+ :type: ref
+ :text: Define C++ Types
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Implement and register custom data types in C++ for seamless integration with vineyard's ecosystem.
diff --git a/_sources/tutorials/extending/define-datatypes-cpp.rst.txt b/_sources/tutorials/extending/define-datatypes-cpp.rst.txt
new file mode 100644
index 0000000000..2d2b0b1aa6
--- /dev/null
+++ b/_sources/tutorials/extending/define-datatypes-cpp.rst.txt
@@ -0,0 +1,312 @@
+.. _define-cpp-types:
+
+Defining Custom Data Types in C++
+=================================
+
+Vineyard provides an extensive set of efficient built-in data types in
+its C++ SDK, such as :code:`Vector`, :code:`HashMap`, :code:`Tensor`,
+:code:`DataFrame`, :code:`Table`, and :code:`Graph` (refer to :ref:`cpp-api`).
+However, there may be situations where users need to develop their
+own data structures and share the data efficiently with Vineyard. This
+step-by-step tutorial guides you through the process of adding custom
+C++ data types with ease.
+
+.. note::
+
+ This tutorial includes code snippets that could be auto-generated to
+ provide a clear understanding of the design internals and to help
+ developers grasp the overall functionality of the Vineyard client.
+
+``Object`` and ``ObjectBuilder``
+--------------------------------
+
+Vineyard has a base class :code:`vineyard::Objects`, and a corresponding
+base class :code:`Vineyard::ObjectBuilder` for builders as follows,
+
+.. code:: cpp
+
+ class Object {
+ public:
+ static std::unique_ptr Create() {
+ ...
+ }
+
+ virtual void Construct(const ObjectMeta& meta);
+ }
+
+and the builder
+
+.. code:: cpp
+
+ class ObjectBuilder {
+ virtual Status Build(Client& client) override = 0;
+
+ virtual std::shared_ptr _Seal(Client& client) = 0;
+ }
+
+Where the object is the base class for user-defined data types, and the
+builders is responsible for placing the data into vineyard.
+
+Defining Your Custom Type
+-------------------------
+
+Let's take the example of defining a custom `Vector` type. Essentially,
+a `Vector` consists of a `vineyard::Blob` as its payload, along with
+metadata such as `dtype` and `size`.
+
+The class definition for the `Vector` type typically appears as follows:
+
+.. code:: cpp
+
+ template
+ class Vector {
+ private:
+ size_t size;
+ const T *data = nullptr;
+ public:
+ Vector(): size(0), data(nullptr) {
+ }
+
+ Vector(const int size, const T *data): size(size), data(data) {
+ }
+
+ size_t length() const {
+ return size;
+ }
+
+ const T& operator[](size_t index) {
+ assert(index < size);
+ return data[index];
+ }
+ };
+
+Registering C++ Types
+---------------------
+
+First, we need to adapt the existing :code:`Vector` to become a Vineyard
+:code:`Object`,
+
+.. code:: diff
+
+ template
+ -class Vector {
+ +class Vector: public vineyard::Registered> {
+ private:
+ size_t size;
+ T *data = nullptr;
+ public:
+ + static std::unique_ptr Create() __attribute__((used)) {
+ + return std::static_pointer_cast(
+ + std::unique_ptr>{
+ + new Vector()});
+ + }
+ +
+ Vector(): size(0), data(nullptr) {
+ }
+
+ Vector(const int size, const T *data): size(size), data(data) {
+ }
+
+ ...
+ }
+
+Observe the two key modifications above:
+
++ Inheriting from :code:`vineyard::Registered>`:
+
+ :code:`vineyard::Registered` serves as a helper to generate static
+ initialization stubs, registering the data type :code:`T` with the type
+ resolving factory and associating the type :code:`T` with its typename.
+ The typename is an auto-generated, human-readable name for C++ types, e.g.,
+ :code:`"Vector"` for :code:`Vector`.
+
++ Implementing the zero-parameter static constructor :code:`Create()`:
+
+ :code:`Create()` is a static function registered with the
+ resolving factory by the helper :code:`vineyard::Registered`. It is
+ used to construct an instance of type :code:`T` when retrieving objects
+ from Vineyard.
+
+ The Vineyard client locates the static constructor using the :code:`typename`
+ found in the metadata of Vineyard objects stored in the daemon server.
+
+To retrieve the object :code:`Vector` from Vineyard's metadata, we need to
+implement a `Construct` method as well. The :code:`Construct` method takes
+a :code:`vineyard::ObjectMeta` as input and extracts metadata and
+members from it to populate its own data members. The memory in the member
+:code:`buffer` (a :code:`vineyard::Blob`) is shared using memory mapping,
+eliminating the need for copying.
+
+.. code:: diff
+
+ template
+ class Vector: public vineyard::Registered> {
+ public:
+ ...
+
+ + void Construct(const ObjectMeta& meta) override {
+ + this->size = meta.GetKeyValue("size");
+ +
+ + auto buffer = std::dynamic_pointer_cast(meta.GetMember("buffer"));
+ + this->data = reinterpret_cast(buffer->data());
+ + }
+ +
+ ...
+ }
+
+Builder
+-------
+
+Moving on to the builder section, the :code:`vineyard::ObjectBuilder` consists of two parts:
+
++ :code:`Build()`: This method is responsible for storing the blobs of custom data
+ structures into Vineyard.
+
++ :code:`_Seal()`: This method is responsible for generating the corresponding metadata
+ and inserting the metadata into Vineyard.
+
+For our :code:`Vector` type, let's first define a general vector builder:
+
+.. code:: cpp
+
+ template
+ class VectorBuilder {
+ private:
+ std::unique_ptr buffer_builder;
+ std::size_t size;
+ T *data;
+
+ public:
+ VectorBuilder(size_t size): size(size) {
+ data = static_cast(malloc(sizeof(T) * size));
+ }
+
+ T& operator[](size_t index) {
+ assert(index < size);
+ return data[index];
+ }
+ };
+
+The builder allocates the necessary memory based on the specified :code:`size` to accommodate
+the elements and provides a `[]` operator to populate the data.
+
+Next, we adapt the above builder as a `ObjectBuilder` in Vineyard,
+
+.. code:: diff
+
+ template
+ -class VectorBuilder {
+ +class VectorBuilder: public vineyard::ObjectBuilder {
+ private:
+ std::unique_ptr buffer_builder;
+ std::size_t size;
+ T *data;
+
+ public:
+ VectorBuilder(size_t size): size(size) {
+ data = static_cast(malloc(sizeof(T) * size));
+ }
+
+ + Status Build(Client& client) override {
+ + RETURN_ON_ERROR(client.CreateBlob(size * sizeof(T), buffer_builder));
+ + memcpy(buffer_builder->data(), data, size * sizeof(T));
+ + return Status::OK();
+ + }
+ +
+ + Status _Seal(Client& client, std::shared_ptr &object) override {
+ + RETURN_ON_ERROR(this->Build(client));
+ +
+ + auto vec = std::make_shared>();
+ object = vec;
+ + std::shared_ptr buffer_object;
+ + RETURN_ON_ERROR(this->buffer_builder->Seal(client, buffer_object));
+ + auto buffer = std::dynamic_pointer_cast(buffer_object);
+ + vec->size = size;
+ + vec->data = reinterpret_cast(buffer->data());
+ +
+ + vec->meta_.SetTypeName(vineyard::type_name>());
+ + vec->meta_.SetNBytes(size * sizeof(T));
+ + vec->meta_.AddKeyValue("size", size);
+ + vec->meta_.AddMember("buffer", buffer);
+ + return client.CreateMetaData(vec->meta_, vec->id_);
+ + }
+ +
+ T& operator[](size_t index) {
+ assert(index < size);
+ return data[index];
+ }
+ };
+
+To access private member fields and methods, the builder may need to be
+added as a friend class of the original type declaration.
+
+.. note::
+
+ Since the builder requires direct access to the private data members of
+ :code:`Vector`, it is necessary to declare the builder as a friend class
+ of our vector type,
+
+.. code:: diff
+
+ template
+ class Vector: public vineyard::Registered> {
+
+ const T& operator[](size_t index) {
+ assert(index < size);
+ return data[index];
+ }
+ +
+ + friend class VectorBuilder;
+ };
+
+In the example above, you may notice that the builder and constructor contain numerous
+boilerplate snippets. These can be auto-generated based on the layout of the class
+:code:`Vector` through static analysis of the user's source code, streamlining
+the process and enhancing readability.
+
+Utilizing Custom Data Types with Vineyard
+-----------------------------------------
+
+At this point, we have successfully defined our custom data types and integrated them
+with Vineyard. Now, we can demonstrate how to build these custom data types using the
+Vineyard client and retrieve them for further processing.
+
+.. code:: cpp
+
+ int main(int argc, char** argv) {
+ std::string ipc_socket = std::string(argv[1]);
+
+ Client client;
+ VINEYARD_CHECK_OK(client.Connect(ipc_socket));
+ LOG(INFO) << "Connected to IPCServer: " << ipc_socket;
+
+ auto builder = VectorBuilder(3);
+ builder[0] = 1;
+ builder[1] = 2;
+ builder[2] = 3;
+ auto result = builder.Seal(client);
+
+ auto vec = std::dynamic_pointer_cast>(client.GetObject(result->id()));
+ for (size_t index = 0; index < vec->length(); ++index) {
+ std::cout << "element at " << index << " is: " << (*vec)[index] << std::endl;
+ }
+ }
+
+Cross-Language Compatibility
+----------------------------
+
+Vineyard maintains consistent design principles across SDKs in various languages,
+such as Java and Python. For an example of Vineyard objects and their builders in
+Python, please refer to :ref:`builder-resolver`.
+
+As demonstrated in the example above, there is a significant amount of boilerplate
+code involved in defining constructors and builders. To simplify the integration
+with Vineyard, we are developing a code generator that will automatically produce
+SDKs in different languages based on a C++-like Domain Specific Language (DSL).
+Stay tuned for updates!
+
+For a sneak peek at how the code generator works, please refer to `array.vineyard-mod`_
+and `arrow.vineyard-mod`_.
+
+.. _array.vineyard-mod: https://github.com/v6d-io/v6d/blob/main/modules/basic/ds/array.vineyard-mod
+.. _arrow.vineyard-mod: https://github.com/v6d-io/v6d/blob/main/modules/basic/ds/arrow.vineyard-mod
diff --git a/_sources/tutorials/extending/define-datatypes-python.rst.txt b/_sources/tutorials/extending/define-datatypes-python.rst.txt
new file mode 100644
index 0000000000..86045f9acc
--- /dev/null
+++ b/_sources/tutorials/extending/define-datatypes-python.rst.txt
@@ -0,0 +1,169 @@
+.. _define-python-types:
+
+Define Data Types in Python
+---------------------------
+
+Objects
+^^^^^^^
+
+As discussed in :ref:`vineyard-objects`, each object in vineyard comprises two components:
+
+1. The data payload, which is stored locally within the corresponding vineyard instance
+2. The hierarchical meta data, which is shared across the entire vineyard cluster
+
+Specifically, a ``Blob`` represents the unit where the data payload resides in a vineyard
+instance. A blob object contains a segment of memory in the bulk store of the vineyard
+instance, allowing users to save their local buffer into a blob and later retrieve the
+blob in another process using a zero-copy approach through memory mapping.
+
+.. code:: python
+
+ >>> payload = b"Hello, World!"
+ >>> blob_id = client.put(payload)
+ >>> blob = client.get_object(blob_id)
+ >>> print(blob.typename, blob.size, blob)
+
+.. code:: console
+
+ vineyard::Blob 28 Object <"o800000011cfa7040": vineyard::Blob>
+
+On the other hand, vineyard objects' hierarchical meta data is shared across the entire
+cluster. In the following example, for the sake of simplicity, we will launch a vineyard
+cluster with two vineyard instances on the same machine. However, in real-world scenarios,
+these vineyard instances would typically be distributed across multiple machines within
+the cluster.
+
+.. code:: console
+
+ $ python3 -m vineyard --socket /var/run/vineyard.sock1
+ $ python3 -m vineyard --socket /var/run/vineyard.sock2
+
+With this setup, we can create a distributed pair of arrays in vineyard, where the first
+array is stored in the first vineyard instance (listening to ipc_socket at `/var/run/vineyard.sock1`),
+and the second array is stored in the second instance (listening to ipc_socket at
+`/var/run/vineyard.sock2`).
+
+.. code:: python
+
+ >>> import numpy as np
+ >>> import vineyard
+ >>> import vineyard.data.tensor
+
+ >>> # build the first array in the first vineyard instance
+ >>> client1 = vineyard.connect('/var/run/vineyard.sock1')
+ >>> id1 = client1.put(np.zeros(8))
+ >>> # persist the object to make it visible to form the global object
+ >>> client1.persist(id1)
+
+ >>> # build the second array in the second vineyard instance
+ >>> client2 = vineyard.connect('/var/run/vineyard.sock2')
+ >>> id2 = client2.put(np.ones(4))
+ >>> # persist the object to make it visible to form the global object
+ >>> client2.persist(id2)
+
+ >>> # build the pair from client1
+ >>> obj1 = client1.get_object(id1)
+ >>> obj2 = client2.get_object(id2)
+ >>> id_pair = client1.put((obj1, obj2))
+
+ >>> # get the pair object from client2
+ >>> obj_pair = client2.get_object(id_pair)
+ >>> print(obj_pair.first.typename, obj_pair.first.size(), obj_pair.second.size())
+
+.. code:: console
+
+ vineyard::Array 8 4
+
+.. code:: console
+
+ >>> # get the pair value from client2
+ >>> value_pair = client2.get(id_pair)
+ >>> print(value_pair)
+
+.. code:: console
+
+ (None, [1, 1, 1, 1])
+
+In this example, we can access the metadata of the pair object from `client2` even
+though it was created by `client1`. However, we cannot retrieve the payload of the
+first element of the pair from `client2`, as it is stored locally within the first
+vineyard instance.
+
+Creating Builders and Resolvers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As demonstrated in :ref:`builder-resolver`, vineyard enables users to register
+builders and resolvers for constructing and resolving vineyard objects from/to
+client-side data types based on specific computational requirements.
+
+For instance, if we use ``pyarrow`` types in our context, we can define the builder and
+resolver for the conversion between ``vineyard::NumericArray`` and ``pyarrow.NumericArray``
+as follows:
+
+.. code:: python
+
+ >>> def numeric_array_builder(client, array, builder):
+ >>> meta = ObjectMeta()
+ >>> meta['typename'] = 'vineyard::NumericArray<%s>' % array.type
+ >>> meta['length_'] = len(array)
+ >>> meta['null_count_'] = array.null_count
+ >>> meta['offset_'] = array.offset
+ >>>
+ >>> null_bitmap = buffer_builder(client, array.buffers()[0], builder)
+ >>> buffer = buffer_builder(client, array.buffers()[1], builder)
+ >>>
+ >>> meta.add_member('buffer_', buffer)
+ >>> meta.add_member('null_bitmap_', null_bitmap)
+ >>> meta['nbytes'] = array.nbytes
+ >>> return client.create_metadata(meta)
+
+ >>> def numeric_array_resolver(obj):
+ >>> meta = obj.meta
+ >>> typename = obj.typename
+ >>> value_type = normalize_dtype(re.match(r'vineyard::NumericArray<([^>]+)>', typename).groups()[0])
+ >>> dtype = pa.from_numpy_dtype(value_type)
+ >>> buffer = as_arrow_buffer(obj.member('buffer_'))
+ >>> null_bitmap = as_arrow_buffer(obj.member('null_bitmap_'))
+ >>> length = int(meta['length_'])
+ >>> null_count = int(meta['null_count_'])
+ >>> offset = int(meta['offset_'])
+ >>> return pa.lib.Array.from_buffers(dtype, length, [null_bitmap, buffer], null_count, offset)
+
+Finally, we register the builder and resolver for automatic building and resolving:
+.. code:: python
+
+ >>> builder_ctx.register(pa.NumericArray, numeric_array_builder)
+ >>> resolver_ctx.register('vineyard::NumericArray', numeric_array_resolver)
+
+In some cases, we may have multiple resolvers or builders for a specific type.
+For instance, the `vineyard::Tensor` object can be resolved as either `numpy.ndarray` or
+`xgboost::DMatrix`. To accommodate this, we could have:
+
+.. code:: python
+
+ >>> resolver_ctx.register('vineyard::Tensor', numpy_resolver)
+ >>> resolver_ctx.register('vineyard::Tensor', xgboost_resolver)
+
+This flexibility enables seamless integration with various libraries and frameworks by
+effectively handling different data types and their corresponding resolvers or builders.
+
+.. code:: python
+
+ def xgboost_resolver(obj):
+ ...
+
+ default_resolver_context.register('vineyard::Tensor', xgboost_resolver)
+
+at the same time. The stackable :code:`resolver_context` could help there,
+
+.. code:: python
+
+ with resolver_context({'vineyard::Tensor', xgboost_resolver}):
+ ...
+
+Assuming the default context resolves `vineyard::Tensor` to `numpy.ndarray`, the
+`with resolver_context` allows for temporary resolution of `vineyard::Tensor` to
+`xgboost::DMatrix`. Upon exiting the context, the global environment reverts to
+its default state.
+
+The `with resolver_context` can be nested for additional flexibility.
diff --git a/_sources/tutorials/kubernetes.rst.txt b/_sources/tutorials/kubernetes.rst.txt
new file mode 100644
index 0000000000..fa45072068
--- /dev/null
+++ b/_sources/tutorials/kubernetes.rst.txt
@@ -0,0 +1,39 @@
+Vineyard on Kubernetes
+======================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: TOC
+ :hidden:
+
+ ./kubernetes/using-vineyard-operator.rst
+ ./kubernetes/ml-pipeline-mars-pytorch.rst
+ ./kubernetes/data-sharing-with-vineyard-on-kubernetes.rst
+ ./kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.rst
+ ./kubernetes/vineyard-on-fluid.rst
+
+Vineyard can be seamlessly deployed on Kubernetes, managed by the :ref:`vineyard-operator`,
+to enhance big-data workflows through its data-aware scheduling policy. This policy
+orchestrates shared objects and routes jobs to where their input data resides. In the
+following tutorials, you will learn how to deploy Vineyard and effectively integrate it
+with Kubernetes.
+
+.. panels::
+ :header: text-center
+ :column: col-lg-12 p-2
+
+ .. link-button:: ./kubernetes/using-vineyard-operator
+ :type: ref
+ :text: Vineyard operator
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ The Vineyard operator serves as the central component for seamless integration with Kubernetes.
+
+ ---
+
+ .. link-button:: ./kubernetes/ml-pipeline-mars-pytorch
+ :type: ref
+ :text: ML with Vineyard
+ :classes: btn-block stretched-link
+ ^^^^^^^^^^^^
+ Vineyard functions as an efficient intermediate data storage solution for machine learning pipelines on Kubernetes.
diff --git a/_sources/tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes.rst.txt b/_sources/tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes.rst.txt
new file mode 100644
index 0000000000..6c998a2a2c
--- /dev/null
+++ b/_sources/tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes.rst.txt
@@ -0,0 +1,269 @@
+Data sharing with Vineyard on Kubernetes
+========================================
+
+If you want to share data between different workloads(pods or containers) on kubernetes, it's a good idea to
+use vineyard as the data-sharing service. In this tutorial, we will show you how to
+share data between different containers or pods on kubernetes step by step.
+
+.. figure:: ../../images/data_sharing_with_sidecar.jpg
+ :width: 75%
+ :alt: Data sharing between containers
+
+ Data sharing between containers
+
+From the above figure, the `vineyardctl inject` command will inject vineyard container into the app pod and
+the app containers will connect to the vineyard container to share the vineyard data.
+
+.. figure:: ../../images/data_sharing_with_deployment.jpg
+ :width: 75%
+ :alt: Data sharing on the vineyard deployment
+
+ Data sharing on the vineyard deployment
+
+From the above figure, the `vineyardctl deploy vineyard-deployment` command will deploy a vineyard deployment
+on the kubernetes cluster (default is 3 replicas) and the app pods will be scheduled to the vineyard deployment
+to share the vineyard data via the command `vineyardctl schedule workload`.
+
+Prerequisites
+-------------
+
+- A kubernetes cluster with version >= 1.25.10.
+- Install the latest vineyardctl command line tool refer to `vineyardctl installation`_.
+
+Data sharing between different containers
+-----------------------------------------
+
+In this section, we will show you how to share data between different containers on kubernetes.
+Assuming you have a pod with two containers, one is a producer and the other is a consumer.
+The producer will generate some data and write it to vineyard, and the consumer will read the data
+from vineyard and do some computation.
+
+Save the following yaml as `pod.yaml`.
+
+.. code:: yaml
+
+ $ cat << EOF >> pod.yaml
+ apiVersion: v1
+ kind: Pod
+ metadata:
+ name: vineyard-producer-consumer
+ namespace: vineyard-test
+ spec:
+ containers:
+ - name: producer
+ image: python:3.10
+ command:
+ - bash
+ - -c
+ - |
+ pip install vineyard numpy pandas;
+ cat << EOF >> producer.py
+ import vineyard;
+ import numpy as np;
+ import pandas as pd;
+ client = vineyard.connect();
+ # put a pandas dataframe to vineyard
+ client.put(pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')), persist=True, name="test_dataframe");
+ # put a basic data unit to vineyard
+ client.put((1, 1.2345, 'xxxxabcd'), persist=True, name="test_basic_data_unit");
+ client.close()
+ EOF
+ python producer.py;
+ sleep infinity;
+ - name: consumer
+ image: python:3.10
+ command:
+ - bash
+ - -c
+ - |
+ # wait for the producer to finish
+ sleep 10;
+ pip install vineyard numpy pandas;
+ cat << EOF >> consumer.py
+ import vineyard;
+ client = vineyard.connect();
+ # get the pandas dataframe from vineyard
+ print(client.get(name="test_dataframe").sum())
+ # get the basic data unit from vineyard
+ print(client.get(name="test_basic_data_unit"))
+ client.close()
+ EOF
+ python consumer.py;
+ sleep infinity;
+ EOF
+
+Use the `vineyardctl` to inject vineyard into the pod and apply them to the kubernetes cluster
+as follows.
+
+.. code:: bash
+
+ # create the namespace
+ $ kubectl create ns vineyard-test
+ # get all injected resources
+ $ python3 -m vineyard.ctl inject -f pod.yaml | kubectl apply -f -
+ pod/vineyard-sidecar-etcd-0 created
+ service/vineyard-sidecar-etcd-0 created
+ service/vineyard-sidecar-etcd-service created
+ service/vineyard-sidecar-rpc created
+ pod/vineyard-producer-consumer created
+
+
+Then you can get the logs of the consumer containers as follows.
+
+.. code:: bash
+
+ # get the logs of the consumer container
+ $ kubectl logs -f vineyard-producer-consumer -n test -c consumer
+ A -30.168469
+ B -19.269489
+ C 6.332533
+ D -9.714950
+ dtype: float64
+ (1, 1.2345000505447388, 'xxxxabcd')
+
+Data sharing between different pods
+-----------------------------------
+
+In this section, we will show you how to share data between different workloads on kubernetes.
+You are supposed to create a vineyard deployment and then deploy the application pods on
+the nodes where the vineyard deployment is running.
+
+Deploy the vineyard deployment (default is 3 replicas) as follows.
+
+.. code:: bash
+
+ # create the namespace if not exists
+ $ kubectl create ns vineyard-test
+ # create the vineyard deployment
+ $ python3 -m vineyard.ctl deploy vineyard-deployment --name vineyardd-sample -n vineyard-test
+ 2023-07-21T15:42:25.981+0800 INFO vineyard cluster deployed successfully
+
+Check the vineyard deployment status and the three vineyardd pods should run on the different nodes.
+
+.. code:: bash
+
+ # check the pods status
+ $ kubectl get pod -lapp.vineyard.io/name=vineyardd-sample -n vineyard-test -owide
+ NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
+ vineyardd-sample-5fd45fdd66-fq55z 1/1 Running 0 3m37s 10.244.1.17 kind-worker3
+ vineyardd-sample-5fd45fdd66-qjr5c 1/1 Running 0 3m37s 10.244.3.35 kind-worker
+ vineyardd-sample-5fd45fdd66-ssqb7 1/1 Running 0 3m37s 10.244.2.29 kind-worker2
+ vineyardd-sample-etcd-0 1/1 Running 0 3m53s 10.244.1.16 kind-worker3
+
+Assume we have two pods, one is a producer and the other is a consumer.
+
+The producer yaml file is as follows.
+
+.. code:: bash
+
+ $ cat << EOF >> producer.yaml
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: producer
+ namespace: vineyard-test
+ spec:
+ selector:
+ matchLabels:
+ app: producer
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: producer
+ spec:
+ containers:
+ - name: producer
+ image: python:3.10
+ command:
+ - bash
+ - -c
+ - |
+ pip install vineyard numpy pandas;
+ cat << EOF >> producer.py
+ import vineyard
+ import numpy as np
+ import pandas as pd
+ client = vineyard.connect()
+ client.put(pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')), persist=True, name="test_dataframe")
+ client.put((1, 1.2345, 'xxxxabcd'), persist=True, name="test_basic_data_unit");
+ client.close()
+ EOF
+ python producer.py;
+ sleep infinity;
+ EOF
+
+The consumer yaml file is as follows.
+
+.. code:: bash
+
+ $ cat << EOF >> consumer.yaml
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: consumer
+ namespace: vineyard-test
+ spec:
+ selector:
+ matchLabels:
+ app: consumer
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: consumer
+ spec:
+ containers:
+ - name: consumer
+ image: python:3.10
+ command:
+ - bash
+ - -c
+ - |
+ pip install vineyard numpy pandas;
+ cat << EOF >> consumer.py
+ import vineyard
+ client = vineyard.connect()
+ dataframe_obj = client.get_name("test_dataframe")
+ print(client.get(dataframe_obj,fetch=True).sum())
+ unit_obj = client.get_name("test_basic_data_unit")
+ print(client.get(unit_obj,fetch=True))
+ client.close()
+ EOF
+ python consumer.py;
+ sleep infinity;
+ EOF
+
+Use the `vineyardctl` to schedule the two workloads on the vineyard cluster.
+
+.. code:: bash
+
+ # schedule the producer workload to the vineyard cluster and apply it to the kubernetes cluster
+ $ python3 -m vineyard.ctl schedule workload -f producer.yaml --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-test -o yaml | kubectl apply -f -
+ deployment.apps/producer created
+
+ # schedule the consumer workload to the vineyard cluster and apply it to the kubernetes cluster
+ $ python3 -m vineyard.ctl schedule workload -f consumer.yaml --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-test -o yaml | kubectl apply -f -
+ deployment.apps/consumer created
+
+Check the logs of the consumer pods as follows.
+
+.. code:: bash
+
+ $ kubectl logs -f $(kubectl get pod -lapp=consumer -n vineyard-test -o jsonpath='{.items[0].metadata.name}') -n vineyard-test
+ A 11.587912
+ B 12.059792
+ C 4.863514
+ D -2.682567
+ dtype: float64
+ (1, 1.2345000505447388, 'xxxxabcd')
+
+From the above example, we can see the code of the consumer is quiet different from the previous sidecar example.
+As the consumer may be scheduled to different node from the producer with the default kubernetes scheduler, the client
+should get the remote object id by name and then fetch it from other vineyard nodes. For more details, please refer to
+the `vineyard objects`_.
+
+.. _vineyardctl installation: https://v6d.io/notes/cloud-native/deploy-kubernetes.html#quick-start
+.. _vineyard objects: https://v6d.io/notes/key-concepts/objects.html#transient-vs-persistent
\ No newline at end of file
diff --git a/_sources/tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.rst.txt b/_sources/tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.rst.txt
new file mode 100644
index 0000000000..1c5b6d8506
--- /dev/null
+++ b/_sources/tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.rst.txt
@@ -0,0 +1,572 @@
+Efficient data sharing in Kubeflow with Vineyard CSI Driver
+-----------------------------------------------------------
+
+If you are using `Kubeflow Pipeline`_ or `Argo Workflow`_ to manage your machine learning workflow,
+you may find that the data saving/loading to the volumes is slow.
+To speed up the data saving/loading within these volumes, we design the Vineyard CSI Driver to
+map each vineyard object to a volume, and the data saving/loading is handled by vineyard.
+Next, we will show you how to use the Vineyard CSI Driver to speed up a kubeflow pipeline.
+
+Prerequisites
+=============
+
+- A kubernetes cluster with version >= 1.25.10. If you don't have one by hand, you can refer to the guide `Initialize Kubernetes Cluster`_ to create one.
+- Install the `Vineyardctl`_ by following the official guide.
+- Install the argo workflow cli >= 3.4.8.
+- Install the kfp package <= 1.8.0 for kubeflow **v1** or >= 2.0.1 for kubeflow **v2**.
+
+Deploy the Vineyard Cluster
+===========================
+
+.. code:: bash
+
+ $ python3 -m vineyard.ctl deploy vineyard-cluster --create-namespace
+
+This command will create a vineyard cluster in the namespace `vineyard-system`.
+You can check as follows:
+
+.. code:: bash
+
+ $ kubectl get pod -n vineyard-system
+ NAME READY STATUS RESTARTS AGE
+ vineyard-controller-manager-648fc9b7bf-zwnhd 2/2 Running 0 4d3h
+ vineyardd-sample-79c8ffb879-6k8mk 1/1 Running 0 4d3h
+ vineyardd-sample-79c8ffb879-f9kkr 1/1 Running 0 4d3h
+ vineyardd-sample-79c8ffb879-lzgwz 1/1 Running 0 4d3h
+ vineyardd-sample-etcd-0 1/1 Running 0 4d3h
+
+Deploy the Vineyard CSI Driver
+==============================
+
+Before deploying the Vineyard CSI Driver, you are supposed to check the vineyard
+deployment is ready as follows:
+
+.. code:: bash
+
+ $ kubectl get deployment -n vineyard-system
+ NAME READY UP-TO-DATE AVAILABLE AGE
+ vineyard-controller-manager 1/1 1 1 4d3h
+ vineyardd-sample 3/3 3 3 4d3h
+
+Then deploy the vineyard csi driver which specifies the vineyard cluster to use:
+
+.. tip::
+
+ If you want to look into the debug logs of the vineyard csi driver, you can add a
+ flag ``--verbose`` in the following command.
+
+.. code:: bash
+
+ $ python3 -m vineyard.ctl deploy csidriver --clusters vineyard-system/vineyardd-sample
+
+Then check the status of the Vineyard CSI Driver:
+
+.. code:: bash
+
+ $ kubectl get pod -n vineyard-system
+ NAME READY STATUS RESTARTS AGE
+ vineyard-controller-manager-648fc9b7bf-zwnhd 2/2 Running 0 4d3h
+ vineyard-csi-sample-csi-driver-fb7cb5b5d-nlrxs 4/4 Running 0 4m23s
+ vineyard-csi-sample-csi-nodes-69j77 3/3 Running 0 4m23s
+ vineyard-csi-sample-csi-nodes-k85hb 3/3 Running 0 4m23s
+ vineyard-csi-sample-csi-nodes-zhfz4 3/3 Running 0 4m23s
+ vineyardd-sample-79c8ffb879-6k8mk 1/1 Running 0 4d3h
+ vineyardd-sample-79c8ffb879-f9kkr 1/1 Running 0 4d3h
+ vineyardd-sample-79c8ffb879-lzgwz 1/1 Running 0 4d3h
+ vineyardd-sample-etcd-0 1/1 Running 0 4d3h
+
+Running the Kubeflow Pipeline example
+=====================================
+
+We provide two examples using different versions of Kubeflow Pipeline: **v1** and **v2**.
+To use the Vineyard CSI Driver, we need to do two modifications:
+
+1. Change APIs like **pd.read_pickle/write_pickle** to **vineyard.csi.write/read** in the source code.
+
+2. Add the ``vineyard object`` VolumeOp to the pipeline's dependencies. The path in the API changed
+in the first step will be mapped to a volume. Notice, the volume used in any task needs to be
+explicitly mounted to the corresponding path in the source code, and the storageclass_name
+format of each VolumeOp is ``{vineyard-deployment-namespace}.{vineyard-deployment-name}.csi``.
+
+There are two ways to add the ``vineyard object`` VolumeOp to the pipeline's dependencies:
+
+- Each path in the source code is mapped to a volume, and each volume is mounted to the actual path
+ in the source code. The benefit is that the source path does not need to be modified.
+
+- Create a volume for the paths with the same prefix in the source code. You can add the prefix ``/vineyard`` for
+ the paths in the source code, and mount a volume to the path ``/vineyard``. In this way, you can
+ only create one volume for multiple paths/vineyard objects.
+
+You may get some insights from the modified pipeline ``pipeline-with-vineyard.py`` and ``pipeline-kfp-v2-with-vineyard``.
+
+Preparations
+^^^^^^^^^^^^
+
+Before running the kubflow examples, we need to do some common preparations, and then
+you can choose to run **KFP V1** or **KFP V2** example.
+
+1. First of all, we need to build the docker images for the pipeline:
+
+.. code:: bash
+
+ $ cd k8s/examples/vineyard-csidriver
+ $ make docker-build
+
+Or build the docker images with your docker registry:
+
+.. code:: bash
+
+ $ make docker-build REGISTRY=
+
+2. Check the images built successfully:
+
+.. code:: bash
+
+ $ docker images
+ train-data latest 5628953ffe08 14 seconds ago 1.47GB
+ test-data latest 94c8c75b960a 14 seconds ago 1.47GB
+ prepare-data latest 5aab1b120261 15 seconds ago 1.47GB
+ preprocess-data latest 5246d09e6f5e 15 seconds ago 1.47GB
+
+3. Push the image to a docker registry that your kubernetes cluster can access.
+
+.. code:: bash
+
+ $ make push-images REGISTRY=
+
+4. Create the namespace for the pipeline:
+
+.. code:: bash
+
+ $ kubectl create namespace kubeflow
+
+5. To simulate the data loading/saving of the actual pipeline, we use the nfs volume
+to store the data. The nfs volume is mounted to the ``/mnt/data`` directory of the
+kind cluster. Then apply the data volume as follows:
+
+.. tip::
+
+ If you already have nfs volume that can be accessed by the kubernetes cluster,
+ you can update the ``prepare-data.yaml`` to use your nfs volume.
+
+.. code:: bash
+
+ $ kubectl apply -f prepare-data.yaml
+
+6. Deploy the rbac for the pipeline:
+
+.. code:: bash
+
+ $ kubectl apply -f rbac.yaml
+
+
+7. **(important)** Download all need images to all kind workers:
+
+.. code:: bash
+
+ registry="ghcr.io/v6d-io/v6d/kubeflow-example"
+ kubeflow_registry="gcr.io/ml-pipeline"
+ worker=($(docker ps | grep kind-worker | awk -F ' ' '{print $1}'))
+ for c in ${worker[@]}; do
+ docker exec -it $c sh -c "
+ crictl pull ${registry}/preprocess-data && \
+ crictl pull ${registry}/train-data && \
+ crictl pull ${registry}/test-data &&\
+ # change the following image to compatible with the installed kubeflow version
+ crictl pull ${kubeflow_registry}/argoexec:v3.3.10-license-compliance && \
+ crictl pull ${kubeflow_registry}/kfp-driver@sha256:0ce9bf20ac9cbb21e84ff0762d5ae508d21e9c85fde2b14b51363bd1b8cd7528
+ # change the following image to compatible with the installed argo workflow version
+ crictl pull quay.io/argoproj/argoexec:v3.4.8
+ "
+ done
+
+
+Running KFP V1 Example
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. tip::
+
+ If you want to run the **KFP V2** example, you can skip this section.
+
+The original **KFP V1** code is shown in ``pipeline.py`` under the directory ``k8s/examples/vineyard-csidriver`` and the
+``pipeline-with-vineyard.py`` is modified to be compatible with the Vineyard CSI Driver. As we use the argo workflow to
+run the **KFP v1** pipeline, we need to install the argo workflow server as follows.
+
+1. Install the argo server on Kubernetes:
+
+.. code:: bash
+
+ $ kubectl create namespace argo
+ $ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.4.8/install.yaml
+
+2. Check the status of the argo server:
+
+.. code:: bash
+
+ $ kubectl get pod -n argo
+ NAME READY STATUS RESTARTS AGE
+ argo-server-7698c96655-ft6sj 1/1 Running 0 4d1h
+ workflow-controller-b888f4458-sfrjd 1/1 Running 0 4d1h
+
+
+3. Submit the kubeflow example without vineyard to the argo server:
+
+.. code:: bash
+
+ $ for data_multiplier in 4000 5000 6000; do \
+ # clean the previous argo workflow
+ argo delete --all -n kubeflow; \
+ # submit the pipeline without vineyard
+ argo submit --watch pipeline.yaml -n kubeflow \
+ -p data_multiplier=${data_multiplier} -p registry="ghcr.io/v6d-io/v6d/kubeflow-example"; \
+ # sleep 60s to record the actual execution time
+ sleep 60; \
+ done
+
+4. Clear the previous resources:
+
+.. code:: bash
+
+ $ argo delete --all -n kubeflow
+
+5. Submit the kubeflow example with vineyard to the argo server:
+
+.. code:: bash
+
+ $ for data_multiplier in 3000 4000 5000; do \
+ # clean the previous argo workflow
+ argo delete --all -n kubeflow; \
+ # submit the pipeline without vineyard
+ argo submit --watch pipeline-with-vineyard.yaml -n kubeflow \
+ -p data_multiplier=${data_multiplier} -p registry="ghcr.io/v6d-io/v6d/kubeflow-example"; \
+ # sleep 60s to record the actual execution time
+ sleep 60; \
+ done
+
+
+Running KFP V2 Example
+^^^^^^^^^^^^^^^^^^^^^^
+
+.. tip::
+
+ If you have installed the argo workflow server, you need to delete it first. As the KFP resources
+ contain the argo workflow server, and the argo workflow server will conflict with the KFP resources.
+
+The original **KFP V2** code is shown in ``pipeline-kfp-v2.py`` under the directory ``k8s/examples/vineyard-csidriver`` and the
+``pipeline-kfp-v2-with-vineyard.py`` is modified to be compatible with the Vineyard CSI Driver. As it can only be compiled to
+the IR YAML, which only recognized by the kubeflow server. Thus, we need to install the kubeflow server as follows.
+
+1. Install a KFP standalone instance on Kubernetes:
+
+.. code:: bash
+
+ export PIPELINE_VERSION=2.0.1
+
+ kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/cluster-scoped-resources?ref=$PIPELINE_VERSION"
+ kubectl wait --for condition=established --timeout=60s crd/applications.app.k8s.io
+ kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/env/dev?ref=$PIPELINE_VERSION"
+
+2. Check the status of the KFP instance:
+
+.. code:: bash
+
+ $ kubectl get pod -n kubeflow
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ NAME READY STATUS RESTARTS AGE
+ cache-deployer-deployment-5c95fc7fdd-d65cf 1/1 Running 0 49m
+ cache-server-6c84679764-k8q6j 1/1 Running 0 49m
+ controller-manager-86bf69dc54-2brxq 1/1 Running 0 49m
+ metadata-envoy-deployment-6448d544f5-z4sc8 1/1 Running 0 49m
+ metadata-grpc-deployment-784b8b5fb4-8mtm7 1/1 Running 2 (49m ago) 49m
+ metadata-writer-79c5499dd8-6jjmm 1/1 Running 0 49m
+ minio-65dff76b66-tdtx5 1/1 Running 0 49m
+ ml-pipeline-6546dcc959-k8t84 1/1 Running 0 48m
+ ml-pipeline-persistenceagent-79479cdb74-q6lq9 1/1 Running 0 49m
+ ml-pipeline-scheduledworkflow-5cbdc7d885-lx9r7 1/1 Running 0 49m
+ ml-pipeline-ui-7c94d6f4b7-z2tvs 1/1 Running 0 49m
+ ml-pipeline-viewer-crd-685f449686-bz55g 1/1 Running 0 49m
+ ml-pipeline-visualizationserver-7c8f97864d-sp8p6 1/1 Running 0 49m
+ mysql-c999c6c8-nwp9d 1/1 Running 0 49m
+ proxy-agent-77d7b57c99-plrpb 0/1 CrashLoopBackOff 14 (2m17s ago) 49m
+ workflow-controller-6c85bc4f95-dw889 1/1 Running 0 49m
+
+3. Delete the proxy deployment as it's not used in the example and will slow down the pipeline:
+
+.. code:: bash
+
+ $ kubectl delete deployment proxy-agent -n kubeflow
+
+4. Open a terminal to portforward the KFP UI to your local machine:
+
+.. code:: bash
+
+ $ kubectl port-forward -n kubeflow svc/ml-pipeline-ui 8088:80
+
+5. Upload the ``pipeline-kfp-v2.yaml`` and ``pipeline-kfp-v2-with-vineyard.yaml`` to the KFP instance:
+
+.. tip::
+
+ If you use the custom docker registry, you need to update the docker image
+ in the ``pipeline-kfp-v2.yaml`` and ``pipeline-kfp-v2-with-vineyard.yaml``.
+
+.. figure:: ../../images/kubeflow_upload_pipeline.png
+ :width: 75%
+ :alt: Upload pipeline in the kubeflow Dashboard
+
+ Upload pipeline in the kubeflow Dashboard
+
+6. **(Important)** Clean the file system cache of the kubeflow server.
+
+As the KFP V2 doesn't support to configure the ``SecurityContext`` of the container, which means
+we can't run the command ``sync; echo 3 > /proc/sys/vm/drop_caches`` in the container to clean the
+file system cache. Thus before creating a new run, we need to clean the file system cache manually
+as follows:
+
+.. code:: bash
+
+ # clean all the file system cache and image cache of all kind workers
+ $ worker=($(docker ps | grep kind-worker | awk -F ' ' '{print $1}')); \
+ for c in ${worker[@]}; do docker exec --privileged -it $c \
+ sh -c 'sync && echo 3 > /proc/sys/vm/drop_caches'; done;
+
+If you use the actual kubernetes cluster, you can login to the kubernetes node and clean the file
+system cache manually.
+
+7. Create the runs using the previously uploaded pipelines:
+
+.. figure:: ../../images/kubeflow_create_run.png
+ :width: 75%
+ :alt: Create runs in the kubeflow Dashboard
+
+ Create runs in the kubeflow Dashboard
+
+KFP V1 Result Analysis
+^^^^^^^^^^^^^^^^^^^^^^
+
+The data scale are 14000 Mi, 18000 Mi and 21000 Mi, which correspond to
+the 4000, 5000 and 6000 in the previous data_multiplier respectively,
+and the time of argo workflow execution of the pipeline is as follows:
+
+Argo workflow duration
+""""""""""""""""""""""
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 14000 Mi | 317s | 270s |
++------------+------------------+---------------+
+| 18000 Mi | 403s | 331s |
++------------+------------------+---------------+
+| 21000 Mi | 504s | 389s |
++------------+------------------+---------------+
+
+
+Actually, the cost time of argo workflow is affected by lots of factors,
+such as the network, the cpu and memory of the cluster, the data volume, etc.
+So the time of argo workflow execution of the pipeline is not stable.
+But we can still find that the time of argo workflow execution of the pipeline
+with vineyard reduced by 15%~25%.
+
+Also, we record the whole execution time via logs. The result is as follows:
+
+Actual execution time
+"""""""""""""""""""""
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 14000 Mi | 215.1s | 140.3s |
++------------+------------------+---------------+
+| 18000 Mi | 298.2s | 198.1s |
++------------+------------------+---------------+
+| 21000 Mi | 398.7s | 257.5s |
++------------+------------------+---------------+
+
+
+According to the above results, we can find that the time of actual
+execution of the pipeline with vineyard reduced by 30%~40%. To be specific,
+we record the write/read time of the following steps:
+
+Writing time
+""""""""""""
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 14000 Mi | 33.2s | 8.8s |
++------------+------------------+---------------+
+| 18000 Mi | 40.8s | 11.6s |
++------------+------------------+---------------+
+| 21000 Mi | 48.6s | 13.9s |
++------------+------------------+---------------+
+
+
+From the above results, we can find that the writing time the pipeline
+with vineyard reduced by 70%~75%. The reason is that the data is stored
+in the vineyard cluster, so it's actually a memory copy operation, which
+is faster than the write operation of the nfs volume.
+
+
+Reading time
+""""""""""""
+
+We delete the time of init data loading, and the results are as follows:
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 14000 Mi | 56.6s | 0.02s |
++------------+------------------+---------------+
+| 18000 Mi | 76.3s | 0.02s |
++------------+------------------+---------------+
+| 21000 Mi | 93.7s | 0.02s |
++------------+------------------+---------------+
+
+Based on the above results, we can find that the read time of vineyard is
+nearly a constant, which is not affected by the data scale.
+The reason is that the data is stored in the shared memory of vineyard cluster,
+so it's actually a pointer copy operation.
+
+As a result, we can find that with vineyard, the argo workflow
+duration of the pipeline is reduced by 15%~25% and the actual
+execution time of the pipeline is reduced by about 30%~40%.
+
+KFP V2 Result Analysis
+^^^^^^^^^^^^^^^^^^^^^^
+
+Different with the previous KFP V1, the KFP V2 will compile the pipeline to the IR YAML,
+and the IR YAML will be submitted to the kubeflow server. Before each component of the
+pipeline is executed, the kubeflow server will create a preprocess container to parse
+the IR YAML and generate the relevant kubernetes resources. That means the kubeflow server
+will create more pods than the previous argo workflow, thereby slowing down the execution
+speed of the entire pipeline.
+
+The execution time of the pipeline shown in the kubeflow dashboard is as follows:
+
+Kubeflow dashboard duration
+"""""""""""""""""""""""""""
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 14000 Mi | 276s | 229s |
++------------+------------------+---------------+
+| 18000 Mi | 365s | 291s |
++------------+------------------+---------------+
+| 21000 Mi | 440s | 352s |
++------------+------------------+---------------+
+
+Based on the above result, we can find that the execution time of kubeflow pipeline with vineyard
+is reduced by 15%~20% on the dashboard. Compared to the kfp v1, the vineyard effect is slightly
+reduced. The reason is that in the kfp v2, CreateVolume and DeleteVolume are regarded as two components,
+and that means more worker pods will be created. The time to create these pods is the main factor
+that reduces vineyard efficiency.
+
+Actual execution time
+"""""""""""""""""""""
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 14000 Mi | 213s | 133.4s |
++------------+------------------+---------------+
+| 18000 Mi | 302.7s | 208.1s |
++------------+------------------+---------------+
+| 21000 Mi | 377.6s | 265.9s |
++------------+------------------+---------------+
+
+From the above results, we can find that the actual execution time of the pipeline with vineyard
+is reduced by 30%~40%. To be specific, we record the write/read time of the following steps:
+
+
+Writing time
+""""""""""""
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 14000 Mi | 33.2s | 8.1s |
++------------+------------------+---------------+
+| 18000 Mi | 41s | 10.8s |
++------------+------------------+---------------+
+| 21000 Mi | 48.3s | 13.7s |
++------------+------------------+---------------+
+
+Similarly, since writing to vineyard is just a memory copy operation, its execution time
+will be greatly reduced.
+
+
+Reading time
+""""""""""""
+
+We delete the time of init data loading, and the results are as follows:
+
++------------+------------------+---------------+
+| data scale | without vineyard | with vineyard |
++============+==================+===============+
+| 8500 Mi | 54.5s | 0.04s |
++------------+------------------+---------------+
+| 12000 Mi | 73.5s | 0.02s |
++------------+------------------+---------------+
+| 15000 Mi | 88.9s | 0.02s |
++------------+------------------+---------------+
+
+
+As the result in kfp v1, reading the vineyard data only requires a
+single operation to get the memory pointer. So the reading time of
+vineyard is almost 0.
+
+In summary, regardless of whether you are using KFP V1 or KFP V2, and whether the backend
+is Argo server or Kubeflow manifests, integrating Vineyard can effectively optimize the data
+sharing among Kubeflow components. This optimization, in turn, leads to a significant reduction
+in the overall execution time of the Kubeflow pipeline.
+
+Clean up
+========
+
+Delete the rbac for the kubeflow example:
+
+.. code:: bash
+
+ $ kubectl delete -f rbac.yaml
+
+Delete all argo workflow
+
+.. code:: bash
+
+ $ argo delete --all
+
+Delete the argo server:
+
+.. code:: bash
+
+ $ kubectl delete ns argo
+
+Delete the vineyard cluster:
+
+.. code:: bash
+
+ $ python3 -m vineyard.ctl delete vineyard-cluster
+
+Delete the data volume:
+
+.. code:: bash
+
+ $ kubectl delete -f prepare-data.yaml
+
+Delete the kubeflow namespace:
+
+.. code:: bash
+
+ $ kubectl delete ns kubeflow
+
+.. _Kubeflow Pipeline: https://github.com/kubeflow/kubeflow
+.. _Argo Workflow: https://github.com/argoproj/argo-workflows
+.. _Initialize Kubernetes Cluster: https://v6d.io/tutorials/kubernetes/using-vineyard-operator.html#step-0-optional-initialize-kubernetes-cluster
+.. _Vineyardctl: https://v6d.io/notes/cloud-native/deploy-kubernetes.html#quick-start
+.. _Argo Workflow CLI: https://github.com/argoproj/argo-workflows/releases/
\ No newline at end of file
diff --git a/_sources/tutorials/kubernetes/ml-pipeline-mars-pytorch.rst.txt b/_sources/tutorials/kubernetes/ml-pipeline-mars-pytorch.rst.txt
new file mode 100644
index 0000000000..1236963832
--- /dev/null
+++ b/_sources/tutorials/kubernetes/ml-pipeline-mars-pytorch.rst.txt
@@ -0,0 +1,211 @@
+Machine learning with Vineyard on Kubernetes
+--------------------------------------------
+
+In this demonstration, we will build a fraudulent transaction classifier for
+fraudulent transaction data. The process consists of the following
+three main steps:
+
+- :code:`prepare-data`: Utilize Vineyard to read and store data in a distributed manner.
+- :code:`process-data`: Employ Mars to process the data across multiple nodes.
+- :code:`train-data`: Use Pytorch to train the model on the distributed data.
+
+We have three tables: user table, product table, and transaction table.
+The user and product tables primarily contain user and product IDs, along with
+their respective ``Feature`` vectors. Each record in the transaction table indicates
+a user purchasing a product, with a ``Fraud`` label identifying whether the
+transaction is fraudulent. Additional features related to these transactions are also
+stored in the transaction table. You can find the three tables in the `dataset repo`_.
+Follow the steps below to reproduce the demonstration. First, create a vineyard cluster
+with 3 worker nodes.
+
+.. code:: bash
+
+ $ cd k8s && make -C k8s/test/e2e install-vineyard-cluster
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ the kubeconfig path is /tmp/e2e-k8s.config
+ Creating the kind cluster with local registry
+ a16c878c5091c1e5c9eff0a1fca065665f47edb4c8c75408b3d33e22f0ec0d05
+ Creating cluster "kind" ...
+ ✓ Ensuring node image (kindest/node:v1.24.0) 🖼
+ ✓ Preparing nodes 📦 📦 📦 📦
+ ✓ Writing configuration 📜
+ ✓ Starting control-plane 🕹️
+ ✓ Installing CNI 🔌
+ ✓ Installing StorageClass 💾
+ ✓ Joining worker nodes 🚜
+ Set kubectl context to "kind-kind"
+ You can now use your cluster with:
+
+ kubectl cluster-info --context kind-kind --kubeconfig /tmp/e2e-k8s.config
+
+ Thanks for using kind! 😊
+ configmap/local-registry-hosting created
+ Installing vineyard-operator...
+ The push refers to repository [localhost:5001/vineyard-operator]
+ c3a672704524: Pushed
+ b14a7037d2e7: Pushed
+ 8d7366c22fd8: Pushed
+ latest: digest: sha256:ea06c833351f19c5db28163406c55e2108676c27fdafea7652500c55ce333b9d size: 946
+ make[1]: Entering directory '/opt/caoye/v6d/k8s'
+ go: creating new go.mod: module tmp
+ /home/gsbot/go/bin/controller-gen rbac:roleName=manager-role crd:maxDescLen=0 webhook paths="./..." output:crd:artifacts:config=config/crd/bases
+ cd config/manager && /usr/local/bin/kustomize edit set image controller=localhost:5001/vineyard-operator:latest
+ /usr/local/bin/kustomize build config/default | kubectl apply -f -
+ namespace/vineyard-system created
+ customresourcedefinition.apiextensions.k8s.io/backups.k8s.v6d.io created
+ customresourcedefinition.apiextensions.k8s.io/globalobjects.k8s.v6d.io created
+ customresourcedefinition.apiextensions.k8s.io/localobjects.k8s.v6d.io created
+ customresourcedefinition.apiextensions.k8s.io/operations.k8s.v6d.io created
+ customresourcedefinition.apiextensions.k8s.io/recovers.k8s.v6d.io created
+ customresourcedefinition.apiextensions.k8s.io/sidecars.k8s.v6d.io created
+ customresourcedefinition.apiextensions.k8s.io/vineyardds.k8s.v6d.io created
+ serviceaccount/vineyard-manager created
+ role.rbac.authorization.k8s.io/vineyard-leader-election-role created
+ clusterrole.rbac.authorization.k8s.io/vineyard-manager-role created
+ clusterrole.rbac.authorization.k8s.io/vineyard-metrics-reader created
+ clusterrole.rbac.authorization.k8s.io/vineyard-proxy-role created
+ clusterrole.rbac.authorization.k8s.io/vineyard-scheduler-plugin-role created
+ rolebinding.rbac.authorization.k8s.io/vineyard-leader-election-rolebinding created
+ clusterrolebinding.rbac.authorization.k8s.io/vineyard-kube-scheduler-rolebinding created
+ clusterrolebinding.rbac.authorization.k8s.io/vineyard-manager-rolebinding created
+ clusterrolebinding.rbac.authorization.k8s.io/vineyard-proxy-rolebinding created
+ clusterrolebinding.rbac.authorization.k8s.io/vineyard-scheduler-plugin-rolebinding created
+ clusterrolebinding.rbac.authorization.k8s.io/vineyard-scheduler-rolebinding created
+ clusterrolebinding.rbac.authorization.k8s.io/vineyard-volume-scheduler-rolebinding created
+ service/vineyard-controller-manager-metrics-service created
+ service/vineyard-webhook-service created
+ deployment.apps/vineyard-controller-manager created
+ mutatingwebhookconfiguration.admissionregistration.k8s.io/vineyard-mutating-webhook-configuration created
+ validatingwebhookconfiguration.admissionregistration.k8s.io/vineyard-validating-webhook-configuration created
+ make[1]: Leaving directory '/opt/caoye/v6d/k8s'
+ deployment.apps/vineyard-controller-manager condition met
+ Vineyard-Operator Ready
+ Installing vineyard cluster...
+ vineyardd.k8s.v6d.io/vineyardd-sample created
+ vineyardd.k8s.v6d.io/vineyardd-sample condition met
+ Vineyard cluster Ready
+
+Verify that all Vineyard pods are running.
+
+.. code:: bash
+
+ $ KUBECONFIG=/tmp/e2e-k8s.config kubectl get pod -n vineyard-system
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ NAME READY STATUS RESTARTS AGE
+ etcd0 1/1 Running 0 68s
+ etcd1 1/1 Running 0 68s
+ etcd2 1/1 Running 0 68s
+ vineyard-controller-manager-7f569b57c5-46tgq 2/2 Running 0 92s
+ vineyardd-sample-6ffcb96cbc-gs2v9 1/1 Running 0 67s
+ vineyardd-sample-6ffcb96cbc-n59gg 1/1 Running 0 67s
+ vineyardd-sample-6ffcb96cbc-xwpzd 1/1 Running 0 67s
+
+First, let's prepare the dataset and download it into the kind worker nodes as follows.
+
+.. code:: bash
+
+ $ worker=($(docker ps | grep kind-worker | awk -F ' ' '{print $1}'))
+ $ for c in ${worker[@]}; do \
+ docker exec $c sh -c "\
+ mkdir -p /datasets; \
+ cd /datasets/; \
+ curl -OL https://raw.githubusercontent.com/GraphScope/gstest/master/vineyard-mars-showcase-dataset/{item,txn,user}.csv" \
+ done
+
+The `prepare-data` job primarily reads the datasets and distributes them across different
+Vineyard nodes. For more information, please refer to the `prepare data code`_. To apply
+the job, follow the steps below:
+
+.. note::
+
+ The `prepare-data` job needs to exec into the other pods. Therefore, you need to
+ create a service account and bind it to the role under the namespace.
+ Please make sure you can have permission to create the following role.
+
+ .. code:: text
+
+ - apiGroups: [""]
+ resources: ["pods", "pods/log", "pods/exec"]
+ verbs: ["get", "patch", "delete", "create", "watch", "list"]
+
+.. code:: bash
+
+ $ kubectl create ns vineyard-job && \
+ kubectl apply -f showcase/vineyard-mars-pytorch/prepare-data/resources && \
+ kubectl wait job -n vineyard-job -l app=prepare-data --for condition=complete --timeout=1200s
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ namespace/vineyard-job created
+ clusterrolebinding.rbac.authorization.k8s.io/prepare-data-rolebinding created
+ clusterrole.rbac.authorization.k8s.io/prepare-data-role created
+ job.batch/prepare-data created
+ serviceaccount/prepare-data created
+ job.batch/prepare-data condition met
+
+.. note::
+
+ The `process-data` job needs to create a new namespace and deploy several kubernetes
+ resources in it. Please make sure you can have permission to create the following role.
+
+ .. code:: text
+
+ - apiGroups: [""]
+ resources: ["pods", "pods/exec", "pods/log", "endpoints", "services"]
+ verbs: ["get", "patch", "delete", "create", "watch", "list"]
+ - apiGroups: [""]
+ resources: ["namespaces"]
+ verbs: ["get", "create", "delete"]
+ - apiGroups: [""]
+ resources: ["nodes"]
+ verbs: ["get", "list"]
+ - apiGroups: ["rbac.authorization.k8s.io"]
+ resources: ["roles", "rolebindings"]
+ verbs: ["patch", "get", "create", "delete"]
+ - apiGroups: ["apps"]
+ resources: ["deployments"]
+ verbs: ["create"]
+
+ Notice, the `process-data` job will require lots of permissions to deal
+ kubernetes resources, so please check the image of `process-data` job
+ if it is an official one.
+
+The `prepare-data` job creates numerous dataframes in Vineyard. To combine these dataframes,
+we use the appropriate join method in `mars`_. For more details, refer to the `process data
+code`_. Apply the `process-data` job as follows:
+
+.. code:: bash
+
+ $ kubectl apply -f showcase/vineyard-mars-pytorch/process-data/resources && \
+ kubectl wait job -n vineyard-job -l app=process-data --for condition=complete --timeout=1200s
+
+Finally, apply the `train-data` job to obtain the fraudulent transaction classifier. You can
+also view the `train data code`_.
+
+.. code:: bash
+
+ $ kubectl apply -f k8s/showcase/vineyard-mars-pytorch/train-data/resources && \
+ kubectl wait pods -n vineyard-job -l app=train-data --for condition=Ready --timeout=1200s
+
+If any of the above steps fail, please refer to the `mars showcase e2e test`_ for further guidance.
+
+
+.. _mars: https://github.com/mars-project/mars
+.. _mars showcase e2e test: https://github.com/v6d-io/v6d/blob/main/k8s/test/e2e/mars-examples/e2e.yaml
+.. _dataset repo: https://github.com/GraphScope/gstest/tree/master/vineyard-mars-showcase-dataset
+.. _prepare data code: https://github.com/v6d-io/v6d/blob/main/k8s/examples/vineyard-mars-pytorch/prepare-data/prepare-data.py
+.. _process data code: https://github.com/v6d-io/v6d/blob/main/k8s/examples/vineyard-mars-pytorch/process-data/process-data.py
+.. _train data code: https://github.com/v6d-io/v6d/blob/main/k8s/examples/vineyard-mars-pytorch/train-data/train-data.py
diff --git a/_sources/tutorials/kubernetes/using-vineyard-operator.rst.txt b/_sources/tutorials/kubernetes/using-vineyard-operator.rst.txt
new file mode 100644
index 0000000000..95b463c991
--- /dev/null
+++ b/_sources/tutorials/kubernetes/using-vineyard-operator.rst.txt
@@ -0,0 +1,469 @@
+Use vineyard operator
+=====================
+
+Vineyard operator has been designed to manage vineyard components within Kubernetes.
+This tutorial provides a step-by-step guide on how to effectively utilize the vineyard
+operator. For more details, please refer to :ref:`vineyard-operator`.
+
+Step 0: (optional) Initialize Kubernetes Cluster
+------------------------------------------------
+
+If you don't have a Kubernetes cluster readily available, we highly recommend using `kind`_ to
+create one. Before setting up the Kubernetes cluster, please ensure you have the following
+tools installed:
+
+- kubectl: version >= 1.19.2
+- kind: version >= 0.14.0
+- docker: version >= 0.19.0
+
+Utilize kind (v0.14.0) to create a Kubernetes cluster consisting of 4 nodes (1 master node and 3
+worker nodes):
+
+.. code:: bash
+
+ $ cat > kind-config.yaml < 114s v1.24.0
+ kind-worker2 Ready 114s v1.24.0
+ kind-worker3 Ready 114s v1.24.0
+
+Step 1: Deploy the Vineyard Operator
+-------------------------------------
+
+Create a dedicated namespace for the Vineyard Operator.
+
+.. code:: bash
+
+ $ kubectl create namespace vineyard-system
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ namespace/vineyard-system created
+
+The Vineyard CRDs、Controllers、Webhooks and Scheduler are packaged by `helm`_, you could
+deploy all resources as follows.
+
+.. note::
+
+ The vineyard operator needs permission to create several CRDs and kubernetes
+ resources, before deploying the vineyard operator, please ensure you can create
+ the `clusterrole`_.
+
+.. code:: bash
+
+ $ helm repo add vineyard https://vineyard.oss-ap-southeast-1.aliyuncs.com/charts/
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ "vineyard" has been added to your repositories
+
+Update the vineyard operator chart to the newest one.
+
+.. code:: bash
+
+ $ helm repo update
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ Hang tight while we grab the latest from your chart repositories...
+ ...Successfully got an update from the "vineyard" chart repository
+ Update Complete. ⎈Happy Helming!⎈
+
+Deploy the vineyard operator in the namespace ``vineyard-system``.
+
+.. code:: bash
+
+ $ helm install vineyard-operator vineyard/vineyard-operator -n vineyard-system
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ NAME: vineyard-operator
+ LAST DEPLOYED: Wed Jan 4 16:41:45 2023
+ NAMESPACE: vineyard-system
+ STATUS: deployed
+ REVISION: 1
+ TEST SUITE: None
+ NOTES:
+ Thanks for installing VINEYARD-OPERATOR, release at namespace: vineyard-system, name: vineyard-operator.
+
+ To learn more about the release, try:
+
+ $ helm status vineyard-operator -n vineyard-system # get status of running vineyard operator
+ $ helm get all vineyard-operator -n vineyard-system # get all deployment yaml of vineyard operator
+
+ To uninstall the release, try:
+
+ $ helm uninstall vineyard-operator -n vineyard-system
+
+You could get all details about vineyard operator in the doc :ref:`vineyard-operator`, just have fun with vineyard operator!
+
+Check the status of all vineyard resources created by helm:
+
+.. code:: bash
+
+ $ kubectl get all -n vineyard-system
+
+.. admonition:: Expected output
+ :class: admonition-details
+
+ .. code:: bash
+
+ NAME READY STATUS RESTARTS AGE
+ pod/vineyard-operator-controller-manager-5bcbb75fb6-cfdpk 2/2 Running 0 2m30s
+
+ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+ service/vineyard-operator-controller-manager-metrics-service ClusterIP 10.96.153.134 8443/TCP 2m30s
+ service/vineyard-operator-webhook-service ClusterIP 10.96.9.101 443/TCP 2m30s
+
+ NAME READY UP-TO-DATE AVAILABLE AGE
+ deployment.apps/vineyard-operator-controller-manager 1/1 1 1 2m30s
+
+ NAME DESIRED CURRENT READY AGE
+ replicaset.apps/vineyard-operator-controller-manager-5bcbb75fb6 1 1 1 2m30s
+
+Step 2: Deploy a Vineyard Cluster
+----------------------------------
+
+After successfully installing the Vineyard operator as described in the previous step,
+you can now proceed to deploy a Vineyard cluster. To create a cluster with two Vineyard
+instances, simply create a `Vineyardd` Custom Resource (CR) as shown below.
+
+.. code:: bash
+
+ $ cat <",
+ "value_type_": "float64",
+ "value_type_meta_": "",
+ "value_type_": "float64",
+ "value_type_meta_": "4800)].index)
+ X = df.drop('SalePrice', axis=1) # Features
+ y = df['SalePrice'] # Target variable
+
+ del df
+
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
+
+ del X, y
+
+ vineyard.put(X_train, name="x_train", persist=True)
+ vineyard.put(X_test, name="x_test", persist=True)
+ vineyard.put(y_train, name="y_train", persist=True)
+ vineyard.put(y_test, name="y_test", persist=True)
+
+ # define the model training task
+ def train():
+ from sklearn.linear_model import LinearRegression
+
+ import joblib
+ import pandas as pd
+ import vineyard
+
+ x_train_data = vineyard.get(name="x_train", fetch=True)
+ y_train_data = vineyard.get(name="y_train", fetch=True)
+
+ model = LinearRegression()
+ model.fit(x_train_data, y_train_data)
+
+ joblib.dump(model, '/data/model.pkl')
+
+ # define the model testing task
+ def test():
+ from sklearn.linear_model import LinearRegression
+ from sklearn.metrics import mean_squared_error
+
+ import vineyard
+ import joblib
+ import pandas as pd
+
+ x_test_data = vineyard.get(name="x_test", fetch=True)
+ y_test_data = vineyard.get(name="y_test", fetch=True)
+
+ model = joblib.load("/data/model.pkl")
+ y_pred = model.predict(x_test_data)
+
+ err = mean_squared_error(y_test_data, y_pred)
+
+ with open('/data/output.txt', 'a') as f:
+ f.write(str(err))
+
+ packages_to_install = ["numpy", "pandas", "pyarrow", "requests", "vineyard", "scikit-learn==1.4.0", "joblib==1.3.2"]
+ pip_index_url = "https://pypi.tuna.tsinghua.edu.cn/simple"
+
+ preprocess_processor = create_processor(preprocess, packages_to_install, pip_index_url)
+ train_processor = create_processor(train, packages_to_install, pip_index_url)
+ test_processor = create_processor(test, packages_to_install, pip_index_url)
+
+ # Create a linear regression model task workflow: data preprocessing -> model training -> model testing
+ # The following mount path "/var/run/vineyard" is the default path of the vineyard configuration file
+ flow = dataset.process(processor=preprocess_processor, dataset_mountpath="/var/run/vineyard") \
+ .process(processor=train_processor, dataset_mountpath="/var/run/vineyard") \
+ .process(processor=test_processor, dataset_mountpath="/var/run/vineyard")
+
+ # Submit the data processing task workflow of the linear regression model and wait for it to run to completion
+ run = flow.run(run_id="linear-regression-with-vineyard")
+ run.wait()
+
+Here's an overview of each part of the code:
+
+1. **Create Fluid client**: This code is responsible for establishing
+a connection with the Fluid control platform using the default kubeconfig file and
+creating a Fluid client instance.
+
+2. **Create and configure the vineyard dataset and runtime environment**: Next, the code
+creates a dataset named ``Vineyard``, then obtains the dataset instance, initializes the vineyard
+runtime configuration, and sets up a copy number and memory size to bind the dataset to the
+runtime environment.
+
+3. **Define the data preprocessing function**: This part defines a python function for data
+preprocessing, which includes splitting the training set and the test set, as well as
+data filtering and other operations.
+
+4. **Define model training function**: As the name suggests, this code defines another
+python function for training a linear regression model.
+
+5. **Define the model testing function**: This section contains the model testing logic
+for evaluating the trained model.
+
+6. **Create a task template and define task workflow**: The code encapsulates a task
+template function named create_processor, which uses the previously defined python functions
+to build data preprocessing, model training and model testing steps respectively.
+These steps are designed to be executed sequentially, forming a complete workflow in which
+data preprocessing is the first step, followed by model training, and finally model testing.
+This serial execution sequence ensures that the output of each stage can be used as the input
+of the next stage, thereby achieving a coherent and orderly machine learning process.
+
+7. **[Optional] Enable data affinity scheduling**: After enabling fuse affinity scheduling,
+add the tag ``"fuse.serverful.fluid.io/inject": "true"`` to ensure that related tasks run on the
+same node first through scheduling. to achieve the best performance in data processing.
+
+8. **Submit and execute the task workflow**: Submit the entire linear regression model task
+workflow to the Fluid platform for execution through the run command.
+
+9. **Resource Cleanup**: Finally, clean up all resources created on the Fluid platform.
+
+.. _Install the cloud native AI suite: https://help.aliyun.com/zh/ack/cloud-native-ai-suite/user-guide/deploy-the-cloud-native-ai-suite?spm=a2c4g.11186623.0.i14#task-2038811
+.. _ossutil: https://help.aliyun.com/zh/oss/developer-reference/ossutil
+.. _Kubectl: https://github.com/kubernetes/kubectl
+.. _Helm: https://github.com/helm/helm
\ No newline at end of file
diff --git a/_sources/tutorials/tutorials.rst.txt b/_sources/tutorials/tutorials.rst.txt
new file mode 100644
index 0000000000..10e83f6d63
--- /dev/null
+++ b/_sources/tutorials/tutorials.rst.txt
@@ -0,0 +1,7 @@
+.. Gather all tutorials as an index page
+
+:orphan:
+
+.. include:: ../tutorials/data-processing.rst
+.. include:: ../tutorials/kubernetes.rst
+.. include:: ../tutorials/extending.rst
diff --git a/_static/airflow_etl.jpg b/_static/airflow_etl.jpg
new file mode 100644
index 0000000000..78842377dc
Binary files /dev/null and b/_static/airflow_etl.jpg differ
diff --git a/_static/basic.css b/_static/basic.css
new file mode 100644
index 0000000000..cfc60b86c7
--- /dev/null
+++ b/_static/basic.css
@@ -0,0 +1,921 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+div.section::after {
+ display: block;
+ content: '';
+ clear: left;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+ word-wrap: break-word;
+ overflow-wrap : break-word;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox form.search {
+ overflow: hidden;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+ float: left;
+ width: 80%;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+ float: left;
+ width: 20%;
+ border-left: none;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+
+img {
+ border: 0;
+ max-width: 100%;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li p.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ list-style-type: none;
+}
+
+table.indextable > tbody > tr > td > ul {
+ padding-left: 0em;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+div.modindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+/* -- domain module index --------------------------------------------------- */
+
+table.modindextable td {
+ padding: 2px;
+ border-collapse: collapse;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+div.body {
+ min-width: 360px;
+ max-width: 800px;
+}
+
+div.body p, div.body dd, div.body li, div.body blockquote {
+ -moz-hyphens: auto;
+ -ms-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+}
+
+a.headerlink {
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink,
+caption:hover > a.headerlink,
+p.caption:hover > a.headerlink,
+div.code-block-caption:hover > a.headerlink {
+ visibility: visible;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+img.align-left, figure.align-left, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, figure.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, figure.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+img.align-default, figure.align-default, .figure.align-default {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ text-align: center;
+}
+
+.align-default {
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar,
+aside.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+ clear: right;
+ overflow-x: auto;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+nav.contents,
+aside.topic,
+div.admonition, div.topic, blockquote {
+ clear: left;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+nav.contents,
+aside.topic,
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- content of sidebars/topics/admonitions -------------------------------- */
+
+div.sidebar > :last-child,
+aside.sidebar > :last-child,
+nav.contents > :last-child,
+aside.topic > :last-child,
+div.topic > :last-child,
+div.admonition > :last-child {
+ margin-bottom: 0;
+}
+
+div.sidebar::after,
+aside.sidebar::after,
+nav.contents::after,
+aside.topic::after,
+div.topic::after,
+div.admonition::after,
+blockquote::after {
+ display: block;
+ content: '';
+ clear: both;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.align-center {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.align-default {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table caption span.caption-number {
+ font-style: italic;
+}
+
+table caption span.caption-text {
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+th > :first-child,
+td > :first-child {
+ margin-top: 0px;
+}
+
+th > :last-child,
+td > :last-child {
+ margin-bottom: 0px;
+}
+
+/* -- figures --------------------------------------------------------------- */
+
+div.figure, figure {
+ margin: 0.5em;
+ padding: 0.5em;
+}
+
+div.figure p.caption, figcaption {
+ padding: 0.3em;
+}
+
+div.figure p.caption span.caption-number,
+figcaption span.caption-number {
+ font-style: italic;
+}
+
+div.figure p.caption span.caption-text,
+figcaption span.caption-text {
+}
+
+/* -- field list styles ----------------------------------------------------- */
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.field-name {
+ -moz-hyphens: manual;
+ -ms-hyphens: manual;
+ -webkit-hyphens: manual;
+ hyphens: manual;
+}
+
+/* -- hlist styles ---------------------------------------------------------- */
+
+table.hlist {
+ margin: 1em 0;
+}
+
+table.hlist td {
+ vertical-align: top;
+}
+
+/* -- object description styles --------------------------------------------- */
+
+.sig {
+ font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+}
+
+.sig-name, code.descname {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+.sig-name {
+ font-size: 1.1em;
+}
+
+code.descname {
+ font-size: 1.2em;
+}
+
+.sig-prename, code.descclassname {
+ background-color: transparent;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.sig-paren {
+ font-size: larger;
+}
+
+.sig-param.n {
+ font-style: italic;
+}
+
+/* C++ specific styling */
+
+.sig-inline.c-texpr,
+.sig-inline.cpp-texpr {
+ font-family: unset;
+}
+
+.sig.c .k, .sig.c .kt,
+.sig.cpp .k, .sig.cpp .kt {
+ color: #0033B3;
+}
+
+.sig.c .m,
+.sig.cpp .m {
+ color: #1750EB;
+}
+
+.sig.c .s, .sig.c .sc,
+.sig.cpp .s, .sig.cpp .sc {
+ color: #067D17;
+}
+
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+ list-style: decimal;
+}
+
+ol.loweralpha {
+ list-style: lower-alpha;
+}
+
+ol.upperalpha {
+ list-style: upper-alpha;
+}
+
+ol.lowerroman {
+ list-style: lower-roman;
+}
+
+ol.upperroman {
+ list-style: upper-roman;
+}
+
+:not(li) > ol > li:first-child > :first-child,
+:not(li) > ul > li:first-child > :first-child {
+ margin-top: 0px;
+}
+
+:not(li) > ol > li:last-child > :last-child,
+:not(li) > ul > li:last-child > :last-child {
+ margin-bottom: 0px;
+}
+
+ol.simple ol p,
+ol.simple ul p,
+ul.simple ol p,
+ul.simple ul p {
+ margin-top: 0;
+}
+
+ol.simple > li:not(:first-child) > p,
+ul.simple > li:not(:first-child) > p {
+ margin-top: 0;
+}
+
+ol.simple p,
+ul.simple p {
+ margin-bottom: 0;
+}
+
+aside.footnote > span,
+div.citation > span {
+ float: left;
+}
+aside.footnote > span:last-of-type,
+div.citation > span:last-of-type {
+ padding-right: 0.5em;
+}
+aside.footnote > p {
+ margin-left: 2em;
+}
+div.citation > p {
+ margin-left: 4em;
+}
+aside.footnote > p:last-of-type,
+div.citation > p:last-of-type {
+ margin-bottom: 0em;
+}
+aside.footnote > p:last-of-type:after,
+div.citation > p:last-of-type:after {
+ content: "";
+ clear: both;
+}
+
+dl.field-list {
+ display: grid;
+ grid-template-columns: fit-content(30%) auto;
+}
+
+dl.field-list > dt {
+ font-weight: bold;
+ word-break: break-word;
+ padding-left: 0.5em;
+ padding-right: 5px;
+}
+
+dl.field-list > dd {
+ padding-left: 0.5em;
+ margin-top: 0em;
+ margin-left: 0em;
+ margin-bottom: 0em;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd > :first-child {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+.sig dd {
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+
+.sig dl {
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+
+dl > dd:last-child,
+dl > dd:last-child > :last-child {
+ margin-bottom: 0;
+}
+
+dt:target, span.highlighted {
+ background-color: #fbe54e;
+}
+
+rect.highlighted {
+ fill: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa;
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+ font-family: sans-serif;
+}
+
+.accelerator {
+ text-decoration: underline;
+}
+
+.classifier {
+ font-style: oblique;
+}
+
+.classifier:before {
+ font-style: normal;
+ margin: 0 0.5em;
+ content: ":";
+ display: inline-block;
+}
+
+abbr, acronym {
+ border-bottom: dotted 1px;
+ cursor: help;
+}
+
+.translated {
+ background-color: rgba(207, 255, 207, 0.2)
+}
+
+.untranslated {
+ background-color: rgba(255, 207, 207, 0.2)
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+ overflow-y: hidden; /* fixes display issues on Chrome browsers */
+}
+
+pre, div[class*="highlight-"] {
+ clear: both;
+}
+
+span.pre {
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ -webkit-hyphens: none;
+ hyphens: none;
+ white-space: nowrap;
+}
+
+div[class*="highlight-"] {
+ margin: 1em 0;
+}
+
+td.linenos pre {
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ display: block;
+}
+
+table.highlighttable tbody {
+ display: block;
+}
+
+table.highlighttable tr {
+ display: flex;
+}
+
+table.highlighttable td {
+ margin: 0;
+ padding: 0;
+}
+
+table.highlighttable td.linenos {
+ padding-right: 0.5em;
+}
+
+table.highlighttable td.code {
+ flex: 1;
+ overflow: hidden;
+}
+
+.highlight .hll {
+ display: block;
+}
+
+div.highlight pre,
+table.highlighttable pre {
+ margin: 0;
+}
+
+div.code-block-caption + div {
+ margin-top: 0;
+}
+
+div.code-block-caption {
+ margin-top: 1em;
+ padding: 2px 5px;
+ font-size: small;
+}
+
+div.code-block-caption code {
+ background-color: transparent;
+}
+
+table.highlighttable td.linenos,
+span.linenos,
+div.highlight span.gp { /* gp: Generic.Prompt */
+ user-select: none;
+ -webkit-user-select: text; /* Safari fallback only */
+ -webkit-user-select: none; /* Chrome/Safari */
+ -moz-user-select: none; /* Firefox */
+ -ms-user-select: none; /* IE10+ */
+}
+
+div.code-block-caption span.caption-number {
+ padding: 0.1em 0.3em;
+ font-style: italic;
+}
+
+div.code-block-caption span.caption-text {
+}
+
+div.literal-block-wrapper {
+ margin: 1em 0;
+}
+
+code.xref, a code {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+ background-color: transparent;
+}
+
+.viewcode-link {
+ float: right;
+}
+
+.viewcode-back {
+ float: right;
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ margin: -1px -10px;
+ padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+span.eqno a.headerlink {
+ position: absolute;
+ z-index: 1;
+}
+
+div.math:hover a.headerlink {
+ visibility: visible;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+}
\ No newline at end of file
diff --git a/_static/check-solid.svg b/_static/check-solid.svg
new file mode 100644
index 0000000000..92fad4b5c0
--- /dev/null
+++ b/_static/check-solid.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js
new file mode 100644
index 0000000000..54b3c46381
--- /dev/null
+++ b/_static/clipboard.min.js
@@ -0,0 +1,7 @@
+/*!
+ * clipboard.js v2.0.8
+ * https://clipboardjs.com/
+ *
+ * Licensed MIT © Zeno Rocha
+ */
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1
\ No newline at end of file
diff --git a/_static/cncf-sandbox-color.svg b/_static/cncf-sandbox-color.svg
new file mode 100644
index 0000000000..d424565eeb
--- /dev/null
+++ b/_static/cncf-sandbox-color.svg
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/_static/cncf-small.png b/_static/cncf-small.png
new file mode 100644
index 0000000000..27bdc98ff2
Binary files /dev/null and b/_static/cncf-small.png differ
diff --git a/_static/cncf-tiny.png b/_static/cncf-tiny.png
new file mode 100644
index 0000000000..2d9fe42414
Binary files /dev/null and b/_static/cncf-tiny.png differ
diff --git a/_static/cncf.png b/_static/cncf.png
new file mode 100644
index 0000000000..97796cba6c
Binary files /dev/null and b/_static/cncf.png differ
diff --git a/_static/copy-button.svg b/_static/copy-button.svg
new file mode 100644
index 0000000000..9c074dae52
--- /dev/null
+++ b/_static/copy-button.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/_static/copybutton.css b/_static/copybutton.css
new file mode 100644
index 0000000000..f1916ec7d1
--- /dev/null
+++ b/_static/copybutton.css
@@ -0,0 +1,94 @@
+/* Copy buttons */
+button.copybtn {
+ position: absolute;
+ display: flex;
+ top: .3em;
+ right: .3em;
+ width: 1.7em;
+ height: 1.7em;
+ opacity: 0;
+ transition: opacity 0.3s, border .3s, background-color .3s;
+ user-select: none;
+ padding: 0;
+ border: none;
+ outline: none;
+ border-radius: 0.4em;
+ /* The colors that GitHub uses */
+ border: #1b1f2426 1px solid;
+ background-color: #f6f8fa;
+ color: #57606a;
+}
+
+button.copybtn.success {
+ border-color: #22863a;
+ color: #22863a;
+}
+
+button.copybtn svg {
+ stroke: currentColor;
+ width: 1.5em;
+ height: 1.5em;
+ padding: 0.1em;
+}
+
+div.highlight {
+ position: relative;
+}
+
+/* Show the copybutton */
+.highlight:hover button.copybtn, button.copybtn.success {
+ opacity: 1;
+}
+
+.highlight button.copybtn:hover {
+ background-color: rgb(235, 235, 235);
+}
+
+.highlight button.copybtn:active {
+ background-color: rgb(187, 187, 187);
+}
+
+/**
+ * A minimal CSS-only tooltip copied from:
+ * https://codepen.io/mildrenben/pen/rVBrpK
+ *
+ * To use, write HTML like the following:
+ *
+ * Short
+ */
+ .o-tooltip--left {
+ position: relative;
+ }
+
+ .o-tooltip--left:after {
+ opacity: 0;
+ visibility: hidden;
+ position: absolute;
+ content: attr(data-tooltip);
+ padding: .2em;
+ font-size: .8em;
+ left: -.2em;
+ background: grey;
+ color: white;
+ white-space: nowrap;
+ z-index: 2;
+ border-radius: 2px;
+ transform: translateX(-102%) translateY(0);
+ transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1);
+}
+
+.o-tooltip--left:hover:after {
+ display: block;
+ opacity: 1;
+ visibility: visible;
+ transform: translateX(-100%) translateY(0);
+ transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1);
+ transition-delay: .5s;
+}
+
+/* By default the copy button shouldn't show up when printing a page */
+@media print {
+ button.copybtn {
+ display: none;
+ }
+}
diff --git a/_static/copybutton.js b/_static/copybutton.js
new file mode 100644
index 0000000000..be65e437f9
--- /dev/null
+++ b/_static/copybutton.js
@@ -0,0 +1,248 @@
+// Localization support
+const messages = {
+ 'en': {
+ 'copy': 'Copy',
+ 'copy_to_clipboard': 'Copy to clipboard',
+ 'copy_success': 'Copied!',
+ 'copy_failure': 'Failed to copy',
+ },
+ 'es' : {
+ 'copy': 'Copiar',
+ 'copy_to_clipboard': 'Copiar al portapapeles',
+ 'copy_success': '¡Copiado!',
+ 'copy_failure': 'Error al copiar',
+ },
+ 'de' : {
+ 'copy': 'Kopieren',
+ 'copy_to_clipboard': 'In die Zwischenablage kopieren',
+ 'copy_success': 'Kopiert!',
+ 'copy_failure': 'Fehler beim Kopieren',
+ },
+ 'fr' : {
+ 'copy': 'Copier',
+ 'copy_to_clipboard': 'Copier dans le presse-papier',
+ 'copy_success': 'Copié !',
+ 'copy_failure': 'Échec de la copie',
+ },
+ 'ru': {
+ 'copy': 'Скопировать',
+ 'copy_to_clipboard': 'Скопировать в буфер',
+ 'copy_success': 'Скопировано!',
+ 'copy_failure': 'Не удалось скопировать',
+ },
+ 'zh-CN': {
+ 'copy': '复制',
+ 'copy_to_clipboard': '复制到剪贴板',
+ 'copy_success': '复制成功!',
+ 'copy_failure': '复制失败',
+ },
+ 'it' : {
+ 'copy': 'Copiare',
+ 'copy_to_clipboard': 'Copiato negli appunti',
+ 'copy_success': 'Copiato!',
+ 'copy_failure': 'Errore durante la copia',
+ }
+}
+
+let locale = 'en'
+if( document.documentElement.lang !== undefined
+ && messages[document.documentElement.lang] !== undefined ) {
+ locale = document.documentElement.lang
+}
+
+let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT;
+if (doc_url_root == '#') {
+ doc_url_root = '';
+}
+
+/**
+ * SVG files for our copy buttons
+ */
+let iconCheck = `
+ ${messages[locale]['copy_success']}
+
+
+ `
+
+// If the user specified their own SVG use that, otherwise use the default
+let iconCopy = ``;
+if (!iconCopy) {
+ iconCopy = `
+ ${messages[locale]['copy_to_clipboard']}
+
+
+
+ `
+}
+
+/**
+ * Set up copy/paste for code blocks
+ */
+
+const runWhenDOMLoaded = cb => {
+ if (document.readyState != 'loading') {
+ cb()
+ } else if (document.addEventListener) {
+ document.addEventListener('DOMContentLoaded', cb)
+ } else {
+ document.attachEvent('onreadystatechange', function() {
+ if (document.readyState == 'complete') cb()
+ })
+ }
+}
+
+const codeCellId = index => `codecell${index}`
+
+// Clears selected text since ClipboardJS will select the text when copying
+const clearSelection = () => {
+ if (window.getSelection) {
+ window.getSelection().removeAllRanges()
+ } else if (document.selection) {
+ document.selection.empty()
+ }
+}
+
+// Changes tooltip text for a moment, then changes it back
+// We want the timeout of our `success` class to be a bit shorter than the
+// tooltip and icon change, so that we can hide the icon before changing back.
+var timeoutIcon = 2000;
+var timeoutSuccessClass = 1500;
+
+const temporarilyChangeTooltip = (el, oldText, newText) => {
+ el.setAttribute('data-tooltip', newText)
+ el.classList.add('success')
+ // Remove success a little bit sooner than we change the tooltip
+ // So that we can use CSS to hide the copybutton first
+ setTimeout(() => el.classList.remove('success'), timeoutSuccessClass)
+ setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon)
+}
+
+// Changes the copy button icon for two seconds, then changes it back
+const temporarilyChangeIcon = (el) => {
+ el.innerHTML = iconCheck;
+ setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon)
+}
+
+const addCopyButtonToCodeCells = () => {
+ // If ClipboardJS hasn't loaded, wait a bit and try again. This
+ // happens because we load ClipboardJS asynchronously.
+ if (window.ClipboardJS === undefined) {
+ setTimeout(addCopyButtonToCodeCells, 250)
+ return
+ }
+
+ // Add copybuttons to all of our code cells
+ const COPYBUTTON_SELECTOR = 'div.notranslate:not(.prompt) div.highlight pre';
+ const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR)
+ codeCells.forEach((codeCell, index) => {
+ const id = codeCellId(index)
+ codeCell.setAttribute('id', id)
+
+ const clipboardButton = id =>
+ `
+ ${iconCopy}
+ `
+ codeCell.insertAdjacentHTML('afterend', clipboardButton(id))
+ })
+
+function escapeRegExp(string) {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+}
+
+/**
+ * Removes excluded text from a Node.
+ *
+ * @param {Node} target Node to filter.
+ * @param {string} exclude CSS selector of nodes to exclude.
+ * @returns {DOMString} Text from `target` with text removed.
+ */
+function filterText(target, exclude) {
+ const clone = target.cloneNode(true); // clone as to not modify the live DOM
+ if (exclude) {
+ // remove excluded nodes
+ clone.querySelectorAll(exclude).forEach(node => node.remove());
+ }
+ return clone.innerText;
+}
+
+// Callback when a copy button is clicked. Will be passed the node that was clicked
+// should then grab the text and replace pieces of text that shouldn't be used in output
+function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") {
+ var regexp;
+ var match;
+
+ // Do we check for line continuation characters and "HERE-documents"?
+ var useLineCont = !!lineContinuationChar
+ var useHereDoc = !!hereDocDelim
+
+ // create regexp to capture prompt and remaining line
+ if (isRegexp) {
+ regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)')
+ } else {
+ regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)')
+ }
+
+ const outputLines = [];
+ var promptFound = false;
+ var gotLineCont = false;
+ var gotHereDoc = false;
+ const lineGotPrompt = [];
+ for (const line of textContent.split('\n')) {
+ match = line.match(regexp)
+ if (match || gotLineCont || gotHereDoc) {
+ promptFound = regexp.test(line)
+ lineGotPrompt.push(promptFound)
+ if (removePrompts && promptFound) {
+ outputLines.push(match[2])
+ } else {
+ outputLines.push(line)
+ }
+ gotLineCont = line.endsWith(lineContinuationChar) & useLineCont
+ if (line.includes(hereDocDelim) & useHereDoc)
+ gotHereDoc = !gotHereDoc
+ } else if (!onlyCopyPromptLines) {
+ outputLines.push(line)
+ } else if (copyEmptyLines && line.trim() === '') {
+ outputLines.push(line)
+ }
+ }
+
+ // If no lines with the prompt were found then just use original lines
+ if (lineGotPrompt.some(v => v === true)) {
+ textContent = outputLines.join('\n');
+ }
+
+ // Remove a trailing newline to avoid auto-running when pasting
+ if (textContent.endsWith("\n")) {
+ textContent = textContent.slice(0, -1)
+ }
+ return textContent
+}
+
+
+var copyTargetText = (trigger) => {
+ var target = document.querySelector(trigger.attributes['data-clipboard-target'].value);
+
+ // get filtered text
+ let exclude = '.linenos';
+
+ let text = filterText(target, exclude);
+ return formatCopyText(text, '', false, true, true, true, '', '')
+}
+
+ // Initialize with a callback so we can modify the text before copy
+ const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText})
+
+ // Update UI with error/success messages
+ clipboard.on('success', event => {
+ clearSelection()
+ temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success'])
+ temporarilyChangeIcon(event.trigger)
+ })
+
+ clipboard.on('error', event => {
+ temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure'])
+ })
+}
+
+runWhenDOMLoaded(addCopyButtonToCodeCells)
\ No newline at end of file
diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js
new file mode 100644
index 0000000000..dbe1aaad79
--- /dev/null
+++ b/_static/copybutton_funcs.js
@@ -0,0 +1,73 @@
+function escapeRegExp(string) {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
+}
+
+/**
+ * Removes excluded text from a Node.
+ *
+ * @param {Node} target Node to filter.
+ * @param {string} exclude CSS selector of nodes to exclude.
+ * @returns {DOMString} Text from `target` with text removed.
+ */
+export function filterText(target, exclude) {
+ const clone = target.cloneNode(true); // clone as to not modify the live DOM
+ if (exclude) {
+ // remove excluded nodes
+ clone.querySelectorAll(exclude).forEach(node => node.remove());
+ }
+ return clone.innerText;
+}
+
+// Callback when a copy button is clicked. Will be passed the node that was clicked
+// should then grab the text and replace pieces of text that shouldn't be used in output
+export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") {
+ var regexp;
+ var match;
+
+ // Do we check for line continuation characters and "HERE-documents"?
+ var useLineCont = !!lineContinuationChar
+ var useHereDoc = !!hereDocDelim
+
+ // create regexp to capture prompt and remaining line
+ if (isRegexp) {
+ regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)')
+ } else {
+ regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)')
+ }
+
+ const outputLines = [];
+ var promptFound = false;
+ var gotLineCont = false;
+ var gotHereDoc = false;
+ const lineGotPrompt = [];
+ for (const line of textContent.split('\n')) {
+ match = line.match(regexp)
+ if (match || gotLineCont || gotHereDoc) {
+ promptFound = regexp.test(line)
+ lineGotPrompt.push(promptFound)
+ if (removePrompts && promptFound) {
+ outputLines.push(match[2])
+ } else {
+ outputLines.push(line)
+ }
+ gotLineCont = line.endsWith(lineContinuationChar) & useLineCont
+ if (line.includes(hereDocDelim) & useHereDoc)
+ gotHereDoc = !gotHereDoc
+ } else if (!onlyCopyPromptLines) {
+ outputLines.push(line)
+ } else if (copyEmptyLines && line.trim() === '') {
+ outputLines.push(line)
+ }
+ }
+
+ // If no lines with the prompt were found then just use original lines
+ if (lineGotPrompt.some(v => v === true)) {
+ textContent = outputLines.join('\n');
+ }
+
+ // Remove a trailing newline to avoid auto-running when pasting
+ if (textContent.endsWith("\n")) {
+ textContent = textContent.slice(0, -1)
+ }
+ return textContent
+}
diff --git a/_static/css/brands.min.css b/_static/css/brands.min.css
new file mode 100644
index 0000000000..714509e6f9
--- /dev/null
+++ b/_static/css/brands.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2022 Fonticons, Inc.
+ */
+:host,:root{--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}@font-face{font-family:"Font Awesome 6 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.ttf) format("truetype")}.fa-brands,.fab{font-family:"Font Awesome 6 Brands";font-weight:400}.fa-42-group:before,.fa-innosoft:before{content:"\e080"}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-adn:before{content:"\f170"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-airbnb:before{content:"\f834"}.fa-algolia:before{content:"\f36c"}.fa-alipay:before{content:"\f642"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-amilia:before{content:"\f36d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-pay:before{content:"\f415"}.fa-artstation:before{content:"\f77a"}.fa-asymmetrik:before{content:"\f372"}.fa-atlassian:before{content:"\f77b"}.fa-audible:before{content:"\f373"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-aws:before{content:"\f375"}.fa-bandcamp:before{content:"\f2d5"}.fa-battle-net:before{content:"\f835"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bilibili:before{content:"\e3d9"}.fa-bimobject:before{content:"\f378"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bootstrap:before{content:"\f836"}.fa-bots:before{content:"\e340"}.fa-btc:before{content:"\f15a"}.fa-buffer:before{content:"\f837"}.fa-buromobelexperte:before{content:"\f37f"}.fa-buy-n-large:before{content:"\f8a6"}.fa-buysellads:before{content:"\f20d"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-chrome:before{content:"\f268"}.fa-chromecast:before{content:"\f838"}.fa-cloudflare:before{content:"\e07d"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cmplid:before{content:"\e360"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cotton-bureau:before{content:"\f89e"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-critical-role:before{content:"\f6c9"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dailymotion:before{content:"\e052"}.fa-dashcube:before{content:"\f210"}.fa-deezer:before{content:"\e077"}.fa-delicious:before{content:"\f1a5"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dhl:before{content:"\f790"}.fa-diaspora:before{content:"\f791"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-draft2digital:before{content:"\f396"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drupal:before{content:"\f1a9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edge-legacy:before{content:"\e078"}.fa-elementor:before{content:"\f430"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envira:before{content:"\f299"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-etsy:before{content:"\f2d7"}.fa-evernote:before{content:"\f839"}.fa-expeditedssl:before{content:"\f23e"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-figma:before{content:"\f799"}.fa-firefox:before{content:"\f269"}.fa-firefox-browser:before{content:"\e007"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-fly:before{content:"\f417"}.fa-font-awesome-flag:before,.fa-font-awesome-logo-full:before,.fa-font-awesome:before{content:"\f2b4"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-fulcrum:before{content:"\f50b"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-git:before{content:"\f1d3"}.fa-git-alt:before{content:"\f841"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-gofore:before{content:"\f3a7"}.fa-golang:before{content:"\e40f"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-pay:before{content:"\e079"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guilded:before{content:"\e07e"}.fa-gulp:before{content:"\f3ae"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hashnode:before{content:"\e499"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-hive:before{content:"\e07f"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-hotjar:before{content:"\f3b1"}.fa-houzz:before{content:"\f27c"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-ideal:before{content:"\e013"}.fa-imdb:before{content:"\f2d8"}.fa-instagram:before{content:"\f16d"}.fa-instagram-square:before{content:"\e055"}.fa-instalod:before{content:"\e081"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-itch-io:before{content:"\f83a"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joomla:before{content:"\f1aa"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaggle:before{content:"\f5fa"}.fa-keybase:before{content:"\f4f5"}.fa-keycdn:before{content:"\f3ba"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-korvue:before{content:"\f42f"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-leanpub:before{content:"\f212"}.fa-less:before{content:"\f41d"}.fa-line:before{content:"\f3c0"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-mailchimp:before{content:"\f59e"}.fa-mandalorian:before{content:"\f50f"}.fa-markdown:before{content:"\f60f"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-mdb:before{content:"\f8ca"}.fa-medapps:before{content:"\f3c6"}.fa-medium-m:before,.fa-medium:before{content:"\f23a"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-mendeley:before{content:"\f7b3"}.fa-microblog:before{content:"\e01a"}.fa-microsoft:before{content:"\f3ca"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mixer:before{content:"\e056"}.fa-mizuni:before{content:"\f3cc"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-nfc-directional:before{content:"\e530"}.fa-nfc-symbol:before{content:"\e531"}.fa-nimblr:before{content:"\f5a8"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-octopus-deploy:before{content:"\e082"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-old-republic:before{content:"\f510"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-orcid:before{content:"\f8d2"}.fa-osi:before{content:"\f41a"}.fa-padlet:before{content:"\e4a0"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-palfed:before{content:"\f3d8"}.fa-patreon:before{content:"\f3d9"}.fa-paypal:before{content:"\f1ed"}.fa-perbyte:before{content:"\e083"}.fa-periscope:before{content:"\f3da"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-square:before{content:"\e01e"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-pix:before{content:"\e43a"}.fa-playstation:before{content:"\f3df"}.fa-product-hunt:before{content:"\f288"}.fa-pushed:before{content:"\f3e1"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-r-project:before{content:"\f4f7"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-renren:before{content:"\f18b"}.fa-replyd:before{content:"\f3e6"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-rev:before{content:"\f5b2"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-rust:before{content:"\e07a"}.fa-safari:before{content:"\f267"}.fa-salesforce:before{content:"\f83b"}.fa-sass:before{content:"\f41e"}.fa-schlix:before{content:"\f3ea"}.fa-screenpal:before{content:"\e570"}.fa-scribd:before{content:"\f28a"}.fa-searchengin:before{content:"\f3eb"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-servicestack:before{content:"\f3ec"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shopify:before{content:"\e057"}.fa-shopware:before{content:"\f5b5"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sith:before{content:"\f512"}.fa-sitrox:before{content:"\e44a"}.fa-sketch:before{content:"\f7c6"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack-hash:before,.fa-slack:before{content:"\f198"}.fa-slideshare:before{content:"\f1e7"}.fa-snapchat-ghost:before,.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-square:before{content:"\f2ad"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-speakap:before{content:"\f3f3"}.fa-speaker-deck:before{content:"\f83c"}.fa-spotify:before{content:"\f1bc"}.fa-square-font-awesome:before{content:"\f425"}.fa-font-awesome-alt:before,.fa-square-font-awesome-stroke:before{content:"\f35c"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stackpath:before{content:"\f842"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-sticker-mule:before{content:"\f3f7"}.fa-strava:before{content:"\f428"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-superpowers:before{content:"\f2dd"}.fa-supple:before{content:"\f3f9"}.fa-suse:before{content:"\f7d6"}.fa-swift:before{content:"\f8e1"}.fa-symfony:before{content:"\f83d"}.fa-teamspeak:before{content:"\f4f9"}.fa-telegram-plane:before,.fa-telegram:before{content:"\f2c6"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-the-red-yeti:before{content:"\f69d"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-think-peaks:before{content:"\f731"}.fa-tiktok:before{content:"\e07b"}.fa-trade-federation:before{content:"\f513"}.fa-trello:before{content:"\f181"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbraco:before{content:"\f8e8"}.fa-uncharted:before{content:"\e084"}.fa-uniregistry:before{content:"\f404"}.fa-unity:before{content:"\e049"}.fa-unsplash:before{content:"\e07c"}.fa-untappd:before{content:"\f405"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-vaadin:before{content:"\f408"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-viber:before{content:"\f409"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-vuejs:before{content:"\f41f"}.fa-watchman-monitoring:before{content:"\e087"}.fa-waze:before{content:"\f83f"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-whmcs:before{content:"\f40d"}.fa-wikipedia-w:before{content:"\f266"}.fa-windows:before{content:"\f17a"}.fa-wirsindhandwerk:before,.fa-wsh:before{content:"\e2d0"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wodu:before{content:"\e088"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yammer:before{content:"\f840"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}
\ No newline at end of file
diff --git a/_static/css/custom.css b/_static/css/custom.css
new file mode 100644
index 0000000000..42f56b2532
--- /dev/null
+++ b/_static/css/custom.css
@@ -0,0 +1,55 @@
+.fa.fa-2x {
+ font-size: 36px;
+}
+
+/* Decrease the padding of button block in panels */
+div.card-body.card-body-less-padding {
+ padding: 0.25em;
+}
+
+/* Disable theme toggle */
+div.theme-toggle-container.theme-toggle-content {
+ display: none;
+}
+
+/* Proper distance at the bottom of TOC tree */
+.sidebar-container > .sidebar-sticky > .sidebar-scroll > .sidebar-tree {
+ padding-bottom: 1em;
+}
+
+/* Admonition for drop-down like details component */
+
+.admonition.admonition-details {
+ padding: 0 0 0 0;
+ margin: 0 auto;
+}
+
+.admonition.admonition-details.active > :not(.admonition-title) {
+ display: inherit;
+}
+
+.admonition.admonition-details > :not(.admonition-title) {
+ display: none;
+}
+
+.admonition.admonition-details > p.admonition-title, p.topic-title {
+ margin: 0 0 0 0;
+}
+
+.admonition.admonition-details > blockquote {
+ padding: 0;
+}
+
+.admonition.admonition-details > blockquote > div > div[class^=highlight-] {
+ margin: 0;
+}
+
+.admonition.admonition-details > blockquote > div > div[class^=table-wrapper] {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding: 0 0 0 0;
+}
+
+.admonition.admonition-details > blockquote > div > div[class^=table-wrapper] > table {
+ min-width: 100%;
+}
diff --git a/_static/css/index.css b/_static/css/index.css
new file mode 100644
index 0000000000..bfeef1af4f
--- /dev/null
+++ b/_static/css/index.css
@@ -0,0 +1,442 @@
+body {
+ font-family: "Lato", sans-serif;
+ margin: 0;
+}
+
+/* nav {
+ position: sticky;
+ top: 0;
+ transition: background-color .25s;
+} */
+
+.list-style-none {
+ list-style: none;
+}
+
+.padding-left-right-20 {
+ padding: 0 20px;
+}
+
+nav i {
+ padding: 0 20px;
+}
+
+h4 > i {
+ padding-right: 10px;
+}
+
+p i {
+ padding-left: 6px;
+}
+
+a {
+ text-decoration: none;
+}
+
+.button {
+ border: none;
+ width: 120px;
+ height: 50px;
+ border-radius: 7px;
+ font-weight: 500;
+ font-size: 0.95rem;
+}
+
+.button:hover {
+ cursor: pointer;
+}
+
+.background-gradient-color {
+ background: linear-gradient(
+ 270deg,
+ rgba(35, 128, 242, 0.5) 15.55%,
+ rgba(35, 128, 242, 0) 99.31%
+ ),
+ rgba(49, 227, 222, 0.7);
+}
+
+/* html:not([data-scroll='0']) {
+ .navigator.background-gradient-color {
+ background: #f5f5f5;
+ box-shadow: 0 0 .5em rgba(0, 0, 0, .5);
+ }
+} */
+
+.main-content {
+ max-width: max(70%, 1080px);
+}
+
+.nav-link {
+ color: white;
+}
+
+.nav-link:hover {
+ color: blue;
+}
+
+.flex {
+ display: flex;
+}
+
+.flex-column {
+ flex-direction: column;
+}
+
+.align-items-center {
+ align-items: center;
+}
+
+.vertical-align-center {
+ margin: 0 auto;
+}
+
+.justify-content-space-around {
+ justify-content: space-around;
+}
+
+.justify-content-space-between {
+ justify-content: space-between;
+}
+
+.justify-content-center {
+ justify-content: center;
+}
+
+.gap-sm {
+ gap: 20px;
+}
+
+.navbar {
+ padding: 30px 3%;
+ margin: 0 auto;
+}
+
+.logo {
+ width: 140px;
+ height: 40px;
+ object-fit: contain;
+}
+
+.logo > a > img {
+ max-width: 100%;
+ max-height: 100%;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-bold {
+ font-size: 1.1rem;
+ font-weight: 600;
+}
+
+.text-underline {
+ text-decoration: underline;
+ text-decoration-thickness: 2px;
+ text-underline-offset: 10px;
+}
+
+.text-white {
+ color: white;
+}
+
+.text-black {
+ color: black;
+}
+
+.padding-bottom-20 {
+ padding-bottom: 20px;
+}
+
+.padding-bottom-10 {
+ padding-bottom: 10px;
+}
+
+.btn-container {
+ display: flex;
+ gap: 15px;
+ margin-top: 30px;
+}
+
+.btn-primary {
+ background-color: #2380f2;
+ color: white;
+}
+
+.btn-secondary {
+ background-color: #f1f1f1;
+ color: #476581;
+}
+
+.termynal {
+ margin-top: 30px;
+ text-align: left;
+}
+
+.breaking-word-all {
+ word-break: break-all;
+}
+
+.font-weight-300 {
+ font-weight: 300;
+}
+
+.hero-container {
+ padding: 100px 3% 100px;
+}
+
+.hero-text {
+ font-size: 3rem;
+ color: #f8f8f8;
+}
+
+.hero-text-secondary {
+ width: 45%;
+ margin-top: -15px;
+ color: white;
+ font-weight: 300;
+ font-size: larger;
+}
+
+.feature-section {
+ padding: 100px 3% 25px;
+ font-size: larger;
+}
+
+.feature-section > .main-content {
+ margin: 0 auto;
+}
+
+.feature-item {
+ width: 45%;
+}
+
+.feature-item > p {
+ font-weight: 300;
+}
+
+.feature-item-sm > h4 {
+ display: inline-block;
+ height: 1rem;
+}
+
+.feature-item-sm > p {
+ font-weight: 100;
+}
+
+.feature-item-sm > span {
+ margin: auto 1em 1em 0;
+ text-align: right;
+}
+
+.feature-item-sm {
+ width: 18em;
+ height: 15em;
+ background-color: #ffffff;
+ padding: 0 0.5em 0 0.5em;
+ display: flex;
+ flex-direction: column;
+ border-radius: 0 1.25em 0 1.25em;
+}
+
+.use-case-section {
+ background-color: ghostwhite;
+}
+
+.banner {
+ padding: 120px 0px 70px;
+ font-weight: 500;
+ font-size: 1.5rem;
+ margin: 0 auto;
+}
+
+.banner-link {
+ text-decoration: underline;
+ color: black;
+}
+
+.footer {
+ padding: 50px 20%;
+ color: white;
+ background-color: black;
+ font-weight: 300;
+}
+
+.footer-info-text {
+ font-size: 0.85rem;
+ padding-top: 10px;
+}
+
+.footer-link-text {
+ color: white;
+ text-decoration: underline;
+}
+
+.img-container {
+ width: 300px;
+ height: 100px;
+ object-fit: cover;
+ margin: 0 auto;
+}
+
+.media-section {
+ display: flex;
+}
+
+.navbar ul {
+ display: flex;
+}
+
+#mobile-menu {
+ display: none;
+}
+
+.text-wrapping {
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ -ms-word-break: break-all;
+ word-break: break-word;
+ -ms-hyphens: auto;
+ -moz-hyphens: auto;
+ -webkit-hyphens: auto;
+ hyphens: auto;
+}
+
+@media only screen and (max-width: 786px) {
+ .media-section {
+ display: none;
+ }
+
+ #mobile-menu {
+ display: block;
+ }
+
+ .menu-toggle {
+ justify-self: end;
+ }
+
+ nav {
+ position: fixed;
+ width: 100vw;
+ }
+
+ .navbar {
+ width: 90%;
+ margin: 0 auto;
+ }
+
+ .navbar-linkss {
+ display: none;
+ }
+
+ .menu-toggle, .bar {
+ display: block;
+ cursor: pointer;
+ }
+
+ .menu-toggle .bar {
+ width: 25px;
+ height: 3px;
+ background-color: #3f3f3f;
+ margin: 5px auto;
+ -webkit-transition: all 0.3s ease-in-out;
+ -o-transition: all 0.3s ease-in-out;
+ transition: all 0.3s ease-in-out;
+ }
+
+ .navbar ul {
+ display: none;
+ }
+
+ .nav-link-container {
+ display: flex;
+ flex-direction: column;
+ position: fixed;
+ justify-content: start;
+ top: 60px;
+ bottom: 0;
+ background-color: #fff;
+ width: 100vw;
+ height: calc(100% - 60px);
+ transform: translate(-12%);
+ text-align: center;
+ overflow: hidden;
+ }
+
+ .navbar li {
+ padding: 25px;
+ }
+
+ .navbar li:first-child {
+ margin-top: 50px;
+ }
+
+ .navbar .nav-link {
+ color: black;
+ font-size: 1.3rem;
+ }
+
+ #mobile-menu.is-active .bar:nth-child(2) {
+ opacity: 0;
+ }
+
+ #mobile-menu.is-active .bar:nth-child(1) {
+ -webkit-transform: translateY(8px) rotate(45deg);
+ -ms-transform: translateY(8px) rotate(45deg);
+ -o-transform: translateY(8px) rotate(45deg);
+ transform: translateY(8px) rotate(45deg);
+ }
+
+ #mobile-menu.is-active .bar:nth-child(3) {
+ -webkit-transform: translateY(-8px) rotate(-45deg);
+ -ms-transform: translateY(-8px) rotate(-45deg);
+ -o-transform: translateY(-8px) rotate(-45deg);
+ transform: translateY(-8px) rotate(-45deg);
+ }
+
+ .hero-container {
+ width: 90%;
+ }
+
+ .hero-text-secondary {
+ width: 70%;
+ }
+
+ .footer {
+ padding: 50px 5%;
+ }
+
+ .footer-container {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ row-gap: 5px;
+ gap: 5px;
+ }
+
+ .feature-container {
+ display: grid;
+ grid-template-columns: repeat(1, 1fr);
+ padding-bottom: 1em;
+ }
+
+ .feature-section-mobile {
+ padding: 100px 3% 0px;
+ }
+
+ .feature-section {
+ padding: 100px 3% 0px;
+ font-size: initial;
+ }
+
+ .feature-item {
+ width: 80%;
+ margin: 0 auto;
+ }
+
+ .feature-item-sm {
+ margin: 0 auto;
+ width: 80%;
+ height: auto;
+ }
+}
diff --git a/_static/css/panels.css b/_static/css/panels.css
new file mode 100644
index 0000000000..5cf775f167
--- /dev/null
+++ b/_static/css/panels.css
@@ -0,0 +1,147 @@
+/* Referred and derived from https://github.com/flyteorg/furo/blob/main/src/furo/assets/styles/flyte.css */
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-weight: bold;
+}
+
+.caption-text {
+ font-size: 15px;
+ /* color: #696969; */
+ color: #333333;
+}
+
+div.sphinx-bs .card {
+ flex-direction: row;
+}
+
+/* sphinx-panels custom styles */
+div.sphinx-bs .card-header {
+ border-bottom: none;
+ background-color: var(--color-background-primary);
+ display: flex;
+ align-items: center;
+ justify-content: left;
+ width: 28%;
+ float: left;
+}
+
+.sphinx-bs .card-header:first-child {
+ border-radius: calc(0.25rem - 1px) 0 0 calc(0.25rem - 1px);
+}
+
+div.sphinx-bs .card-header .sphinx-bs.btn,
+div.sphinx-bs .card-body .sphinx-bs.btn,
+div.sphinx-bs .card-header p.card-text {
+ font-size: 1rem;
+ text-decoration: none;
+ word-spacing: 2.5px;
+ color: var(--color-sidebar-link-text);
+}
+
+div.sphinx-bs .card-header p.card-text a {
+ text-align: left;
+}
+
+.sphinx-bs.btn:focus {
+ box-shadow: none;
+}
+
+div.sphinx-bs .card-body {
+ width: 72%;
+ float: left;
+}
+
+.sphinx-bs .card-body .fa {
+ color: var(--color-sidebar-link-text);
+}
+
+.sphinx-bs .card-body:hover .fa {
+ color: var(--color-link--hover);
+}
+
+.sphinx-bs .card-body .fa {
+ font-size: 2rem;
+}
+
+div.sphinx-bs .card:hover {
+ box-shadow: none !important;
+ border-color: #cca9ff;
+}
+
+div.sphinx-bs .card:hover .card-header {
+ background-color: #f2e9ff;
+ color: #fff;
+}
+
+body[data-theme="dark"] div.sphinx-bs .card:hover {
+ border-color: #2a144a;
+}
+
+body[data-theme="dark"] div.sphinx-bs .card:hover .card-header {
+ background-color: #2a144a;
+ color: #fff;
+}
+
+/* make sure hover style is consistent if user prefers dark theme at OS level */
+@media (prefers-color-scheme: dark) {
+ body:not([data-theme="light"]) div.sphinx-bs .card:hover {
+ border-color: #2a144a;
+ }
+ body:not([data-theme="light"]) div.sphinx-bs .card:hover .card-header {
+ background-color: #2a144a;
+ color: #fff;
+ }
+}
+
+div.sphinx-bs .card:hover .sphinx-bs.btn {
+ color: var(--color-link);
+}
+
+div.sphinx-bs .card:hover .card-body .sphinx-bs.btn {
+ color: var(--color-link--hover);
+}
+
+.getting-started-panels div.sphinx-bs .sphinx-bs.btn:hover {
+ border-color: var(--color-link);
+ background-color: #9d68e4;
+ color: #ffffff;
+}
+
+div.sphinx-bs .card {
+ background-color: var(--color-background-secondary);
+ border: 1px solid var(--color-background-border);
+}
+
+.center-card-content p {
+ margin: auto !important;
+}
+
+.sphinx-tabs {
+ padding-top: 10px;
+}
+
+.sphinx-tabs-tab {
+ color: var(--color-link);
+}
+
+/* sphinx tabs */
+.sphinx-tabs-tab[aria-selected="true"] {
+ background-color: var(--color-background-secondary);
+ border: 1px solid var(--color-background-border);
+ border-bottom: 1px solid var(--color-background-secondary);
+}
+
+.sphinx-tabs-panel {
+ border: 1px solid var(--color-background-border);
+ background: var(--color-background-secondary);
+ border-top: 0;
+}
+
+[role="tablist"] {
+ border-bottom: 1px solid var(--color-background-border);
+}
diff --git a/_static/css/termynal.css b/_static/css/termynal.css
new file mode 100644
index 0000000000..76a7d02cf2
--- /dev/null
+++ b/_static/css/termynal.css
@@ -0,0 +1,101 @@
+/**
+ * termynal.js
+ *
+ * @author Ines Montani
+ * @version 0.0.1
+ * @license MIT
+ */
+
+ :root {
+ --color-bg: #252a33;
+ --color-text: #eee;
+ --color-text-subtle: #a2a2a2;
+}
+
+[data-termynal] {
+ width: 750px;
+ max-width: 100%;
+ background: var(--color-bg);
+ color: var(--color-text);
+ font-size: 18px;
+ font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace;
+ border-radius: 4px;
+ padding: 75px 45px 35px;
+ position: relative;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+[data-termynal]:before {
+ content: '';
+ position: absolute;
+ top: 15px;
+ left: 15px;
+ display: inline-block;
+ width: 15px;
+ height: 15px;
+ border-radius: 50%;
+ /* A little hack to display the window buttons in one pseudo element. */
+ background: #d9515d;
+ -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
+ box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930;
+}
+
+[data-termynal]:after {
+ content: 'bash';
+ position: absolute;
+ color: var(--color-text-subtle);
+ top: 5px;
+ left: 0;
+ width: 100%;
+ text-align: center;
+}
+
+[data-ty] {
+ display: block;
+ line-height: 2;
+}
+
+[data-ty]:before {
+ /* Set up defaults and ensure empty lines are displayed. */
+ content: '';
+ display: inline-block;
+ vertical-align: middle;
+}
+
+[data-ty="input"]:before,
+[data-ty-prompt]:before {
+ margin-right: 0.75em;
+ color: var(--color-text-subtle);
+}
+
+[data-ty="input"]:before {
+ content: '$';
+}
+
+[data-ty][data-ty-prompt]:before {
+ content: attr(data-ty-prompt);
+}
+
+[data-ty-cursor]:after {
+ content: attr(data-ty-cursor);
+ font-family: monospace;
+ margin-left: 0.5em;
+ -webkit-animation: blink 1s infinite;
+ animation: blink 1s infinite;
+}
+
+
+/* Cursor animation */
+
+@-webkit-keyframes blink {
+ 50% {
+ opacity: 0;
+ }
+}
+
+@keyframes blink {
+ 50% {
+ opacity: 0;
+ }
+}
diff --git a/_static/css/v4-shims.min.css b/_static/css/v4-shims.min.css
new file mode 100644
index 0000000000..f742adcbe9
--- /dev/null
+++ b/_static/css/v4-shims.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2022 Fonticons, Inc.
+ */
+.fa.fa-glass:before{content:"\f000"}.fa.fa-envelope-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-envelope-o:before{content:"\f0e0"}.fa.fa-star-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-o:before{content:"\f005"}.fa.fa-close:before,.fa.fa-remove:before{content:"\f00d"}.fa.fa-gear:before{content:"\f013"}.fa.fa-trash-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-trash-o:before{content:"\f2ed"}.fa.fa-home:before{content:"\f015"}.fa.fa-file-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-o:before{content:"\f15b"}.fa.fa-clock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-clock-o:before{content:"\f017"}.fa.fa-arrow-circle-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-down:before{content:"\f358"}.fa.fa-arrow-circle-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-up:before{content:"\f35b"}.fa.fa-play-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-play-circle-o:before{content:"\f144"}.fa.fa-repeat:before,.fa.fa-rotate-right:before{content:"\f01e"}.fa.fa-refresh:before{content:"\f021"}.fa.fa-list-alt{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-list-alt:before{content:"\f022"}.fa.fa-dedent:before{content:"\f03b"}.fa.fa-video-camera:before{content:"\f03d"}.fa.fa-picture-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-picture-o:before{content:"\f03e"}.fa.fa-photo{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-photo:before{content:"\f03e"}.fa.fa-image{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-image:before{content:"\f03e"}.fa.fa-map-marker:before{content:"\f3c5"}.fa.fa-pencil-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-pencil-square-o:before{content:"\f044"}.fa.fa-edit{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-edit:before{content:"\f044"}.fa.fa-share-square-o:before{content:"\f14d"}.fa.fa-check-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-check-square-o:before{content:"\f14a"}.fa.fa-arrows:before{content:"\f0b2"}.fa.fa-times-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-circle-o:before{content:"\f057"}.fa.fa-check-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-check-circle-o:before{content:"\f058"}.fa.fa-mail-forward:before{content:"\f064"}.fa.fa-expand:before{content:"\f424"}.fa.fa-compress:before{content:"\f422"}.fa.fa-eye,.fa.fa-eye-slash{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-warning:before{content:"\f071"}.fa.fa-calendar:before{content:"\f073"}.fa.fa-arrows-v:before{content:"\f338"}.fa.fa-arrows-h:before{content:"\f337"}.fa.fa-bar-chart-o:before,.fa.fa-bar-chart:before{content:"\e0e3"}.fa.fa-facebook-square,.fa.fa-twitter-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-gears:before{content:"\f085"}.fa.fa-thumbs-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-thumbs-o-up:before{content:"\f164"}.fa.fa-thumbs-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-thumbs-o-down:before{content:"\f165"}.fa.fa-heart-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-heart-o:before{content:"\f004"}.fa.fa-sign-out:before{content:"\f2f5"}.fa.fa-linkedin-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-linkedin-square:before{content:"\f08c"}.fa.fa-thumb-tack:before{content:"\f08d"}.fa.fa-external-link:before{content:"\f35d"}.fa.fa-sign-in:before{content:"\f2f6"}.fa.fa-github-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-lemon-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-lemon-o:before{content:"\f094"}.fa.fa-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-square-o:before{content:"\f0c8"}.fa.fa-bookmark-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bookmark-o:before{content:"\f02e"}.fa.fa-facebook,.fa.fa-twitter{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook:before{content:"\f39e"}.fa.fa-facebook-f{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-f:before{content:"\f39e"}.fa.fa-github{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-credit-card{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-feed:before{content:"\f09e"}.fa.fa-hdd-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hdd-o:before{content:"\f0a0"}.fa.fa-hand-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-right:before{content:"\f0a4"}.fa.fa-hand-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-left:before{content:"\f0a5"}.fa.fa-hand-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-up:before{content:"\f0a6"}.fa.fa-hand-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-o-down:before{content:"\f0a7"}.fa.fa-globe:before{content:"\f57d"}.fa.fa-tasks:before{content:"\f828"}.fa.fa-arrows-alt:before{content:"\f31e"}.fa.fa-group:before{content:"\f0c0"}.fa.fa-chain:before{content:"\f0c1"}.fa.fa-cut:before{content:"\f0c4"}.fa.fa-files-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-files-o:before{content:"\f0c5"}.fa.fa-floppy-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-floppy-o:before{content:"\f0c7"}.fa.fa-save{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-save:before{content:"\f0c7"}.fa.fa-navicon:before,.fa.fa-reorder:before{content:"\f0c9"}.fa.fa-magic:before{content:"\e2ca"}.fa.fa-google-plus,.fa.fa-google-plus-square,.fa.fa-pinterest,.fa.fa-pinterest-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus:before{content:"\f0d5"}.fa.fa-money:before{content:"\f3d1"}.fa.fa-unsorted:before{content:"\f0dc"}.fa.fa-sort-desc:before{content:"\f0dd"}.fa.fa-sort-asc:before{content:"\f0de"}.fa.fa-linkedin{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-linkedin:before{content:"\f0e1"}.fa.fa-rotate-left:before{content:"\f0e2"}.fa.fa-legal:before{content:"\f0e3"}.fa.fa-dashboard:before,.fa.fa-tachometer:before{content:"\f625"}.fa.fa-comment-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-comment-o:before{content:"\f075"}.fa.fa-comments-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-comments-o:before{content:"\f086"}.fa.fa-flash:before{content:"\f0e7"}.fa.fa-clipboard:before{content:"\f0ea"}.fa.fa-lightbulb-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-lightbulb-o:before{content:"\f0eb"}.fa.fa-exchange:before{content:"\f362"}.fa.fa-cloud-download:before{content:"\f0ed"}.fa.fa-cloud-upload:before{content:"\f0ee"}.fa.fa-bell-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bell-o:before{content:"\f0f3"}.fa.fa-cutlery:before{content:"\f2e7"}.fa.fa-file-text-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-text-o:before{content:"\f15c"}.fa.fa-building-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-building-o:before{content:"\f1ad"}.fa.fa-hospital-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hospital-o:before{content:"\f0f8"}.fa.fa-tablet:before{content:"\f3fa"}.fa.fa-mobile-phone:before,.fa.fa-mobile:before{content:"\f3cd"}.fa.fa-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-circle-o:before{content:"\f111"}.fa.fa-mail-reply:before{content:"\f3e5"}.fa.fa-github-alt{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-folder-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-folder-o:before{content:"\f07b"}.fa.fa-folder-open-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-folder-open-o:before{content:"\f07c"}.fa.fa-smile-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-smile-o:before{content:"\f118"}.fa.fa-frown-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-frown-o:before{content:"\f119"}.fa.fa-meh-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-meh-o:before{content:"\f11a"}.fa.fa-keyboard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-keyboard-o:before{content:"\f11c"}.fa.fa-flag-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-flag-o:before{content:"\f024"}.fa.fa-mail-reply-all:before{content:"\f122"}.fa.fa-star-half-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-o:before{content:"\f5c0"}.fa.fa-star-half-empty{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-empty:before{content:"\f5c0"}.fa.fa-star-half-full{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-star-half-full:before{content:"\f5c0"}.fa.fa-code-fork:before{content:"\f126"}.fa.fa-chain-broken:before,.fa.fa-unlink:before{content:"\f127"}.fa.fa-calendar-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-o:before{content:"\f133"}.fa.fa-css3,.fa.fa-html5,.fa.fa-maxcdn{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-unlock-alt:before{content:"\f09c"}.fa.fa-minus-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-minus-square-o:before{content:"\f146"}.fa.fa-level-up:before{content:"\f3bf"}.fa.fa-level-down:before{content:"\f3be"}.fa.fa-pencil-square:before{content:"\f14b"}.fa.fa-external-link-square:before{content:"\f360"}.fa.fa-compass{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-down:before{content:"\f150"}.fa.fa-toggle-down{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-down:before{content:"\f150"}.fa.fa-caret-square-o-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-up:before{content:"\f151"}.fa.fa-toggle-up{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-up:before{content:"\f151"}.fa.fa-caret-square-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-right:before{content:"\f152"}.fa.fa-toggle-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-right:before{content:"\f152"}.fa.fa-eur:before,.fa.fa-euro:before{content:"\f153"}.fa.fa-gbp:before{content:"\f154"}.fa.fa-dollar:before,.fa.fa-usd:before{content:"\24"}.fa.fa-inr:before,.fa.fa-rupee:before{content:"\e1bc"}.fa.fa-cny:before,.fa.fa-jpy:before,.fa.fa-rmb:before,.fa.fa-yen:before{content:"\f157"}.fa.fa-rouble:before,.fa.fa-rub:before,.fa.fa-ruble:before{content:"\f158"}.fa.fa-krw:before,.fa.fa-won:before{content:"\f159"}.fa.fa-bitcoin,.fa.fa-btc{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bitcoin:before{content:"\f15a"}.fa.fa-file-text:before{content:"\f15c"}.fa.fa-sort-alpha-asc:before{content:"\f15d"}.fa.fa-sort-alpha-desc:before{content:"\f881"}.fa.fa-sort-amount-asc:before{content:"\f884"}.fa.fa-sort-amount-desc:before{content:"\f160"}.fa.fa-sort-numeric-asc:before{content:"\f162"}.fa.fa-sort-numeric-desc:before{content:"\f886"}.fa.fa-xing,.fa.fa-xing-square,.fa.fa-youtube,.fa.fa-youtube-play,.fa.fa-youtube-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-youtube-play:before{content:"\f167"}.fa.fa-adn,.fa.fa-bitbucket,.fa.fa-bitbucket-square,.fa.fa-dropbox,.fa.fa-flickr,.fa.fa-instagram,.fa.fa-stack-overflow{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bitbucket-square:before{content:"\f171"}.fa.fa-tumblr,.fa.fa-tumblr-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-long-arrow-down:before{content:"\f309"}.fa.fa-long-arrow-up:before{content:"\f30c"}.fa.fa-long-arrow-left:before{content:"\f30a"}.fa.fa-long-arrow-right:before{content:"\f30b"}.fa.fa-android,.fa.fa-apple,.fa.fa-dribbble,.fa.fa-foursquare,.fa.fa-gittip,.fa.fa-gratipay,.fa.fa-linux,.fa.fa-skype,.fa.fa-trello,.fa.fa-windows{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-gittip:before{content:"\f184"}.fa.fa-sun-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-sun-o:before{content:"\f185"}.fa.fa-moon-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-moon-o:before{content:"\f186"}.fa.fa-pagelines,.fa.fa-renren,.fa.fa-stack-exchange,.fa.fa-vk,.fa.fa-weibo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-arrow-circle-o-right{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-right:before{content:"\f35a"}.fa.fa-arrow-circle-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-arrow-circle-o-left:before{content:"\f359"}.fa.fa-caret-square-o-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-caret-square-o-left:before{content:"\f191"}.fa.fa-toggle-left{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-toggle-left:before{content:"\f191"}.fa.fa-dot-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-dot-circle-o:before{content:"\f192"}.fa.fa-vimeo-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-try:before,.fa.fa-turkish-lira:before{content:"\e2bb"}.fa.fa-plus-square-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-plus-square-o:before{content:"\f0fe"}.fa.fa-openid,.fa.fa-slack,.fa.fa-wordpress{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bank:before,.fa.fa-institution:before{content:"\f19c"}.fa.fa-mortar-board:before{content:"\f19d"}.fa.fa-behance,.fa.fa-behance-square,.fa.fa-delicious,.fa.fa-digg,.fa.fa-drupal,.fa.fa-google,.fa.fa-joomla,.fa.fa-pied-piper-alt,.fa.fa-pied-piper-pp,.fa.fa-reddit,.fa.fa-reddit-square,.fa.fa-steam,.fa.fa-steam-square,.fa.fa-stumbleupon,.fa.fa-stumbleupon-circle,.fa.fa-yahoo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-automobile:before{content:"\f1b9"}.fa.fa-cab:before{content:"\f1ba"}.fa.fa-deviantart,.fa.fa-soundcloud,.fa.fa-spotify{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-file-pdf-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-pdf-o:before{content:"\f1c1"}.fa.fa-file-word-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-word-o:before{content:"\f1c2"}.fa.fa-file-excel-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-excel-o:before{content:"\f1c3"}.fa.fa-file-powerpoint-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-powerpoint-o:before{content:"\f1c4"}.fa.fa-file-image-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-image-o:before{content:"\f1c5"}.fa.fa-file-photo-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-photo-o:before{content:"\f1c5"}.fa.fa-file-picture-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-picture-o:before{content:"\f1c5"}.fa.fa-file-archive-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-archive-o:before{content:"\f1c6"}.fa.fa-file-zip-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-zip-o:before{content:"\f1c6"}.fa.fa-file-audio-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-audio-o:before{content:"\f1c7"}.fa.fa-file-sound-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-sound-o:before{content:"\f1c7"}.fa.fa-file-video-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-video-o:before{content:"\f1c8"}.fa.fa-file-movie-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-movie-o:before{content:"\f1c8"}.fa.fa-file-code-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-file-code-o:before{content:"\f1c9"}.fa.fa-codepen,.fa.fa-jsfiddle,.fa.fa-vine{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-life-bouy:before,.fa.fa-life-buoy:before,.fa.fa-life-saver:before,.fa.fa-support:before{content:"\f1cd"}.fa.fa-circle-o-notch:before{content:"\f1ce"}.fa.fa-ra,.fa.fa-rebel{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-ra:before{content:"\f1d0"}.fa.fa-resistance{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-resistance:before{content:"\f1d0"}.fa.fa-empire,.fa.fa-ge{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-ge:before{content:"\f1d1"}.fa.fa-git,.fa.fa-git-square,.fa.fa-hacker-news,.fa.fa-y-combinator-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-y-combinator-square:before{content:"\f1d4"}.fa.fa-yc-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-yc-square:before{content:"\f1d4"}.fa.fa-qq,.fa.fa-tencent-weibo,.fa.fa-wechat,.fa.fa-weixin{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-wechat:before{content:"\f1d7"}.fa.fa-send:before{content:"\f1d8"}.fa.fa-paper-plane-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-paper-plane-o:before{content:"\f1d8"}.fa.fa-send-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-send-o:before{content:"\f1d8"}.fa.fa-circle-thin{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-circle-thin:before{content:"\f111"}.fa.fa-header:before{content:"\f1dc"}.fa.fa-futbol-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-futbol-o:before{content:"\f1e3"}.fa.fa-soccer-ball-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-soccer-ball-o:before{content:"\f1e3"}.fa.fa-slideshare,.fa.fa-twitch,.fa.fa-yelp{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-newspaper-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-newspaper-o:before{content:"\f1ea"}.fa.fa-cc-amex,.fa.fa-cc-discover,.fa.fa-cc-mastercard,.fa.fa-cc-paypal,.fa.fa-cc-stripe,.fa.fa-cc-visa,.fa.fa-google-wallet,.fa.fa-paypal{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-bell-slash-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-bell-slash-o:before{content:"\f1f6"}.fa.fa-trash:before{content:"\f2ed"}.fa.fa-copyright{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-eyedropper:before{content:"\f1fb"}.fa.fa-area-chart:before{content:"\f1fe"}.fa.fa-pie-chart:before{content:"\f200"}.fa.fa-line-chart:before{content:"\f201"}.fa.fa-angellist,.fa.fa-ioxhost,.fa.fa-lastfm,.fa.fa-lastfm-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-cc{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-cc:before{content:"\f20a"}.fa.fa-ils:before,.fa.fa-shekel:before,.fa.fa-sheqel:before{content:"\f20b"}.fa.fa-buysellads,.fa.fa-connectdevelop,.fa.fa-dashcube,.fa.fa-forumbee,.fa.fa-leanpub,.fa.fa-sellsy,.fa.fa-shirtsinbulk,.fa.fa-simplybuilt,.fa.fa-skyatlas{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-diamond{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-diamond:before{content:"\f3a5"}.fa.fa-intersex:before,.fa.fa-transgender:before{content:"\f224"}.fa.fa-transgender-alt:before{content:"\f225"}.fa.fa-facebook-official{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-facebook-official:before{content:"\f09a"}.fa.fa-pinterest-p,.fa.fa-whatsapp{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-hotel:before{content:"\f236"}.fa.fa-medium,.fa.fa-viacoin,.fa.fa-y-combinator,.fa.fa-yc{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-yc:before{content:"\f23b"}.fa.fa-expeditedssl,.fa.fa-opencart,.fa.fa-optin-monster{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-battery-4:before,.fa.fa-battery:before{content:"\f240"}.fa.fa-battery-3:before{content:"\f241"}.fa.fa-battery-2:before{content:"\f242"}.fa.fa-battery-1:before{content:"\f243"}.fa.fa-battery-0:before{content:"\f244"}.fa.fa-object-group,.fa.fa-object-ungroup,.fa.fa-sticky-note-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-sticky-note-o:before{content:"\f249"}.fa.fa-cc-diners-club,.fa.fa-cc-jcb{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-clone{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hourglass-o:before{content:"\f252"}.fa.fa-hourglass-1:before{content:"\f251"}.fa.fa-hourglass-2:before,.fa.fa-hourglass-half:before{content:"\f254"}.fa.fa-hourglass-3:before{content:"\f253"}.fa.fa-hand-rock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-rock-o:before{content:"\f255"}.fa.fa-hand-grab-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-grab-o:before{content:"\f255"}.fa.fa-hand-paper-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-paper-o:before{content:"\f256"}.fa.fa-hand-stop-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-stop-o:before{content:"\f256"}.fa.fa-hand-scissors-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-scissors-o:before{content:"\f257"}.fa.fa-hand-lizard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-lizard-o:before{content:"\f258"}.fa.fa-hand-spock-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-spock-o:before{content:"\f259"}.fa.fa-hand-pointer-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-pointer-o:before{content:"\f25a"}.fa.fa-hand-peace-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-hand-peace-o:before{content:"\f25b"}.fa.fa-registered{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-chrome,.fa.fa-creative-commons,.fa.fa-firefox,.fa.fa-get-pocket,.fa.fa-gg,.fa.fa-gg-circle,.fa.fa-internet-explorer,.fa.fa-odnoklassniki,.fa.fa-odnoklassniki-square,.fa.fa-opera,.fa.fa-safari,.fa.fa-wikipedia-w{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-television:before{content:"\f26c"}.fa.fa-500px,.fa.fa-amazon,.fa.fa-contao{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-calendar-plus-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-plus-o:before{content:"\f271"}.fa.fa-calendar-minus-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-minus-o:before{content:"\f272"}.fa.fa-calendar-times-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-times-o:before{content:"\f273"}.fa.fa-calendar-check-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-calendar-check-o:before{content:"\f274"}.fa.fa-map-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-map-o:before{content:"\f279"}.fa.fa-commenting:before{content:"\f4ad"}.fa.fa-commenting-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-commenting-o:before{content:"\f4ad"}.fa.fa-houzz,.fa.fa-vimeo{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-vimeo:before{content:"\f27d"}.fa.fa-black-tie,.fa.fa-edge,.fa.fa-fonticons,.fa.fa-reddit-alien{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-credit-card-alt:before{content:"\f09d"}.fa.fa-codiepie,.fa.fa-fort-awesome,.fa.fa-mixcloud,.fa.fa-modx,.fa.fa-product-hunt,.fa.fa-scribd,.fa.fa-usb{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-pause-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-pause-circle-o:before{content:"\f28b"}.fa.fa-stop-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-stop-circle-o:before{content:"\f28d"}.fa.fa-bluetooth,.fa.fa-bluetooth-b,.fa.fa-envira,.fa.fa-gitlab,.fa.fa-wheelchair-alt,.fa.fa-wpbeginner,.fa.fa-wpforms{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-wheelchair-alt:before{content:"\f368"}.fa.fa-question-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-question-circle-o:before{content:"\f059"}.fa.fa-volume-control-phone:before{content:"\f2a0"}.fa.fa-asl-interpreting:before{content:"\f2a3"}.fa.fa-deafness:before,.fa.fa-hard-of-hearing:before{content:"\f2a4"}.fa.fa-glide,.fa.fa-glide-g{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-signing:before{content:"\f2a7"}.fa.fa-snapchat,.fa.fa-snapchat-ghost,.fa.fa-viadeo,.fa.fa-viadeo-square{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-snapchat-ghost:before{content:"\f2ab"}.fa.fa-first-order,.fa.fa-google-plus-official,.fa.fa-pied-piper,.fa.fa-snapchat-square,.fa.fa-themeisle,.fa.fa-yoast{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-official:before{content:"\f2b3"}.fa.fa-google-plus-circle{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-google-plus-circle:before{content:"\f2b3"}.fa.fa-fa,.fa.fa-font-awesome{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-fa:before{content:"\f2b4"}.fa.fa-handshake-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-handshake-o:before{content:"\f2b5"}.fa.fa-envelope-open-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-envelope-open-o:before{content:"\f2b6"}.fa.fa-linode{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-address-book-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-address-book-o:before{content:"\f2b9"}.fa.fa-vcard:before{content:"\f2bb"}.fa.fa-address-card-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-address-card-o:before{content:"\f2bb"}.fa.fa-vcard-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-vcard-o:before{content:"\f2bb"}.fa.fa-user-circle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-user-circle-o:before{content:"\f2bd"}.fa.fa-user-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-user-o:before{content:"\f007"}.fa.fa-id-badge{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-drivers-license:before{content:"\f2c2"}.fa.fa-id-card-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-id-card-o:before{content:"\f2c2"}.fa.fa-drivers-license-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-drivers-license-o:before{content:"\f2c2"}.fa.fa-free-code-camp,.fa.fa-quora,.fa.fa-telegram{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-thermometer-4:before,.fa.fa-thermometer:before{content:"\f2c7"}.fa.fa-thermometer-3:before{content:"\f2c8"}.fa.fa-thermometer-2:before{content:"\f2c9"}.fa.fa-thermometer-1:before{content:"\f2ca"}.fa.fa-thermometer-0:before{content:"\f2cb"}.fa.fa-bathtub:before,.fa.fa-s15:before{content:"\f2cd"}.fa.fa-window-maximize,.fa.fa-window-restore{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-rectangle:before{content:"\f410"}.fa.fa-window-close-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-window-close-o:before{content:"\f410"}.fa.fa-times-rectangle-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-times-rectangle-o:before{content:"\f410"}.fa.fa-bandcamp,.fa.fa-eercast,.fa.fa-etsy,.fa.fa-grav,.fa.fa-imdb,.fa.fa-ravelry{font-family:"Font Awesome 6 Brands";font-weight:400}.fa.fa-eercast:before{content:"\f2da"}.fa.fa-snowflake-o{font-family:"Font Awesome 6 Free";font-weight:400}.fa.fa-snowflake-o:before{content:"\f2dc"}.fa.fa-meetup,.fa.fa-superpowers,.fa.fa-wpexplorer{font-family:"Font Awesome 6 Brands";font-weight:400}
\ No newline at end of file
diff --git a/_static/dask-tf.jpg b/_static/dask-tf.jpg
new file mode 100644
index 0000000000..e33dddd526
Binary files /dev/null and b/_static/dask-tf.jpg differ
diff --git a/_static/data_sharing_with_deployment.jpg b/_static/data_sharing_with_deployment.jpg
new file mode 100644
index 0000000000..7053b4875e
Binary files /dev/null and b/_static/data_sharing_with_deployment.jpg differ
diff --git a/_static/data_sharing_with_sidecar.jpg b/_static/data_sharing_with_sidecar.jpg
new file mode 100644
index 0000000000..99f6b909ac
Binary files /dev/null and b/_static/data_sharing_with_sidecar.jpg differ
diff --git a/_static/debug.css b/_static/debug.css
new file mode 100644
index 0000000000..74d4aec33e
--- /dev/null
+++ b/_static/debug.css
@@ -0,0 +1,69 @@
+/*
+ This CSS file should be overridden by the theme authors. It's
+ meant for debugging and developing the skeleton that this theme provides.
+*/
+body {
+ font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji";
+ background: lavender;
+}
+.sb-announcement {
+ background: rgb(131, 131, 131);
+}
+.sb-announcement__inner {
+ background: black;
+ color: white;
+}
+.sb-header {
+ background: lightskyblue;
+}
+.sb-header__inner {
+ background: royalblue;
+ color: white;
+}
+.sb-header-secondary {
+ background: lightcyan;
+}
+.sb-header-secondary__inner {
+ background: cornflowerblue;
+ color: white;
+}
+.sb-sidebar-primary {
+ background: lightgreen;
+}
+.sb-main {
+ background: blanchedalmond;
+}
+.sb-main__inner {
+ background: antiquewhite;
+}
+.sb-header-article {
+ background: lightsteelblue;
+}
+.sb-article-container {
+ background: snow;
+}
+.sb-article-main {
+ background: white;
+}
+.sb-footer-article {
+ background: lightpink;
+}
+.sb-sidebar-secondary {
+ background: lightgoldenrodyellow;
+}
+.sb-footer-content {
+ background: plum;
+}
+.sb-footer-content__inner {
+ background: palevioletred;
+}
+.sb-footer {
+ background: pink;
+}
+.sb-footer__inner {
+ background: salmon;
+}
+.sb-article {
+ background: white;
+}
diff --git a/_static/doctools.js b/_static/doctools.js
new file mode 100644
index 0000000000..d06a71d751
--- /dev/null
+++ b/_static/doctools.js
@@ -0,0 +1,156 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Base JavaScript utilities for all Sphinx HTML documentation.
+ *
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+"use strict";
+
+const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([
+ "TEXTAREA",
+ "INPUT",
+ "SELECT",
+ "BUTTON",
+]);
+
+const _ready = (callback) => {
+ if (document.readyState !== "loading") {
+ callback();
+ } else {
+ document.addEventListener("DOMContentLoaded", callback);
+ }
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+const Documentation = {
+ init: () => {
+ Documentation.initDomainIndexTable();
+ Documentation.initOnKeyListeners();
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS: {},
+ PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
+ LOCALE: "unknown",
+
+ // gettext and ngettext don't access this so that the functions
+ // can safely bound to a different name (_ = Documentation.gettext)
+ gettext: (string) => {
+ const translated = Documentation.TRANSLATIONS[string];
+ switch (typeof translated) {
+ case "undefined":
+ return string; // no translation
+ case "string":
+ return translated; // translation exists
+ default:
+ return translated[0]; // (singular, plural) translation tuple exists
+ }
+ },
+
+ ngettext: (singular, plural, n) => {
+ const translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated !== "undefined")
+ return translated[Documentation.PLURAL_EXPR(n)];
+ return n === 1 ? singular : plural;
+ },
+
+ addTranslations: (catalog) => {
+ Object.assign(Documentation.TRANSLATIONS, catalog.messages);
+ Documentation.PLURAL_EXPR = new Function(
+ "n",
+ `return (${catalog.plural_expr})`
+ );
+ Documentation.LOCALE = catalog.locale;
+ },
+
+ /**
+ * helper function to focus on search bar
+ */
+ focusSearchBar: () => {
+ document.querySelectorAll("input[name=q]")[0]?.focus();
+ },
+
+ /**
+ * Initialise the domain index toggle buttons
+ */
+ initDomainIndexTable: () => {
+ const toggler = (el) => {
+ const idNumber = el.id.substr(7);
+ const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
+ if (el.src.substr(-9) === "minus.png") {
+ el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
+ toggledRows.forEach((el) => (el.style.display = "none"));
+ } else {
+ el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
+ toggledRows.forEach((el) => (el.style.display = ""));
+ }
+ };
+
+ const togglerElements = document.querySelectorAll("img.toggler");
+ togglerElements.forEach((el) =>
+ el.addEventListener("click", (event) => toggler(event.currentTarget))
+ );
+ togglerElements.forEach((el) => (el.style.display = ""));
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
+ },
+
+ initOnKeyListeners: () => {
+ // only install a listener if it is really needed
+ if (
+ !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
+ !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
+ )
+ return;
+
+ document.addEventListener("keydown", (event) => {
+ // bail for input elements
+ if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
+ // bail with special keys
+ if (event.altKey || event.ctrlKey || event.metaKey) return;
+
+ if (!event.shiftKey) {
+ switch (event.key) {
+ case "ArrowLeft":
+ if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
+
+ const prevLink = document.querySelector('link[rel="prev"]');
+ if (prevLink && prevLink.href) {
+ window.location.href = prevLink.href;
+ event.preventDefault();
+ }
+ break;
+ case "ArrowRight":
+ if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
+
+ const nextLink = document.querySelector('link[rel="next"]');
+ if (nextLink && nextLink.href) {
+ window.location.href = nextLink.href;
+ event.preventDefault();
+ }
+ break;
+ }
+ }
+
+ // some keyboard layouts may need Shift to get /
+ switch (event.key) {
+ case "/":
+ if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
+ Documentation.focusSearchBar();
+ event.preventDefault();
+ }
+ });
+ },
+};
+
+// quick alias for translations
+const _ = Documentation.gettext;
+
+_ready(Documentation.init);
diff --git a/_static/documentation_options.js b/_static/documentation_options.js
new file mode 100644
index 0000000000..902bb33589
--- /dev/null
+++ b/_static/documentation_options.js
@@ -0,0 +1,14 @@
+var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
+ VERSION: '',
+ LANGUAGE: 'en',
+ COLLAPSE_INDEX: false,
+ BUILDER: 'html',
+ FILE_SUFFIX: '.html',
+ LINK_SUFFIX: '.html',
+ HAS_SOURCE: true,
+ SOURCELINK_SUFFIX: '.txt',
+ NAVIGATION_WITH_KEYS: true,
+ SHOW_SEARCH_SUMMARY: true,
+ ENABLE_SEARCH_SHORTCUTS: true,
+};
\ No newline at end of file
diff --git a/_static/file.png b/_static/file.png
new file mode 100644
index 0000000000..a858a410e4
Binary files /dev/null and b/_static/file.png differ
diff --git a/_static/fraud-detection-job.jpg b/_static/fraud-detection-job.jpg
new file mode 100644
index 0000000000..34005ee5a7
Binary files /dev/null and b/_static/fraud-detection-job.jpg differ
diff --git a/_static/js/termynal.js b/_static/js/termynal.js
new file mode 100644
index 0000000000..77ec6cb01c
--- /dev/null
+++ b/_static/js/termynal.js
@@ -0,0 +1,197 @@
+/**
+ * termynal.js
+ * A lightweight, modern and extensible animated terminal window, using
+ * async/await.
+ *
+ * @author Ines Montani
+ * @version 0.0.1
+ * @license MIT
+ */
+
+'use strict';
+
+/** Generate a terminal widget. */
+class Termynal {
+ /**
+ * Construct the widget's settings.
+ * @param {(string|Node)=} container - Query selector or container element.
+ * @param {Object=} options - Custom settings.
+ * @param {string} options.prefix - Prefix to use for data attributes.
+ * @param {number} options.startDelay - Delay before animation, in ms.
+ * @param {number} options.typeDelay - Delay between each typed character, in ms.
+ * @param {number} options.lineDelay - Delay between each line, in ms.
+ * @param {number} options.progressLength - Number of characters displayed as progress bar.
+ * @param {string} options.progressChar – Character to use for progress bar, defaults to █.
+ * @param {number} options.progressPercent - Max percent of progress.
+ * @param {string} options.cursor – Character to use for cursor, defaults to ▋.
+ * @param {Object[]} lineData - Dynamically loaded line data objects.
+ * @param {boolean} options.noInit - Don't initialise the animation.
+ */
+ constructor(container = '#termynal', options = {}) {
+ this.container = (typeof container === 'string') ? document.querySelector(container) : container;
+ this.pfx = `data-${options.prefix || 'ty'}`;
+ this.startDelay = options.startDelay
+ || parseFloat(this.container.getAttribute(`${this.pfx}-startDelay`)) || 600;
+ this.typeDelay = options.typeDelay
+ || parseFloat(this.container.getAttribute(`${this.pfx}-typeDelay`)) || 90;
+ this.lineDelay = options.lineDelay
+ || parseFloat(this.container.getAttribute(`${this.pfx}-lineDelay`)) || 1500;
+ this.progressLength = options.progressLength
+ || parseFloat(this.container.getAttribute(`${this.pfx}-progressLength`)) || 40;
+ this.progressChar = options.progressChar
+ || this.container.getAttribute(`${this.pfx}-progressChar`) || '█';
+ this.progressPercent = options.progressPercent
+ || parseFloat(this.container.getAttribute(`${this.pfx}-progressPercent`)) || 100;
+ this.cursor = options.cursor
+ || this.container.getAttribute(`${this.pfx}-cursor`) || '▋';
+ this.lineData = this.lineDataToElements(options.lineData || []);
+ if (!options.noInit) this.init()
+ }
+
+ /**
+ * Initialise the widget, get lines, clear container and start animation.
+ */
+ init() {
+ // Appends dynamically loaded lines to existing line elements.
+ this.lines = [...this.container.querySelectorAll(`[${this.pfx}]`)].concat(this.lineData);
+
+ /**
+ * Calculates width and height of Termynal container.
+ * If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS.
+ */
+ const containerStyle = getComputedStyle(this.container);
+ this.container.style.width = containerStyle.width !== '0px' ?
+ containerStyle.width : undefined;
+ this.container.style.minHeight = containerStyle.height !== '0px' ?
+ containerStyle.height : undefined;
+
+ this.container.setAttribute('data-termynal', '');
+ this.container.innerHTML = '';
+ this.start();
+ }
+
+ /**
+ * Start the animation and rener the lines depending on their data attributes.
+ */
+ async start() {
+ await this._wait(this.startDelay);
+
+ for (let line of this.lines) {
+ const type = line.getAttribute(this.pfx);
+ const delay = line.getAttribute(`${this.pfx}-delay`) || this.lineDelay;
+
+ if (type == 'input') {
+ line.setAttribute(`${this.pfx}-cursor`, this.cursor);
+ await this.type(line);
+ await this._wait(delay);
+ }
+
+ else if (type == 'progress') {
+ await this.progress(line);
+ await this._wait(delay);
+ }
+
+ else {
+ this.container.appendChild(line);
+ await this._wait(delay);
+ }
+
+ line.removeAttribute(`${this.pfx}-cursor`);
+ }
+ }
+
+ /**
+ * Animate a typed line.
+ * @param {Node} line - The line element to render.
+ */
+ async type(line) {
+ const chars = [...line.textContent];
+ const delay = line.getAttribute(`${this.pfx}-typeDelay`) || this.typeDelay;
+ line.textContent = '';
+ this.container.appendChild(line);
+
+ for (let char of chars) {
+ await this._wait(delay);
+ line.textContent += char;
+ }
+ }
+
+ /**
+ * Animate a progress bar.
+ * @param {Node} line - The line element to render.
+ */
+ async progress(line) {
+ const progressLength = line.getAttribute(`${this.pfx}-progressLength`)
+ || this.progressLength;
+ const progressChar = line.getAttribute(`${this.pfx}-progressChar`)
+ || this.progressChar;
+ const chars = progressChar.repeat(progressLength);
+ const progressPercent = line.getAttribute(`${this.pfx}-progressPercent`)
+ || this.progressPercent;
+ line.textContent = '';
+ this.container.appendChild(line);
+
+ for (let i = 1; i < chars.length + 1; i++) {
+ await this._wait(this.typeDelay);
+ const percent = Math.round(i / chars.length * 100);
+ line.textContent = `${chars.slice(0, i)} ${percent}%`;
+ if (percent>progressPercent) {
+ break;
+ }
+ }
+ }
+
+ /**
+ * Helper function for animation delays, called with `await`.
+ * @param {number} time - Timeout, in ms.
+ */
+ _wait(time) {
+ return new Promise(resolve => setTimeout(resolve, time));
+ }
+
+ /**
+ * Converts line data objects into line elements.
+ *
+ * @param {Object[]} lineData - Dynamically loaded lines.
+ * @param {Object} line - Line data object.
+ * @returns {Element[]} - Array of line elements.
+ */
+ lineDataToElements(lineData) {
+ return lineData.map(line => {
+ let div = document.createElement('div');
+ div.innerHTML = `${line.value || ''} `;
+
+ return div.firstElementChild;
+ });
+ }
+
+ /**
+ * Helper function for generating attributes string.
+ *
+ * @param {Object} line - Line data object.
+ * @returns {string} - String of attributes.
+ */
+ _attributes(line) {
+ let attrs = '';
+ for (let prop in line) {
+ attrs += this.pfx;
+
+ if (prop === 'type') {
+ attrs += `="${line[prop]}" `
+ } else if (prop !== 'value') {
+ attrs += `-${prop}="${line[prop]}" `
+ }
+ }
+
+ return attrs;
+ }
+}
+
+/**
+* HTML API: If current script has container(s) specified, initialise Termynal.
+*/
+if (document.currentScript.hasAttribute('data-termynal-container')) {
+ const containers = document.currentScript.getAttribute('data-termynal-container');
+ containers.split('|')
+ .forEach(container => new Termynal(container))
+}
diff --git a/_static/kubeflow_create_run.png b/_static/kubeflow_create_run.png
new file mode 100644
index 0000000000..84ac8dd621
Binary files /dev/null and b/_static/kubeflow_create_run.png differ
diff --git a/_static/kubeflow_upload_pipeline.png b/_static/kubeflow_upload_pipeline.png
new file mode 100644
index 0000000000..bd9321fa06
Binary files /dev/null and b/_static/kubeflow_upload_pipeline.png differ
diff --git a/_static/language_data.js b/_static/language_data.js
new file mode 100644
index 0000000000..250f5665fa
--- /dev/null
+++ b/_static/language_data.js
@@ -0,0 +1,199 @@
+/*
+ * language_data.js
+ * ~~~~~~~~~~~~~~~~
+ *
+ * This script contains the language-specific data used by searchtools.js,
+ * namely the list of stopwords, stemmer, scorer and splitter.
+ *
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
+
+
+/* Non-minified version is copied as a separate JS file, is available */
+
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+ var step2list = {
+ ational: 'ate',
+ tional: 'tion',
+ enci: 'ence',
+ anci: 'ance',
+ izer: 'ize',
+ bli: 'ble',
+ alli: 'al',
+ entli: 'ent',
+ eli: 'e',
+ ousli: 'ous',
+ ization: 'ize',
+ ation: 'ate',
+ ator: 'ate',
+ alism: 'al',
+ iveness: 'ive',
+ fulness: 'ful',
+ ousness: 'ous',
+ aliti: 'al',
+ iviti: 'ive',
+ biliti: 'ble',
+ logi: 'log'
+ };
+
+ var step3list = {
+ icate: 'ic',
+ ative: '',
+ alize: 'al',
+ iciti: 'ic',
+ ical: 'ic',
+ ful: '',
+ ness: ''
+ };
+
+ var c = "[^aeiou]"; // consonant
+ var v = "[aeiouy]"; // vowel
+ var C = c + "[^aeiouy]*"; // consonant sequence
+ var V = v + "[aeiou]*"; // vowel sequence
+
+ var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
+ var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
+ var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
+ var s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ this.stemWord = function (w) {
+ var stem;
+ var suffix;
+ var firstch;
+ var origword = w;
+
+ if (w.length < 3)
+ return w;
+
+ var re;
+ var re2;
+ var re3;
+ var re4;
+
+ firstch = w.substr(0,1);
+ if (firstch == "y")
+ w = firstch.toUpperCase() + w.substr(1);
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w))
+ w = w.replace(re,"$1$2");
+ else if (re2.test(w))
+ w = w.replace(re2,"$1$2");
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w))
+ w = w + "e";
+ else if (re3.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ else if (re4.test(w))
+ w = w + "e";
+ }
+ }
+
+ // Step 1c
+ re = /^(.+?)y$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(s_v);
+ if (re.test(stem))
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step2list[suffix];
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step3list[suffix];
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem))
+ w = stem;
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem))
+ w = stem;
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+ w = stem;
+ }
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+ if (firstch == "y")
+ w = firstch.toLowerCase() + w.substr(1);
+ return w;
+ }
+}
+
diff --git a/_static/minus.png b/_static/minus.png
new file mode 100644
index 0000000000..d96755fdaf
Binary files /dev/null and b/_static/minus.png differ
diff --git a/_static/nbsphinx-broken-thumbnail.svg b/_static/nbsphinx-broken-thumbnail.svg
new file mode 100644
index 0000000000..4919ca8829
--- /dev/null
+++ b/_static/nbsphinx-broken-thumbnail.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/_static/nbsphinx-code-cells.css b/_static/nbsphinx-code-cells.css
new file mode 100644
index 0000000000..a3fb27c30f
--- /dev/null
+++ b/_static/nbsphinx-code-cells.css
@@ -0,0 +1,259 @@
+/* remove conflicting styling from Sphinx themes */
+div.nbinput.container div.prompt *,
+div.nboutput.container div.prompt *,
+div.nbinput.container div.input_area pre,
+div.nboutput.container div.output_area pre,
+div.nbinput.container div.input_area .highlight,
+div.nboutput.container div.output_area .highlight {
+ border: none;
+ padding: 0;
+ margin: 0;
+ box-shadow: none;
+}
+
+div.nbinput.container > div[class*=highlight],
+div.nboutput.container > div[class*=highlight] {
+ margin: 0;
+}
+
+div.nbinput.container div.prompt *,
+div.nboutput.container div.prompt * {
+ background: none;
+}
+
+div.nboutput.container div.output_area .highlight,
+div.nboutput.container div.output_area pre {
+ background: unset;
+}
+
+div.nboutput.container div.output_area div.highlight {
+ color: unset; /* override Pygments text color */
+}
+
+/* avoid gaps between output lines */
+div.nboutput.container div[class*=highlight] pre {
+ line-height: normal;
+}
+
+/* input/output containers */
+div.nbinput.container,
+div.nboutput.container {
+ display: -webkit-flex;
+ display: flex;
+ align-items: flex-start;
+ margin: 0;
+ width: 100%;
+}
+@media (max-width: 540px) {
+ div.nbinput.container,
+ div.nboutput.container {
+ flex-direction: column;
+ }
+}
+
+/* input container */
+div.nbinput.container {
+ padding-top: 5px;
+}
+
+/* last container */
+div.nblast.container {
+ padding-bottom: 5px;
+}
+
+/* input prompt */
+div.nbinput.container div.prompt pre,
+/* for sphinx_immaterial theme: */
+div.nbinput.container div.prompt pre > code {
+ color: #307FC1;
+}
+
+/* output prompt */
+div.nboutput.container div.prompt pre,
+/* for sphinx_immaterial theme: */
+div.nboutput.container div.prompt pre > code {
+ color: #BF5B3D;
+}
+
+/* all prompts */
+div.nbinput.container div.prompt,
+div.nboutput.container div.prompt {
+ width: 4.5ex;
+ padding-top: 5px;
+ position: relative;
+ user-select: none;
+}
+
+div.nbinput.container div.prompt > div,
+div.nboutput.container div.prompt > div {
+ position: absolute;
+ right: 0;
+ margin-right: 0.3ex;
+}
+
+@media (max-width: 540px) {
+ div.nbinput.container div.prompt,
+ div.nboutput.container div.prompt {
+ width: unset;
+ text-align: left;
+ padding: 0.4em;
+ }
+ div.nboutput.container div.prompt.empty {
+ padding: 0;
+ }
+
+ div.nbinput.container div.prompt > div,
+ div.nboutput.container div.prompt > div {
+ position: unset;
+ }
+}
+
+/* disable scrollbars and line breaks on prompts */
+div.nbinput.container div.prompt pre,
+div.nboutput.container div.prompt pre {
+ overflow: hidden;
+ white-space: pre;
+}
+
+/* input/output area */
+div.nbinput.container div.input_area,
+div.nboutput.container div.output_area {
+ -webkit-flex: 1;
+ flex: 1;
+ overflow: auto;
+}
+@media (max-width: 540px) {
+ div.nbinput.container div.input_area,
+ div.nboutput.container div.output_area {
+ width: 100%;
+ }
+}
+
+/* input area */
+div.nbinput.container div.input_area {
+ border: 1px solid #e0e0e0;
+ border-radius: 2px;
+ /*background: #f5f5f5;*/
+}
+
+/* override MathJax center alignment in output cells */
+div.nboutput.container div[class*=MathJax] {
+ text-align: left !important;
+}
+
+/* override sphinx.ext.imgmath center alignment in output cells */
+div.nboutput.container div.math p {
+ text-align: left;
+}
+
+/* standard error */
+div.nboutput.container div.output_area.stderr {
+ background: #fdd;
+}
+
+/* ANSI colors */
+.ansi-black-fg { color: #3E424D; }
+.ansi-black-bg { background-color: #3E424D; }
+.ansi-black-intense-fg { color: #282C36; }
+.ansi-black-intense-bg { background-color: #282C36; }
+.ansi-red-fg { color: #E75C58; }
+.ansi-red-bg { background-color: #E75C58; }
+.ansi-red-intense-fg { color: #B22B31; }
+.ansi-red-intense-bg { background-color: #B22B31; }
+.ansi-green-fg { color: #00A250; }
+.ansi-green-bg { background-color: #00A250; }
+.ansi-green-intense-fg { color: #007427; }
+.ansi-green-intense-bg { background-color: #007427; }
+.ansi-yellow-fg { color: #DDB62B; }
+.ansi-yellow-bg { background-color: #DDB62B; }
+.ansi-yellow-intense-fg { color: #B27D12; }
+.ansi-yellow-intense-bg { background-color: #B27D12; }
+.ansi-blue-fg { color: #208FFB; }
+.ansi-blue-bg { background-color: #208FFB; }
+.ansi-blue-intense-fg { color: #0065CA; }
+.ansi-blue-intense-bg { background-color: #0065CA; }
+.ansi-magenta-fg { color: #D160C4; }
+.ansi-magenta-bg { background-color: #D160C4; }
+.ansi-magenta-intense-fg { color: #A03196; }
+.ansi-magenta-intense-bg { background-color: #A03196; }
+.ansi-cyan-fg { color: #60C6C8; }
+.ansi-cyan-bg { background-color: #60C6C8; }
+.ansi-cyan-intense-fg { color: #258F8F; }
+.ansi-cyan-intense-bg { background-color: #258F8F; }
+.ansi-white-fg { color: #C5C1B4; }
+.ansi-white-bg { background-color: #C5C1B4; }
+.ansi-white-intense-fg { color: #A1A6B2; }
+.ansi-white-intense-bg { background-color: #A1A6B2; }
+
+.ansi-default-inverse-fg { color: #FFFFFF; }
+.ansi-default-inverse-bg { background-color: #000000; }
+
+.ansi-bold { font-weight: bold; }
+.ansi-underline { text-decoration: underline; }
+
+
+div.nbinput.container div.input_area div[class*=highlight] > pre,
+div.nboutput.container div.output_area div[class*=highlight] > pre,
+div.nboutput.container div.output_area div[class*=highlight].math,
+div.nboutput.container div.output_area.rendered_html,
+div.nboutput.container div.output_area > div.output_javascript,
+div.nboutput.container div.output_area:not(.rendered_html) > img{
+ padding: 5px;
+ margin: 0;
+}
+
+/* fix copybtn overflow problem in chromium (needed for 'sphinx_copybutton') */
+div.nbinput.container div.input_area > div[class^='highlight'],
+div.nboutput.container div.output_area > div[class^='highlight']{
+ overflow-y: hidden;
+}
+
+/* hide copy button on prompts for 'sphinx_copybutton' extension ... */
+.prompt .copybtn,
+/* ... and 'sphinx_immaterial' theme */
+.prompt .md-clipboard.md-icon {
+ display: none;
+}
+
+/* Some additional styling taken form the Jupyter notebook CSS */
+.jp-RenderedHTMLCommon table,
+div.rendered_html table {
+ border: none;
+ border-collapse: collapse;
+ border-spacing: 0;
+ color: black;
+ font-size: 12px;
+ table-layout: fixed;
+}
+.jp-RenderedHTMLCommon thead,
+div.rendered_html thead {
+ border-bottom: 1px solid black;
+ vertical-align: bottom;
+}
+.jp-RenderedHTMLCommon tr,
+.jp-RenderedHTMLCommon th,
+.jp-RenderedHTMLCommon td,
+div.rendered_html tr,
+div.rendered_html th,
+div.rendered_html td {
+ text-align: right;
+ vertical-align: middle;
+ padding: 0.5em 0.5em;
+ line-height: normal;
+ white-space: normal;
+ max-width: none;
+ border: none;
+}
+.jp-RenderedHTMLCommon th,
+div.rendered_html th {
+ font-weight: bold;
+}
+.jp-RenderedHTMLCommon tbody tr:nth-child(odd),
+div.rendered_html tbody tr:nth-child(odd) {
+ background: #f5f5f5;
+}
+.jp-RenderedHTMLCommon tbody tr:hover,
+div.rendered_html tbody tr:hover {
+ background: rgba(66, 165, 245, 0.2);
+}
+
diff --git a/_static/nbsphinx-gallery.css b/_static/nbsphinx-gallery.css
new file mode 100644
index 0000000000..365c27a96b
--- /dev/null
+++ b/_static/nbsphinx-gallery.css
@@ -0,0 +1,31 @@
+.nbsphinx-gallery {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
+ gap: 5px;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.nbsphinx-gallery > a {
+ padding: 5px;
+ border: 1px dotted currentColor;
+ border-radius: 2px;
+ text-align: center;
+}
+
+.nbsphinx-gallery > a:hover {
+ border-style: solid;
+}
+
+.nbsphinx-gallery img {
+ max-width: 100%;
+ max-height: 100%;
+}
+
+.nbsphinx-gallery > a > div:first-child {
+ display: flex;
+ align-items: start;
+ justify-content: center;
+ height: 120px;
+ margin-bottom: 5px;
+}
diff --git a/_static/nbsphinx-no-thumbnail.svg b/_static/nbsphinx-no-thumbnail.svg
new file mode 100644
index 0000000000..9dca7588fa
--- /dev/null
+++ b/_static/nbsphinx-no-thumbnail.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/_static/panels-bootstrap.5fd3999ee7762ccc51105388f4a9d115.css b/_static/panels-bootstrap.5fd3999ee7762ccc51105388f4a9d115.css
new file mode 100644
index 0000000000..1b057df2f2
--- /dev/null
+++ b/_static/panels-bootstrap.5fd3999ee7762ccc51105388f4a9d115.css
@@ -0,0 +1 @@
+.badge{border-radius:.25rem;display:inline-block;font-size:75%;font-weight:700;line-height:1;padding:.25em .4em;text-align:center;vertical-align:baseline;white-space:nowrap}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{border-radius:10rem;padding-left:.6em;padding-right:.6em}.badge-primary{background-color:#007bff;color:#fff}.badge-primary[href]:focus,.badge-primary[href]:hover{background-color:#0062cc;color:#fff;text-decoration:none}.badge-secondary{background-color:#6c757d;color:#fff}.badge-secondary[href]:focus,.badge-secondary[href]:hover{background-color:#545b62;color:#fff;text-decoration:none}.badge-success{background-color:#28a745;color:#fff}.badge-success[href]:focus,.badge-success[href]:hover{background-color:#1e7e34;color:#fff;text-decoration:none}.badge-info{background-color:#17a2b8;color:#fff}.badge-info[href]:focus,.badge-info[href]:hover{background-color:#117a8b;color:#fff;text-decoration:none}.badge-warning{background-color:#ffc107;color:#212529}.badge-warning[href]:focus,.badge-warning[href]:hover{background-color:#d39e00;color:#212529;text-decoration:none}.badge-danger{background-color:#dc3545;color:#fff}.badge-danger[href]:focus,.badge-danger[href]:hover{background-color:#bd2130;color:#fff;text-decoration:none}.badge-light{background-color:#f8f9fa;color:#212529}.badge-light[href]:focus,.badge-light[href]:hover{background-color:#dae0e5;color:#212529;text-decoration:none}.badge-dark{background-color:#343a40;color:#fff}.badge-dark[href]:focus,.badge-dark[href]:hover{background-color:#1d2124;color:#fff;text-decoration:none}.border-0{border:0 !important}.border-top-0{border-top:0 !important}.border-right-0{border-right:0 !important}.border-bottom-0{border-bottom:0 !important}.border-left-0{border-left:0 !important}.p-0{padding:0 !important}.pt-0,.py-0{padding-top:0 !important}.pr-0,.px-0{padding-right:0 !important}.pb-0,.py-0{padding-bottom:0 !important}.pl-0,.px-0{padding-left:0 !important}.p-1{padding:.25rem !important}.pt-1,.py-1{padding-top:.25rem !important}.pr-1,.px-1{padding-right:.25rem !important}.pb-1,.py-1{padding-bottom:.25rem !important}.pl-1,.px-1{padding-left:.25rem !important}.p-2{padding:.5rem !important}.pt-2,.py-2{padding-top:.5rem !important}.pr-2,.px-2{padding-right:.5rem !important}.pb-2,.py-2{padding-bottom:.5rem !important}.pl-2,.px-2{padding-left:.5rem !important}.p-3{padding:1rem !important}.pt-3,.py-3{padding-top:1rem !important}.pr-3,.px-3{padding-right:1rem !important}.pb-3,.py-3{padding-bottom:1rem !important}.pl-3,.px-3{padding-left:1rem !important}.p-4{padding:1.5rem !important}.pt-4,.py-4{padding-top:1.5rem !important}.pr-4,.px-4{padding-right:1.5rem !important}.pb-4,.py-4{padding-bottom:1.5rem !important}.pl-4,.px-4{padding-left:1.5rem !important}.p-5{padding:3rem !important}.pt-5,.py-5{padding-top:3rem !important}.pr-5,.px-5{padding-right:3rem !important}.pb-5,.py-5{padding-bottom:3rem !important}.pl-5,.px-5{padding-left:3rem !important}.m-0{margin:0 !important}.mt-0,.my-0{margin-top:0 !important}.mr-0,.mx-0{margin-right:0 !important}.mb-0,.my-0{margin-bottom:0 !important}.ml-0,.mx-0{margin-left:0 !important}.m-1{margin:.25rem !important}.mt-1,.my-1{margin-top:.25rem !important}.mr-1,.mx-1{margin-right:.25rem !important}.mb-1,.my-1{margin-bottom:.25rem !important}.ml-1,.mx-1{margin-left:.25rem !important}.m-2{margin:.5rem !important}.mt-2,.my-2{margin-top:.5rem !important}.mr-2,.mx-2{margin-right:.5rem !important}.mb-2,.my-2{margin-bottom:.5rem !important}.ml-2,.mx-2{margin-left:.5rem !important}.m-3{margin:1rem !important}.mt-3,.my-3{margin-top:1rem !important}.mr-3,.mx-3{margin-right:1rem !important}.mb-3,.my-3{margin-bottom:1rem !important}.ml-3,.mx-3{margin-left:1rem !important}.m-4{margin:1.5rem !important}.mt-4,.my-4{margin-top:1.5rem !important}.mr-4,.mx-4{margin-right:1.5rem !important}.mb-4,.my-4{margin-bottom:1.5rem !important}.ml-4,.mx-4{margin-left:1.5rem !important}.m-5{margin:3rem !important}.mt-5,.my-5{margin-top:3rem !important}.mr-5,.mx-5{margin-right:3rem !important}.mb-5,.my-5{margin-bottom:3rem !important}.ml-5,.mx-5{margin-left:3rem !important}.btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;color:#212529;cursor:pointer;display:inline-block;font-size:1rem;font-weight:400;line-height:1.5;padding:.375rem .75rem;text-align:center;transition:color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none;vertical-align:middle}.btn:hover{color:#212529;text-decoration:none}.btn:visited{color:#212529}.btn.focus,.btn:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.25);outline:0}.btn.disabled,.btn:disabled{opacity:.65}@media (prefers-reduced-motion: reduce){.btn{transition:none}}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{background-color:#007bff;border-color:#007bff;color:#fff}.btn-primary:visited{color:#fff}.btn-primary:hover{background-color:#0069d9;border-color:#0062cc;color:#fff}.btn-primary.focus,.btn-primary:focus{background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(0,123,255,0.5);color:#fff}.btn-primary.disabled,.btn-primary:disabled{background-color:#007bff;border-color:#007bff;color:#fff}.btn-primary.active:not(:disabled):not(.disabled),.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{background-color:#0062cc;border-color:#005cbf;color:#fff}.btn-primary.active:not(:disabled):not(.disabled):focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-secondary{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-secondary:visited{color:#fff}.btn-secondary:hover{background-color:#5a6268;border-color:#545b62;color:#fff}.btn-secondary.focus,.btn-secondary:focus{background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(108,117,125,0.5);color:#fff}.btn-secondary.disabled,.btn-secondary:disabled{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-secondary.active:not(:disabled):not(.disabled),.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{background-color:#545b62;border-color:#4e555b;color:#fff}.btn-secondary.active:not(:disabled):not(.disabled):focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-success{background-color:#28a745;border-color:#28a745;color:#fff}.btn-success:visited{color:#fff}.btn-success:hover{background-color:#218838;border-color:#1e7e34;color:#fff}.btn-success.focus,.btn-success:focus{background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(40,167,69,0.5);color:#fff}.btn-success.disabled,.btn-success:disabled{background-color:#28a745;border-color:#28a745;color:#fff}.btn-success.active:not(:disabled):not(.disabled),.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{background-color:#1e7e34;border-color:#1c7430;color:#fff}.btn-success.active:not(:disabled):not(.disabled):focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-info{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-info:visited{color:#fff}.btn-info:hover{background-color:#138496;border-color:#117a8b;color:#fff}.btn-info.focus,.btn-info:focus{background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(23,162,184,0.5);color:#fff}.btn-info.disabled,.btn-info:disabled{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-info.active:not(:disabled):not(.disabled),.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{background-color:#117a8b;border-color:#10707f;color:#fff}.btn-info.active:not(:disabled):not(.disabled):focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-warning{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-warning:visited{color:#212529}.btn-warning:hover{background-color:#e0a800;border-color:#d39e00;color:#212529}.btn-warning.focus,.btn-warning:focus{background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(255,193,7,0.5);color:#212529}.btn-warning.disabled,.btn-warning:disabled{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-warning.active:not(:disabled):not(.disabled),.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{background-color:#d39e00;border-color:#c69500;color:#212529}.btn-warning.active:not(:disabled):not(.disabled):focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-danger{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-danger:visited{color:#fff}.btn-danger:hover{background-color:#c82333;border-color:#bd2130;color:#fff}.btn-danger.focus,.btn-danger:focus{background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(220,53,69,0.5);color:#fff}.btn-danger.disabled,.btn-danger:disabled{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-danger.active:not(:disabled):not(.disabled),.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{background-color:#bd2130;border-color:#b21f2d;color:#fff}.btn-danger.active:not(:disabled):not(.disabled):focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-light{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-light:visited{color:#212529}.btn-light:hover{background-color:#e2e6ea;border-color:#dae0e5;color:#212529}.btn-light.focus,.btn-light:focus{background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(248,249,250,0.5);color:#212529}.btn-light.disabled,.btn-light:disabled{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-light.active:not(:disabled):not(.disabled),.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{background-color:#dae0e5;border-color:#d3d9df;color:#212529}.btn-light.active:not(:disabled):not(.disabled):focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-dark{background-color:#343a40;border-color:#343a40;color:#fff}.btn-dark:visited{color:#fff}.btn-dark:hover{background-color:#23272b;border-color:#1d2124;color:#fff}.btn-dark.focus,.btn-dark:focus{background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(52,58,64,0.5);color:#fff}.btn-dark.disabled,.btn-dark:disabled{background-color:#343a40;border-color:#343a40;color:#fff}.btn-dark.active:not(:disabled):not(.disabled),.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{background-color:#1d2124;border-color:#171a1d;color:#fff}.btn-dark.active:not(:disabled):not(.disabled):focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-primary{border-color:#007bff;color:#007bff}.btn-outline-primary:visited{color:#007bff}.btn-outline-primary:hover{background-color:#007bff;border-color:#007bff;color:#fff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{background-color:transparent;color:#007bff}.btn-outline-primary.active:not(:disabled):not(.disabled),.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{background-color:#007bff;border-color:#007bff;color:#fff}.btn-outline-primary.active:not(:disabled):not(.disabled):focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,0.5)}.btn-outline-secondary{border-color:#6c757d;color:#6c757d}.btn-outline-secondary:visited{color:#6c757d}.btn-outline-secondary:hover{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{background-color:transparent;color:#6c757d}.btn-outline-secondary.active:not(:disabled):not(.disabled),.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{background-color:#6c757d;border-color:#6c757d;color:#fff}.btn-outline-secondary.active:not(:disabled):not(.disabled):focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,0.5)}.btn-outline-success{border-color:#28a745;color:#28a745}.btn-outline-success:visited{color:#28a745}.btn-outline-success:hover{background-color:#28a745;border-color:#28a745;color:#fff}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{background-color:transparent;color:#28a745}.btn-outline-success.active:not(:disabled):not(.disabled),.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{background-color:#28a745;border-color:#28a745;color:#fff}.btn-outline-success.active:not(:disabled):not(.disabled):focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,0.5)}.btn-outline-info{border-color:#17a2b8;color:#17a2b8}.btn-outline-info:visited{color:#17a2b8}.btn-outline-info:hover{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{background-color:transparent;color:#17a2b8}.btn-outline-info.active:not(:disabled):not(.disabled),.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.btn-outline-info.active:not(:disabled):not(.disabled):focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,0.5)}.btn-outline-warning{border-color:#ffc107;color:#ffc107}.btn-outline-warning:visited{color:#ffc107}.btn-outline-warning:hover{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{background-color:transparent;color:#ffc107}.btn-outline-warning.active:not(:disabled):not(.disabled),.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{background-color:#ffc107;border-color:#ffc107;color:#212529}.btn-outline-warning.active:not(:disabled):not(.disabled):focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,0.5)}.btn-outline-danger{border-color:#dc3545;color:#dc3545}.btn-outline-danger:visited{color:#dc3545}.btn-outline-danger:hover{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{background-color:transparent;color:#dc3545}.btn-outline-danger.active:not(:disabled):not(.disabled),.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{background-color:#dc3545;border-color:#dc3545;color:#fff}.btn-outline-danger.active:not(:disabled):not(.disabled):focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,0.5)}.btn-outline-light{border-color:#f8f9fa;color:#f8f9fa}.btn-outline-light:visited{color:#f8f9fa}.btn-outline-light:hover{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{background-color:transparent;color:#f8f9fa}.btn-outline-light.active:not(:disabled):not(.disabled),.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{background-color:#f8f9fa;border-color:#f8f9fa;color:#212529}.btn-outline-light.active:not(:disabled):not(.disabled):focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,0.5)}.btn-outline-dark{border-color:#343a40;color:#343a40}.btn-outline-dark:visited{color:#343a40}.btn-outline-dark:hover{background-color:#343a40;border-color:#343a40;color:#fff}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{background-color:transparent;color:#343a40}.btn-outline-dark.active:not(:disabled):not(.disabled),.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{background-color:#343a40;border-color:#343a40;color:#fff}.btn-outline-dark.active:not(:disabled):not(.disabled):focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,0.5)}.btn-link{color:#007bff;font-weight:400;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{box-shadow:none;text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{border-radius:.3rem;font-size:1.25rem;line-height:1.5;padding:.5rem 1rem}.btn-group-sm>.btn,.btn-sm{border-radius:.2rem;font-size:.875rem;line-height:1.5;padding:.25rem .5rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input.btn-block[type=button],input.btn-block[type=reset],input.btn-block[type=submit]{width:100%}.stretched-link::after{background-color:rgba(0,0,0,0);bottom:0;content:'';left:0;pointer-events:auto;position:absolute;right:0;top:0;z-index:1}.text-wrap{white-space:normal !important}.card{background-clip:border-box;background-color:#fff;border:1px solid rgba(0,0,0,0.125);border-radius:.25rem;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.card>hr{margin-left:0;margin-right:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-bottom:0;margin-top:-.375rem}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{background-color:rgba(0,0,0,0.03);border-bottom:1px solid rgba(0,0,0,0.125);margin-bottom:0;padding:.75rem 1.25rem}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{background-color:rgba(0,0,0,0.03);border-top:1px solid rgba(0,0,0,0.125);padding:.75rem 1.25rem}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{border-bottom:0;margin-bottom:-.75rem;margin-left:-.625rem;margin-right:-.625rem}.card-header-pills{margin-left:-.625rem;margin-right:-.625rem}.card-img-overlay{bottom:0;left:0;padding:1.25rem;position:absolute;right:0;top:0}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-left-radius:calc(.25rem - 1px);border-bottom-right-radius:calc(.25rem - 1px)}.w-100{width:100% !important}.shadow{box-shadow:0 0.5rem 1rem rgba(0,0,0,0.15) !important}.bg-primary{background-color:#007bff !important}button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc !important}a.bg-primary:focus,a.bg-primary:hover{background-color:#0062cc !important}a.text-primary:focus,a.text-primary:hover{color:#121416 !important}.bg-secondary{background-color:#6c757d !important}button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62 !important}a.bg-secondary:focus,a.bg-secondary:hover{background-color:#545b62 !important}a.text-secondary:focus,a.text-secondary:hover{color:#121416 !important}.bg-success{background-color:#28a745 !important}button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34 !important}a.bg-success:focus,a.bg-success:hover{background-color:#1e7e34 !important}a.text-success:focus,a.text-success:hover{color:#121416 !important}.bg-info{background-color:#17a2b8 !important}button.bg-info:focus,button.bg-info:hover{background-color:#117a8b !important}a.bg-info:focus,a.bg-info:hover{background-color:#117a8b !important}a.text-info:focus,a.text-info:hover{color:#121416 !important}.bg-warning{background-color:#ffc107 !important}button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00 !important}a.bg-warning:focus,a.bg-warning:hover{background-color:#d39e00 !important}a.text-warning:focus,a.text-warning:hover{color:#121416 !important}.bg-danger{background-color:#dc3545 !important}button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130 !important}a.bg-danger:focus,a.bg-danger:hover{background-color:#bd2130 !important}a.text-danger:focus,a.text-danger:hover{color:#121416 !important}.bg-light{background-color:#f8f9fa !important}button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5 !important}a.bg-light:focus,a.bg-light:hover{background-color:#dae0e5 !important}a.text-light:focus,a.text-light:hover{color:#121416 !important}.bg-dark{background-color:#343a40 !important}button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124 !important}a.bg-dark:focus,a.bg-dark:hover{background-color:#1d2124 !important}a.text-dark:focus,a.text-dark:hover{color:#121416 !important}.bg-white{background-color:#fff !important}button.bg-white:focus,button.bg-white:hover{background-color:#e6e6e6 !important}a.bg-white:focus,a.bg-white:hover{background-color:#e6e6e6 !important}a.text-white:focus,a.text-white:hover{color:#121416 !important}.text-primary{color:#007bff !important}.text-secondary{color:#6c757d !important}.text-success{color:#28a745 !important}.text-info{color:#17a2b8 !important}.text-warning{color:#ffc107 !important}.text-danger{color:#dc3545 !important}.text-light{color:#f8f9fa !important}.text-dark{color:#343a40 !important}.text-white{color:#fff !important}.text-body{color:#212529 !important}.text-muted{color:#6c757d !important}.text-black-50{color:rgba(0,0,0,0.5) !important}.text-white-50{color:rgba(255,255,255,0.5) !important}.bg-transparent{background-color:transparent !important}.text-justify{text-align:justify !important}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.font-weight-light{font-weight:300 !important}.font-weight-lighter{font-weight:lighter !important}.font-weight-normal{font-weight:400 !important}.font-weight-bold{font-weight:700 !important}.font-weight-bolder{font-weight:bolder !important}.font-italic{font-style:italic !important}.container{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media (min-width: 576px){.container{max-width:540px}}@media (min-width: 768px){.container{max-width:720px}}@media (min-width: 992px){.container{max-width:960px}}@media (min-width: 1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px;width:100%}@media (min-width: 576px){.container,.container-sm{max-width:540px}}@media (min-width: 768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width: 992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width: 1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-left:-15px;margin-right:-15px}.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{padding-left:15px;padding-right:15px;position:relative;width:100%}@media (min-width: 576px){.col-sm{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-sm-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-sm-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-sm-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-sm-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-sm-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media (min-width: 768px){.col-md{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-md-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-md-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-md-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-md-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-md-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media (min-width: 992px){.col-lg{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-lg-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-lg-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-lg-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-lg-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-lg-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}@media (min-width: 1200px){.col-xl{flex-basis:0;flex-grow:1;-ms-flex-positive:1;-ms-flex-preferred-size:0;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;max-width:100%;width:auto}.col-xl-1{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%;max-width:8.33333%}.col-xl-2{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%;max-width:16.66667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%;max-width:33.33333%}.col-xl-5{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%;max-width:41.66667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%;max-width:58.33333%}.col-xl-8{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%;max-width:66.66667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%;max-width:83.33333%}.col-xl-11{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%;max-width:91.66667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}}.d-flex{display:-ms-flexbox !important;display:flex !important}.sphinx-bs,.sphinx-bs *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sphinx-bs p{margin-top:0}
diff --git a/_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css b/_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css
new file mode 100644
index 0000000000..fc14abc85d
--- /dev/null
+++ b/_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css
@@ -0,0 +1 @@
+details.dropdown .summary-title{padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.dropdown:hover{cursor:pointer}details.dropdown .summary-content{cursor:default}details.dropdown summary{list-style:none;padding:1em}details.dropdown summary .octicon.no-title{vertical-align:middle}details.dropdown[open] summary .octicon.no-title{visibility:hidden}details.dropdown summary::-webkit-details-marker{display:none}details.dropdown summary:focus{outline:none}details.dropdown summary:hover .summary-up svg,details.dropdown summary:hover .summary-down svg{opacity:1}details.dropdown .summary-up svg,details.dropdown .summary-down svg{display:block;opacity:.6}details.dropdown .summary-up,details.dropdown .summary-down{pointer-events:none;position:absolute;right:1em;top:.75em}details.dropdown[open] .summary-down{visibility:hidden}details.dropdown:not([open]) .summary-up{visibility:hidden}details.dropdown.fade-in[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out;animation:panels-fade-in .5s ease-in-out}details.dropdown.fade-in-slide-down[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out}@keyframes panels-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes panels-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.octicon{display:inline-block;fill:currentColor;vertical-align:text-top}.tabbed-content{box-shadow:0 -.0625rem var(--tabs-color-overline),0 .0625rem var(--tabs-color-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.tabbed-content>:first-child{margin-top:0 !important}.tabbed-content>:last-child{margin-bottom:0 !important}.tabbed-content>.tabbed-set{margin:0}.tabbed-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.tabbed-set>input{opacity:0;position:absolute}.tabbed-set>input:checked+label{border-color:var(--tabs-color-label-active);color:var(--tabs-color-label-active)}.tabbed-set>input:checked+label+.tabbed-content{display:block}.tabbed-set>input:focus+label{outline-style:auto}.tabbed-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.tabbed-set>label{border-bottom:.125rem solid transparent;color:var(--tabs-color-label-inactive);cursor:pointer;font-size:var(--tabs-size-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .tabbed-set>label:hover{color:var(--tabs-color-label-active)}
diff --git a/_static/panels-variables.06eb56fa6e07937060861dad626602ad.css b/_static/panels-variables.06eb56fa6e07937060861dad626602ad.css
new file mode 100644
index 0000000000..adc6166222
--- /dev/null
+++ b/_static/panels-variables.06eb56fa6e07937060861dad626602ad.css
@@ -0,0 +1,7 @@
+:root {
+--tabs-color-label-active: hsla(231, 99%, 66%, 1);
+--tabs-color-label-inactive: rgba(178, 206, 245, 0.62);
+--tabs-color-overline: rgb(207, 236, 238);
+--tabs-color-underline: rgb(207, 236, 238);
+--tabs-size-label: 1rem;
+}
\ No newline at end of file
diff --git a/_static/plus.png b/_static/plus.png
new file mode 100644
index 0000000000..7107cec93a
Binary files /dev/null and b/_static/plus.png differ
diff --git a/_static/pygments.css b/_static/pygments.css
new file mode 100644
index 0000000000..02b4b12812
--- /dev/null
+++ b/_static/pygments.css
@@ -0,0 +1,258 @@
+.highlight pre { line-height: 125%; }
+.highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+.highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+.highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+.highlight .hll { background-color: #ffffcc }
+.highlight { background: #f8f8f8; }
+.highlight .c { color: #8f5902; font-style: italic } /* Comment */
+.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */
+.highlight .g { color: #000000 } /* Generic */
+.highlight .k { color: #204a87; font-weight: bold } /* Keyword */
+.highlight .l { color: #000000 } /* Literal */
+.highlight .n { color: #000000 } /* Name */
+.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */
+.highlight .x { color: #000000 } /* Other */
+.highlight .p { color: #000000; font-weight: bold } /* Punctuation */
+.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */
+.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */
+.highlight .gd { color: #a40000 } /* Generic.Deleted */
+.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */
+.highlight .ges { color: #000000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
+.highlight .gr { color: #ef2929 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #000000; font-style: italic } /* Generic.Output */
+.highlight .gp { color: #8f5902 } /* Generic.Prompt */
+.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */
+.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */
+.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */
+.highlight .ld { color: #000000 } /* Literal.Date */
+.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */
+.highlight .s { color: #4e9a06 } /* Literal.String */
+.highlight .na { color: #c4a000 } /* Name.Attribute */
+.highlight .nb { color: #204a87 } /* Name.Builtin */
+.highlight .nc { color: #000000 } /* Name.Class */
+.highlight .no { color: #000000 } /* Name.Constant */
+.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #ce5c00 } /* Name.Entity */
+.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */
+.highlight .nf { color: #000000 } /* Name.Function */
+.highlight .nl { color: #f57900 } /* Name.Label */
+.highlight .nn { color: #000000 } /* Name.Namespace */
+.highlight .nx { color: #000000 } /* Name.Other */
+.highlight .py { color: #000000 } /* Name.Property */
+.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #000000 } /* Name.Variable */
+.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */
+.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */
+.highlight .w { color: #f8f8f8 } /* Text.Whitespace */
+.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */
+.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */
+.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */
+.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */
+.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */
+.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */
+.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */
+.highlight .sc { color: #4e9a06 } /* Literal.String.Char */
+.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */
+.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */
+.highlight .se { color: #4e9a06 } /* Literal.String.Escape */
+.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */
+.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */
+.highlight .sx { color: #4e9a06 } /* Literal.String.Other */
+.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */
+.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */
+.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */
+.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #000000 } /* Name.Function.Magic */
+.highlight .vc { color: #000000 } /* Name.Variable.Class */
+.highlight .vg { color: #000000 } /* Name.Variable.Global */
+.highlight .vi { color: #000000 } /* Name.Variable.Instance */
+.highlight .vm { color: #000000 } /* Name.Variable.Magic */
+.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */
+@media not print {
+body[data-theme="dark"] .highlight pre { line-height: 125%; }
+body[data-theme="dark"] .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+body[data-theme="dark"] .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+body[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+body[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+body[data-theme="dark"] .highlight .hll { background-color: #404040 }
+body[data-theme="dark"] .highlight { background: #202020; color: #d0d0d0 }
+body[data-theme="dark"] .highlight .c { color: #ababab; font-style: italic } /* Comment */
+body[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+body[data-theme="dark"] .highlight .esc { color: #d0d0d0 } /* Escape */
+body[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */
+body[data-theme="dark"] .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */
+body[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */
+body[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */
+body[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */
+body[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */
+body[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */
+body[data-theme="dark"] .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */
+body[data-theme="dark"] .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */
+body[data-theme="dark"] .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */
+body[data-theme="dark"] .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */
+body[data-theme="dark"] .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */
+body[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
+body[data-theme="dark"] .highlight .gd { color: #ff3a3a } /* Generic.Deleted */
+body[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
+body[data-theme="dark"] .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
+body[data-theme="dark"] .highlight .gr { color: #ff3a3a } /* Generic.Error */
+body[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
+body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */
+body[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */
+body[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
+body[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
+body[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
+body[data-theme="dark"] .highlight .gt { color: #ff3a3a } /* Generic.Traceback */
+body[data-theme="dark"] .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */
+body[data-theme="dark"] .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */
+body[data-theme="dark"] .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */
+body[data-theme="dark"] .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */
+body[data-theme="dark"] .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */
+body[data-theme="dark"] .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */
+body[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */
+body[data-theme="dark"] .highlight .m { color: #51b2fd } /* Literal.Number */
+body[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */
+body[data-theme="dark"] .highlight .na { color: #bbbbbb } /* Name.Attribute */
+body[data-theme="dark"] .highlight .nb { color: #2fbccd } /* Name.Builtin */
+body[data-theme="dark"] .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */
+body[data-theme="dark"] .highlight .no { color: #40ffff } /* Name.Constant */
+body[data-theme="dark"] .highlight .nd { color: #ffa500 } /* Name.Decorator */
+body[data-theme="dark"] .highlight .ni { color: #d0d0d0 } /* Name.Entity */
+body[data-theme="dark"] .highlight .ne { color: #bbbbbb } /* Name.Exception */
+body[data-theme="dark"] .highlight .nf { color: #71adff } /* Name.Function */
+body[data-theme="dark"] .highlight .nl { color: #d0d0d0 } /* Name.Label */
+body[data-theme="dark"] .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */
+body[data-theme="dark"] .highlight .nx { color: #d0d0d0 } /* Name.Other */
+body[data-theme="dark"] .highlight .py { color: #d0d0d0 } /* Name.Property */
+body[data-theme="dark"] .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */
+body[data-theme="dark"] .highlight .nv { color: #40ffff } /* Name.Variable */
+body[data-theme="dark"] .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */
+body[data-theme="dark"] .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */
+body[data-theme="dark"] .highlight .w { color: #666666 } /* Text.Whitespace */
+body[data-theme="dark"] .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */
+body[data-theme="dark"] .highlight .mf { color: #51b2fd } /* Literal.Number.Float */
+body[data-theme="dark"] .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */
+body[data-theme="dark"] .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */
+body[data-theme="dark"] .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */
+body[data-theme="dark"] .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */
+body[data-theme="dark"] .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */
+body[data-theme="dark"] .highlight .sc { color: #ed9d13 } /* Literal.String.Char */
+body[data-theme="dark"] .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */
+body[data-theme="dark"] .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */
+body[data-theme="dark"] .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */
+body[data-theme="dark"] .highlight .se { color: #ed9d13 } /* Literal.String.Escape */
+body[data-theme="dark"] .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */
+body[data-theme="dark"] .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */
+body[data-theme="dark"] .highlight .sx { color: #ffa500 } /* Literal.String.Other */
+body[data-theme="dark"] .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */
+body[data-theme="dark"] .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */
+body[data-theme="dark"] .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */
+body[data-theme="dark"] .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */
+body[data-theme="dark"] .highlight .fm { color: #71adff } /* Name.Function.Magic */
+body[data-theme="dark"] .highlight .vc { color: #40ffff } /* Name.Variable.Class */
+body[data-theme="dark"] .highlight .vg { color: #40ffff } /* Name.Variable.Global */
+body[data-theme="dark"] .highlight .vi { color: #40ffff } /* Name.Variable.Instance */
+body[data-theme="dark"] .highlight .vm { color: #40ffff } /* Name.Variable.Magic */
+body[data-theme="dark"] .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */
+@media (prefers-color-scheme: dark) {
+body:not([data-theme="light"]) .highlight pre { line-height: 125%; }
+body:not([data-theme="light"]) .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+body:not([data-theme="light"]) .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; }
+body:not([data-theme="light"]) .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+body:not([data-theme="light"]) .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
+body:not([data-theme="light"]) .highlight .hll { background-color: #404040 }
+body:not([data-theme="light"]) .highlight { background: #202020; color: #d0d0d0 }
+body:not([data-theme="light"]) .highlight .c { color: #ababab; font-style: italic } /* Comment */
+body:not([data-theme="light"]) .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+body:not([data-theme="light"]) .highlight .esc { color: #d0d0d0 } /* Escape */
+body:not([data-theme="light"]) .highlight .g { color: #d0d0d0 } /* Generic */
+body:not([data-theme="light"]) .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */
+body:not([data-theme="light"]) .highlight .l { color: #d0d0d0 } /* Literal */
+body:not([data-theme="light"]) .highlight .n { color: #d0d0d0 } /* Name */
+body:not([data-theme="light"]) .highlight .o { color: #d0d0d0 } /* Operator */
+body:not([data-theme="light"]) .highlight .x { color: #d0d0d0 } /* Other */
+body:not([data-theme="light"]) .highlight .p { color: #d0d0d0 } /* Punctuation */
+body:not([data-theme="light"]) .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */
+body:not([data-theme="light"]) .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */
+body:not([data-theme="light"]) .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */
+body:not([data-theme="light"]) .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */
+body:not([data-theme="light"]) .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */
+body:not([data-theme="light"]) .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
+body:not([data-theme="light"]) .highlight .gd { color: #ff3a3a } /* Generic.Deleted */
+body:not([data-theme="light"]) .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
+body:not([data-theme="light"]) .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
+body:not([data-theme="light"]) .highlight .gr { color: #ff3a3a } /* Generic.Error */
+body:not([data-theme="light"]) .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
+body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */
+body:not([data-theme="light"]) .highlight .go { color: #cccccc } /* Generic.Output */
+body:not([data-theme="light"]) .highlight .gp { color: #aaaaaa } /* Generic.Prompt */
+body:not([data-theme="light"]) .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
+body:not([data-theme="light"]) .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
+body:not([data-theme="light"]) .highlight .gt { color: #ff3a3a } /* Generic.Traceback */
+body:not([data-theme="light"]) .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */
+body:not([data-theme="light"]) .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */
+body:not([data-theme="light"]) .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */
+body:not([data-theme="light"]) .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */
+body:not([data-theme="light"]) .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */
+body:not([data-theme="light"]) .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */
+body:not([data-theme="light"]) .highlight .ld { color: #d0d0d0 } /* Literal.Date */
+body:not([data-theme="light"]) .highlight .m { color: #51b2fd } /* Literal.Number */
+body:not([data-theme="light"]) .highlight .s { color: #ed9d13 } /* Literal.String */
+body:not([data-theme="light"]) .highlight .na { color: #bbbbbb } /* Name.Attribute */
+body:not([data-theme="light"]) .highlight .nb { color: #2fbccd } /* Name.Builtin */
+body:not([data-theme="light"]) .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */
+body:not([data-theme="light"]) .highlight .no { color: #40ffff } /* Name.Constant */
+body:not([data-theme="light"]) .highlight .nd { color: #ffa500 } /* Name.Decorator */
+body:not([data-theme="light"]) .highlight .ni { color: #d0d0d0 } /* Name.Entity */
+body:not([data-theme="light"]) .highlight .ne { color: #bbbbbb } /* Name.Exception */
+body:not([data-theme="light"]) .highlight .nf { color: #71adff } /* Name.Function */
+body:not([data-theme="light"]) .highlight .nl { color: #d0d0d0 } /* Name.Label */
+body:not([data-theme="light"]) .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */
+body:not([data-theme="light"]) .highlight .nx { color: #d0d0d0 } /* Name.Other */
+body:not([data-theme="light"]) .highlight .py { color: #d0d0d0 } /* Name.Property */
+body:not([data-theme="light"]) .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */
+body:not([data-theme="light"]) .highlight .nv { color: #40ffff } /* Name.Variable */
+body:not([data-theme="light"]) .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */
+body:not([data-theme="light"]) .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */
+body:not([data-theme="light"]) .highlight .w { color: #666666 } /* Text.Whitespace */
+body:not([data-theme="light"]) .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */
+body:not([data-theme="light"]) .highlight .mf { color: #51b2fd } /* Literal.Number.Float */
+body:not([data-theme="light"]) .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */
+body:not([data-theme="light"]) .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */
+body:not([data-theme="light"]) .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */
+body:not([data-theme="light"]) .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */
+body:not([data-theme="light"]) .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */
+body:not([data-theme="light"]) .highlight .sc { color: #ed9d13 } /* Literal.String.Char */
+body:not([data-theme="light"]) .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */
+body:not([data-theme="light"]) .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */
+body:not([data-theme="light"]) .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */
+body:not([data-theme="light"]) .highlight .se { color: #ed9d13 } /* Literal.String.Escape */
+body:not([data-theme="light"]) .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */
+body:not([data-theme="light"]) .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */
+body:not([data-theme="light"]) .highlight .sx { color: #ffa500 } /* Literal.String.Other */
+body:not([data-theme="light"]) .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */
+body:not([data-theme="light"]) .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */
+body:not([data-theme="light"]) .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */
+body:not([data-theme="light"]) .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */
+body:not([data-theme="light"]) .highlight .fm { color: #71adff } /* Name.Function.Magic */
+body:not([data-theme="light"]) .highlight .vc { color: #40ffff } /* Name.Variable.Class */
+body:not([data-theme="light"]) .highlight .vg { color: #40ffff } /* Name.Variable.Global */
+body:not([data-theme="light"]) .highlight .vi { color: #40ffff } /* Name.Variable.Instance */
+body:not([data-theme="light"]) .highlight .vm { color: #40ffff } /* Name.Variable.Magic */
+body:not([data-theme="light"]) .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */
+}
+}
\ No newline at end of file
diff --git a/_static/sandbox-small.png b/_static/sandbox-small.png
new file mode 100644
index 0000000000..a7e86244dd
Binary files /dev/null and b/_static/sandbox-small.png differ
diff --git a/_static/sandbox-tiny.png b/_static/sandbox-tiny.png
new file mode 100644
index 0000000000..02965183c0
Binary files /dev/null and b/_static/sandbox-tiny.png differ
diff --git a/_static/sandbox.png b/_static/sandbox.png
new file mode 100644
index 0000000000..4623d5e5b6
Binary files /dev/null and b/_static/sandbox.png differ
diff --git a/_static/scripts/furo-extensions.js b/_static/scripts/furo-extensions.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/_static/scripts/furo.js b/_static/scripts/furo.js
new file mode 100644
index 0000000000..0267c7e112
--- /dev/null
+++ b/_static/scripts/furo.js
@@ -0,0 +1,3 @@
+/*! For license information please see furo.js.LICENSE.txt */
+(()=>{var t={856:function(t,e,n){var o,r;r=void 0!==n.g?n.g:"undefined"!=typeof window?window:this,o=function(){return function(t){"use strict";var e={navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:0,reflow:!1,events:!0},n=function(t,e,n){if(n.settings.events){var o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n});e.dispatchEvent(o)}},o=function(t){var e=0;if(t.offsetParent)for(;t;)e+=t.offsetTop,t=t.offsetParent;return e>=0?e:0},r=function(t){t&&t.sort((function(t,e){return o(t.content)=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},l=function(t,e){var n=t[t.length-1];if(function(t,e){return!(!s()||!c(t.content,e,!0))}(n,e))return n;for(var o=t.length-1;o>=0;o--)if(c(t[o].content,e))return t[o]},a=function(t,e){if(e.nested&&t.parentNode){var n=t.parentNode.closest("li");n&&(n.classList.remove(e.nestedClass),a(n,e))}},i=function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.remove(e.navClass),t.content.classList.remove(e.contentClass),a(o,e),n("gumshoeDeactivate",o,{link:t.nav,content:t.content,settings:e}))}},u=function(t,e){if(e.nested){var n=t.parentNode.closest("li");n&&(n.classList.add(e.nestedClass),u(n,e))}};return function(o,c){var s,a,d,f,m,v={setup:function(){s=document.querySelectorAll(o),a=[],Array.prototype.forEach.call(s,(function(t){var e=document.getElementById(decodeURIComponent(t.hash.substr(1)));e&&a.push({nav:t,content:e})})),r(a)},detect:function(){var t=l(a,m);t?d&&t.content===d.content||(i(d,m),function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.add(e.navClass),t.content.classList.add(e.contentClass),u(o,e),n("gumshoeActivate",o,{link:t.nav,content:t.content,settings:e}))}}(t,m),d=t):d&&(i(d,m),d=null)}},h=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame(v.detect)},g=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame((function(){r(a),v.detect()}))};return v.destroy=function(){d&&i(d,m),t.removeEventListener("scroll",h,!1),m.reflow&&t.removeEventListener("resize",g,!1),a=null,s=null,d=null,f=null,m=null},m=function(){var t={};return Array.prototype.forEach.call(arguments,(function(e){for(var n in e){if(!e.hasOwnProperty(n))return;t[n]=e[n]}})),t}(e,c||{}),v.setup(),v.detect(),t.addEventListener("scroll",h,!1),m.reflow&&t.addEventListener("resize",g,!1),v}}(r)}.apply(e,[]),void 0===o||(t.exports=o)}},e={};function n(o){var r=e[o];if(void 0!==r)return r.exports;var c=e[o]={exports:{}};return t[o].call(c.exports,c,c.exports,n),c.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";var t=n(856),e=n.n(t),o=null,r=null,c=window.pageYOffset||document.documentElement.scrollTop;const s=64;function l(){const t=localStorage.getItem("theme")||"auto";var e;"light"!==(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"auto"===t?"light":"light"==t?"dark":"auto":"auto"===t?"dark":"dark"==t?"light":"auto")&&"dark"!==e&&"auto"!==e&&(console.error(`Got invalid theme mode: ${e}. Resetting to auto.`),e="auto"),document.body.dataset.theme=e,localStorage.setItem("theme",e),console.log(`Changed to ${e} mode.`)}function a(){!function(){const t=document.getElementsByClassName("theme-toggle");Array.from(t).forEach((t=>{t.addEventListener("click",l)}))}(),function(){let t=0,e=!1;window.addEventListener("scroll",(function(n){t=window.scrollY,e||(window.requestAnimationFrame((function(){var n;n=t,0==Math.floor(r.getBoundingClientRect().top)?r.classList.add("scrolled"):r.classList.remove("scrolled"),function(t){tc&&document.documentElement.classList.remove("show-back-to-top"),c=t}(n),function(t){null!==o&&(0==t?o.scrollTo(0,0):Math.ceil(t)>=Math.floor(document.documentElement.scrollHeight-window.innerHeight)?o.scrollTo(0,o.scrollHeight):document.querySelector(".scroll-current"))}(n),e=!1})),e=!0)})),window.scroll()}(),null!==o&&new(e())(".toc-tree a",{reflow:!0,recursive:!0,navClass:"scroll-current",offset:()=>{let t=parseFloat(getComputedStyle(document.documentElement).fontSize);return r.getBoundingClientRect().height+2.5*t+1}})}document.addEventListener("DOMContentLoaded",(function(){document.body.parentNode.classList.remove("no-js"),r=document.querySelector("header"),o=document.querySelector(".toc-scroll"),a()}))})()})();
+//# sourceMappingURL=furo.js.map
\ No newline at end of file
diff --git a/_static/scripts/furo.js.LICENSE.txt b/_static/scripts/furo.js.LICENSE.txt
new file mode 100644
index 0000000000..1632189c7e
--- /dev/null
+++ b/_static/scripts/furo.js.LICENSE.txt
@@ -0,0 +1,7 @@
+/*!
+ * gumshoejs v5.1.2 (patched by @pradyunsg)
+ * A simple, framework-agnostic scrollspy script.
+ * (c) 2019 Chris Ferdinandi
+ * MIT License
+ * http://github.com/cferdinandi/gumshoe
+ */
diff --git a/_static/scripts/furo.js.map b/_static/scripts/furo.js.map
new file mode 100644
index 0000000000..c3b37aaa94
--- /dev/null
+++ b/_static/scripts/furo.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"scripts/furo.js","mappings":";iCAAA,MAQWA,SAWS,IAAX,EAAAC,EACH,EAAAA,EACkB,oBAAXC,OACLA,OACAC,KAbO,EAAF,WACP,OAaJ,SAAUD,GACR,aAMA,IAAIE,EAAW,CAEbC,SAAU,SACVC,aAAc,SAGdC,QAAQ,EACRC,YAAa,SAGbC,OAAQ,EACRC,QAAQ,EAGRC,QAAQ,GA6BNC,EAAY,SAAUC,EAAMC,EAAMC,GAEpC,GAAKA,EAAOC,SAASL,OAArB,CAGA,IAAIM,EAAQ,IAAIC,YAAYL,EAAM,CAChCM,SAAS,EACTC,YAAY,EACZL,OAAQA,IAIVD,EAAKO,cAAcJ,EAVgB,CAWrC,EAOIK,EAAe,SAAUR,GAC3B,IAAIS,EAAW,EACf,GAAIT,EAAKU,aACP,KAAOV,GACLS,GAAYT,EAAKW,UACjBX,EAAOA,EAAKU,aAGhB,OAAOD,GAAY,EAAIA,EAAW,CACpC,EAMIG,EAAe,SAAUC,GACvBA,GACFA,EAASC,MAAK,SAAUC,EAAOC,GAG7B,OAFcR,EAAaO,EAAME,SACnBT,EAAaQ,EAAMC,UACF,EACxB,CACT,GAEJ,EAwCIC,EAAW,SAAUlB,EAAME,EAAUiB,GACvC,IAAIC,EAASpB,EAAKqB,wBACd1B,EAnCU,SAAUO,GAExB,MAA+B,mBAApBA,EAASP,OACX2B,WAAWpB,EAASP,UAItB2B,WAAWpB,EAASP,OAC7B,CA2Be4B,CAAUrB,GACvB,OAAIiB,EAEAK,SAASJ,EAAOD,OAAQ,KACvB/B,EAAOqC,aAAeC,SAASC,gBAAgBC,cAG7CJ,SAASJ,EAAOS,IAAK,KAAOlC,CACrC,EAMImC,EAAa,WACf,OACEC,KAAKC,KAAK5C,EAAOqC,YAAcrC,EAAO6C,cAnCjCF,KAAKG,IACVR,SAASS,KAAKC,aACdV,SAASC,gBAAgBS,aACzBV,SAASS,KAAKE,aACdX,SAASC,gBAAgBU,aACzBX,SAASS,KAAKP,aACdF,SAASC,gBAAgBC,aAkC7B,EAmBIU,EAAY,SAAUzB,EAAUX,GAClC,IAAIqC,EAAO1B,EAASA,EAAS2B,OAAS,GACtC,GAbgB,SAAUC,EAAMvC,GAChC,SAAI4B,MAAgBZ,EAASuB,EAAKxB,QAASf,GAAU,GAEvD,CAUMwC,CAAYH,EAAMrC,GAAW,OAAOqC,EACxC,IAAK,IAAII,EAAI9B,EAAS2B,OAAS,EAAGG,GAAK,EAAGA,IACxC,GAAIzB,EAASL,EAAS8B,GAAG1B,QAASf,GAAW,OAAOW,EAAS8B,EAEjE,EAOIC,EAAmB,SAAUC,EAAK3C,GAEpC,GAAKA,EAAST,QAAWoD,EAAIC,WAA7B,CAGA,IAAIC,EAAKF,EAAIC,WAAWE,QAAQ,MAC3BD,IAGLA,EAAGE,UAAUC,OAAOhD,EAASR,aAG7BkD,EAAiBG,EAAI7C,GAV0B,CAWjD,EAOIiD,EAAa,SAAUC,EAAOlD,GAEhC,GAAKkD,EAAL,CAGA,IAAIL,EAAKK,EAAMP,IAAIG,QAAQ,MACtBD,IAGLA,EAAGE,UAAUC,OAAOhD,EAASX,UAC7B6D,EAAMnC,QAAQgC,UAAUC,OAAOhD,EAASV,cAGxCoD,EAAiBG,EAAI7C,GAGrBJ,EAAU,oBAAqBiD,EAAI,CACjCM,KAAMD,EAAMP,IACZ5B,QAASmC,EAAMnC,QACff,SAAUA,IAjBM,CAmBpB,EAOIoD,EAAiB,SAAUT,EAAK3C,GAElC,GAAKA,EAAST,OAAd,CAGA,IAAIsD,EAAKF,EAAIC,WAAWE,QAAQ,MAC3BD,IAGLA,EAAGE,UAAUM,IAAIrD,EAASR,aAG1B4D,EAAeP,EAAI7C,GAVS,CAW9B,EA6LA,OA1JkB,SAAUsD,EAAUC,GAKpC,IACIC,EAAU7C,EAAU8C,EAASC,EAAS1D,EADtC2D,EAAa,CAUjBA,MAAmB,WAEjBH,EAAWhC,SAASoC,iBAAiBN,GAGrC3C,EAAW,GAGXkD,MAAMC,UAAUC,QAAQC,KAAKR,GAAU,SAAUjB,GAE/C,IAAIxB,EAAUS,SAASyC,eACrBC,mBAAmB3B,EAAK4B,KAAKC,OAAO,KAEjCrD,GAGLJ,EAAS0D,KAAK,CACZ1B,IAAKJ,EACLxB,QAASA,GAEb,IAGAL,EAAaC,EACf,EAKAgD,OAAoB,WAElB,IAAIW,EAASlC,EAAUzB,EAAUX,GAG5BsE,EASDb,GAAWa,EAAOvD,UAAY0C,EAAQ1C,UAG1CkC,EAAWQ,EAASzD,GAzFT,SAAUkD,EAAOlD,GAE9B,GAAKkD,EAAL,CAGA,IAAIL,EAAKK,EAAMP,IAAIG,QAAQ,MACtBD,IAGLA,EAAGE,UAAUM,IAAIrD,EAASX,UAC1B6D,EAAMnC,QAAQgC,UAAUM,IAAIrD,EAASV,cAGrC8D,EAAeP,EAAI7C,GAGnBJ,EAAU,kBAAmBiD,EAAI,CAC/BM,KAAMD,EAAMP,IACZ5B,QAASmC,EAAMnC,QACff,SAAUA,IAjBM,CAmBpB,CAqEIuE,CAASD,EAAQtE,GAGjByD,EAAUa,GAfJb,IACFR,EAAWQ,EAASzD,GACpByD,EAAU,KAchB,GAMIe,EAAgB,SAAUvE,GAExByD,GACFxE,EAAOuF,qBAAqBf,GAI9BA,EAAUxE,EAAOwF,sBAAsBf,EAAWgB,OACpD,EAMIC,EAAgB,SAAU3E,GAExByD,GACFxE,EAAOuF,qBAAqBf,GAI9BA,EAAUxE,EAAOwF,uBAAsB,WACrChE,EAAaC,GACbgD,EAAWgB,QACb,GACF,EAkDA,OA7CAhB,EAAWkB,QAAU,WAEfpB,GACFR,EAAWQ,EAASzD,GAItBd,EAAO4F,oBAAoB,SAAUN,GAAe,GAChDxE,EAASN,QACXR,EAAO4F,oBAAoB,SAAUF,GAAe,GAItDjE,EAAW,KACX6C,EAAW,KACXC,EAAU,KACVC,EAAU,KACV1D,EAAW,IACb,EAOEA,EA3XS,WACX,IAAI+E,EAAS,CAAC,EAOd,OANAlB,MAAMC,UAAUC,QAAQC,KAAKgB,WAAW,SAAUC,GAChD,IAAK,IAAIC,KAAOD,EAAK,CACnB,IAAKA,EAAIE,eAAeD,GAAM,OAC9BH,EAAOG,GAAOD,EAAIC,EACpB,CACF,IACOH,CACT,CAkXeK,CAAOhG,EAAUmE,GAAW,CAAC,GAGxCI,EAAW0B,QAGX1B,EAAWgB,SAGXzF,EAAOoG,iBAAiB,SAAUd,GAAe,GAC7CxE,EAASN,QACXR,EAAOoG,iBAAiB,SAAUV,GAAe,GAS9CjB,CACT,CAOF,CArcW4B,CAAQvG,EAChB,UAFM,SAEN,uBCXDwG,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaE,QAGrB,IAAIC,EAASN,EAAyBE,GAAY,CAGjDG,QAAS,CAAC,GAOX,OAHAE,EAAoBL,GAAU1B,KAAK8B,EAAOD,QAASC,EAAQA,EAAOD,QAASJ,GAGpEK,EAAOD,OACf,CCrBAJ,EAAoBO,EAAKF,IACxB,IAAIG,EAASH,GAAUA,EAAOI,WAC7B,IAAOJ,EAAiB,QACxB,IAAM,EAEP,OADAL,EAAoBU,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,CAAM,ECLdR,EAAoBU,EAAI,CAACN,EAASQ,KACjC,IAAI,IAAInB,KAAOmB,EACXZ,EAAoBa,EAAED,EAAYnB,KAASO,EAAoBa,EAAET,EAASX,IAC5EqB,OAAOC,eAAeX,EAASX,EAAK,CAAEuB,YAAY,EAAMC,IAAKL,EAAWnB,IAE1E,ECNDO,EAAoBxG,EAAI,WACvB,GAA0B,iBAAf0H,WAAyB,OAAOA,WAC3C,IACC,OAAOxH,MAAQ,IAAIyH,SAAS,cAAb,EAChB,CAAE,MAAOC,GACR,GAAsB,iBAAX3H,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCAxBuG,EAAoBa,EAAI,CAACrB,EAAK6B,IAAUP,OAAOzC,UAAUqB,eAAenB,KAAKiB,EAAK6B,4CCK9EC,EAAY,KACZC,EAAS,KACTC,EAAgB/H,OAAO6C,aAAeP,SAASC,gBAAgByF,UACnE,MAAMC,EAAmB,GA2EzB,SAASC,IACP,MAAMC,EAAeC,aAAaC,QAAQ,UAAY,OAZxD,IAAkBC,EACH,WADGA,EAaItI,OAAOuI,WAAW,gCAAgCC,QAI/C,SAAjBL,EACO,QACgB,SAAhBA,EACA,OAEA,OAIU,SAAjBA,EACO,OACgB,QAAhBA,EACA,QAEA,SA9BoB,SAATG,GAA4B,SAATA,IACzCG,QAAQC,MAAM,2BAA2BJ,yBACzCA,EAAO,QAGThG,SAASS,KAAK4F,QAAQC,MAAQN,EAC9BF,aAAaS,QAAQ,QAASP,GAC9BG,QAAQK,IAAI,cAAcR,UA0B5B,CAkDA,SAASnC,KART,WAEE,MAAM4C,EAAUzG,SAAS0G,uBAAuB,gBAChDrE,MAAMsE,KAAKF,GAASlE,SAASqE,IAC3BA,EAAI9C,iBAAiB,QAAS8B,EAAe,GAEjD,CAGEiB,GA9CF,WAEE,IAAIC,EAA6B,EAC7BC,GAAU,EAEdrJ,OAAOoG,iBAAiB,UAAU,SAAUuB,GAC1CyB,EAA6BpJ,OAAOsJ,QAE/BD,IACHrJ,OAAOwF,uBAAsB,WAzDnC,IAAuB+D,IA0DDH,EA9GkC,GAAlDzG,KAAK6G,MAAM1B,EAAO7F,wBAAwBQ,KAC5CqF,EAAOjE,UAAUM,IAAI,YAErB2D,EAAOjE,UAAUC,OAAO,YAI5B,SAAmCyF,GAC7BA,EAAYtB,EACd3F,SAASC,gBAAgBsB,UAAUC,OAAO,oBAEtCyF,EAAYxB,EACdzF,SAASC,gBAAgBsB,UAAUM,IAAI,oBAC9BoF,EAAYxB,GACrBzF,SAASC,gBAAgBsB,UAAUC,OAAO,oBAG9CiE,EAAgBwB,CAClB,CAoCEE,CAA0BF,GAlC5B,SAA6BA,GACT,OAAd1B,IAKa,GAAb0B,EACF1B,EAAU6B,SAAS,EAAG,GAGtB/G,KAAKC,KAAK2G,IACV5G,KAAK6G,MAAMlH,SAASC,gBAAgBS,aAAehD,OAAOqC,aAE1DwF,EAAU6B,SAAS,EAAG7B,EAAU7E,cAGhBV,SAASqH,cAAc,mBAc3C,CAKEC,CAAoBL,GAwDdF,GAAU,CACZ,IAEAA,GAAU,EAEd,IACArJ,OAAO6J,QACT,CA6BEC,GA1BkB,OAAdjC,GAKJ,IAAI,IAAJ,CAAY,cAAe,CACzBrH,QAAQ,EACRuJ,WAAW,EACX5J,SAAU,iBACVI,OAAQ,KACN,IAAIyJ,EAAM9H,WAAW+H,iBAAiB3H,SAASC,iBAAiB2H,UAChE,OAAOpC,EAAO7F,wBAAwBkI,OAAS,IAAMH,EAAM,CAAC,GAiBlE,CAcA1H,SAAS8D,iBAAiB,oBAT1B,WACE9D,SAASS,KAAKW,WAAWG,UAAUC,OAAO,SAE1CgE,EAASxF,SAASqH,cAAc,UAChC9B,EAAYvF,SAASqH,cAAc,eAEnCxD,GACF","sources":["webpack:///./src/furo/assets/scripts/gumshoe-patched.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/global","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///./src/furo/assets/scripts/furo.js"],"sourcesContent":["/*!\n * gumshoejs v5.1.2 (patched by @pradyunsg)\n * A simple, framework-agnostic scrollspy script.\n * (c) 2019 Chris Ferdinandi\n * MIT License\n * http://github.com/cferdinandi/gumshoe\n */\n\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], function () {\n return factory(root);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(root);\n } else {\n root.Gumshoe = factory(root);\n }\n})(\n typeof global !== \"undefined\"\n ? global\n : typeof window !== \"undefined\"\n ? window\n : this,\n function (window) {\n \"use strict\";\n\n //\n // Defaults\n //\n\n var defaults = {\n // Active classes\n navClass: \"active\",\n contentClass: \"active\",\n\n // Nested navigation\n nested: false,\n nestedClass: \"active\",\n\n // Offset & reflow\n offset: 0,\n reflow: false,\n\n // Event support\n events: true,\n };\n\n //\n // Methods\n //\n\n /**\n * Merge two or more objects together.\n * @param {Object} objects The objects to merge together\n * @returns {Object} Merged values of defaults and options\n */\n var extend = function () {\n var merged = {};\n Array.prototype.forEach.call(arguments, function (obj) {\n for (var key in obj) {\n if (!obj.hasOwnProperty(key)) return;\n merged[key] = obj[key];\n }\n });\n return merged;\n };\n\n /**\n * Emit a custom event\n * @param {String} type The event type\n * @param {Node} elem The element to attach the event to\n * @param {Object} detail Any details to pass along with the event\n */\n var emitEvent = function (type, elem, detail) {\n // Make sure events are enabled\n if (!detail.settings.events) return;\n\n // Create a new event\n var event = new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n detail: detail,\n });\n\n // Dispatch the event\n elem.dispatchEvent(event);\n };\n\n /**\n * Get an element's distance from the top of the Document.\n * @param {Node} elem The element\n * @return {Number} Distance from the top in pixels\n */\n var getOffsetTop = function (elem) {\n var location = 0;\n if (elem.offsetParent) {\n while (elem) {\n location += elem.offsetTop;\n elem = elem.offsetParent;\n }\n }\n return location >= 0 ? location : 0;\n };\n\n /**\n * Sort content from first to last in the DOM\n * @param {Array} contents The content areas\n */\n var sortContents = function (contents) {\n if (contents) {\n contents.sort(function (item1, item2) {\n var offset1 = getOffsetTop(item1.content);\n var offset2 = getOffsetTop(item2.content);\n if (offset1 < offset2) return -1;\n return 1;\n });\n }\n };\n\n /**\n * Get the offset to use for calculating position\n * @param {Object} settings The settings for this instantiation\n * @return {Float} The number of pixels to offset the calculations\n */\n var getOffset = function (settings) {\n // if the offset is a function run it\n if (typeof settings.offset === \"function\") {\n return parseFloat(settings.offset());\n }\n\n // Otherwise, return it as-is\n return parseFloat(settings.offset);\n };\n\n /**\n * Get the document element's height\n * @private\n * @returns {Number}\n */\n var getDocumentHeight = function () {\n return Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.offsetHeight,\n document.body.clientHeight,\n document.documentElement.clientHeight,\n );\n };\n\n /**\n * Determine if an element is in view\n * @param {Node} elem The element\n * @param {Object} settings The settings for this instantiation\n * @param {Boolean} bottom If true, check if element is above bottom of viewport instead\n * @return {Boolean} Returns true if element is in the viewport\n */\n var isInView = function (elem, settings, bottom) {\n var bounds = elem.getBoundingClientRect();\n var offset = getOffset(settings);\n if (bottom) {\n return (\n parseInt(bounds.bottom, 10) <\n (window.innerHeight || document.documentElement.clientHeight)\n );\n }\n return parseInt(bounds.top, 10) <= offset;\n };\n\n /**\n * Check if at the bottom of the viewport\n * @return {Boolean} If true, page is at the bottom of the viewport\n */\n var isAtBottom = function () {\n if (\n Math.ceil(window.innerHeight + window.pageYOffset) >=\n getDocumentHeight()\n )\n return true;\n return false;\n };\n\n /**\n * Check if the last item should be used (even if not at the top of the page)\n * @param {Object} item The last item\n * @param {Object} settings The settings for this instantiation\n * @return {Boolean} If true, use the last item\n */\n var useLastItem = function (item, settings) {\n if (isAtBottom() && isInView(item.content, settings, true)) return true;\n return false;\n };\n\n /**\n * Get the active content\n * @param {Array} contents The content areas\n * @param {Object} settings The settings for this instantiation\n * @return {Object} The content area and matching navigation link\n */\n var getActive = function (contents, settings) {\n var last = contents[contents.length - 1];\n if (useLastItem(last, settings)) return last;\n for (var i = contents.length - 1; i >= 0; i--) {\n if (isInView(contents[i].content, settings)) return contents[i];\n }\n };\n\n /**\n * Deactivate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var deactivateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested || !nav.parentNode) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Remove the active class\n li.classList.remove(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n deactivateNested(li, settings);\n };\n\n /**\n * Deactivate a nav and content area\n * @param {Object} items The nav item and content to deactivate\n * @param {Object} settings The settings for this instantiation\n */\n var deactivate = function (items, settings) {\n // Make sure there are items to deactivate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Remove the active class from the nav and content\n li.classList.remove(settings.navClass);\n items.content.classList.remove(settings.contentClass);\n\n // Deactivate any parent navs in a nested navigation\n deactivateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeDeactivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Activate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var activateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Add the active class\n li.classList.add(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n activateNested(li, settings);\n };\n\n /**\n * Activate a nav and content area\n * @param {Object} items The nav item and content to activate\n * @param {Object} settings The settings for this instantiation\n */\n var activate = function (items, settings) {\n // Make sure there are items to activate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Add the active class to the nav and content\n li.classList.add(settings.navClass);\n items.content.classList.add(settings.contentClass);\n\n // Activate any parent navs in a nested navigation\n activateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeActivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Create the Constructor object\n * @param {String} selector The selector to use for navigation items\n * @param {Object} options User options and settings\n */\n var Constructor = function (selector, options) {\n //\n // Variables\n //\n\n var publicAPIs = {};\n var navItems, contents, current, timeout, settings;\n\n //\n // Methods\n //\n\n /**\n * Set variables from DOM elements\n */\n publicAPIs.setup = function () {\n // Get all nav items\n navItems = document.querySelectorAll(selector);\n\n // Create contents array\n contents = [];\n\n // Loop through each item, get it's matching content, and push to the array\n Array.prototype.forEach.call(navItems, function (item) {\n // Get the content for the nav item\n var content = document.getElementById(\n decodeURIComponent(item.hash.substr(1)),\n );\n if (!content) return;\n\n // Push to the contents array\n contents.push({\n nav: item,\n content: content,\n });\n });\n\n // Sort contents by the order they appear in the DOM\n sortContents(contents);\n };\n\n /**\n * Detect which content is currently active\n */\n publicAPIs.detect = function () {\n // Get the active content\n var active = getActive(contents, settings);\n\n // if there's no active content, deactivate and bail\n if (!active) {\n if (current) {\n deactivate(current, settings);\n current = null;\n }\n return;\n }\n\n // If the active content is the one currently active, do nothing\n if (current && active.content === current.content) return;\n\n // Deactivate the current content and activate the new content\n deactivate(current, settings);\n activate(active, settings);\n\n // Update the currently active content\n current = active;\n };\n\n /**\n * Detect the active content on scroll\n * Debounced for performance\n */\n var scrollHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(publicAPIs.detect);\n };\n\n /**\n * Update content sorting on resize\n * Debounced for performance\n */\n var resizeHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(function () {\n sortContents(contents);\n publicAPIs.detect();\n });\n };\n\n /**\n * Destroy the current instantiation\n */\n publicAPIs.destroy = function () {\n // Undo DOM changes\n if (current) {\n deactivate(current, settings);\n }\n\n // Remove event listeners\n window.removeEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.removeEventListener(\"resize\", resizeHandler, false);\n }\n\n // Reset variables\n contents = null;\n navItems = null;\n current = null;\n timeout = null;\n settings = null;\n };\n\n /**\n * Initialize the current instantiation\n */\n var init = function () {\n // Merge user options into defaults\n settings = extend(defaults, options || {});\n\n // Setup variables based on the current DOM\n publicAPIs.setup();\n\n // Find the currently active content\n publicAPIs.detect();\n\n // Setup event listeners\n window.addEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.addEventListener(\"resize\", resizeHandler, false);\n }\n };\n\n //\n // Initialize and return the public APIs\n //\n\n init();\n return publicAPIs;\n };\n\n //\n // Return the Constructor\n //\n\n return Constructor;\n },\n);\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import Gumshoe from \"./gumshoe-patched.js\";\n\n////////////////////////////////////////////////////////////////////////////////\n// Scroll Handling\n////////////////////////////////////////////////////////////////////////////////\nvar tocScroll = null;\nvar header = null;\nvar lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;\nconst GO_TO_TOP_OFFSET = 64;\n\nfunction scrollHandlerForHeader() {\n if (Math.floor(header.getBoundingClientRect().top) == 0) {\n header.classList.add(\"scrolled\");\n } else {\n header.classList.remove(\"scrolled\");\n }\n}\n\nfunction scrollHandlerForBackToTop(positionY) {\n if (positionY < GO_TO_TOP_OFFSET) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n } else {\n if (positionY < lastScrollTop) {\n document.documentElement.classList.add(\"show-back-to-top\");\n } else if (positionY > lastScrollTop) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n }\n }\n lastScrollTop = positionY;\n}\n\nfunction scrollHandlerForTOC(positionY) {\n if (tocScroll === null) {\n return;\n }\n\n // top of page.\n if (positionY == 0) {\n tocScroll.scrollTo(0, 0);\n } else if (\n // bottom of page.\n Math.ceil(positionY) >=\n Math.floor(document.documentElement.scrollHeight - window.innerHeight)\n ) {\n tocScroll.scrollTo(0, tocScroll.scrollHeight);\n } else {\n // somewhere in the middle.\n const current = document.querySelector(\".scroll-current\");\n if (current == null) {\n return;\n }\n\n // https://github.com/pypa/pip/issues/9159 This breaks scroll behaviours.\n // // scroll the currently \"active\" heading in toc, into view.\n // const rect = current.getBoundingClientRect();\n // if (0 > rect.top) {\n // current.scrollIntoView(true); // the argument is \"alignTop\"\n // } else if (rect.bottom > window.innerHeight) {\n // current.scrollIntoView(false);\n // }\n }\n}\n\nfunction scrollHandler(positionY) {\n scrollHandlerForHeader();\n scrollHandlerForBackToTop(positionY);\n scrollHandlerForTOC(positionY);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Theme Toggle\n////////////////////////////////////////////////////////////////////////////////\nfunction setTheme(mode) {\n if (mode !== \"light\" && mode !== \"dark\" && mode !== \"auto\") {\n console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`);\n mode = \"auto\";\n }\n\n document.body.dataset.theme = mode;\n localStorage.setItem(\"theme\", mode);\n console.log(`Changed to ${mode} mode.`);\n}\n\nfunction cycleThemeOnce() {\n const currentTheme = localStorage.getItem(\"theme\") || \"auto\";\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n\n if (prefersDark) {\n // Auto (dark) -> Light -> Dark\n if (currentTheme === \"auto\") {\n setTheme(\"light\");\n } else if (currentTheme == \"light\") {\n setTheme(\"dark\");\n } else {\n setTheme(\"auto\");\n }\n } else {\n // Auto (light) -> Dark -> Light\n if (currentTheme === \"auto\") {\n setTheme(\"dark\");\n } else if (currentTheme == \"dark\") {\n setTheme(\"light\");\n } else {\n setTheme(\"auto\");\n }\n }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Setup\n////////////////////////////////////////////////////////////////////////////////\nfunction setupScrollHandler() {\n // Taken from https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event\n let last_known_scroll_position = 0;\n let ticking = false;\n\n window.addEventListener(\"scroll\", function (e) {\n last_known_scroll_position = window.scrollY;\n\n if (!ticking) {\n window.requestAnimationFrame(function () {\n scrollHandler(last_known_scroll_position);\n ticking = false;\n });\n\n ticking = true;\n }\n });\n window.scroll();\n}\n\nfunction setupScrollSpy() {\n if (tocScroll === null) {\n return;\n }\n\n // Scrollspy -- highlight table on contents, based on scroll\n new Gumshoe(\".toc-tree a\", {\n reflow: true,\n recursive: true,\n navClass: \"scroll-current\",\n offset: () => {\n let rem = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return header.getBoundingClientRect().height + 2.5 * rem + 1;\n },\n });\n}\n\nfunction setupTheme() {\n // Attach event handlers for toggling themes\n const buttons = document.getElementsByClassName(\"theme-toggle\");\n Array.from(buttons).forEach((btn) => {\n btn.addEventListener(\"click\", cycleThemeOnce);\n });\n}\n\nfunction setup() {\n setupTheme();\n setupScrollHandler();\n setupScrollSpy();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Main entrypoint\n////////////////////////////////////////////////////////////////////////////////\nfunction main() {\n document.body.parentNode.classList.remove(\"no-js\");\n\n header = document.querySelector(\"header\");\n tocScroll = document.querySelector(\".toc-scroll\");\n\n setup();\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", main);\n"],"names":["root","g","window","this","defaults","navClass","contentClass","nested","nestedClass","offset","reflow","events","emitEvent","type","elem","detail","settings","event","CustomEvent","bubbles","cancelable","dispatchEvent","getOffsetTop","location","offsetParent","offsetTop","sortContents","contents","sort","item1","item2","content","isInView","bottom","bounds","getBoundingClientRect","parseFloat","getOffset","parseInt","innerHeight","document","documentElement","clientHeight","top","isAtBottom","Math","ceil","pageYOffset","max","body","scrollHeight","offsetHeight","getActive","last","length","item","useLastItem","i","deactivateNested","nav","parentNode","li","closest","classList","remove","deactivate","items","link","activateNested","add","selector","options","navItems","current","timeout","publicAPIs","querySelectorAll","Array","prototype","forEach","call","getElementById","decodeURIComponent","hash","substr","push","active","activate","scrollHandler","cancelAnimationFrame","requestAnimationFrame","detect","resizeHandler","destroy","removeEventListener","merged","arguments","obj","key","hasOwnProperty","extend","setup","addEventListener","factory","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","n","getter","__esModule","d","a","definition","o","Object","defineProperty","enumerable","get","globalThis","Function","e","prop","tocScroll","header","lastScrollTop","scrollTop","GO_TO_TOP_OFFSET","cycleThemeOnce","currentTheme","localStorage","getItem","mode","matchMedia","matches","console","error","dataset","theme","setItem","log","buttons","getElementsByClassName","from","btn","setupTheme","last_known_scroll_position","ticking","scrollY","positionY","floor","scrollHandlerForBackToTop","scrollTo","querySelector","scrollHandlerForTOC","scroll","setupScrollHandler","recursive","rem","getComputedStyle","fontSize","height"],"sourceRoot":""}
\ No newline at end of file
diff --git a/_static/searchtools.js b/_static/searchtools.js
new file mode 100644
index 0000000000..97d56a74d8
--- /dev/null
+++ b/_static/searchtools.js
@@ -0,0 +1,566 @@
+/*
+ * searchtools.js
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for the full-text search.
+ *
+ * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+"use strict";
+
+/**
+ * Simple result scoring code.
+ */
+if (typeof Scorer === "undefined") {
+ var Scorer = {
+ // Implement the following function to further tweak the score for each result
+ // The function takes a result array [docname, title, anchor, descr, score, filename]
+ // and returns the new score.
+ /*
+ score: result => {
+ const [docname, title, anchor, descr, score, filename] = result
+ return score
+ },
+ */
+
+ // query matches the full name of an object
+ objNameMatch: 11,
+ // or matches in the last dotted part of the object name
+ objPartialMatch: 6,
+ // Additive scores depending on the priority of the object
+ objPrio: {
+ 0: 15, // used to be importantResults
+ 1: 5, // used to be objectResults
+ 2: -5, // used to be unimportantResults
+ },
+ // Used when the priority is not in the mapping.
+ objPrioDefault: 0,
+
+ // query found in title
+ title: 15,
+ partialTitle: 7,
+ // query found in terms
+ term: 5,
+ partialTerm: 2,
+ };
+}
+
+const _removeChildren = (element) => {
+ while (element && element.lastChild) element.removeChild(element.lastChild);
+};
+
+/**
+ * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
+ */
+const _escapeRegExp = (string) =>
+ string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+
+const _displayItem = (item, searchTerms) => {
+ const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
+ const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
+ const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
+ const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
+ const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
+
+ const [docName, title, anchor, descr, score, _filename] = item;
+
+ let listItem = document.createElement("li");
+ let requestUrl;
+ let linkUrl;
+ if (docBuilder === "dirhtml") {
+ // dirhtml builder
+ let dirname = docName + "/";
+ if (dirname.match(/\/index\/$/))
+ dirname = dirname.substring(0, dirname.length - 6);
+ else if (dirname === "index/") dirname = "";
+ requestUrl = docUrlRoot + dirname;
+ linkUrl = requestUrl;
+ } else {
+ // normal html builders
+ requestUrl = docUrlRoot + docName + docFileSuffix;
+ linkUrl = docName + docLinkSuffix;
+ }
+ let linkEl = listItem.appendChild(document.createElement("a"));
+ linkEl.href = linkUrl + anchor;
+ linkEl.dataset.score = score;
+ linkEl.innerHTML = title;
+ if (descr)
+ listItem.appendChild(document.createElement("span")).innerHTML =
+ " (" + descr + ")";
+ else if (showSearchSummary)
+ fetch(requestUrl)
+ .then((responseData) => responseData.text())
+ .then((data) => {
+ if (data)
+ listItem.appendChild(
+ Search.makeSearchSummary(data, searchTerms)
+ );
+ });
+ Search.output.appendChild(listItem);
+};
+const _finishSearch = (resultCount) => {
+ Search.stopPulse();
+ Search.title.innerText = _("Search Results");
+ if (!resultCount)
+ Search.status.innerText = Documentation.gettext(
+ "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
+ );
+ else
+ Search.status.innerText = _(
+ `Search finished, found ${resultCount} page(s) matching the search query.`
+ );
+};
+const _displayNextItem = (
+ results,
+ resultCount,
+ searchTerms
+) => {
+ // results left, load the summary and display it
+ // this is intended to be dynamic (don't sub resultsCount)
+ if (results.length) {
+ _displayItem(results.pop(), searchTerms);
+ setTimeout(
+ () => _displayNextItem(results, resultCount, searchTerms),
+ 5
+ );
+ }
+ // search finished, update title and status message
+ else _finishSearch(resultCount);
+};
+
+/**
+ * Default splitQuery function. Can be overridden in ``sphinx.search`` with a
+ * custom function per language.
+ *
+ * The regular expression works by splitting the string on consecutive characters
+ * that are not Unicode letters, numbers, underscores, or emoji characters.
+ * This is the same as ``\W+`` in Python, preserving the surrogate pair area.
+ */
+if (typeof splitQuery === "undefined") {
+ var splitQuery = (query) => query
+ .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
+ .filter(term => term) // remove remaining empty strings
+}
+
+/**
+ * Search Module
+ */
+const Search = {
+ _index: null,
+ _queued_query: null,
+ _pulse_status: -1,
+
+ htmlToText: (htmlString) => {
+ const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
+ htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
+ const docContent = htmlElement.querySelector('[role="main"]');
+ if (docContent !== undefined) return docContent.textContent;
+ console.warn(
+ "Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
+ );
+ return "";
+ },
+
+ init: () => {
+ const query = new URLSearchParams(window.location.search).get("q");
+ document
+ .querySelectorAll('input[name="q"]')
+ .forEach((el) => (el.value = query));
+ if (query) Search.performSearch(query);
+ },
+
+ loadIndex: (url) =>
+ (document.body.appendChild(document.createElement("script")).src = url),
+
+ setIndex: (index) => {
+ Search._index = index;
+ if (Search._queued_query !== null) {
+ const query = Search._queued_query;
+ Search._queued_query = null;
+ Search.query(query);
+ }
+ },
+
+ hasIndex: () => Search._index !== null,
+
+ deferQuery: (query) => (Search._queued_query = query),
+
+ stopPulse: () => (Search._pulse_status = -1),
+
+ startPulse: () => {
+ if (Search._pulse_status >= 0) return;
+
+ const pulse = () => {
+ Search._pulse_status = (Search._pulse_status + 1) % 4;
+ Search.dots.innerText = ".".repeat(Search._pulse_status);
+ if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
+ };
+ pulse();
+ },
+
+ /**
+ * perform a search for something (or wait until index is loaded)
+ */
+ performSearch: (query) => {
+ // create the required interface elements
+ const searchText = document.createElement("h2");
+ searchText.textContent = _("Searching");
+ const searchSummary = document.createElement("p");
+ searchSummary.classList.add("search-summary");
+ searchSummary.innerText = "";
+ const searchList = document.createElement("ul");
+ searchList.classList.add("search");
+
+ const out = document.getElementById("search-results");
+ Search.title = out.appendChild(searchText);
+ Search.dots = Search.title.appendChild(document.createElement("span"));
+ Search.status = out.appendChild(searchSummary);
+ Search.output = out.appendChild(searchList);
+
+ const searchProgress = document.getElementById("search-progress");
+ // Some themes don't use the search progress node
+ if (searchProgress) {
+ searchProgress.innerText = _("Preparing search...");
+ }
+ Search.startPulse();
+
+ // index already loaded, the browser was quick!
+ if (Search.hasIndex()) Search.query(query);
+ else Search.deferQuery(query);
+ },
+
+ /**
+ * execute search (requires search index to be loaded)
+ */
+ query: (query) => {
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const titles = Search._index.titles;
+ const allTitles = Search._index.alltitles;
+ const indexEntries = Search._index.indexentries;
+
+ // stem the search terms and add them to the correct list
+ const stemmer = new Stemmer();
+ const searchTerms = new Set();
+ const excludedTerms = new Set();
+ const highlightTerms = new Set();
+ const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
+ splitQuery(query.trim()).forEach((queryTerm) => {
+ const queryTermLower = queryTerm.toLowerCase();
+
+ // maybe skip this "word"
+ // stopwords array is from language_data.js
+ if (
+ stopwords.indexOf(queryTermLower) !== -1 ||
+ queryTerm.match(/^\d+$/)
+ )
+ return;
+
+ // stem the word
+ let word = stemmer.stemWord(queryTermLower);
+ // select the correct list
+ if (word[0] === "-") excludedTerms.add(word.substr(1));
+ else {
+ searchTerms.add(word);
+ highlightTerms.add(queryTermLower);
+ }
+ });
+
+ if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js
+ localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" "))
+ }
+
+ // console.debug("SEARCH: searching for:");
+ // console.info("required: ", [...searchTerms]);
+ // console.info("excluded: ", [...excludedTerms]);
+
+ // array of [docname, title, anchor, descr, score, filename]
+ let results = [];
+ _removeChildren(document.getElementById("search-progress"));
+
+ const queryLower = query.toLowerCase();
+ for (const [title, foundTitles] of Object.entries(allTitles)) {
+ if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {
+ for (const [file, id] of foundTitles) {
+ let score = Math.round(100 * queryLower.length / title.length)
+ results.push([
+ docNames[file],
+ titles[file] !== title ? `${titles[file]} > ${title}` : title,
+ id !== null ? "#" + id : "",
+ null,
+ score,
+ filenames[file],
+ ]);
+ }
+ }
+ }
+
+ // search for explicit entries in index directives
+ for (const [entry, foundEntries] of Object.entries(indexEntries)) {
+ if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) {
+ for (const [file, id] of foundEntries) {
+ let score = Math.round(100 * queryLower.length / entry.length)
+ results.push([
+ docNames[file],
+ titles[file],
+ id ? "#" + id : "",
+ null,
+ score,
+ filenames[file],
+ ]);
+ }
+ }
+ }
+
+ // lookup as object
+ objectTerms.forEach((term) =>
+ results.push(...Search.performObjectSearch(term, objectTerms))
+ );
+
+ // lookup as search terms in fulltext
+ results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
+
+ // let the scorer override scores with a custom scoring function
+ if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
+
+ // now sort the results by score (in opposite order of appearance, since the
+ // display function below uses pop() to retrieve items) and then
+ // alphabetically
+ results.sort((a, b) => {
+ const leftScore = a[4];
+ const rightScore = b[4];
+ if (leftScore === rightScore) {
+ // same score: sort alphabetically
+ const leftTitle = a[1].toLowerCase();
+ const rightTitle = b[1].toLowerCase();
+ if (leftTitle === rightTitle) return 0;
+ return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
+ }
+ return leftScore > rightScore ? 1 : -1;
+ });
+
+ // remove duplicate search results
+ // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
+ let seen = new Set();
+ results = results.reverse().reduce((acc, result) => {
+ let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
+ if (!seen.has(resultStr)) {
+ acc.push(result);
+ seen.add(resultStr);
+ }
+ return acc;
+ }, []);
+
+ results = results.reverse();
+
+ // for debugging
+ //Search.lastresults = results.slice(); // a copy
+ // console.info("search results:", Search.lastresults);
+
+ // print the results
+ _displayNextItem(results, results.length, searchTerms);
+ },
+
+ /**
+ * search for object names
+ */
+ performObjectSearch: (object, objectTerms) => {
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const objects = Search._index.objects;
+ const objNames = Search._index.objnames;
+ const titles = Search._index.titles;
+
+ const results = [];
+
+ const objectSearchCallback = (prefix, match) => {
+ const name = match[4]
+ const fullname = (prefix ? prefix + "." : "") + name;
+ const fullnameLower = fullname.toLowerCase();
+ if (fullnameLower.indexOf(object) < 0) return;
+
+ let score = 0;
+ const parts = fullnameLower.split(".");
+
+ // check for different match types: exact matches of full name or
+ // "last name" (i.e. last dotted part)
+ if (fullnameLower === object || parts.slice(-1)[0] === object)
+ score += Scorer.objNameMatch;
+ else if (parts.slice(-1)[0].indexOf(object) > -1)
+ score += Scorer.objPartialMatch; // matches in last name
+
+ const objName = objNames[match[1]][2];
+ const title = titles[match[0]];
+
+ // If more than one term searched for, we require other words to be
+ // found in the name/title/description
+ const otherTerms = new Set(objectTerms);
+ otherTerms.delete(object);
+ if (otherTerms.size > 0) {
+ const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
+ if (
+ [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
+ )
+ return;
+ }
+
+ let anchor = match[3];
+ if (anchor === "") anchor = fullname;
+ else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
+
+ const descr = objName + _(", in ") + title;
+
+ // add custom score for some objects according to scorer
+ if (Scorer.objPrio.hasOwnProperty(match[2]))
+ score += Scorer.objPrio[match[2]];
+ else score += Scorer.objPrioDefault;
+
+ results.push([
+ docNames[match[0]],
+ fullname,
+ "#" + anchor,
+ descr,
+ score,
+ filenames[match[0]],
+ ]);
+ };
+ Object.keys(objects).forEach((prefix) =>
+ objects[prefix].forEach((array) =>
+ objectSearchCallback(prefix, array)
+ )
+ );
+ return results;
+ },
+
+ /**
+ * search for full-text terms in the index
+ */
+ performTermsSearch: (searchTerms, excludedTerms) => {
+ // prepare search
+ const terms = Search._index.terms;
+ const titleTerms = Search._index.titleterms;
+ const filenames = Search._index.filenames;
+ const docNames = Search._index.docnames;
+ const titles = Search._index.titles;
+
+ const scoreMap = new Map();
+ const fileMap = new Map();
+
+ // perform the search on the required terms
+ searchTerms.forEach((word) => {
+ const files = [];
+ const arr = [
+ { files: terms[word], score: Scorer.term },
+ { files: titleTerms[word], score: Scorer.title },
+ ];
+ // add support for partial matches
+ if (word.length > 2) {
+ const escapedWord = _escapeRegExp(word);
+ Object.keys(terms).forEach((term) => {
+ if (term.match(escapedWord) && !terms[word])
+ arr.push({ files: terms[term], score: Scorer.partialTerm });
+ });
+ Object.keys(titleTerms).forEach((term) => {
+ if (term.match(escapedWord) && !titleTerms[word])
+ arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
+ });
+ }
+
+ // no match but word was a required one
+ if (arr.every((record) => record.files === undefined)) return;
+
+ // found search word in contents
+ arr.forEach((record) => {
+ if (record.files === undefined) return;
+
+ let recordFiles = record.files;
+ if (recordFiles.length === undefined) recordFiles = [recordFiles];
+ files.push(...recordFiles);
+
+ // set score for the word in each file
+ recordFiles.forEach((file) => {
+ if (!scoreMap.has(file)) scoreMap.set(file, {});
+ scoreMap.get(file)[word] = record.score;
+ });
+ });
+
+ // create the mapping
+ files.forEach((file) => {
+ if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
+ fileMap.get(file).push(word);
+ else fileMap.set(file, [word]);
+ });
+ });
+
+ // now check if the files don't contain excluded terms
+ const results = [];
+ for (const [file, wordList] of fileMap) {
+ // check if all requirements are matched
+
+ // as search terms with length < 3 are discarded
+ const filteredTermCount = [...searchTerms].filter(
+ (term) => term.length > 2
+ ).length;
+ if (
+ wordList.length !== searchTerms.size &&
+ wordList.length !== filteredTermCount
+ )
+ continue;
+
+ // ensure that none of the excluded terms is in the search result
+ if (
+ [...excludedTerms].some(
+ (term) =>
+ terms[term] === file ||
+ titleTerms[term] === file ||
+ (terms[term] || []).includes(file) ||
+ (titleTerms[term] || []).includes(file)
+ )
+ )
+ break;
+
+ // select one (max) score for the file.
+ const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
+ // add result to the result list
+ results.push([
+ docNames[file],
+ titles[file],
+ "",
+ null,
+ score,
+ filenames[file],
+ ]);
+ }
+ return results;
+ },
+
+ /**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words.
+ */
+ makeSearchSummary: (htmlText, keywords) => {
+ const text = Search.htmlToText(htmlText);
+ if (text === "") return null;
+
+ const textLower = text.toLowerCase();
+ const actualStartPosition = [...keywords]
+ .map((k) => textLower.indexOf(k.toLowerCase()))
+ .filter((i) => i > -1)
+ .slice(-1)[0];
+ const startWithContext = Math.max(actualStartPosition - 120, 0);
+
+ const top = startWithContext === 0 ? "" : "...";
+ const tail = startWithContext + 240 < text.length ? "..." : "";
+
+ let summary = document.createElement("p");
+ summary.classList.add("context");
+ summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
+
+ return summary;
+ },
+};
+
+_ready(Search.init);
diff --git a/_static/skeleton.css b/_static/skeleton.css
new file mode 100644
index 0000000000..467c878c62
--- /dev/null
+++ b/_static/skeleton.css
@@ -0,0 +1,296 @@
+/* Some sane resets. */
+html {
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ min-height: 100%;
+}
+
+/* All the flexbox magic! */
+body,
+.sb-announcement,
+.sb-content,
+.sb-main,
+.sb-container,
+.sb-container__inner,
+.sb-article-container,
+.sb-footer-content,
+.sb-header,
+.sb-header-secondary,
+.sb-footer {
+ display: flex;
+}
+
+/* These order things vertically */
+body,
+.sb-main,
+.sb-article-container {
+ flex-direction: column;
+}
+
+/* Put elements in the center */
+.sb-header,
+.sb-header-secondary,
+.sb-container,
+.sb-content,
+.sb-footer,
+.sb-footer-content {
+ justify-content: center;
+}
+/* Put elements at the ends */
+.sb-article-container {
+ justify-content: space-between;
+}
+
+/* These elements grow. */
+.sb-main,
+.sb-content,
+.sb-container,
+article {
+ flex-grow: 1;
+}
+
+/* Because padding making this wider is not fun */
+article {
+ box-sizing: border-box;
+}
+
+/* The announcements element should never be wider than the page. */
+.sb-announcement {
+ max-width: 100%;
+}
+
+.sb-sidebar-primary,
+.sb-sidebar-secondary {
+ flex-shrink: 0;
+ width: 17rem;
+}
+
+.sb-announcement__inner {
+ justify-content: center;
+
+ box-sizing: border-box;
+ height: 3rem;
+
+ overflow-x: auto;
+ white-space: nowrap;
+}
+
+/* Sidebars, with checkbox-based toggle */
+.sb-sidebar-primary,
+.sb-sidebar-secondary {
+ position: fixed;
+ height: 100%;
+ top: 0;
+}
+
+.sb-sidebar-primary {
+ left: -17rem;
+ transition: left 250ms ease-in-out;
+}
+.sb-sidebar-secondary {
+ right: -17rem;
+ transition: right 250ms ease-in-out;
+}
+
+.sb-sidebar-toggle {
+ display: none;
+}
+.sb-sidebar-overlay {
+ position: fixed;
+ top: 0;
+ width: 0;
+ height: 0;
+
+ transition: width 0ms ease 250ms, height 0ms ease 250ms, opacity 250ms ease;
+
+ opacity: 0;
+ background-color: rgba(0, 0, 0, 0.54);
+}
+
+#sb-sidebar-toggle--primary:checked
+ ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--primary"],
+#sb-sidebar-toggle--secondary:checked
+ ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--secondary"] {
+ width: 100%;
+ height: 100%;
+ opacity: 1;
+ transition: width 0ms ease, height 0ms ease, opacity 250ms ease;
+}
+
+#sb-sidebar-toggle--primary:checked ~ .sb-container .sb-sidebar-primary {
+ left: 0;
+}
+#sb-sidebar-toggle--secondary:checked ~ .sb-container .sb-sidebar-secondary {
+ right: 0;
+}
+
+/* Full-width mode */
+.drop-secondary-sidebar-for-full-width-content
+ .hide-when-secondary-sidebar-shown {
+ display: none !important;
+}
+.drop-secondary-sidebar-for-full-width-content .sb-sidebar-secondary {
+ display: none !important;
+}
+
+/* Mobile views */
+.sb-page-width {
+ width: 100%;
+}
+
+.sb-article-container,
+.sb-footer-content__inner,
+.drop-secondary-sidebar-for-full-width-content .sb-article,
+.drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 100vw;
+}
+
+.sb-article,
+.match-content-width {
+ padding: 0 1rem;
+ box-sizing: border-box;
+}
+
+@media (min-width: 32rem) {
+ .sb-article,
+ .match-content-width {
+ padding: 0 2rem;
+ }
+}
+
+/* Tablet views */
+@media (min-width: 42rem) {
+ .sb-article-container {
+ width: auto;
+ }
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 42rem;
+ }
+ .sb-article,
+ .match-content-width {
+ width: 42rem;
+ }
+}
+@media (min-width: 46rem) {
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 46rem;
+ }
+ .sb-article,
+ .match-content-width {
+ width: 46rem;
+ }
+}
+@media (min-width: 50rem) {
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 50rem;
+ }
+ .sb-article,
+ .match-content-width {
+ width: 50rem;
+ }
+}
+
+/* Tablet views */
+@media (min-width: 59rem) {
+ .sb-sidebar-secondary {
+ position: static;
+ }
+ .hide-when-secondary-sidebar-shown {
+ display: none !important;
+ }
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 59rem;
+ }
+ .sb-article,
+ .match-content-width {
+ width: 42rem;
+ }
+}
+@media (min-width: 63rem) {
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 63rem;
+ }
+ .sb-article,
+ .match-content-width {
+ width: 46rem;
+ }
+}
+@media (min-width: 67rem) {
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 67rem;
+ }
+ .sb-article,
+ .match-content-width {
+ width: 50rem;
+ }
+}
+
+/* Desktop views */
+@media (min-width: 76rem) {
+ .sb-sidebar-primary {
+ position: static;
+ }
+ .hide-when-primary-sidebar-shown {
+ display: none !important;
+ }
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 59rem;
+ }
+ .sb-article,
+ .match-content-width {
+ width: 42rem;
+ }
+}
+
+/* Full desktop views */
+@media (min-width: 80rem) {
+ .sb-article,
+ .match-content-width {
+ width: 46rem;
+ }
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 63rem;
+ }
+}
+
+@media (min-width: 84rem) {
+ .sb-article,
+ .match-content-width {
+ width: 50rem;
+ }
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 67rem;
+ }
+}
+
+@media (min-width: 88rem) {
+ .sb-footer-content__inner,
+ .drop-secondary-sidebar-for-full-width-content .sb-article,
+ .drop-secondary-sidebar-for-full-width-content .match-content-width {
+ width: 67rem;
+ }
+ .sb-page-width {
+ width: 88rem;
+ }
+}
diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js
new file mode 100644
index 0000000000..aae669d7ea
--- /dev/null
+++ b/_static/sphinx_highlight.js
@@ -0,0 +1,144 @@
+/* Highlighting utilities for Sphinx HTML documentation. */
+"use strict";
+
+const SPHINX_HIGHLIGHT_ENABLED = true
+
+/**
+ * highlight a given string on a node by wrapping it in
+ * span elements with the given class name.
+ */
+const _highlight = (node, addItems, text, className) => {
+ if (node.nodeType === Node.TEXT_NODE) {
+ const val = node.nodeValue;
+ const parent = node.parentNode;
+ const pos = val.toLowerCase().indexOf(text);
+ if (
+ pos >= 0 &&
+ !parent.classList.contains(className) &&
+ !parent.classList.contains("nohighlight")
+ ) {
+ let span;
+
+ const closestNode = parent.closest("body, svg, foreignObject");
+ const isInSVG = closestNode && closestNode.matches("svg");
+ if (isInSVG) {
+ span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
+ } else {
+ span = document.createElement("span");
+ span.classList.add(className);
+ }
+
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ parent.insertBefore(
+ span,
+ parent.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling
+ )
+ );
+ node.nodeValue = val.substr(0, pos);
+
+ if (isInSVG) {
+ const rect = document.createElementNS(
+ "http://www.w3.org/2000/svg",
+ "rect"
+ );
+ const bbox = parent.getBBox();
+ rect.x.baseVal.value = bbox.x;
+ rect.y.baseVal.value = bbox.y;
+ rect.width.baseVal.value = bbox.width;
+ rect.height.baseVal.value = bbox.height;
+ rect.setAttribute("class", className);
+ addItems.push({ parent: parent, target: rect });
+ }
+ }
+ } else if (node.matches && !node.matches("button, select, textarea")) {
+ node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
+ }
+};
+const _highlightText = (thisNode, text, className) => {
+ let addItems = [];
+ _highlight(thisNode, addItems, text, className);
+ addItems.forEach((obj) =>
+ obj.parent.insertAdjacentElement("beforebegin", obj.target)
+ );
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+const SphinxHighlight = {
+
+ /**
+ * highlight the search words provided in localstorage in the text
+ */
+ highlightSearchWords: () => {
+ if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight
+
+ // get and clear terms from localstorage
+ const url = new URL(window.location);
+ const highlight =
+ localStorage.getItem("sphinx_highlight_terms")
+ || url.searchParams.get("highlight")
+ || "";
+ localStorage.removeItem("sphinx_highlight_terms")
+ url.searchParams.delete("highlight");
+ window.history.replaceState({}, "", url);
+
+ // get individual terms from highlight string
+ const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
+ if (terms.length === 0) return; // nothing to do
+
+ // There should never be more than one element matching "div.body"
+ const divBody = document.querySelectorAll("div.body");
+ const body = divBody.length ? divBody[0] : document.querySelector("body");
+ window.setTimeout(() => {
+ terms.forEach((term) => _highlightText(body, term, "highlighted"));
+ }, 10);
+
+ const searchBox = document.getElementById("searchbox");
+ if (searchBox === null) return;
+ searchBox.appendChild(
+ document
+ .createRange()
+ .createContextualFragment(
+ ' ' +
+ '' +
+ _("Hide Search Matches") +
+ "
"
+ )
+ );
+ },
+
+ /**
+ * helper function to hide the search marks again
+ */
+ hideSearchWords: () => {
+ document
+ .querySelectorAll("#searchbox .highlight-link")
+ .forEach((el) => el.remove());
+ document
+ .querySelectorAll("span.highlighted")
+ .forEach((el) => el.classList.remove("highlighted"));
+ localStorage.removeItem("sphinx_highlight_terms")
+ },
+
+ initEscapeListener: () => {
+ // only install a listener if it is really needed
+ if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return;
+
+ document.addEventListener("keydown", (event) => {
+ // bail for input elements
+ if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return;
+ // bail with special keys
+ if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
+ if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) {
+ SphinxHighlight.hideSearchWords();
+ event.preventDefault();
+ }
+ });
+ },
+};
+
+_ready(SphinxHighlight.highlightSearchWords);
+_ready(SphinxHighlight.initEscapeListener);
diff --git a/_static/styles/furo-extensions.css b/_static/styles/furo-extensions.css
new file mode 100644
index 0000000000..bc447f228f
--- /dev/null
+++ b/_static/styles/furo-extensions.css
@@ -0,0 +1,2 @@
+#furo-sidebar-ad-placement{padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)}#furo-sidebar-ad-placement .ethical-sidebar{background:var(--color-background-secondary);border:none;box-shadow:none}#furo-sidebar-ad-placement .ethical-sidebar:hover{background:var(--color-background-hover)}#furo-sidebar-ad-placement .ethical-sidebar a{color:var(--color-foreground-primary)}#furo-sidebar-ad-placement .ethical-callout a{color:var(--color-foreground-secondary)!important}#furo-readthedocs-versions{background:transparent;display:block;position:static;width:100%}#furo-readthedocs-versions .rst-versions{background:#1a1c1e}#furo-readthedocs-versions .rst-current-version{background:var(--color-sidebar-item-background);cursor:unset}#furo-readthedocs-versions .rst-current-version:hover{background:var(--color-sidebar-item-background)}#furo-readthedocs-versions .rst-current-version .fa-book{color:var(--color-foreground-primary)}#furo-readthedocs-versions>.rst-other-versions{padding:0}#furo-readthedocs-versions>.rst-other-versions small{opacity:1}#furo-readthedocs-versions .injected .rst-versions{position:unset}#furo-readthedocs-versions:focus-within,#furo-readthedocs-versions:hover{box-shadow:0 0 0 1px var(--color-sidebar-background-border)}#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:hover .rst-current-version{background:#1a1c1e;font-size:inherit;height:auto;line-height:inherit;padding:12px;text-align:right}#furo-readthedocs-versions:focus-within .rst-current-version .fa-book,#furo-readthedocs-versions:hover .rst-current-version .fa-book{color:#fff;float:left}#furo-readthedocs-versions:focus-within .fa-caret-down,#furo-readthedocs-versions:hover .fa-caret-down{display:none}#furo-readthedocs-versions:focus-within .injected,#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:focus-within .rst-other-versions,#furo-readthedocs-versions:hover .injected,#furo-readthedocs-versions:hover .rst-current-version,#furo-readthedocs-versions:hover .rst-other-versions{display:block}#furo-readthedocs-versions:focus-within>.rst-current-version,#furo-readthedocs-versions:hover>.rst-current-version{display:none}.highlight:hover button.copybtn{color:var(--color-code-foreground)}.highlight button.copybtn{align-items:center;background-color:var(--color-code-background);border:none;color:var(--color-background-item);cursor:pointer;height:1.25em;opacity:1;right:.5rem;top:.625rem;transition:color .3s,opacity .3s;width:1.25em}.highlight button.copybtn:hover{background-color:var(--color-code-background);color:var(--color-brand-content)}.highlight button.copybtn:after{background-color:transparent;color:var(--color-code-foreground);display:none}.highlight button.copybtn.success{color:#22863a;transition:color 0ms}.highlight button.copybtn.success:after{display:block}.highlight button.copybtn svg{padding:0}body{--sd-color-primary:var(--color-brand-primary);--sd-color-primary-highlight:var(--color-brand-content);--sd-color-primary-text:var(--color-background-primary);--sd-color-shadow:rgba(0,0,0,.05);--sd-color-card-border:var(--color-card-border);--sd-color-card-border-hover:var(--color-brand-content);--sd-color-card-background:var(--color-card-background);--sd-color-card-text:var(--color-foreground-primary);--sd-color-card-header:var(--color-card-marginals-background);--sd-color-card-footer:var(--color-card-marginals-background);--sd-color-tabs-label-active:var(--color-brand-content);--sd-color-tabs-label-hover:var(--color-foreground-muted);--sd-color-tabs-label-inactive:var(--color-foreground-muted);--sd-color-tabs-underline-active:var(--color-brand-content);--sd-color-tabs-underline-hover:var(--color-foreground-border);--sd-color-tabs-underline-inactive:var(--color-background-border);--sd-color-tabs-overline:var(--color-background-border);--sd-color-tabs-underline:var(--color-background-border)}.sd-tab-content{box-shadow:0 -2px var(--sd-color-tabs-overline),0 1px var(--sd-color-tabs-underline)}.sd-card{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)}.sd-shadow-sm{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-md{box-shadow:0 .3rem .75rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-lg{box-shadow:0 .6rem 1.5rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-card-hover:hover{transform:none}.sd-cards-carousel{gap:.25rem;padding:.25rem}body{--tabs--label-text:var(--color-foreground-muted);--tabs--label-text--hover:var(--color-foreground-muted);--tabs--label-text--active:var(--color-brand-content);--tabs--label-text--active--hover:var(--color-brand-content);--tabs--label-background:transparent;--tabs--label-background--hover:transparent;--tabs--label-background--active:transparent;--tabs--label-background--active--hover:transparent;--tabs--padding-x:0.25em;--tabs--margin-x:1em;--tabs--border:var(--color-background-border);--tabs--label-border:transparent;--tabs--label-border--hover:var(--color-foreground-muted);--tabs--label-border--active:var(--color-brand-content);--tabs--label-border--active--hover:var(--color-brand-content)}[role=main] .container{max-width:none;padding-left:0;padding-right:0}.shadow.docutils{border:none;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)!important}.sphinx-bs .card{background-color:var(--color-background-secondary);color:var(--color-foreground)}
+/*# sourceMappingURL=furo-extensions.css.map*/
\ No newline at end of file
diff --git a/_static/styles/furo-extensions.css.map b/_static/styles/furo-extensions.css.map
new file mode 100644
index 0000000000..9ba5637f9a
--- /dev/null
+++ b/_static/styles/furo-extensions.css.map
@@ -0,0 +1 @@
+{"version":3,"file":"styles/furo-extensions.css","mappings":"AAGA,2BACE,oFACA,4CAKE,6CAHA,YACA,eAEA,CACA,kDACE,yCAEF,8CACE,sCAEJ,8CACE,kDAEJ,2BAGE,uBACA,cAHA,gBACA,UAEA,CAGA,yCACE,mBAEF,gDAEE,gDADA,YACA,CACA,sDACE,gDACF,yDACE,sCAEJ,+CACE,UACA,qDACE,UAGF,mDACE,eAEJ,yEAEE,4DAEA,mHASE,mBAPA,kBAEA,YADA,oBAGA,aADA,gBAIA,CAEA,qIAEE,WADA,UACA,CAEJ,uGACE,aAEF,iUAGE,cAEF,mHACE,aC1EJ,gCACE,mCAEF,0BAKE,mBAUA,8CACA,YAFA,mCAKA,eAZA,cALA,UASA,YADA,YAYA,iCAdA,YAcA,CAEA,gCAEE,8CADA,gCACA,CAEF,gCAGE,6BADA,mCADA,YAEA,CAEF,kCAEE,cADA,oBACA,CACA,wCACE,cAEJ,8BACE,UC5CN,KAEE,6CAA8C,CAC9C,uDAAwD,CACxD,uDAAwD,CAGxD,iCAAsC,CAGtC,+CAAgD,CAChD,uDAAwD,CACxD,uDAAwD,CACxD,oDAAqD,CACrD,6DAA8D,CAC9D,6DAA8D,CAG9D,uDAAwD,CACxD,yDAA0D,CAC1D,4DAA6D,CAC7D,2DAA4D,CAC5D,8DAA+D,CAC/D,iEAAkE,CAClE,uDAAwD,CACxD,wDAAyD,CAG3D,gBACE,qFAGF,SACE,6EAEF,cACE,uFAEF,cACE,uFAEF,cACE,uFAGF,qBACE,eAEF,mBACE,WACA,eChDF,KACE,gDAAiD,CACjD,uDAAwD,CACxD,qDAAsD,CACtD,4DAA6D,CAC7D,oCAAqC,CACrC,2CAA4C,CAC5C,4CAA6C,CAC7C,mDAAoD,CACpD,wBAAyB,CACzB,oBAAqB,CACrB,6CAA8C,CAC9C,gCAAiC,CACjC,yDAA0D,CAC1D,uDAAwD,CACxD,8DAA+D,CCbjE,uBACE,eACA,eACA,gBAGF,iBACE,YACA,+EAGF,iBACE,mDACA","sources":["webpack:///./src/furo/assets/styles/extensions/_readthedocs.sass","webpack:///./src/furo/assets/styles/extensions/_copybutton.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-design.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-inline-tabs.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-panels.sass"],"sourcesContent":["// This file contains the styles used for tweaking how ReadTheDoc's embedded\n// contents would show up inside the theme.\n\n#furo-sidebar-ad-placement\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n .ethical-sidebar\n // Remove the border and box-shadow.\n border: none\n box-shadow: none\n // Manage the background colors.\n background: var(--color-background-secondary)\n &:hover\n background: var(--color-background-hover)\n // Ensure the text is legible.\n a\n color: var(--color-foreground-primary)\n\n .ethical-callout a\n color: var(--color-foreground-secondary) !important\n\n#furo-readthedocs-versions\n position: static\n width: 100%\n background: transparent\n display: block\n\n // Make the background color fit with the theme's aesthetic.\n .rst-versions\n background: rgb(26, 28, 30)\n\n .rst-current-version\n cursor: unset\n background: var(--color-sidebar-item-background)\n &:hover\n background: var(--color-sidebar-item-background)\n .fa-book\n color: var(--color-foreground-primary)\n\n > .rst-other-versions\n padding: 0\n small\n opacity: 1\n\n .injected\n .rst-versions\n position: unset\n\n &:hover,\n &:focus-within\n box-shadow: 0 0 0 1px var(--color-sidebar-background-border)\n\n .rst-current-version\n // Undo the tweaks done in RTD's CSS\n font-size: inherit\n line-height: inherit\n height: auto\n text-align: right\n padding: 12px\n\n // Match the rest of the body\n background: #1a1c1e\n\n .fa-book\n float: left\n color: white\n\n .fa-caret-down\n display: none\n\n .rst-current-version,\n .rst-other-versions,\n .injected\n display: block\n\n > .rst-current-version\n display: none\n",".highlight\n &:hover button.copybtn\n color: var(--color-code-foreground)\n\n button.copybtn\n // Make it visible\n opacity: 1\n\n // Align things correctly\n align-items: center\n\n height: 1.25em\n width: 1.25em\n\n top: 0.625rem // $code-spacing-vertical\n right: 0.5rem\n\n // Make it look better\n color: var(--color-background-item)\n background-color: var(--color-code-background)\n border: none\n\n // Change to cursor to make it obvious that you can click on it\n cursor: pointer\n\n // Transition smoothly, for aesthetics\n transition: color 300ms, opacity 300ms\n\n &:hover\n color: var(--color-brand-content)\n background-color: var(--color-code-background)\n\n &::after\n display: none\n color: var(--color-code-foreground)\n background-color: transparent\n\n &.success\n transition: color 0ms\n color: #22863a\n &::after\n display: block\n\n svg\n padding: 0\n","body\n // Colors\n --sd-color-primary: var(--color-brand-primary)\n --sd-color-primary-highlight: var(--color-brand-content)\n --sd-color-primary-text: var(--color-background-primary)\n\n // Shadows\n --sd-color-shadow: rgba(0, 0, 0, 0.05)\n\n // Cards\n --sd-color-card-border: var(--color-card-border)\n --sd-color-card-border-hover: var(--color-brand-content)\n --sd-color-card-background: var(--color-card-background)\n --sd-color-card-text: var(--color-foreground-primary)\n --sd-color-card-header: var(--color-card-marginals-background)\n --sd-color-card-footer: var(--color-card-marginals-background)\n\n // Tabs\n --sd-color-tabs-label-active: var(--color-brand-content)\n --sd-color-tabs-label-hover: var(--color-foreground-muted)\n --sd-color-tabs-label-inactive: var(--color-foreground-muted)\n --sd-color-tabs-underline-active: var(--color-brand-content)\n --sd-color-tabs-underline-hover: var(--color-foreground-border)\n --sd-color-tabs-underline-inactive: var(--color-background-border)\n --sd-color-tabs-overline: var(--color-background-border)\n --sd-color-tabs-underline: var(--color-background-border)\n\n// Tabs\n.sd-tab-content\n box-shadow: 0 -2px var(--sd-color-tabs-overline), 0 1px var(--sd-color-tabs-underline)\n\n// Shadows\n.sd-card // Have a shadow by default\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n.sd-shadow-sm\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-md\n box-shadow: 0 0.3rem 0.75rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-lg\n box-shadow: 0 0.6rem 1.5rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Cards\n.sd-card-hover:hover // Don't change scale on hover\n transform: none\n\n.sd-cards-carousel // Have a bit of gap in the carousel by default\n gap: 0.25rem\n padding: 0.25rem\n","// This file contains styles to tweak sphinx-inline-tabs to work well with Furo.\n\nbody\n --tabs--label-text: var(--color-foreground-muted)\n --tabs--label-text--hover: var(--color-foreground-muted)\n --tabs--label-text--active: var(--color-brand-content)\n --tabs--label-text--active--hover: var(--color-brand-content)\n --tabs--label-background: transparent\n --tabs--label-background--hover: transparent\n --tabs--label-background--active: transparent\n --tabs--label-background--active--hover: transparent\n --tabs--padding-x: 0.25em\n --tabs--margin-x: 1em\n --tabs--border: var(--color-background-border)\n --tabs--label-border: transparent\n --tabs--label-border--hover: var(--color-foreground-muted)\n --tabs--label-border--active: var(--color-brand-content)\n --tabs--label-border--active--hover: var(--color-brand-content)\n","// This file contains styles to tweak sphinx-panels to work well with Furo.\n\n// sphinx-panels includes Bootstrap 4, which uses .container which can conflict\n// with docutils' `.. container::` directive.\n[role=\"main\"] .container\n max-width: initial\n padding-left: initial\n padding-right: initial\n\n// Make the panels look nicer!\n.shadow.docutils\n border: none\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Make panel colors respond to dark mode\n.sphinx-bs .card\n background-color: var(--color-background-secondary)\n color: var(--color-foreground)\n"],"names":[],"sourceRoot":""}
\ No newline at end of file
diff --git a/_static/styles/furo.css b/_static/styles/furo.css
new file mode 100644
index 0000000000..e3d4e57b86
--- /dev/null
+++ b/_static/styles/furo.css
@@ -0,0 +1,2 @@
+/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}@media print{.content-icon-container,.headerlink,.mobile-header,.related-pages{display:none!important}.highlight{border:.1pt solid var(--color-foreground-border)}a,blockquote,dl,ol,pre,table,ul{page-break-inside:avoid}caption,figure,h1,h2,h3,h4,h5,h6,img{page-break-after:avoid;page-break-inside:avoid}dl,ol,ul{page-break-before:avoid}}.visually-hidden{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;background:var(--color-background-primary);border:0!important;color:var(--color-foreground-primary);white-space:nowrap!important}:-moz-focusring{outline:auto}body{--font-stack:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;--font-stack--monospace:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-stack--headings:var(--font-stack);--font-size--normal:100%;--font-size--small:87.5%;--font-size--small--2:81.25%;--font-size--small--3:75%;--font-size--small--4:62.5%;--sidebar-caption-font-size:var(--font-size--small--2);--sidebar-item-font-size:var(--font-size--small);--sidebar-search-input-font-size:var(--font-size--small);--toc-font-size:var(--font-size--small--3);--toc-font-size--mobile:var(--font-size--normal);--toc-title-font-size:var(--font-size--small--4);--admonition-font-size:0.8125rem;--admonition-title-font-size:0.8125rem;--code-font-size:var(--font-size--small--2);--api-font-size:var(--font-size--small);--header-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*4);--header-padding:0.5rem;--sidebar-tree-space-above:1.5rem;--sidebar-caption-space-above:1rem;--sidebar-item-line-height:1rem;--sidebar-item-spacing-vertical:0.5rem;--sidebar-item-spacing-horizontal:1rem;--sidebar-item-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*2);--sidebar-expander-width:var(--sidebar-item-height);--sidebar-search-space-above:0.5rem;--sidebar-search-input-spacing-vertical:0.5rem;--sidebar-search-input-spacing-horizontal:0.5rem;--sidebar-search-input-height:1rem;--sidebar-search-icon-size:var(--sidebar-search-input-height);--toc-title-padding:0.25rem 0;--toc-spacing-vertical:1.5rem;--toc-spacing-horizontal:1.5rem;--toc-item-spacing-vertical:0.4rem;--toc-item-spacing-horizontal:1rem;--icon-search:url('data:image/svg+xml;charset=utf-8, ');--icon-pencil:url('data:image/svg+xml;charset=utf-8, ');--icon-abstract:url('data:image/svg+xml;charset=utf-8, ');--icon-info:url('data:image/svg+xml;charset=utf-8, ');--icon-flame:url('data:image/svg+xml;charset=utf-8, ');--icon-question:url('data:image/svg+xml;charset=utf-8, ');--icon-warning:url('data:image/svg+xml;charset=utf-8, ');--icon-failure:url('data:image/svg+xml;charset=utf-8, ');--icon-spark:url('data:image/svg+xml;charset=utf-8, ');--color-admonition-title--caution:#ff9100;--color-admonition-title-background--caution:rgba(255,145,0,.2);--color-admonition-title--warning:#ff9100;--color-admonition-title-background--warning:rgba(255,145,0,.2);--color-admonition-title--danger:#ff5252;--color-admonition-title-background--danger:rgba(255,82,82,.2);--color-admonition-title--attention:#ff5252;--color-admonition-title-background--attention:rgba(255,82,82,.2);--color-admonition-title--error:#ff5252;--color-admonition-title-background--error:rgba(255,82,82,.2);--color-admonition-title--hint:#00c852;--color-admonition-title-background--hint:rgba(0,200,82,.2);--color-admonition-title--tip:#00c852;--color-admonition-title-background--tip:rgba(0,200,82,.2);--color-admonition-title--important:#00bfa5;--color-admonition-title-background--important:rgba(0,191,165,.2);--color-admonition-title--note:#00b0ff;--color-admonition-title-background--note:rgba(0,176,255,.2);--color-admonition-title--seealso:#448aff;--color-admonition-title-background--seealso:rgba(68,138,255,.2);--color-admonition-title--admonition-todo:grey;--color-admonition-title-background--admonition-todo:hsla(0,0%,50%,.2);--color-admonition-title:#651fff;--color-admonition-title-background:rgba(101,31,255,.2);--icon-admonition-default:var(--icon-abstract);--color-topic-title:#14b8a6;--color-topic-title-background:rgba(20,184,166,.2);--icon-topic-default:var(--icon-pencil);--color-problematic:#b30000;--color-foreground-primary:#000;--color-foreground-secondary:#5a5c63;--color-foreground-muted:#6b6f76;--color-foreground-border:#878787;--color-background-primary:#fff;--color-background-secondary:#f8f9fb;--color-background-hover:#efeff4;--color-background-hover--transparent:#efeff400;--color-background-border:#eeebee;--color-background-item:#ccc;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#0a4bff;--color-brand-content:#2757dd;--color-brand-visited:#872ee0;--color-api-background:var(--color-background-hover--transparent);--color-api-background-hover:var(--color-background-hover);--color-api-overall:var(--color-foreground-secondary);--color-api-name:var(--color-problematic);--color-api-pre-name:var(--color-problematic);--color-api-paren:var(--color-foreground-secondary);--color-api-keyword:var(--color-foreground-primary);--color-api-added:#21632c;--color-api-added-border:#38a84d;--color-api-changed:#046172;--color-api-changed-border:#06a1bc;--color-api-deprecated:#605706;--color-api-deprecated-border:#f0d90f;--color-api-removed:#b30000;--color-api-removed-border:#ff5c5c;--color-highlight-on-target:#ffc;--color-inline-code-background:var(--color-background-secondary);--color-highlighted-background:#def;--color-highlighted-text:var(--color-foreground-primary);--color-guilabel-background:#ddeeff80;--color-guilabel-border:#bedaf580;--color-guilabel-text:var(--color-foreground-primary);--color-admonition-background:transparent;--color-table-header-background:var(--color-background-secondary);--color-table-border:var(--color-background-border);--color-card-border:var(--color-background-secondary);--color-card-background:transparent;--color-card-marginals-background:var(--color-background-secondary);--color-header-background:var(--color-background-primary);--color-header-border:var(--color-background-border);--color-header-text:var(--color-foreground-primary);--color-sidebar-background:var(--color-background-secondary);--color-sidebar-background-border:var(--color-background-border);--color-sidebar-brand-text:var(--color-foreground-primary);--color-sidebar-caption-text:var(--color-foreground-muted);--color-sidebar-link-text:var(--color-foreground-secondary);--color-sidebar-link-text--top-level:var(--color-brand-primary);--color-sidebar-item-background:var(--color-sidebar-background);--color-sidebar-item-background--current:var( --color-sidebar-item-background );--color-sidebar-item-background--hover:linear-gradient(90deg,var(--color-background-hover--transparent) 0%,var(--color-background-hover) var(--sidebar-item-spacing-horizontal),var(--color-background-hover) 100%);--color-sidebar-item-expander-background:transparent;--color-sidebar-item-expander-background--hover:var( --color-background-hover );--color-sidebar-search-text:var(--color-foreground-primary);--color-sidebar-search-background:var(--color-background-secondary);--color-sidebar-search-background--focus:var(--color-background-primary);--color-sidebar-search-border:var(--color-background-border);--color-sidebar-search-icon:var(--color-foreground-muted);--color-toc-background:var(--color-background-primary);--color-toc-title-text:var(--color-foreground-muted);--color-toc-item-text:var(--color-foreground-secondary);--color-toc-item-text--hover:var(--color-foreground-primary);--color-toc-item-text--active:var(--color-brand-primary);--color-content-foreground:var(--color-foreground-primary);--color-content-background:transparent;--color-link:var(--color-brand-content);--color-link-underline:var(--color-background-border);--color-link--hover:var(--color-brand-content);--color-link-underline--hover:var(--color-foreground-border);--color-link--visited:var(--color-brand-visited);--color-link-underline--visited:var(--color-background-border);--color-link--visited--hover:var(--color-brand-visited);--color-link-underline--visited--hover:var(--color-foreground-border)}.only-light{display:block!important}html body .only-dark{display:none!important}@media not print{body[data-theme=dark]{--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body[data-theme=dark] .only-light{display:none!important}body[data-theme=dark] .only-dark{display:block!important}@media(prefers-color-scheme:dark){body:not([data-theme=light]){--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body:not([data-theme=light]) .only-light{display:none!important}body:not([data-theme=light]) .only-dark{display:block!important}}}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:block}@media(prefers-color-scheme:dark){body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-dark{display:block}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:none}}body[data-theme=dark] .theme-toggle svg.theme-icon-when-dark,body[data-theme=light] .theme-toggle svg.theme-icon-when-light{display:block}body{font-family:var(--font-stack)}code,kbd,pre,samp{font-family:var(--font-stack--monospace)}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article{line-height:1.5}h1,h2,h3,h4,h5,h6{border-radius:.5rem;font-family:var(--font-stack--headings);font-weight:700;line-height:1.25;margin:.5rem -.5rem;padding-left:.5rem;padding-right:.5rem}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p{margin-top:0}h1{font-size:2.5em;margin-bottom:1rem}h1,h2{margin-top:1.75rem}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.25em}h5{font-size:1.125em}h6{font-size:1em}small{font-size:80%;opacity:75%}p{margin-bottom:.75rem;margin-top:.5rem}hr.docutils{background-color:var(--color-background-border);border:0;height:1px;margin:2rem 0;padding:0}.centered{text-align:center}a{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}a:visited{color:var(--color-link--visited);text-decoration-color:var(--color-link-underline--visited)}a:visited:hover{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}a:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link{color:inherit}a.muted-link:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link:hover:visited{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}html{overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth}.sidebar-scroll,.toc-scroll,article[role=main] *{scrollbar-color:var(--color-foreground-border) transparent;scrollbar-width:thin}.sidebar-scroll::-webkit-scrollbar,.toc-scroll::-webkit-scrollbar,article[role=main] ::-webkit-scrollbar{height:.25rem;width:.25rem}.sidebar-scroll::-webkit-scrollbar-thumb,.toc-scroll::-webkit-scrollbar-thumb,article[role=main] ::-webkit-scrollbar-thumb{background-color:var(--color-foreground-border);border-radius:.125rem}body,html{height:100%}.skip-to-content,body,html{background:var(--color-background-primary);color:var(--color-foreground-primary)}.skip-to-content{border-radius:1rem;left:.25rem;padding:1rem;position:fixed;top:.25rem;transform:translateY(-200%);transition:transform .3s ease-in-out;z-index:40}.skip-to-content:focus-within{transform:translateY(0)}article{background:var(--color-content-background);color:var(--color-content-foreground);overflow-wrap:break-word}.page{display:flex;min-height:100%}.mobile-header{background-color:var(--color-header-background);border-bottom:1px solid var(--color-header-border);color:var(--color-header-text);display:none;height:var(--header-height);width:100%;z-index:10}.mobile-header.scrolled{border-bottom:none;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.mobile-header .header-center a{color:var(--color-header-text);text-decoration:none}.main{display:flex;flex:1}.sidebar-drawer{background:var(--color-sidebar-background);border-right:1px solid var(--color-sidebar-background-border);box-sizing:border-box;display:flex;justify-content:flex-end;min-width:15em;width:calc(50% - 26em)}.sidebar-container,.toc-drawer{box-sizing:border-box;width:15em}.toc-drawer{background:var(--color-toc-background);padding-right:1rem}.sidebar-sticky,.toc-sticky{display:flex;flex-direction:column;height:min(100%,100vh);height:100vh;position:sticky;top:0}.sidebar-scroll,.toc-scroll{flex-grow:1;flex-shrink:1;overflow:auto;scroll-behavior:smooth}.content{display:flex;flex-direction:column;justify-content:space-between;padding:0 3em;width:46em}.icon{display:inline-block;height:1rem;width:1rem}.icon svg{height:100%;width:100%}.announcement{align-items:center;background-color:var(--color-announcement-background);color:var(--color-announcement-text);display:flex;height:var(--header-height);overflow-x:auto}.announcement+.page{min-height:calc(100% - var(--header-height))}.announcement-content{box-sizing:border-box;min-width:100%;padding:.5rem;text-align:center;white-space:nowrap}.announcement-content a{color:var(--color-announcement-text);text-decoration-color:var(--color-announcement-text)}.announcement-content a:hover{color:var(--color-announcement-text);text-decoration-color:var(--color-link--hover)}.no-js .theme-toggle-container{display:none}.theme-toggle-container{vertical-align:middle}.theme-toggle{background:transparent;border:none;cursor:pointer;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1.25rem;vertical-align:middle;width:1.25rem}.theme-toggle-header{float:left;padding:1rem .5rem}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1.25rem;width:1.25rem}.nav-overlay-icon,.toc-header-icon{align-items:center;justify-content:center}.toc-content-icon{height:1.5rem;width:1.5rem}.content-icon-container{display:flex;float:right;gap:.5rem;margin-bottom:1rem;margin-left:1rem;margin-top:1.5rem}.content-icon-container .edit-this-page svg,.content-icon-container .view-this-page svg{color:inherit;height:1.25rem;width:1.25rem}.sidebar-toggle{display:none;position:absolute}.sidebar-toggle[name=__toc]{left:20px}.sidebar-toggle:checked{left:40px}.overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms,height 0ms,opacity .25s ease-out;width:0}.sidebar-overlay{z-index:20}.toc-overlay{z-index:40}.sidebar-drawer{transition:left .25s ease-in-out;z-index:30}.toc-drawer{transition:right .25s ease-in-out;z-index:50}#__navigation:checked~.sidebar-overlay{height:100%;opacity:1;width:100%}#__navigation:checked~.page .sidebar-drawer{left:0;top:0}#__toc:checked~.toc-overlay{height:100%;opacity:1;width:100%}#__toc:checked~.page .toc-drawer{right:0;top:0}.back-to-top{background:var(--color-background-primary);border-radius:1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 1px 0 hsla(220,9%,46%,.502);display:none;font-size:.8125rem;left:0;margin-left:50%;padding:.5rem .75rem .5rem .5rem;position:fixed;text-decoration:none;top:1rem;transform:translateX(-50%);z-index:10}.back-to-top svg{height:1rem;width:1rem;fill:currentColor;display:inline-block}.back-to-top span{margin-left:.25rem}.show-back-to-top .back-to-top{align-items:center;display:flex}@media(min-width:97em){html{font-size:110%}}@media(max-width:82em){.toc-content-icon{display:flex}.toc-drawer{border-left:1px solid var(--color-background-muted);height:100vh;position:fixed;right:-15em;top:0}.toc-tree{border-left:none;font-size:var(--toc-font-size--mobile)}.sidebar-drawer{width:calc(50% - 18.5em)}}@media(max-width:67em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.theme-toggle-header{display:block}.mobile-header{align-items:center;display:flex;justify-content:space-between;position:sticky;top:0}.mobile-header .header-left,.mobile-header .header-right{display:flex;height:var(--header-height);padding:0 var(--header-padding)}.mobile-header .header-left label,.mobile-header .header-right label{height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.nav-overlay-icon .icon,.theme-toggle svg{height:1.25rem;width:1.25rem}:target{scroll-margin-top:calc(var(--header-height) + 2.5rem)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}.content{margin-left:auto;margin-right:auto}}@media(max-width:52em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){.content{padding:0 1em}article aside.sidebar{float:none;margin:1rem 0;width:100%}}.admonition,.topic{background:var(--color-admonition-background);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);font-size:var(--admonition-font-size);margin:1rem auto;overflow:hidden;padding:0 .5rem .5rem;page-break-inside:avoid}.admonition>:nth-child(2),.topic>:nth-child(2){margin-top:0}.admonition>:last-child,.topic>:last-child{margin-bottom:0}.admonition p.admonition-title,p.topic-title{font-size:var(--admonition-title-font-size);font-weight:500;line-height:1.3;margin:0 -.5rem .5rem;padding:.4rem .5rem .4rem 2rem;position:relative}.admonition p.admonition-title:before,p.topic-title:before{content:"";height:1rem;left:.5rem;position:absolute;width:1rem}p.admonition-title{background-color:var(--color-admonition-title-background)}p.admonition-title:before{background-color:var(--color-admonition-title);-webkit-mask-image:var(--icon-admonition-default);mask-image:var(--icon-admonition-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}p.topic-title{background-color:var(--color-topic-title-background)}p.topic-title:before{background-color:var(--color-topic-title);-webkit-mask-image:var(--icon-topic-default);mask-image:var(--icon-topic-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.admonition{border-left:.2rem solid var(--color-admonition-title)}.admonition.caution{border-left-color:var(--color-admonition-title--caution)}.admonition.caution>.admonition-title{background-color:var(--color-admonition-title-background--caution)}.admonition.caution>.admonition-title:before{background-color:var(--color-admonition-title--caution);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.warning{border-left-color:var(--color-admonition-title--warning)}.admonition.warning>.admonition-title{background-color:var(--color-admonition-title-background--warning)}.admonition.warning>.admonition-title:before{background-color:var(--color-admonition-title--warning);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.danger{border-left-color:var(--color-admonition-title--danger)}.admonition.danger>.admonition-title{background-color:var(--color-admonition-title-background--danger)}.admonition.danger>.admonition-title:before{background-color:var(--color-admonition-title--danger);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.attention{border-left-color:var(--color-admonition-title--attention)}.admonition.attention>.admonition-title{background-color:var(--color-admonition-title-background--attention)}.admonition.attention>.admonition-title:before{background-color:var(--color-admonition-title--attention);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.error{border-left-color:var(--color-admonition-title--error)}.admonition.error>.admonition-title{background-color:var(--color-admonition-title-background--error)}.admonition.error>.admonition-title:before{background-color:var(--color-admonition-title--error);-webkit-mask-image:var(--icon-failure);mask-image:var(--icon-failure)}.admonition.hint{border-left-color:var(--color-admonition-title--hint)}.admonition.hint>.admonition-title{background-color:var(--color-admonition-title-background--hint)}.admonition.hint>.admonition-title:before{background-color:var(--color-admonition-title--hint);-webkit-mask-image:var(--icon-question);mask-image:var(--icon-question)}.admonition.tip{border-left-color:var(--color-admonition-title--tip)}.admonition.tip>.admonition-title{background-color:var(--color-admonition-title-background--tip)}.admonition.tip>.admonition-title:before{background-color:var(--color-admonition-title--tip);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.important{border-left-color:var(--color-admonition-title--important)}.admonition.important>.admonition-title{background-color:var(--color-admonition-title-background--important)}.admonition.important>.admonition-title:before{background-color:var(--color-admonition-title--important);-webkit-mask-image:var(--icon-flame);mask-image:var(--icon-flame)}.admonition.note{border-left-color:var(--color-admonition-title--note)}.admonition.note>.admonition-title{background-color:var(--color-admonition-title-background--note)}.admonition.note>.admonition-title:before{background-color:var(--color-admonition-title--note);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition.seealso{border-left-color:var(--color-admonition-title--seealso)}.admonition.seealso>.admonition-title{background-color:var(--color-admonition-title-background--seealso)}.admonition.seealso>.admonition-title:before{background-color:var(--color-admonition-title--seealso);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.admonition-todo{border-left-color:var(--color-admonition-title--admonition-todo)}.admonition.admonition-todo>.admonition-title{background-color:var(--color-admonition-title-background--admonition-todo)}.admonition.admonition-todo>.admonition-title:before{background-color:var(--color-admonition-title--admonition-todo);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition-todo>.admonition-title{text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:first-child{margin-top:.125rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:last-child{margin-bottom:.75rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list>dt{font-size:var(--font-size--small);text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd:empty{margin-bottom:.5rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul{margin-left:-1.2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p:nth-child(2){margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p+p:last-child:empty{margin-bottom:0;margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{color:var(--color-api-overall)}.sig:not(.sig-inline){background:var(--color-api-background);border-radius:.25rem;font-family:var(--font-stack--monospace);font-size:var(--api-font-size);font-weight:700;margin-left:-.25rem;margin-right:-.25rem;padding:.25rem .5rem .25rem 3em;text-indent:-2.5em;transition:background .1s ease-out}.sig:not(.sig-inline):hover{background:var(--color-api-background-hover)}.sig:not(.sig-inline) a.reference .viewcode-link{font-weight:400;width:4.25rem}em.property{font-style:normal}em.property:first-child{color:var(--color-api-keyword)}.sig-name{color:var(--color-api-name)}.sig-prename{color:var(--color-api-pre-name);font-weight:400}.sig-paren{color:var(--color-api-paren)}.sig-param{font-style:normal}div.deprecated,div.versionadded,div.versionchanged,div.versionremoved{border-left:.1875rem solid;border-radius:.125rem;padding-left:.75rem}div.deprecated p,div.versionadded p,div.versionchanged p,div.versionremoved p{margin-bottom:.125rem;margin-top:.125rem}div.versionadded{border-color:var(--color-api-added-border)}div.versionadded .versionmodified{color:var(--color-api-added)}div.versionchanged{border-color:var(--color-api-changed-border)}div.versionchanged .versionmodified{color:var(--color-api-changed)}div.deprecated{border-color:var(--color-api-deprecated-border)}div.deprecated .versionmodified{color:var(--color-api-deprecated)}div.versionremoved{border-color:var(--color-api-removed-border)}div.versionremoved .versionmodified{color:var(--color-api-removed)}.viewcode-back,.viewcode-link{float:right;text-align:right}.line-block{margin-bottom:.75rem;margin-top:.5rem}.line-block .line-block{margin-bottom:0;margin-top:0;padding-left:1rem}.code-block-caption,article p.caption,table>caption{font-size:var(--font-size--small);text-align:center}.toctree-wrapper.compound .caption,.toctree-wrapper.compound :not(.caption)>.caption-text{font-size:var(--font-size--small);margin-bottom:0;text-align:initial;text-transform:uppercase}.toctree-wrapper.compound>ul{margin-bottom:0;margin-top:0}.sig-inline,code.literal{background:var(--color-inline-code-background);border-radius:.2em;font-size:var(--font-size--small--2);padding:.1em .2em}pre.literal-block .sig-inline,pre.literal-block code.literal{font-size:inherit;padding:0}p .sig-inline,p code.literal{border:1px solid var(--color-background-border)}.sig-inline{font-family:var(--font-stack--monospace)}div[class*=" highlight-"],div[class^=highlight-]{display:flex;margin:1em 0}div[class*=" highlight-"] .table-wrapper,div[class^=highlight-] .table-wrapper,pre{margin:0;padding:0}pre{overflow:auto}article[role=main] .highlight pre{line-height:1.5}.highlight pre,pre.literal-block{font-size:var(--code-font-size);padding:.625rem .875rem}pre.literal-block{background-color:var(--color-code-background);border-radius:.2rem;color:var(--color-code-foreground);margin-bottom:1rem;margin-top:1rem}.highlight{border-radius:.2rem;width:100%}.highlight .gp,.highlight span.linenos{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .hll{display:block;margin-left:-.875rem;margin-right:-.875rem;padding-left:.875rem;padding-right:.875rem}.code-block-caption{background-color:var(--color-code-background);border-bottom:1px solid;border-radius:.25rem;border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:var(--color-background-border);color:var(--color-code-foreground);display:flex;font-weight:300;padding:.625rem .875rem}.code-block-caption+div[class]{margin-top:0}.code-block-caption+div[class] pre{border-top-left-radius:0;border-top-right-radius:0}.highlighttable{display:block;width:100%}.highlighttable tbody{display:block}.highlighttable tr{display:flex}.highlighttable td.linenos{background-color:var(--color-code-background);border-bottom-left-radius:.2rem;border-top-left-radius:.2rem;color:var(--color-code-foreground);padding:.625rem 0 .625rem .875rem}.highlighttable .linenodiv{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;font-size:var(--code-font-size);padding-right:.875rem}.highlighttable td.code{display:block;flex:1;overflow:hidden;padding:0}.highlighttable td.code .highlight{border-bottom-left-radius:0;border-top-left-radius:0}.highlight span.linenos{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;display:inline-block;margin-right:.875rem;padding-left:0;padding-right:.875rem}.footnote-reference{font-size:var(--font-size--small--4);vertical-align:super}dl.footnote.brackets{color:var(--color-foreground-secondary);display:grid;font-size:var(--font-size--small);grid-template-columns:max-content auto}dl.footnote.brackets dt{margin:0}dl.footnote.brackets dt>.fn-backref{margin-left:.25rem}dl.footnote.brackets dt:after{content:":"}dl.footnote.brackets dt .brackets:before{content:"["}dl.footnote.brackets dt .brackets:after{content:"]"}dl.footnote.brackets dd{margin:0;padding:0 1rem}aside.footnote{color:var(--color-foreground-secondary);font-size:var(--font-size--small)}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>:not(span),div.citation>p{margin-left:2rem}img{box-sizing:border-box;height:auto;max-width:100%}article .figure,article figure{border-radius:.2rem;margin:0}article .figure :last-child,article figure :last-child{margin-bottom:0}article .align-left{clear:left;float:left;margin:0 1rem 1rem}article .align-right{clear:right;float:right;margin:0 1rem 1rem}article .align-center,article .align-default{display:block;margin-left:auto;margin-right:auto;text-align:center}article table.align-default{display:table;text-align:initial}.domainindex-jumpbox,.genindex-jumpbox{border-bottom:1px solid var(--color-background-border);border-top:1px solid var(--color-background-border);padding:.25rem}.domainindex-section h2,.genindex-section h2{margin-bottom:.5rem;margin-top:.75rem}.domainindex-section ul,.genindex-section ul{margin-bottom:0;margin-top:0}ol,ul{margin-bottom:1rem;margin-top:1rem;padding-left:1.2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}ol li>p:last-child,ul li>p:last-child{margin-top:.25rem}ol li>ol,ol li>ul,ul li>ol,ul li>ul{margin-bottom:.5rem;margin-top:.5rem}ol.arabic{list-style:decimal}ol.loweralpha{list-style:lower-alpha}ol.upperalpha{list-style:upper-alpha}ol.lowerroman{list-style:lower-roman}ol.upperroman{list-style:upper-roman}.simple li>ol,.simple li>ul,.toctree-wrapper li>ol,.toctree-wrapper li>ul{margin-bottom:0;margin-top:0}.field-list dt,.option-list dt,dl.footnote dt,dl.glossary dt,dl.simple dt,dl:not([class]) dt{font-weight:500;margin-top:.25rem}.field-list dt+dt,.option-list dt+dt,dl.footnote dt+dt,dl.glossary dt+dt,dl.simple dt+dt,dl:not([class]) dt+dt{margin-top:0}.field-list dt .classifier:before,.option-list dt .classifier:before,dl.footnote dt .classifier:before,dl.glossary dt .classifier:before,dl.simple dt .classifier:before,dl:not([class]) dt .classifier:before{content:":";margin-left:.2rem;margin-right:.2rem}.field-list dd ul,.field-list dd>p:first-child,.option-list dd ul,.option-list dd>p:first-child,dl.footnote dd ul,dl.footnote dd>p:first-child,dl.glossary dd ul,dl.glossary dd>p:first-child,dl.simple dd ul,dl.simple dd>p:first-child,dl:not([class]) dd ul,dl:not([class]) dd>p:first-child{margin-top:.125rem}.field-list dd ul,.option-list dd ul,dl.footnote dd ul,dl.glossary dd ul,dl.simple dd ul,dl:not([class]) dd ul{margin-bottom:.125rem}.math-wrapper{overflow-x:auto;width:100%}div.math{position:relative;text-align:center}div.math .headerlink,div.math:focus .headerlink{display:none}div.math:hover .headerlink{display:inline-block}div.math span.eqno{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);z-index:1}abbr[title]{cursor:help}.problematic{color:var(--color-problematic)}kbd:not(.compound){background-color:var(--color-background-secondary);border:1px solid var(--color-foreground-border);border-radius:.2rem;box-shadow:0 .0625rem 0 rgba(0,0,0,.2),inset 0 0 0 .125rem var(--color-background-primary);color:var(--color-foreground-primary);display:inline-block;font-size:var(--font-size--small--3);margin:0 .2rem;padding:0 .2rem;vertical-align:text-bottom}blockquote{background:var(--color-background-secondary);border-left:4px solid var(--color-background-border);margin-left:0;margin-right:0;padding:.5rem 1rem}blockquote .attribution{font-weight:600;text-align:right}blockquote.highlights,blockquote.pull-quote{font-size:1.25em}blockquote.epigraph,blockquote.pull-quote{border-left-width:0;border-radius:.5rem}blockquote.highlights{background:transparent;border-left-width:0}p .reference img{vertical-align:middle}p.rubric{font-size:1.125em;font-weight:700;line-height:1.25}dd p.rubric{font-size:var(--font-size--small);font-weight:inherit;line-height:inherit;text-transform:uppercase}article .sidebar{background-color:var(--color-background-secondary);border:1px solid var(--color-background-border);border-radius:.2rem;clear:right;float:right;margin-left:1rem;margin-right:0;width:30%}article .sidebar>*{padding-left:1rem;padding-right:1rem}article .sidebar>ol,article .sidebar>ul{padding-left:2.2rem}article .sidebar .sidebar-title{border-bottom:1px solid var(--color-background-border);font-weight:500;margin:0;padding:.5rem 1rem}.table-wrapper{margin-bottom:.5rem;margin-top:1rem;overflow-x:auto;padding:.2rem .2rem .75rem;width:100%}table.docutils{border-collapse:collapse;border-radius:.2rem;border-spacing:0;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)}table.docutils th{background:var(--color-table-header-background)}table.docutils td,table.docutils th{border-bottom:1px solid var(--color-table-border);border-left:1px solid var(--color-table-border);border-right:1px solid var(--color-table-border);padding:0 .25rem}table.docutils td p,table.docutils th p{margin:.25rem}table.docutils td:first-child,table.docutils th:first-child{border-left:none}table.docutils td:last-child,table.docutils th:last-child{border-right:none}table.docutils td.text-left,table.docutils th.text-left{text-align:left}table.docutils td.text-right,table.docutils th.text-right{text-align:right}table.docutils td.text-center,table.docutils th.text-center{text-align:center}:target{scroll-margin-top:2.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(2.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(2.8rem + var(--header-height))}}.headerlink{font-weight:100;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-block-caption>.headerlink,dl dt>.headerlink,figcaption p>.headerlink,h1>.headerlink,h2>.headerlink,h3>.headerlink,h4>.headerlink,h5>.headerlink,h6>.headerlink,p.caption>.headerlink,table>caption>.headerlink{margin-left:.5rem;visibility:hidden}.code-block-caption:hover>.headerlink,dl dt:hover>.headerlink,figcaption p:hover>.headerlink,h1:hover>.headerlink,h2:hover>.headerlink,h3:hover>.headerlink,h4:hover>.headerlink,h5:hover>.headerlink,h6:hover>.headerlink,p.caption:hover>.headerlink,table>caption:hover>.headerlink{visibility:visible}.code-block-caption>.toc-backref,dl dt>.toc-backref,figcaption p>.toc-backref,h1>.toc-backref,h2>.toc-backref,h3>.toc-backref,h4>.toc-backref,h5>.toc-backref,h6>.toc-backref,p.caption>.toc-backref,table>caption>.toc-backref{color:inherit;text-decoration-line:none}figure:hover>figcaption>p>.headerlink,table:hover>caption>.headerlink{visibility:visible}:target>h1:first-of-type,:target>h2:first-of-type,:target>h3:first-of-type,:target>h4:first-of-type,:target>h5:first-of-type,:target>h6:first-of-type,span:target~h1:first-of-type,span:target~h2:first-of-type,span:target~h3:first-of-type,span:target~h4:first-of-type,span:target~h5:first-of-type,span:target~h6:first-of-type{background-color:var(--color-highlight-on-target)}:target>h1:first-of-type code.literal,:target>h2:first-of-type code.literal,:target>h3:first-of-type code.literal,:target>h4:first-of-type code.literal,:target>h5:first-of-type code.literal,:target>h6:first-of-type code.literal,span:target~h1:first-of-type code.literal,span:target~h2:first-of-type code.literal,span:target~h3:first-of-type code.literal,span:target~h4:first-of-type code.literal,span:target~h5:first-of-type code.literal,span:target~h6:first-of-type code.literal{background-color:transparent}.literal-block-wrapper:target .code-block-caption,.this-will-duplicate-information-and-it-is-still-useful-here li :target,figure:target,table:target>caption{background-color:var(--color-highlight-on-target)}dt:target{background-color:var(--color-highlight-on-target)!important}.footnote-reference:target,.footnote>dt:target+dd{background-color:var(--color-highlight-on-target)}.guilabel{background-color:var(--color-guilabel-background);border:1px solid var(--color-guilabel-border);border-radius:.5em;color:var(--color-guilabel-text);font-size:.9em;padding:0 .3em}footer{display:flex;flex-direction:column;font-size:var(--font-size--small);margin-top:2rem}.bottom-of-page{align-items:center;border-top:1px solid var(--color-background-border);color:var(--color-foreground-secondary);display:flex;justify-content:space-between;line-height:1.5;margin-top:1rem;padding-bottom:1rem;padding-top:1rem}@media(max-width:46em){.bottom-of-page{flex-direction:column-reverse;gap:.25rem;text-align:center}}.bottom-of-page .left-details{font-size:var(--font-size--small)}.bottom-of-page .right-details{display:flex;flex-direction:column;gap:.25rem;text-align:right}.bottom-of-page .icons{display:flex;font-size:1rem;gap:.25rem;justify-content:flex-end}.bottom-of-page .icons a{text-decoration:none}.bottom-of-page .icons img,.bottom-of-page .icons svg{font-size:1.125rem;height:1em;width:1em}.related-pages a{align-items:center;display:flex;text-decoration:none}.related-pages a:hover .page-info .title{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}.related-pages a svg.furo-related-icon,.related-pages a svg.furo-related-icon>use{color:var(--color-foreground-border);flex-shrink:0;height:.75rem;margin:0 .5rem;width:.75rem}.related-pages a.next-page{clear:right;float:right;max-width:50%;text-align:right}.related-pages a.prev-page{clear:left;float:left;max-width:50%}.related-pages a.prev-page svg{transform:rotate(180deg)}.page-info{display:flex;flex-direction:column;overflow-wrap:anywhere}.next-page .page-info{align-items:flex-end}.page-info .context{align-items:center;color:var(--color-foreground-muted);display:flex;font-size:var(--font-size--small);padding-bottom:.1rem;text-decoration:none}ul.search{list-style:none;padding-left:0}ul.search li{border-bottom:1px solid var(--color-background-border);padding:1rem 0}[role=main] .highlighted{background-color:var(--color-highlighted-background);color:var(--color-highlighted-text)}.sidebar-brand{display:flex;flex-direction:column;flex-shrink:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none}.sidebar-brand-text{color:var(--color-sidebar-brand-text);font-size:1.5rem;overflow-wrap:break-word}.sidebar-brand-text,.sidebar-logo-container{margin:var(--sidebar-item-spacing-vertical) 0}.sidebar-logo{display:block;margin:0 auto;max-width:100%}.sidebar-search-container{align-items:center;background:var(--color-sidebar-search-background);display:flex;margin-top:var(--sidebar-search-space-above);position:relative}.sidebar-search-container:focus-within,.sidebar-search-container:hover{background:var(--color-sidebar-search-background--focus)}.sidebar-search-container:before{background-color:var(--color-sidebar-search-icon);content:"";height:var(--sidebar-search-icon-size);left:var(--sidebar-item-spacing-horizontal);-webkit-mask-image:var(--icon-search);mask-image:var(--icon-search);position:absolute;width:var(--sidebar-search-icon-size)}.sidebar-search{background:transparent;border:none;border-bottom:1px solid var(--color-sidebar-search-border);border-top:1px solid var(--color-sidebar-search-border);box-sizing:border-box;color:var(--color-sidebar-search-foreground);padding:var(--sidebar-search-input-spacing-vertical) var(--sidebar-search-input-spacing-horizontal) var(--sidebar-search-input-spacing-vertical) calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size));width:100%;z-index:10}.sidebar-search:focus{outline:none}.sidebar-search::-moz-placeholder{font-size:var(--sidebar-search-input-font-size)}.sidebar-search::placeholder{font-size:var(--sidebar-search-input-font-size)}#searchbox .highlight-link{margin:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0;text-align:center}#searchbox .highlight-link a{color:var(--color-sidebar-search-icon);font-size:var(--font-size--small--2)}.sidebar-tree{font-size:var(--sidebar-item-font-size);margin-bottom:var(--sidebar-item-spacing-vertical);margin-top:var(--sidebar-tree-space-above)}.sidebar-tree ul{display:flex;flex-direction:column;list-style:none;margin-bottom:0;margin-top:0;padding:0}.sidebar-tree li{margin:0;position:relative}.sidebar-tree li>ul{margin-left:var(--sidebar-item-spacing-horizontal)}.sidebar-tree .icon,.sidebar-tree .reference{color:var(--color-sidebar-link-text)}.sidebar-tree .reference{box-sizing:border-box;display:inline-block;height:100%;line-height:var(--sidebar-item-line-height);overflow-wrap:anywhere;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none;width:100%}.sidebar-tree .reference:hover{background:var(--color-sidebar-item-background--hover);color:var(--color-sidebar-link-text)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23607D8B' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' viewBox='0 0 24 24'%3E%3Cpath stroke='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M11 7H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-5M10 14 20 4M15 4h5v5'/%3E%3C/svg%3E");margin:0 .25rem;vertical-align:middle}.sidebar-tree .current-page>.reference{font-weight:700}.sidebar-tree label{align-items:center;cursor:pointer;display:flex;height:var(--sidebar-item-height);justify-content:center;position:absolute;right:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--sidebar-expander-width)}.sidebar-tree .caption,.sidebar-tree :not(.caption)>.caption-text{color:var(--color-sidebar-caption-text);font-size:var(--sidebar-caption-font-size);font-weight:700;margin:var(--sidebar-caption-space-above) 0 0 0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-transform:uppercase}.sidebar-tree li.has-children>.reference{padding-right:var(--sidebar-expander-width)}.sidebar-tree .toctree-l1>.reference,.sidebar-tree .toctree-l1>label .icon{color:var(--color-sidebar-link-text--top-level)}.sidebar-tree label{background:var(--color-sidebar-item-expander-background)}.sidebar-tree label:hover{background:var(--color-sidebar-item-expander-background--hover)}.sidebar-tree .current>.reference{background:var(--color-sidebar-item-background--current)}.sidebar-tree .current>.reference:hover{background:var(--color-sidebar-item-background--hover)}.toctree-checkbox{display:none;position:absolute}.toctree-checkbox~ul{display:none}.toctree-checkbox~label .icon svg{transform:rotate(90deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label .icon svg{transform:rotate(-90deg)}.toc-title-container{padding:var(--toc-title-padding);padding-top:var(--toc-spacing-vertical)}.toc-title{color:var(--color-toc-title-text);font-size:var(--toc-title-font-size);padding-left:var(--toc-spacing-horizontal);text-transform:uppercase}.no-toc{display:none}.toc-tree-container{padding-bottom:var(--toc-spacing-vertical)}.toc-tree{border-left:1px solid var(--color-background-border);font-size:var(--toc-font-size);line-height:1.3;padding-left:calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))}.toc-tree>ul>li:first-child{padding-top:0}.toc-tree>ul>li:first-child>ul{padding-left:0}.toc-tree>ul>li:first-child>a{display:none}.toc-tree ul{list-style-type:none;margin-bottom:0;margin-top:0;padding-left:var(--toc-item-spacing-horizontal)}.toc-tree li{padding-top:var(--toc-item-spacing-vertical)}.toc-tree li.scroll-current>.reference{color:var(--color-toc-item-text--active);font-weight:700}.toc-tree a.reference{color:var(--color-toc-item-text);overflow-wrap:anywhere;text-decoration:none}.toc-scroll{max-height:100vh;overflow-y:scroll}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here){background:rgba(255,0,0,.25);color:var(--color-problematic)}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here):before{content:"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling. Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch."}.text-align\:left>p{text-align:left}.text-align\:center>p{text-align:center}.text-align\:right>p{text-align:right}
+/*# sourceMappingURL=furo.css.map*/
\ No newline at end of file
diff --git a/_static/styles/furo.css.map b/_static/styles/furo.css.map
new file mode 100644
index 0000000000..6e02d0b1aa
--- /dev/null
+++ b/_static/styles/furo.css.map
@@ -0,0 +1 @@
+{"version":3,"file":"styles/furo.css","mappings":"AAAA,2EAA2E,CAU3E,KACE,gBAAiB,CACjB,6BACF,CASA,KACE,QACF,CAMA,KACE,aACF,CAOA,GACE,aAAc,CACd,cACF,CAUA,GACE,sBAAuB,CACvB,QAAS,CACT,gBACF,CAOA,IACE,+BAAiC,CACjC,aACF,CASA,EACE,4BACF,CAOA,YACE,kBAAmB,CACnB,yBAA0B,CAC1B,gCACF,CAMA,SAEE,kBACF,CAOA,cAGE,+BAAiC,CACjC,aACF,CAeA,QAEE,aAAc,CACd,aAAc,CACd,iBAAkB,CAClB,uBACF,CAEA,IACE,aACF,CAEA,IACE,SACF,CASA,IACE,iBACF,CAUA,sCAKE,mBAAoB,CACpB,cAAe,CACf,gBAAiB,CACjB,QACF,CAOA,aAEE,gBACF,CAOA,cAEE,mBACF,CAMA,gDAIE,yBACF,CAMA,wHAIE,iBAAkB,CAClB,SACF,CAMA,4GAIE,6BACF,CAMA,SACE,0BACF,CASA,OACE,qBAAsB,CACtB,aAAc,CACd,aAAc,CACd,cAAe,CACf,SAAU,CACV,kBACF,CAMA,SACE,uBACF,CAMA,SACE,aACF,CAOA,6BAEE,qBAAsB,CACtB,SACF,CAMA,kFAEE,WACF,CAOA,cACE,4BAA6B,CAC7B,mBACF,CAMA,yCACE,uBACF,CAOA,6BACE,yBAA0B,CAC1B,YACF,CASA,QACE,aACF,CAMA,QACE,iBACF,CAiBA,kBACE,YACF,CCvVA,aAcE,kEACE,uBAOF,WACE,iDAMF,gCACE,wBAEF,qCAEE,uBADA,uBACA,CAEF,SACE,wBAtBA,CCpBJ,iBAGE,qBAEA,sBACA,0BAFA,oBAHA,4BACA,oBAKA,6BAIA,2CAFA,mBACA,sCAFA,4BAGA,CAEF,gBACE,aCTF,KCGE,mHAEA,wGAEA,wCAAyC,CAEzC,wBAAyB,CACzB,wBAAyB,CACzB,4BAA6B,CAC7B,yBAA0B,CAC1B,2BAA4B,CAG5B,sDAAuD,CACvD,gDAAiD,CACjD,wDAAyD,CAGzD,0CAA2C,CAC3C,gDAAiD,CACjD,gDAAiD,CAKjD,gCAAiC,CACjC,sCAAuC,CAGvC,2CAA4C,CAG5C,uCAAwC,CCjCxC,+FAGA,uBAAwB,CAGxB,iCAAkC,CAClC,kCAAmC,CAEnC,+BAAgC,CAChC,sCAAuC,CACvC,sCAAuC,CACvC,qGAIA,mDAAoD,CAEpD,mCAAoC,CACpC,8CAA+C,CAC/C,gDAAiD,CACjD,kCAAmC,CACnC,6DAA8D,CAG9D,6BAA8B,CAC9B,6BAA8B,CAC9B,+BAAgC,CAChC,kCAAmC,CACnC,kCAAmC,CCPjC,+jBCYA,iqCAZF,iaCVA,8KAOA,4SAWA,4SAUA,0CACA,gEAGA,0CAGA,gEAGA,yCACA,+DAIA,4CACA,kEAGA,wCAUA,8DACA,uCAGA,4DACA,sCACA,2DAGA,4CACA,kEACA,uCAGA,6DACA,2GAGA,sHAEA,yFAEA,+CACA,+EAGA,4MAOA,gCACA,sHAIA,kCACA,uEACA,gEACA,4DACA,kEAGA,2DACA,sDACA,0CACA,8CACA,wGAGA,0BACA,iCAGA,+DACA,+BACA,sCACA,+DAEA,kGACA,oCACA,yDACA,sCL7HF,kCAEA,sDAIA,0CK2HE,kEAIA,oDACA,sDAGA,oCACA,oEAEA,0DACA,qDAIA,oDACA,6DAIA,iEAIA,2DAIA,2DAGA,4DACA,gEAIA,gEAEA,gFAEA,oNASA,qDLxKE,gFAGE,4DAIF,oEKkHF,yEAEA,6DAGA,0DAEA,uDACA,qDACA,wDAIA,6DAIA,yDACA,2DAIA,uCAGA,wCACA,sDAGA,+CAGA,6DAEA,iDACA,+DAEA,wDAEA,sEAMA,0DACA,sBACA,mEL9JI,wEAEA,iCACE,+BAMN,wEAGA,iCACE,kFAEA,uEAIF,gEACE,8BAGF,qEMvDA,sCAKA,wFAKA,iCAIA,0BAWA,iCACA,4BACA,mCAGA,+BAEA,sCACA,4BAEA,mCAEA,sCAKA,sDAIA,gCAEA,gEAQF,wCAME,sBACA,kCAKA,uBAEA,gEAIA,2BAIA,mCAEA,qCACA,iCAGE,+BACA,wEAEE,iCACA,kFAGF,6BACA,0CACF,kCAEE,8BACE,8BACA,qEAEE,sCACA,wFCjFN,iCAGF,2DAEE,4BACA,oCAGA,mIAGA,4HACE,gEAMJ,+CAGE,sBACA,yCAEF,uBAEE,sEAKA,gDACA,kEAGA,iFAGE,YAGF,EACA,4HAQF,mBACE,6BACA,mBACA,wCACA,wCACA,2CAIA,eAGA,mBAKE,mBAGA,CAJA,uCACA,iBAFF,gBACE,CAKE,mBACA,mBAGJ,oBAIF,+BAGE,kDACA,OADA,kBAGA,CAFA,gBAEA,mBACA,oBAEA,sCACA,OAGF,cAHE,WAGF,GAEE,oBACA,CAHF,gBAGE,CChHc,YDmHd,+CAIF,SAEE,CAPF,UACE,wBAMA,4BAEA,GAGA,uBACA,CAJA,yBAGA,CACA,iDAKA,2CAGA,2DAQA,iBACA,uCAGA,kEAKE,SAKJ,8BACE,yDACA,2BAEA,oBACA,8BAEA,yDAEE,4BAEJ,uCACE,CACA,iEAGA,CAEA,wCACE,uBACA,kDAEA,0DAEE,CAJF,oBAIE,0GASJ,aAEF,CAFE,YAEF,4HASE,+CACA,sBAGF,sBASE,4BAFF,0CAEE,CARA,qCAwBF,CAhBE,iBAEA,kBACE,aADF,4BACE,WAOF,2BAEF,qCAIA,CAbI,UAaJ,+BACE,uBAEA,SAGA,0CAGE,CANF,qCAGA,CAGE,2DACE,gBAKJ,+CAGF,CAEA,kDAME,CARF,8BAEA,CAQE,YAEA,CAlBI,2BAGJ,CAJI,UACA,CAcJ,UAIA,4GAIF,iCAGE,8BAIA,qBACA,mBACF,QACE,gBAOE,0CAGA,CATF,6DAME,CANF,sBASE,qCAKF,CAEE,cACA,CAHF,sBAGE,gCAEA,qBAOJ,wBACE,sCAIA,mBAEA,6BAKA,kCACA,CAHA,sBAEA,cAJA,eACA,MAIA,2FAIA,UACA,YACA,sBACE,8BAEA,CALF,aACA,WAIE,CACA,0BAEF,aACE,qBAEF,qCAgBA,kBACE,CAhBA,qDASA,qCAEJ,CAGI,YACF,CAJF,2BAGI,CAGA,eACE,CAAF,oBAEA,mEAEA,qBACA,eAGF,CAHE,cAIA,kBADF,kBACE,yBAEJ,oCAGI,qDAIA,+BAMF,oCAEA,+CAEA,gCAIA,YACE,yBAEA,qBACA,eAGA,uBAFA,WAEA,CAHA,cACA,CAEA,4BAIE,qCACA,cAFA,eADA,qBACA,cAEA,mDACE,CACA,oCACA,4EAEN,uCAMA,eACE,kDAIA,mBADF,sBACE,mBAIA,aACA,sCAGA,aADA,WACA,CAMA,UAFF,kBAEE,CAJJ,gBAEE,CAJE,iBAMA,yFAQA,aACA,eEpbJ,cACE,iBACA,YAEA,CAFA,iBAEA,+DAGA,mBAKA,gCAGA,CARA,SAIA,SACA,CALA,0EAIA,CAJA,OAQA,0CACE,UAGF,iDAGF,CAHE,UAGF,8CAEE,CAFF,UAEE,CACA,uCAEA,WACA,WAFA,UAEA,6CAIA,yCACA,WAGA,WAJA,UAIA,gDACE,aASF,0CACE,CAFF,mBAEE,wEACA,CATA,YACA,CAKF,kBACA,CALE,MAGJ,CAII,eACA,CAJF,iCALE,cACA,CAHA,oBACA,CAKJ,SAKI,2BADA,UACA,6BAEJ,WACE,0DACA,kBACE,gCACA,mBADA,YACA,oEACA,2CAMF,mDAII,CAJJ,aADF,cACE,kBAII,kEACA,iBACE,mEACA,6BACE,wBADF,cACE,mCACA,qDANN,kCACE,6BAEE,mBADF,0CACE,CAFF,eACA,MACE,0DACA,wCACE,sGACA,WANN,yBACE,uCACA,CAFF,UAEE,2CACE,0FACA,cACE,kEACA,mEANN,yBACE,4DACA,sBACE,+EAEE,iEACA,qEANN,sCACE,CAGE,iBAHF,gBAGE,qBACE,CAJJ,uBACA,gDACE,wDACA,6DAHF,2CACA,CADA,gBACA,eACE,CAGE,sBANN,8BACE,CAII,iBAFF,4DACA,WACE,YADF,uCACE,6EACA,2BANN,8CACE,kDACA,0CACE,8BACA,yFACE,sBACA,sFALJ,mEACA,sBACE,kEACA,6EACE,uCACA,kEALJ,qGAEE,kEACA,6EACE,uCACA,kEALJ,8CACA,uDACE,sEACA,2EACE,sCACA,iEALJ,mGACA,qCACE,oDACA,0DACE,6GACA,gDAGR,yDCrEA,sEACE,CACA,6GACE,gEACF,iGAIF,wFACE,qDAGA,mGAEE,2CAEF,4FACE,gCACF,wGACE,8DAEE,6FAIA,iJAKN,6GACE,gDAKF,yDACA,qCAGA,6BACA,kBACA,qDAKA,oCAEA,+DAGA,2CAGE,oDAIA,oEAEE,qBAGJ,wDAEE,uCAEF,kEAGA,8CAEA,uDAIF,gEAIE,6BACA,gEAIA,+CACE,0EAIF,sDAEE,+DAGF,sCACA,8BACE,oCAEJ,wBACE,4FAEE,gBAEJ,yGAGI,kBAGJ,CCnHE,2MCFF,oBAGE,wGAKA,iCACE,CADF,wBACE,8GAQA,mBCjBJ,2GAIE,mBACA,6HAMA,YACE,mIAYF,eACA,CAHF,YAGE,4FAGE,8BAKF,uBAkBE,sCACA,CADA,qBAbA,wCAIA,CALF,8BACE,CADF,gBAKE,wCACA,CAOA,kDACA,CACA,kCAKF,6BAGA,4CACE,kDACA,eAGF,cACE,aACA,iBACA,yBACA,8BACA,WAGJ,2BACE,cAGA,+BACA,CAHA,eAGA,wCACA,YACA,iBACA,uEAGA,0BACA,2CAEA,8EAGI,qBACA,CAFF,kBAEE,kBAGN,0CAGE,mCAGA,4BAIA,gEACE,qCACA,8BAEA,gBACA,+CACA,iCAEF,iCAEE,gEACA,qCAGF,8BAEE,+BAIA,yCAEE,qBADA,gBACA,yBAKF,eACA,CAFF,YACE,CACA,iBACA,qDAEA,mDCvIJ,2FAOE,iCACA,CAEA,eACA,CAHA,kBAEA,CAFA,wBAGA,8BACA,eACE,CAFF,YAEE,0BACA,8CAGA,oBACE,oCAGA,kBACE,8DAEA,iBAEN,UACE,8BAIJ,+CAEE,qDAEF,kDAIE,YAEF,CAFE,YAEF,CCpCE,mFADA,kBAKE,CAJF,IAGA,aACE,mCAGA,iDACE,+BAEJ,wBAEE,mBAMA,6CAEF,CAJE,mBAEA,CAEF,kCAGE,CARF,kBACE,CAHA,eAUA,YACA,mBACA,CADA,UACA,wCC9BF,oBDkCE,wBCnCJ,uCACE,+BACA,+DACA,sBAGA,qBCDA,6CAIE,CAPF,uBAGA,CDGE,oBACF,yDAEE,CCDE,2CAGF,CAJA,kCACE,CDJJ,YACE,CAIA,eCTF,CDKE,uBCMA,gCACE,YAEF,oCAEE,wBACA,0BAIF,iBAEA,cADF,UACE,uBAEA,iCAEA,wCAEA,6CAMA,CAYF,gCATI,4BASJ,CAZE,mCAEE,iCAUJ,4BAGE,4DADA,+BACA,CAHF,qBAGE,sCACE,OAEF,iBAHA,SAGA,iHACE,2DAKF,CANA,8EAMA,uSAEE,kBAEF,+FACE,yCCjEJ,WACA,yBAGA,uBACA,gBAEA,uCAIA,CAJA,iCAIA,uCAGA,UACE,gBACA,qBAEA,0CClBJ,gBACE,KAGF,qBACE,YAGF,CAHE,cAGF,gCAEE,mBACA,iEAEA,oCACA,wCAEA,sBACA,WAEA,CAFA,YAEA,8EAEA,mCAFA,iBAEA,6BAIA,wEAKA,sDAIE,CARF,mDAIA,CAIE,cAEF,8CAIA,oBAFE,iBAEF,8CAGE,eAEF,CAFE,YAEF,OAEE,kBAGJ,CAJI,eACA,CAFF,mBAKF,yCCjDE,oBACA,CAFA,iBAEA,uCAKE,iBACA,qCAGA,mBCZJ,CDWI,gBCXJ,6BAEE,eACA,sBAGA,eAEA,sBACA,oDACA,iGAMA,gBAFE,YAEF,8FAME,iJClBF,YACA,gNAUE,6BAEF,oTAcI,kBACF,gHAIA,qBACE,eACF,qDACE,kBACF,6DACE,4BCxCJ,oBAEF,qCAEI,+CAGF,uBACE,uDAGJ,oBAiBI,kDACF,CAhBA,+CAaA,CAbA,oBAaA,0FAEE,CAFF,gGAdA,cACA,iBAaA,0BAGA,mQAIA,oNAEE,iBAGJ,CAHI,gBAFF,gBAKF,8CAYI,CAZJ,wCAYI,sVACE,iCAGA,uEAHA,QAGA,qXAKJ,iDAGF,CARM,+CACE,iDAIN,CALI,gBAQN,mHACE,gBAGF,2DACE,0EAOA,0EAGF,gBAEE,6DC/EA,kDACA,gCACA,qDAGA,qBACA,qDCFA,cACA,eAEA,yBAGF,sBAEE,iBACA,sNAWA,iBACE,kBACA,wRAgBA,kBAEA,iOAgBA,uCACE,uEAEA,kBAEF,qUAuBE,iDAIJ,CACA,geCxFF,4BAEE,CAQA,6JACA,iDAIA,sEAGA,mDAOF,iDAGE,4DAIA,8CACA,qDAEE,eAFF,cAEE,oBAEF,uBAFE,kCAGA,eACA,iBACA,mBAIA,mDACA,CAHA,uCAEA,CAJA,0CACA,CAIA,gBAJA,gBACA,oBADA,gBAIA,wBAEJ,gBAGE,6BACA,YAHA,iBAGA,gCACA,iEAEA,6CACA,sDACA,0BADA,wBACA,0BACA,oIAIA,mBAFA,YAEA,qBACA,0CAIE,uBAEF,CAHA,yBACE,CAEF,iDACE,mFAKJ,oCACE,CANE,aAKJ,CACE,qEAIA,YAFA,WAEA,CAHA,aACA,CAEA,gBACE,4BACA,sBADA,aACA,gCAMF,oCACA,yDACA,2CAEA,qBAGE,kBAEA,CACA,mCAIF,CARE,YACA,CAOF,iCAEE,CAPA,oBACA,CAQA,oBACE,uDAEJ,sDAGA,CAHA,cAGA,0BACE,oDAIA,oCACA,4BACA,sBAGA,cAEA,oFAGA,sBAEA,yDACE,CAIF,iBAJE,wBAIF,6CAHE,6CAKA,eACA,aACA,CADA,cACA,yCAGJ,kBACE,CAKA,iDAEA,CARF,aACE,4CAGA,kBAIA,wEAGA,wDAGA,kCAOA,iDAGA,CAPF,WAEE,sCAEA,CAJF,2CACE,CAMA,qCACA,+BARF,kBACE,qCAOA,iBAsBA,sBACE,CAvBF,WAKA,CACE,0DAIF,CALA,uDACE,CANF,sBAqBA,4CACA,CALA,gRAIA,YAEE,6CAEN,mCAEE,+CASA,6EAIA,4BChNA,SDmNA,qFCnNA,gDACA,sCAGA,qCACA,sDACA,CAKA,kDAGA,CARA,0CAQA,kBAGA,YACA,sBACA,iBAFA,gBADF,YACE,CAHA,SAKA,kBAEA,SAFA,iBAEA,uEAGA,CAEE,6CAFF,oCAgBI,CAdF,yBACE,qBACF,CAGF,oBACE,CAIF,WACE,CALA,2CAGA,uBACF,CACE,mFAGE,CALF,qBAEA,UAGE,gCAIF,sDAEA,CALE,oCAKF,yCC7CJ,oCACE,CD+CA,yXAQE,sCCrDJ,wCAGA,oCACE","sources":["webpack:///./node_modules/normalize.css/normalize.css","webpack:///./src/furo/assets/styles/base/_print.sass","webpack:///./src/furo/assets/styles/base/_screen-readers.sass","webpack:///./src/furo/assets/styles/base/_theme.sass","webpack:///./src/furo/assets/styles/variables/_fonts.scss","webpack:///./src/furo/assets/styles/variables/_spacing.scss","webpack:///./src/furo/assets/styles/variables/_icons.scss","webpack:///./src/furo/assets/styles/variables/_admonitions.scss","webpack:///./src/furo/assets/styles/variables/_colors.scss","webpack:///./src/furo/assets/styles/base/_typography.sass","webpack:///./src/furo/assets/styles/_scaffold.sass","webpack:///./src/furo/assets/styles/variables/_layout.scss","webpack:///./src/furo/assets/styles/content/_admonitions.sass","webpack:///./src/furo/assets/styles/content/_api.sass","webpack:///./src/furo/assets/styles/content/_blocks.sass","webpack:///./src/furo/assets/styles/content/_captions.sass","webpack:///./src/furo/assets/styles/content/_code.sass","webpack:///./src/furo/assets/styles/content/_footnotes.sass","webpack:///./src/furo/assets/styles/content/_images.sass","webpack:///./src/furo/assets/styles/content/_indexes.sass","webpack:///./src/furo/assets/styles/content/_lists.sass","webpack:///./src/furo/assets/styles/content/_math.sass","webpack:///./src/furo/assets/styles/content/_misc.sass","webpack:///./src/furo/assets/styles/content/_rubrics.sass","webpack:///./src/furo/assets/styles/content/_sidebar.sass","webpack:///./src/furo/assets/styles/content/_tables.sass","webpack:///./src/furo/assets/styles/content/_target.sass","webpack:///./src/furo/assets/styles/content/_gui-labels.sass","webpack:///./src/furo/assets/styles/components/_footer.sass","webpack:///./src/furo/assets/styles/components/_sidebar.sass","webpack:///./src/furo/assets/styles/components/_table_of_contents.sass","webpack:///./src/furo/assets/styles/_shame.sass"],"sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","// This file contains styles for managing print media.\n\n////////////////////////////////////////////////////////////////////////////////\n// Hide elements not relevant to print media.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Hide icon container.\n .content-icon-container\n display: none !important\n\n // Hide showing header links if hovering over when printing.\n .headerlink\n display: none !important\n\n // Hide mobile header.\n .mobile-header\n display: none !important\n\n // Hide navigation links.\n .related-pages\n display: none !important\n\n////////////////////////////////////////////////////////////////////////////////\n// Tweaks related to decolorization.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Apply a border around code which no longer have a color background.\n .highlight\n border: 0.1pt solid var(--color-foreground-border)\n\n////////////////////////////////////////////////////////////////////////////////\n// Avoid page break in some relevant cases.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n ul, ol, dl, a, table, pre, blockquote\n page-break-inside: avoid\n\n h1, h2, h3, h4, h5, h6, img, figure, caption\n page-break-inside: avoid\n page-break-after: avoid\n\n ul, ol, dl\n page-break-before: avoid\n",".visually-hidden\n position: absolute !important\n width: 1px !important\n height: 1px !important\n padding: 0 !important\n margin: -1px !important\n overflow: hidden !important\n clip: rect(0,0,0,0) !important\n white-space: nowrap !important\n border: 0 !important\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n:-moz-focusring\n outline: auto\n","// This file serves as the \"skeleton\" of the theming logic.\n//\n// This contains the bulk of the logic for handling dark mode, color scheme\n// toggling and the handling of color-scheme-specific hiding of elements.\n\nbody\n @include fonts\n @include spacing\n @include icons\n @include admonitions\n @include default-admonition(#651fff, \"abstract\")\n @include default-topic(#14B8A6, \"pencil\")\n\n @include colors\n\n.only-light\n display: block !important\nhtml body .only-dark\n display: none !important\n\n// Ignore dark-mode hints if print media.\n@media not print\n // Enable dark-mode, if requested.\n body[data-theme=\"dark\"]\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n // Enable dark mode, unless explicitly told to avoid.\n @media (prefers-color-scheme: dark)\n body:not([data-theme=\"light\"])\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n//\n// Theme toggle presentation\n//\nbody[data-theme=\"auto\"]\n .theme-toggle svg.theme-icon-when-auto-light\n display: block\n\n @media (prefers-color-scheme: dark)\n .theme-toggle svg.theme-icon-when-auto-dark\n display: block\n .theme-toggle svg.theme-icon-when-auto-light\n display: none\n\nbody[data-theme=\"dark\"]\n .theme-toggle svg.theme-icon-when-dark\n display: block\n\nbody[data-theme=\"light\"]\n .theme-toggle svg.theme-icon-when-light\n display: block\n","// Fonts used by this theme.\n//\n// There are basically two things here -- using the system font stack and\n// defining sizes for various elements in %ages. We could have also used `em`\n// but %age is easier to reason about for me.\n\n@mixin fonts {\n // These are adapted from https://systemfontstack.com/\n --font-stack: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,\n sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --font-stack--monospace: \"SFMono-Regular\", Menlo, Consolas, Monaco,\n Liberation Mono, Lucida Console, monospace;\n --font-stack--headings: var(--font-stack);\n\n --font-size--normal: 100%;\n --font-size--small: 87.5%;\n --font-size--small--2: 81.25%;\n --font-size--small--3: 75%;\n --font-size--small--4: 62.5%;\n\n // Sidebar\n --sidebar-caption-font-size: var(--font-size--small--2);\n --sidebar-item-font-size: var(--font-size--small);\n --sidebar-search-input-font-size: var(--font-size--small);\n\n // Table of Contents\n --toc-font-size: var(--font-size--small--3);\n --toc-font-size--mobile: var(--font-size--normal);\n --toc-title-font-size: var(--font-size--small--4);\n\n // Admonitions\n //\n // These aren't defined in terms of %ages, since nesting these is permitted.\n --admonition-font-size: 0.8125rem;\n --admonition-title-font-size: 0.8125rem;\n\n // Code\n --code-font-size: var(--font-size--small--2);\n\n // API\n --api-font-size: var(--font-size--small);\n}\n","// Spacing for various elements on the page\n//\n// If the user wants to tweak things in a certain way, they are permitted to.\n// They also have to deal with the consequences though!\n\n@mixin spacing {\n // Header!\n --header-height: calc(\n var(--sidebar-item-line-height) + 4 * #{var(--sidebar-item-spacing-vertical)}\n );\n --header-padding: 0.5rem;\n\n // Sidebar\n --sidebar-tree-space-above: 1.5rem;\n --sidebar-caption-space-above: 1rem;\n\n --sidebar-item-line-height: 1rem;\n --sidebar-item-spacing-vertical: 0.5rem;\n --sidebar-item-spacing-horizontal: 1rem;\n --sidebar-item-height: calc(\n var(--sidebar-item-line-height) + 2 *#{var(--sidebar-item-spacing-vertical)}\n );\n\n --sidebar-expander-width: var(--sidebar-item-height); // be square\n\n --sidebar-search-space-above: 0.5rem;\n --sidebar-search-input-spacing-vertical: 0.5rem;\n --sidebar-search-input-spacing-horizontal: 0.5rem;\n --sidebar-search-input-height: 1rem;\n --sidebar-search-icon-size: var(--sidebar-search-input-height);\n\n // Table of Contents\n --toc-title-padding: 0.25rem 0;\n --toc-spacing-vertical: 1.5rem;\n --toc-spacing-horizontal: 1.5rem;\n --toc-item-spacing-vertical: 0.4rem;\n --toc-item-spacing-horizontal: 1rem;\n}\n","// Expose theme icons as CSS variables.\n\n$icons: (\n // Adapted from tabler-icons\n // url: https://tablericons.com/\n \"search\":\n url('data:image/svg+xml;charset=utf-8, '),\n // Factored out from mkdocs-material on 24-Aug-2020.\n // url: https://squidfunk.github.io/mkdocs-material/reference/admonitions/\n \"pencil\":\n url('data:image/svg+xml;charset=utf-8, '),\n \"abstract\":\n url('data:image/svg+xml;charset=utf-8, '),\n \"info\":\n url('data:image/svg+xml;charset=utf-8, '),\n \"flame\":\n url('data:image/svg+xml;charset=utf-8, '),\n \"question\":\n url('data:image/svg+xml;charset=utf-8, '),\n \"warning\":\n url('data:image/svg+xml;charset=utf-8, '),\n \"failure\":\n url('data:image/svg+xml;charset=utf-8, '),\n \"spark\":\n url('data:image/svg+xml;charset=utf-8, ')\n);\n\n@mixin icons {\n @each $name, $glyph in $icons {\n --icon-#{$name}: #{$glyph};\n }\n}\n","// Admonitions\n\n// Structure of these is:\n// admonition-class: color \"icon-name\";\n//\n// The colors are translated into CSS variables below. The icons are\n// used directly in the main declarations to set the `mask-image` in\n// the title.\n\n// prettier-ignore\n$admonitions: (\n // Each of these has an reST directives for it.\n \"caution\": #ff9100 \"spark\",\n \"warning\": #ff9100 \"warning\",\n \"danger\": #ff5252 \"spark\",\n \"attention\": #ff5252 \"warning\",\n \"error\": #ff5252 \"failure\",\n \"hint\": #00c852 \"question\",\n \"tip\": #00c852 \"info\",\n \"important\": #00bfa5 \"flame\",\n \"note\": #00b0ff \"pencil\",\n \"seealso\": #448aff \"info\",\n \"admonition-todo\": #808080 \"pencil\"\n);\n\n@mixin default-admonition($color, $icon-name) {\n --color-admonition-title: #{$color};\n --color-admonition-title-background: #{rgba($color, 0.2)};\n\n --icon-admonition-default: var(--icon-#{$icon-name});\n}\n\n@mixin default-topic($color, $icon-name) {\n --color-topic-title: #{$color};\n --color-topic-title-background: #{rgba($color, 0.2)};\n\n --icon-topic-default: var(--icon-#{$icon-name});\n}\n\n@mixin admonitions {\n @each $name, $values in $admonitions {\n --color-admonition-title--#{$name}: #{nth($values, 1)};\n --color-admonition-title-background--#{$name}: #{rgba(\n nth($values, 1),\n 0.2\n )};\n }\n}\n","// Colors used throughout this theme.\n//\n// The aim is to give the user more control. Thus, instead of hard-coding colors\n// in various parts of the stylesheet, the approach taken is to define all\n// colors as CSS variables and reusing them in all the places.\n//\n// `colors-dark` depends on `colors` being included at a lower specificity.\n\n@mixin colors {\n --color-problematic: #b30000;\n\n // Base Colors\n --color-foreground-primary: black; // for main text and headings\n --color-foreground-secondary: #5a5c63; // for secondary text\n --color-foreground-muted: #6b6f76; // for muted text\n --color-foreground-border: #878787; // for content borders\n\n --color-background-primary: white; // for content\n --color-background-secondary: #f8f9fb; // for navigation + ToC\n --color-background-hover: #efeff4ff; // for navigation-item hover\n --color-background-hover--transparent: #efeff400;\n --color-background-border: #eeebee; // for UI borders\n --color-background-item: #ccc; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #0a4bff;\n --color-brand-content: #2757dd;\n --color-brand-visited: #872ee0;\n\n // API documentation\n --color-api-background: var(--color-background-hover--transparent);\n --color-api-background-hover: var(--color-background-hover);\n --color-api-overall: var(--color-foreground-secondary);\n --color-api-name: var(--color-problematic);\n --color-api-pre-name: var(--color-problematic);\n --color-api-paren: var(--color-foreground-secondary);\n --color-api-keyword: var(--color-foreground-primary);\n\n --color-api-added: #21632c;\n --color-api-added-border: #38a84d;\n --color-api-changed: #046172;\n --color-api-changed-border: #06a1bc;\n --color-api-deprecated: #605706;\n --color-api-deprecated-border: #f0d90f;\n --color-api-removed: #b30000;\n --color-api-removed-border: #ff5c5c;\n\n --color-highlight-on-target: #ffffcc;\n\n // Inline code background\n --color-inline-code-background: var(--color-background-secondary);\n\n // Highlighted text (search)\n --color-highlighted-background: #ddeeff;\n --color-highlighted-text: var(--color-foreground-primary);\n\n // GUI Labels\n --color-guilabel-background: #ddeeff80;\n --color-guilabel-border: #bedaf580;\n --color-guilabel-text: var(--color-foreground-primary);\n\n // Admonitions!\n --color-admonition-background: transparent;\n\n //////////////////////////////////////////////////////////////////////////////\n // Everything below this should be one of:\n // - var(...)\n // - *-gradient(...)\n // - special literal values (eg: transparent, none)\n //////////////////////////////////////////////////////////////////////////////\n\n // Tables\n --color-table-header-background: var(--color-background-secondary);\n --color-table-border: var(--color-background-border);\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: transparent;\n --color-card-marginals-background: var(--color-background-secondary);\n\n // Header\n --color-header-background: var(--color-background-primary);\n --color-header-border: var(--color-background-border);\n --color-header-text: var(--color-foreground-primary);\n\n // Sidebar (left)\n --color-sidebar-background: var(--color-background-secondary);\n --color-sidebar-background-border: var(--color-background-border);\n\n --color-sidebar-brand-text: var(--color-foreground-primary);\n --color-sidebar-caption-text: var(--color-foreground-muted);\n --color-sidebar-link-text: var(--color-foreground-secondary);\n --color-sidebar-link-text--top-level: var(--color-brand-primary);\n\n --color-sidebar-item-background: var(--color-sidebar-background);\n --color-sidebar-item-background--current: var(\n --color-sidebar-item-background\n );\n --color-sidebar-item-background--hover: linear-gradient(\n 90deg,\n var(--color-background-hover--transparent) 0%,\n var(--color-background-hover) var(--sidebar-item-spacing-horizontal),\n var(--color-background-hover) 100%\n );\n\n --color-sidebar-item-expander-background: transparent;\n --color-sidebar-item-expander-background--hover: var(\n --color-background-hover\n );\n\n --color-sidebar-search-text: var(--color-foreground-primary);\n --color-sidebar-search-background: var(--color-background-secondary);\n --color-sidebar-search-background--focus: var(--color-background-primary);\n --color-sidebar-search-border: var(--color-background-border);\n --color-sidebar-search-icon: var(--color-foreground-muted);\n\n // Table of Contents (right)\n --color-toc-background: var(--color-background-primary);\n --color-toc-title-text: var(--color-foreground-muted);\n --color-toc-item-text: var(--color-foreground-secondary);\n --color-toc-item-text--hover: var(--color-foreground-primary);\n --color-toc-item-text--active: var(--color-brand-primary);\n\n // Actual page contents\n --color-content-foreground: var(--color-foreground-primary);\n --color-content-background: transparent;\n\n // Links\n --color-link: var(--color-brand-content);\n --color-link-underline: var(--color-background-border);\n --color-link--hover: var(--color-brand-content);\n --color-link-underline--hover: var(--color-foreground-border);\n\n --color-link--visited: var(--color-brand-visited);\n --color-link-underline--visited: var(--color-background-border);\n --color-link--visited--hover: var(--color-brand-visited);\n --color-link-underline--visited--hover: var(--color-foreground-border);\n}\n\n@mixin colors-dark {\n --color-problematic: #ee5151;\n\n // Base Colors\n --color-foreground-primary: #cfd0d0; // for main text and headings\n --color-foreground-secondary: #9ca0a5; // for secondary text\n --color-foreground-muted: #81868d; // for muted text\n --color-foreground-border: #666666; // for content borders\n\n --color-background-primary: #131416; // for content\n --color-background-secondary: #1a1c1e; // for navigation + ToC\n --color-background-hover: #1e2124ff; // for navigation-item hover\n --color-background-hover--transparent: #1e212400;\n --color-background-border: #303335; // for UI borders\n --color-background-item: #444; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #3d94ff;\n --color-brand-content: #5ca5ff;\n --color-brand-visited: #b27aeb;\n\n // Highlighted text (search)\n --color-highlighted-background: #083563;\n\n // GUI Labels\n --color-guilabel-background: #08356380;\n --color-guilabel-border: #13395f80;\n\n // API documentation\n --color-api-keyword: var(--color-foreground-secondary);\n --color-highlight-on-target: #333300;\n\n --color-api-added: #3db854;\n --color-api-added-border: #267334;\n --color-api-changed: #09b0ce;\n --color-api-changed-border: #056d80;\n --color-api-deprecated: #b1a10b;\n --color-api-deprecated-border: #6e6407;\n --color-api-removed: #ff7575;\n --color-api-removed-border: #b03b3b;\n\n // Admonitions\n --color-admonition-background: #18181a;\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: #18181a;\n --color-card-marginals-background: var(--color-background-hover);\n}\n","// This file contains the styling for making the content throughout the page,\n// including fonts, paragraphs, headings and spacing among these elements.\n\nbody\n font-family: var(--font-stack)\npre,\ncode,\nkbd,\nsamp\n font-family: var(--font-stack--monospace)\n\n// Make fonts look slightly nicer.\nbody\n -webkit-font-smoothing: antialiased\n -moz-osx-font-smoothing: grayscale\n\n// Line height from Bootstrap 4.1\narticle\n line-height: 1.5\n\n//\n// Headings\n//\nh1,\nh2,\nh3,\nh4,\nh5,\nh6\n line-height: 1.25\n font-family: var(--font-stack--headings)\n font-weight: bold\n\n border-radius: 0.5rem\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n margin-left: -0.5rem\n margin-right: -0.5rem\n padding-left: 0.5rem\n padding-right: 0.5rem\n\n + p\n margin-top: 0\n\nh1\n font-size: 2.5em\n margin-top: 1.75rem\n margin-bottom: 1rem\nh2\n font-size: 2em\n margin-top: 1.75rem\nh3\n font-size: 1.5em\nh4\n font-size: 1.25em\nh5\n font-size: 1.125em\nh6\n font-size: 1em\n\nsmall\n opacity: 75%\n font-size: 80%\n\n// Paragraph\np\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n\n// Horizontal rules\nhr.docutils\n height: 1px\n padding: 0\n margin: 2rem 0\n background-color: var(--color-background-border)\n border: 0\n\n.centered\n text-align: center\n\n// Links\na\n text-decoration: underline\n\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n &:visited\n color: var(--color-link--visited)\n text-decoration-color: var(--color-link-underline--visited)\n &:hover\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &.muted-link\n color: inherit\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &:visited\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n","// This file contains the styles for the overall layouting of the documentation\n// skeleton, including the responsive changes as well as sidebar toggles.\n//\n// This is implemented as a mobile-last design, which isn't ideal, but it is\n// reasonably good-enough and I got pretty tired by the time I'd finished this\n// to move the rules around to fix this. Shouldn't take more than 3-4 hours,\n// if you know what you're doing tho.\n\n// HACK: Not all browsers account for the scrollbar width in media queries.\n// This results in horizontal scrollbars in the breakpoint where we go\n// from displaying everything to hiding the ToC. We accomodate for this by\n// adding a bit of padding to the TOC drawer, disabling the horizontal\n// scrollbar and allowing the scrollbars to cover the padding.\n// https://www.456bereastreet.com/archive/201301/media_query_width_and_vertical_scrollbars/\n\n// HACK: Always having the scrollbar visible, prevents certain browsers from\n// causing the content to stutter horizontally between taller-than-viewport and\n// not-taller-than-viewport pages.\n\n$icon-size: 1.25rem\n\nhtml\n overflow-x: hidden\n overflow-y: scroll\n scroll-behavior: smooth\n\n.sidebar-scroll, .toc-scroll, article[role=main] *\n // Override Firefox scrollbar style\n scrollbar-width: thin\n scrollbar-color: var(--color-foreground-border) transparent\n\n // Override Chrome scrollbar styles\n &::-webkit-scrollbar\n width: 0.25rem\n height: 0.25rem\n &::-webkit-scrollbar-thumb\n background-color: var(--color-foreground-border)\n border-radius: 0.125rem\n\n//\n// Overalls\n//\nhtml,\nbody\n height: 100%\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n.skip-to-content\n position: fixed\n padding: 1rem\n border-radius: 1rem\n left: 0.25rem\n top: 0.25rem\n z-index: 40\n background: var(--color-background-primary)\n color: var(--color-foreground-primary)\n\n transform: translateY(-200%)\n transition: transform 300ms ease-in-out\n\n &:focus-within\n transform: translateY(0%)\n\narticle\n color: var(--color-content-foreground)\n background: var(--color-content-background)\n overflow-wrap: break-word\n\n.page\n display: flex\n // fill the viewport for pages with little content.\n min-height: 100%\n\n.mobile-header\n width: 100%\n height: var(--header-height)\n background-color: var(--color-header-background)\n color: var(--color-header-text)\n border-bottom: 1px solid var(--color-header-border)\n\n // Looks like sub-script/super-script have this, and we need this to\n // be \"on top\" of those.\n z-index: 10\n\n // We don't show the header on large screens.\n display: none\n\n // Add shadow when scrolled\n &.scrolled\n border-bottom: none\n box-shadow: 0 0 0.2rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.4rem rgba(0, 0, 0, 0.2)\n\n .header-center\n a\n color: var(--color-header-text)\n text-decoration: none\n\n.main\n display: flex\n flex: 1\n\n// Sidebar (left) also covers the entire left portion of screen.\n.sidebar-drawer\n box-sizing: border-box\n\n border-right: 1px solid var(--color-sidebar-background-border)\n background: var(--color-sidebar-background)\n\n display: flex\n justify-content: flex-end\n // These next two lines took me two days to figure out.\n width: calc((100% - #{$full-width}) / 2 + #{$sidebar-width})\n min-width: $sidebar-width\n\n// Scroll-along sidebars\n.sidebar-container,\n.toc-drawer\n box-sizing: border-box\n width: $sidebar-width\n\n.toc-drawer\n background: var(--color-toc-background)\n // See HACK described on top of this document\n padding-right: 1rem\n\n.sidebar-sticky,\n.toc-sticky\n position: sticky\n top: 0\n height: min(100%, 100vh)\n height: 100vh\n\n display: flex\n flex-direction: column\n\n.sidebar-scroll,\n.toc-scroll\n flex-grow: 1\n flex-shrink: 1\n\n overflow: auto\n scroll-behavior: smooth\n\n// Central items.\n.content\n padding: 0 $content-padding\n width: $content-width\n\n display: flex\n flex-direction: column\n justify-content: space-between\n\n.icon\n display: inline-block\n height: 1rem\n width: 1rem\n svg\n width: 100%\n height: 100%\n\n//\n// Accommodate announcement banner\n//\n.announcement\n background-color: var(--color-announcement-background)\n color: var(--color-announcement-text)\n\n height: var(--header-height)\n display: flex\n align-items: center\n overflow-x: auto\n & + .page\n min-height: calc(100% - var(--header-height))\n\n.announcement-content\n box-sizing: border-box\n padding: 0.5rem\n min-width: 100%\n white-space: nowrap\n text-align: center\n\n a\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-announcement-text)\n\n &:hover\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-link--hover)\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for theme\n////////////////////////////////////////////////////////////////////////////////\n.no-js .theme-toggle-container // don't show theme toggle if there's no JS\n display: none\n\n.theme-toggle-container\n vertical-align: middle\n\n.theme-toggle\n cursor: pointer\n border: none\n padding: 0\n background: transparent\n\n.theme-toggle svg\n vertical-align: middle\n height: $icon-size\n width: $icon-size\n color: var(--color-foreground-primary)\n display: none\n\n.theme-toggle-header\n float: left\n padding: 1rem 0.5rem\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for elements\n////////////////////////////////////////////////////////////////////////////////\n.toc-overlay-icon, .nav-overlay-icon\n display: none\n cursor: pointer\n\n .icon\n color: var(--color-foreground-secondary)\n height: $icon-size\n width: $icon-size\n\n.toc-header-icon, .nav-overlay-icon\n // for when we set display: flex\n justify-content: center\n align-items: center\n\n.toc-content-icon\n height: 1.5rem\n width: 1.5rem\n\n.content-icon-container\n float: right\n display: flex\n margin-top: 1.5rem\n margin-left: 1rem\n margin-bottom: 1rem\n gap: 0.5rem\n\n .edit-this-page, .view-this-page\n svg\n color: inherit\n height: $icon-size\n width: $icon-size\n\n.sidebar-toggle\n position: absolute\n display: none\n// \n.sidebar-toggle[name=\"__toc\"]\n left: 20px\n.sidebar-toggle:checked\n left: 40px\n// \n\n.overlay\n position: fixed\n top: 0\n width: 0\n height: 0\n\n transition: width 0ms, height 0ms, opacity 250ms ease-out\n\n opacity: 0\n background-color: rgba(0, 0, 0, 0.54)\n.sidebar-overlay\n z-index: 20\n.toc-overlay\n z-index: 40\n\n// Keep things on top and smooth.\n.sidebar-drawer\n z-index: 30\n transition: left 250ms ease-in-out\n.toc-drawer\n z-index: 50\n transition: right 250ms ease-in-out\n\n// Show the Sidebar\n#__navigation:checked\n & ~ .sidebar-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .sidebar-drawer\n top: 0\n left: 0\n // Show the toc sidebar\n#__toc:checked\n & ~ .toc-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .toc-drawer\n top: 0\n right: 0\n\n////////////////////////////////////////////////////////////////////////////////\n// Back to top\n////////////////////////////////////////////////////////////////////////////////\n.back-to-top\n text-decoration: none\n\n display: none\n position: fixed\n left: 0\n top: 1rem\n padding: 0.5rem\n padding-right: 0.75rem\n border-radius: 1rem\n font-size: 0.8125rem\n\n background: var(--color-background-primary)\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), #6b728080 0px 0px 1px 0px\n\n z-index: 10\n\n margin-left: 50%\n transform: translateX(-50%)\n svg\n height: 1rem\n width: 1rem\n fill: currentColor\n display: inline-block\n\n span\n margin-left: 0.25rem\n\n .show-back-to-top &\n display: flex\n align-items: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Responsive layouting\n////////////////////////////////////////////////////////////////////////////////\n// Make things a bit bigger on bigger screens.\n@media (min-width: $full-width + $sidebar-width)\n html\n font-size: 110%\n\n@media (max-width: $full-width)\n // Collapse \"toc\" into the icon.\n .toc-content-icon\n display: flex\n .toc-drawer\n position: fixed\n height: 100vh\n top: 0\n right: -$sidebar-width\n border-left: 1px solid var(--color-background-muted)\n .toc-tree\n border-left: none\n font-size: var(--toc-font-size--mobile)\n\n // Accomodate for a changed content width.\n .sidebar-drawer\n width: calc((100% - #{$full-width - $sidebar-width}) / 2 + #{$sidebar-width})\n\n@media (max-width: $full-width - $sidebar-width)\n // Collapse \"navigation\".\n .nav-overlay-icon\n display: flex\n .sidebar-drawer\n position: fixed\n height: 100vh\n width: $sidebar-width\n\n top: 0\n left: -$sidebar-width\n\n // Swap which icon is visible.\n .toc-header-icon\n display: flex\n .toc-content-icon, .theme-toggle-content\n display: none\n .theme-toggle-header\n display: block\n\n // Show the header.\n .mobile-header\n position: sticky\n top: 0\n display: flex\n justify-content: space-between\n align-items: center\n\n .header-left,\n .header-right\n display: flex\n height: var(--header-height)\n padding: 0 var(--header-padding)\n label\n height: 100%\n width: 100%\n user-select: none\n\n .nav-overlay-icon .icon,\n .theme-toggle svg\n height: $icon-size\n width: $icon-size\n\n // Add a scroll margin for the content\n :target\n scroll-margin-top: calc(var(--header-height) + 2.5rem)\n\n // Show back-to-top below the header\n .back-to-top\n top: calc(var(--header-height) + 0.5rem)\n\n // Center the page, and accommodate for the header.\n .page\n flex-direction: column\n justify-content: center\n .content\n margin-left: auto\n margin-right: auto\n\n@media (max-width: $content-width + 2* $content-padding)\n // Content should respect window limits.\n .content\n width: 100%\n overflow-x: auto\n\n@media (max-width: $content-width)\n .content\n padding: 0 $content-padding--small\n // Don't float sidebars to the right.\n article aside.sidebar\n float: none\n width: 100%\n margin: 1rem 0\n","// Overall Layout Variables\n//\n// Because CSS variables can't be used in media queries. The fact that this\n// makes the layout non-user-configurable is a good thing.\n$content-padding: 3em;\n$content-padding--small: 1em;\n$content-width: 46em;\n$sidebar-width: 15em;\n$full-width: $content-width + 2 * ($content-padding + $sidebar-width);\n","//\n// The design here is strongly inspired by mkdocs-material.\n.admonition, .topic\n margin: 1rem auto\n padding: 0 0.5rem 0.5rem 0.5rem\n\n background: var(--color-admonition-background)\n\n border-radius: 0.2rem\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n font-size: var(--admonition-font-size)\n\n overflow: hidden\n page-break-inside: avoid\n\n // First element should have no margin, since the title has it.\n > :nth-child(2)\n margin-top: 0\n\n // Last item should have no margin, since we'll control that w/ padding\n > :last-child\n margin-bottom: 0\n\n.admonition p.admonition-title,\np.topic-title\n position: relative\n margin: 0 -0.5rem 0.5rem\n padding-left: 2rem\n padding-right: .5rem\n padding-top: .4rem\n padding-bottom: .4rem\n\n font-weight: 500\n font-size: var(--admonition-title-font-size)\n line-height: 1.3\n\n // Our fancy icon\n &::before\n content: \"\"\n position: absolute\n left: 0.5rem\n width: 1rem\n height: 1rem\n\n// Default styles\np.admonition-title\n background-color: var(--color-admonition-title-background)\n &::before\n background-color: var(--color-admonition-title)\n mask-image: var(--icon-admonition-default)\n mask-repeat: no-repeat\n\np.topic-title\n background-color: var(--color-topic-title-background)\n &::before\n background-color: var(--color-topic-title)\n mask-image: var(--icon-topic-default)\n mask-repeat: no-repeat\n\n//\n// Variants\n//\n.admonition\n border-left: 0.2rem solid var(--color-admonition-title)\n\n @each $type, $value in $admonitions\n &.#{$type}\n border-left-color: var(--color-admonition-title--#{$type})\n > .admonition-title\n background-color: var(--color-admonition-title-background--#{$type})\n &::before\n background-color: var(--color-admonition-title--#{$type})\n mask-image: var(--icon-#{nth($value, 2)})\n\n.admonition-todo > .admonition-title\n text-transform: uppercase\n","// This file stylizes the API documentation (stuff generated by autodoc). It's\n// deeply nested due to how autodoc structures the HTML without enough classes\n// to select the relevant items.\n\n// API docs!\ndl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)\n // Tweak the spacing of all the things!\n dd\n margin-left: 2rem\n > :first-child\n margin-top: 0.125rem\n > :last-child\n margin-bottom: 0.75rem\n\n // This is used for the arguments\n .field-list\n margin-bottom: 0.75rem\n\n // \"Headings\" (like \"Parameters\" and \"Return\")\n > dt\n text-transform: uppercase\n font-size: var(--font-size--small)\n\n dd:empty\n margin-bottom: 0.5rem\n dd > ul\n margin-left: -1.2rem\n > li\n > p:nth-child(2)\n margin-top: 0\n // When the last-empty-paragraph follows a paragraph, it doesn't need\n // to augument the existing spacing.\n > p + p:last-child:empty\n margin-top: 0\n margin-bottom: 0\n\n // Colorize the elements\n > dt\n color: var(--color-api-overall)\n\n.sig:not(.sig-inline)\n font-weight: bold\n\n font-size: var(--api-font-size)\n font-family: var(--font-stack--monospace)\n\n margin-left: -0.25rem\n margin-right: -0.25rem\n padding-top: 0.25rem\n padding-bottom: 0.25rem\n padding-right: 0.5rem\n\n // These are intentionally em, to properly match the font size.\n padding-left: 3em\n text-indent: -2.5em\n\n border-radius: 0.25rem\n\n background: var(--color-api-background)\n transition: background 100ms ease-out\n\n &:hover\n background: var(--color-api-background-hover)\n\n // adjust the size of the [source] link on the right.\n a.reference\n .viewcode-link\n font-weight: normal\n width: 4.25rem\n\nem.property\n font-style: normal\n &:first-child\n color: var(--color-api-keyword)\n.sig-name\n color: var(--color-api-name)\n.sig-prename\n font-weight: normal\n color: var(--color-api-pre-name)\n.sig-paren\n color: var(--color-api-paren)\n.sig-param\n font-style: normal\n\ndiv.versionadded,\ndiv.versionchanged,\ndiv.deprecated,\ndiv.versionremoved\n border-left: 0.1875rem solid\n border-radius: 0.125rem\n\n padding-left: 0.75rem\n\n p\n margin-top: 0.125rem\n margin-bottom: 0.125rem\n\ndiv.versionadded\n border-color: var(--color-api-added-border)\n .versionmodified\n color: var(--color-api-added)\n\ndiv.versionchanged\n border-color: var(--color-api-changed-border)\n .versionmodified\n color: var(--color-api-changed)\n\ndiv.deprecated\n border-color: var(--color-api-deprecated-border)\n .versionmodified\n color: var(--color-api-deprecated)\n\ndiv.versionremoved\n border-color: var(--color-api-removed-border)\n .versionmodified\n color: var(--color-api-removed)\n\n// Align the [docs] and [source] to the right.\n.viewcode-link, .viewcode-back\n float: right\n text-align: right\n",".line-block\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n .line-block\n margin-top: 0rem\n margin-bottom: 0rem\n padding-left: 1rem\n","// Captions\narticle p.caption,\ntable > caption,\n.code-block-caption\n font-size: var(--font-size--small)\n text-align: center\n\n// Caption above a TOCTree\n.toctree-wrapper.compound\n .caption, :not(.caption) > .caption-text\n font-size: var(--font-size--small)\n text-transform: uppercase\n\n text-align: initial\n margin-bottom: 0\n\n > ul\n margin-top: 0\n margin-bottom: 0\n","// Inline code\ncode.literal, .sig-inline\n background: var(--color-inline-code-background)\n border-radius: 0.2em\n // Make the font smaller, and use padding to recover.\n font-size: var(--font-size--small--2)\n padding: 0.1em 0.2em\n\n pre.literal-block &\n font-size: inherit\n padding: 0\n\n p &\n border: 1px solid var(--color-background-border)\n\n.sig-inline\n font-family: var(--font-stack--monospace)\n\n// Code and Literal Blocks\n$code-spacing-vertical: 0.625rem\n$code-spacing-horizontal: 0.875rem\n\n// Wraps every literal block + line numbers.\ndiv[class*=\" highlight-\"],\ndiv[class^=\"highlight-\"]\n margin: 1em 0\n display: flex\n\n .table-wrapper\n margin: 0\n padding: 0\n\npre\n margin: 0\n padding: 0\n overflow: auto\n\n // Needed to have more specificity than pygments' \"pre\" selector. :(\n article[role=\"main\"] .highlight &\n line-height: 1.5\n\n &.literal-block,\n .highlight &\n font-size: var(--code-font-size)\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n // Make it look like all the other blocks.\n &.literal-block\n margin-top: 1rem\n margin-bottom: 1rem\n\n border-radius: 0.2rem\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n\n// All code is always contained in this.\n.highlight\n width: 100%\n border-radius: 0.2rem\n\n // Make line numbers and prompts un-selectable.\n .gp, span.linenos\n user-select: none\n pointer-events: none\n\n // Expand the line-highlighting.\n .hll\n display: block\n margin-left: -$code-spacing-horizontal\n margin-right: -$code-spacing-horizontal\n padding-left: $code-spacing-horizontal\n padding-right: $code-spacing-horizontal\n\n/* Make code block captions be nicely integrated */\n.code-block-caption\n display: flex\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n border-radius: 0.25rem\n border-bottom-left-radius: 0\n border-bottom-right-radius: 0\n font-weight: 300\n border-bottom: 1px solid\n\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n border-color: var(--color-background-border)\n\n + div[class]\n margin-top: 0\n pre\n border-top-left-radius: 0\n border-top-right-radius: 0\n\n// When `html_codeblock_linenos_style` is table.\n.highlighttable\n width: 100%\n display: block\n tbody\n display: block\n\n tr\n display: flex\n\n // Line numbers\n td.linenos\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n padding: $code-spacing-vertical $code-spacing-horizontal\n padding-right: 0\n border-top-left-radius: 0.2rem\n border-bottom-left-radius: 0.2rem\n\n .linenodiv\n padding-right: $code-spacing-horizontal\n font-size: var(--code-font-size)\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n\n // Actual code\n td.code\n padding: 0\n display: block\n flex: 1\n overflow: hidden\n\n .highlight\n border-top-left-radius: 0\n border-bottom-left-radius: 0\n\n// When `html_codeblock_linenos_style` is inline.\n.highlight\n span.linenos\n display: inline-block\n padding-left: 0\n padding-right: $code-spacing-horizontal\n margin-right: $code-spacing-horizontal\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n","// Inline Footnote Reference\n.footnote-reference\n font-size: var(--font-size--small--4)\n vertical-align: super\n\n// Definition list, listing the content of each note.\n// docutils <= 0.17\ndl.footnote.brackets\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\n display: grid\n grid-template-columns: max-content auto\n dt\n margin: 0\n > .fn-backref\n margin-left: 0.25rem\n\n &:after\n content: \":\"\n\n .brackets\n &:before\n content: \"[\"\n &:after\n content: \"]\"\n\n dd\n margin: 0\n padding: 0 1rem\n\n// docutils >= 0.18\naside.footnote\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\naside.footnote > span,\ndiv.citation > span\n float: left\n font-weight: 500\n padding-right: 0.25rem\n\naside.footnote > *:not(span),\ndiv.citation > p\n margin-left: 2rem\n","//\n// Figures\n//\nimg\n box-sizing: border-box\n max-width: 100%\n height: auto\n\narticle\n figure, .figure\n border-radius: 0.2rem\n\n margin: 0\n :last-child\n margin-bottom: 0\n\n .align-left\n float: left\n clear: left\n margin: 0 1rem 1rem\n\n .align-right\n float: right\n clear: right\n margin: 0 1rem 1rem\n\n .align-default,\n .align-center\n display: block\n text-align: center\n margin-left: auto\n margin-right: auto\n\n // WELL, table needs to be stylised like a table.\n table.align-default\n display: table\n text-align: initial\n",".genindex-jumpbox, .domainindex-jumpbox\n border-top: 1px solid var(--color-background-border)\n border-bottom: 1px solid var(--color-background-border)\n padding: 0.25rem\n\n.genindex-section, .domainindex-section\n h2\n margin-top: 0.75rem\n margin-bottom: 0.5rem\n ul\n margin-top: 0\n margin-bottom: 0\n","ul,\nol\n padding-left: 1.2rem\n\n // Space lists out like paragraphs\n margin-top: 1rem\n margin-bottom: 1rem\n // reduce margins within li.\n li\n > p:first-child\n margin-top: 0.25rem\n margin-bottom: 0.25rem\n\n > p:last-child\n margin-top: 0.25rem\n\n > ul,\n > ol\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n\nol\n &.arabic\n list-style: decimal\n &.loweralpha\n list-style: lower-alpha\n &.upperalpha\n list-style: upper-alpha\n &.lowerroman\n list-style: lower-roman\n &.upperroman\n list-style: upper-roman\n\n// Don't space lists out when they're \"simple\" or in a `.. toctree::`\n.simple,\n.toctree-wrapper\n li\n > ul,\n > ol\n margin-top: 0\n margin-bottom: 0\n\n// Definition Lists\n.field-list,\n.option-list,\ndl:not([class]),\ndl.simple,\ndl.footnote,\ndl.glossary\n dt\n font-weight: 500\n margin-top: 0.25rem\n + dt\n margin-top: 0\n\n .classifier::before\n content: \":\"\n margin-left: 0.2rem\n margin-right: 0.2rem\n\n dd\n > p:first-child,\n ul\n margin-top: 0.125rem\n\n ul\n margin-bottom: 0.125rem\n",".math-wrapper\n width: 100%\n overflow-x: auto\n\ndiv.math\n position: relative\n text-align: center\n\n .headerlink,\n &:focus .headerlink\n display: none\n\n &:hover .headerlink\n display: inline-block\n\n span.eqno\n position: absolute\n right: 0.5rem\n top: 50%\n transform: translate(0, -50%)\n z-index: 1\n","// Abbreviations\nabbr[title]\n cursor: help\n\n// \"Problematic\" content, as identified by Sphinx\n.problematic\n color: var(--color-problematic)\n\n// Keyboard / Mouse \"instructions\"\nkbd:not(.compound)\n margin: 0 0.2rem\n padding: 0 0.2rem\n border-radius: 0.2rem\n border: 1px solid var(--color-foreground-border)\n color: var(--color-foreground-primary)\n vertical-align: text-bottom\n\n font-size: var(--font-size--small--3)\n display: inline-block\n\n box-shadow: 0 0.0625rem 0 rgba(0, 0, 0, 0.2), inset 0 0 0 0.125rem var(--color-background-primary)\n\n background-color: var(--color-background-secondary)\n\n// Blockquote\nblockquote\n border-left: 4px solid var(--color-background-border)\n background: var(--color-background-secondary)\n\n margin-left: 0\n margin-right: 0\n padding: 0.5rem 1rem\n\n .attribution\n font-weight: 600\n text-align: right\n\n &.pull-quote,\n &.highlights\n font-size: 1.25em\n\n &.epigraph,\n &.pull-quote\n border-left-width: 0\n border-radius: 0.5rem\n\n &.highlights\n border-left-width: 0\n background: transparent\n\n// Center align embedded-in-text images\np .reference img\n vertical-align: middle\n","p.rubric\n line-height: 1.25\n font-weight: bold\n font-size: 1.125em\n\n // For Numpy-style documentation that's got rubrics within it.\n // https://github.com/pradyunsg/furo/discussions/505\n dd &\n line-height: inherit\n font-weight: inherit\n\n font-size: var(--font-size--small)\n text-transform: uppercase\n","article .sidebar\n float: right\n clear: right\n width: 30%\n\n margin-left: 1rem\n margin-right: 0\n\n border-radius: 0.2rem\n background-color: var(--color-background-secondary)\n border: var(--color-background-border) 1px solid\n\n > *\n padding-left: 1rem\n padding-right: 1rem\n\n > ul, > ol // lists need additional padding, because bullets.\n padding-left: 2.2rem\n\n .sidebar-title\n margin: 0\n padding: 0.5rem 1rem\n border-bottom: var(--color-background-border) 1px solid\n\n font-weight: 500\n\n// TODO: subtitle\n// TODO: dedicated variables?\n",".table-wrapper\n width: 100%\n overflow-x: auto\n margin-top: 1rem\n margin-bottom: 0.5rem\n padding: 0.2rem 0.2rem 0.75rem\n\ntable.docutils\n border-radius: 0.2rem\n border-spacing: 0\n border-collapse: collapse\n\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n th\n background: var(--color-table-header-background)\n\n td,\n th\n // Space things out properly\n padding: 0 0.25rem\n\n // Get the borders looking just-right.\n border-left: 1px solid var(--color-table-border)\n border-right: 1px solid var(--color-table-border)\n border-bottom: 1px solid var(--color-table-border)\n\n p\n margin: 0.25rem\n\n &:first-child\n border-left: none\n &:last-child\n border-right: none\n\n // MyST-parser tables set these classes for control of column alignment\n &.text-left\n text-align: left\n &.text-right\n text-align: right\n &.text-center\n text-align: center\n",":target\n scroll-margin-top: 2.5rem\n\n@media (max-width: $full-width - $sidebar-width)\n :target\n scroll-margin-top: calc(2.5rem + var(--header-height))\n\n // When a heading is selected\n section > span:target\n scroll-margin-top: calc(2.8rem + var(--header-height))\n\n// Permalinks\n.headerlink\n font-weight: 100\n user-select: none\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\ndl dt,\np.caption,\nfigcaption p,\ntable > caption,\n.code-block-caption\n > .headerlink\n margin-left: 0.5rem\n visibility: hidden\n &:hover > .headerlink\n visibility: visible\n\n // Don't change to link-like, if someone adds the contents directive.\n > .toc-backref\n color: inherit\n text-decoration-line: none\n\n// Figure and table captions are special.\nfigure:hover > figcaption > p > .headerlink,\ntable:hover > caption > .headerlink\n visibility: visible\n\n:target >, // Regular section[id] style anchors\nspan:target ~ // Non-regular span[id] style \"extra\" anchors\n h1,\n h2,\n h3,\n h4,\n h5,\n h6\n &:nth-of-type(1)\n background-color: var(--color-highlight-on-target)\n // .headerlink\n // visibility: visible\n code.literal\n background-color: transparent\n\ntable:target > caption,\nfigure:target\n background-color: var(--color-highlight-on-target)\n\n// Inline page contents\n.this-will-duplicate-information-and-it-is-still-useful-here li :target\n background-color: var(--color-highlight-on-target)\n\n// Code block permalinks\n.literal-block-wrapper:target .code-block-caption\n background-color: var(--color-highlight-on-target)\n\n// When a definition list item is selected\n//\n// There isn't really an alternative to !important here, due to the\n// high-specificity of API documentation's selector.\ndt:target\n background-color: var(--color-highlight-on-target) !important\n\n// When a footnote reference is selected\n.footnote > dt:target + dd,\n.footnote-reference:target\n background-color: var(--color-highlight-on-target)\n",".guilabel\n background-color: var(--color-guilabel-background)\n border: 1px solid var(--color-guilabel-border)\n color: var(--color-guilabel-text)\n\n padding: 0 0.3em\n border-radius: 0.5em\n font-size: 0.9em\n","// This file contains the styles used for stylizing the footer that's shown\n// below the content.\n\nfooter\n font-size: var(--font-size--small)\n display: flex\n flex-direction: column\n\n margin-top: 2rem\n\n// Bottom of page information\n.bottom-of-page\n display: flex\n align-items: center\n justify-content: space-between\n\n margin-top: 1rem\n padding-top: 1rem\n padding-bottom: 1rem\n\n color: var(--color-foreground-secondary)\n border-top: 1px solid var(--color-background-border)\n\n line-height: 1.5\n\n @media (max-width: $content-width)\n text-align: center\n flex-direction: column-reverse\n gap: 0.25rem\n\n .left-details\n font-size: var(--font-size--small)\n\n .right-details\n display: flex\n flex-direction: column\n gap: 0.25rem\n text-align: right\n\n .icons\n display: flex\n justify-content: flex-end\n gap: 0.25rem\n font-size: 1rem\n\n a\n text-decoration: none\n\n svg,\n img\n font-size: 1.125rem\n height: 1em\n width: 1em\n\n// Next/Prev page information\n.related-pages\n a\n display: flex\n align-items: center\n\n text-decoration: none\n &:hover .page-info .title\n text-decoration: underline\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n svg.furo-related-icon,\n svg.furo-related-icon > use\n flex-shrink: 0\n\n color: var(--color-foreground-border)\n\n width: 0.75rem\n height: 0.75rem\n margin: 0 0.5rem\n\n &.next-page\n max-width: 50%\n\n float: right\n clear: right\n text-align: right\n\n &.prev-page\n max-width: 50%\n\n float: left\n clear: left\n\n svg\n transform: rotate(180deg)\n\n.page-info\n display: flex\n flex-direction: column\n overflow-wrap: anywhere\n\n .next-page &\n align-items: flex-end\n\n .context\n display: flex\n align-items: center\n\n padding-bottom: 0.1rem\n\n color: var(--color-foreground-muted)\n font-size: var(--font-size--small)\n text-decoration: none\n","// This file contains the styles for the contents of the left sidebar, which\n// contains the navigation tree, logo, search etc.\n\n////////////////////////////////////////////////////////////////////////////////\n// Brand on top of the scrollable tree.\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-brand\n display: flex\n flex-direction: column\n flex-shrink: 0\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n text-decoration: none\n\n.sidebar-brand-text\n color: var(--color-sidebar-brand-text)\n overflow-wrap: break-word\n margin: var(--sidebar-item-spacing-vertical) 0\n font-size: 1.5rem\n\n.sidebar-logo-container\n margin: var(--sidebar-item-spacing-vertical) 0\n\n.sidebar-logo\n margin: 0 auto\n display: block\n max-width: 100%\n\n////////////////////////////////////////////////////////////////////////////////\n// Search\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-search-container\n display: flex\n align-items: center\n margin-top: var(--sidebar-search-space-above)\n\n position: relative\n\n background: var(--color-sidebar-search-background)\n &:hover,\n &:focus-within\n background: var(--color-sidebar-search-background--focus)\n\n &::before\n content: \"\"\n position: absolute\n left: var(--sidebar-item-spacing-horizontal)\n width: var(--sidebar-search-icon-size)\n height: var(--sidebar-search-icon-size)\n\n background-color: var(--color-sidebar-search-icon)\n mask-image: var(--icon-search)\n\n.sidebar-search\n box-sizing: border-box\n\n border: none\n border-top: 1px solid var(--color-sidebar-search-border)\n border-bottom: 1px solid var(--color-sidebar-search-border)\n\n padding-top: var(--sidebar-search-input-spacing-vertical)\n padding-bottom: var(--sidebar-search-input-spacing-vertical)\n padding-right: var(--sidebar-search-input-spacing-horizontal)\n padding-left: calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size))\n\n width: 100%\n\n color: var(--color-sidebar-search-foreground)\n background: transparent\n z-index: 10\n\n &:focus\n outline: none\n\n &::placeholder\n font-size: var(--sidebar-search-input-font-size)\n\n//\n// Hide Search Matches link\n//\n#searchbox .highlight-link\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0\n margin: 0\n text-align: center\n\n a\n color: var(--color-sidebar-search-icon)\n font-size: var(--font-size--small--2)\n\n////////////////////////////////////////////////////////////////////////////////\n// Structure/Skeleton of the navigation tree (left)\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-tree\n font-size: var(--sidebar-item-font-size)\n margin-top: var(--sidebar-tree-space-above)\n margin-bottom: var(--sidebar-item-spacing-vertical)\n\n ul\n padding: 0\n margin-top: 0\n margin-bottom: 0\n\n display: flex\n flex-direction: column\n\n list-style: none\n\n li\n position: relative\n margin: 0\n\n > ul\n margin-left: var(--sidebar-item-spacing-horizontal)\n\n .icon\n color: var(--color-sidebar-link-text)\n\n .reference\n box-sizing: border-box\n color: var(--color-sidebar-link-text)\n\n // Fill the parent.\n display: inline-block\n line-height: var(--sidebar-item-line-height)\n text-decoration: none\n\n // Don't allow long words to cause wrapping.\n overflow-wrap: anywhere\n\n height: 100%\n width: 100%\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n &:hover\n color: var(--color-sidebar-link-text)\n background: var(--color-sidebar-item-background--hover)\n\n // Add a nice little \"external-link\" arrow here.\n &.external::after\n content: url('data:image/svg+xml, ')\n margin: 0 0.25rem\n vertical-align: middle\n color: var(--color-sidebar-link-text)\n\n // Make the current page reference bold.\n .current-page > .reference\n font-weight: bold\n\n label\n position: absolute\n top: 0\n right: 0\n height: var(--sidebar-item-height)\n width: var(--sidebar-expander-width)\n\n cursor: pointer\n user-select: none\n\n display: flex\n justify-content: center\n align-items: center\n\n .caption, :not(.caption) > .caption-text\n font-size: var(--sidebar-caption-font-size)\n color: var(--color-sidebar-caption-text)\n\n font-weight: bold\n text-transform: uppercase\n\n margin: var(--sidebar-caption-space-above) 0 0 0\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n // If it has children, add a bit more padding to wrap the content to avoid\n // overlapping with the \n li.has-children\n > .reference\n padding-right: var(--sidebar-expander-width)\n\n // Colorize the top-level list items and icon.\n .toctree-l1\n & > .reference,\n & > label .icon\n color: var(--color-sidebar-link-text--top-level)\n\n // Color changes on hover\n label\n background: var(--color-sidebar-item-expander-background)\n &:hover\n background: var(--color-sidebar-item-expander-background--hover)\n\n .current > .reference\n background: var(--color-sidebar-item-background--current)\n &:hover\n background: var(--color-sidebar-item-background--hover)\n\n.toctree-checkbox\n position: absolute\n display: none\n\n////////////////////////////////////////////////////////////////////////////////\n// Togglable expand/collapse\n////////////////////////////////////////////////////////////////////////////////\n.toctree-checkbox\n ~ ul\n display: none\n\n ~ label .icon svg\n transform: rotate(90deg)\n\n.toctree-checkbox:checked\n ~ ul\n display: block\n\n ~ label .icon svg\n transform: rotate(-90deg)\n","// This file contains the styles for the contents of the right sidebar, which\n// contains the table of contents for the current page.\n.toc-title-container\n padding: var(--toc-title-padding)\n padding-top: var(--toc-spacing-vertical)\n\n.toc-title\n color: var(--color-toc-title-text)\n font-size: var(--toc-title-font-size)\n padding-left: var(--toc-spacing-horizontal)\n text-transform: uppercase\n\n// If the ToC is not present, hide these elements coz they're not relevant.\n.no-toc\n display: none\n\n.toc-tree-container\n padding-bottom: var(--toc-spacing-vertical)\n\n.toc-tree\n font-size: var(--toc-font-size)\n line-height: 1.3\n border-left: 1px solid var(--color-background-border)\n\n padding-left: calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))\n\n // Hide the first \"top level\" bullet.\n > ul > li:first-child\n padding-top: 0\n & > ul\n padding-left: 0\n & > a\n display: none\n\n ul\n list-style-type: none\n margin-top: 0\n margin-bottom: 0\n padding-left: var(--toc-item-spacing-horizontal)\n li\n padding-top: var(--toc-item-spacing-vertical)\n\n &.scroll-current > .reference\n color: var(--color-toc-item-text--active)\n font-weight: bold\n\n a.reference\n color: var(--color-toc-item-text)\n text-decoration: none\n overflow-wrap: anywhere\n\n.toc-scroll\n max-height: 100vh\n overflow-y: scroll\n\n// Be very annoying when someone includes the table of contents\n.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here)\n color: var(--color-problematic)\n background: rgba(255, 0, 0, 0.25)\n &::before\n content: \"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling. Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch.\"\n","// Shameful hacks, to work around bugs.\n\n// MyST parser doesn't correctly generate classes, to align table contents.\n// https://github.com/executablebooks/MyST-Parser/issues/412\n.text-align\\:left > p\n text-align: left\n\n.text-align\\:center > p\n text-align: center\n\n.text-align\\:right > p\n text-align: right\n"],"names":[],"sourceRoot":""}
\ No newline at end of file
diff --git a/_static/twemoji.css b/_static/twemoji.css
new file mode 100644
index 0000000000..878d070d16
--- /dev/null
+++ b/_static/twemoji.css
@@ -0,0 +1,6 @@
+img.emoji {
+ height: 1em;
+ width: 1em;
+ margin: 0 .05em 0 .1em;
+ vertical-align: -0.1em;
+}
diff --git a/_static/twemoji.js b/_static/twemoji.js
new file mode 100644
index 0000000000..91bc868f4f
--- /dev/null
+++ b/_static/twemoji.js
@@ -0,0 +1,10 @@
+function addEvent(element, eventName, fn) {
+ if (element.addEventListener)
+ element.addEventListener(eventName, fn, false);
+ else if (element.attachEvent)
+ element.attachEvent('on' + eventName, fn);
+}
+
+addEvent(window, 'load', function() {
+ twemoji.parse(document.body, {'folder': 'svg', 'ext': '.svg'});
+});
diff --git a/_static/vineyard-logo-h.png b/_static/vineyard-logo-h.png
new file mode 100644
index 0000000000..ec609dd5f0
Binary files /dev/null and b/_static/vineyard-logo-h.png differ
diff --git a/_static/vineyard-logo-notext.png b/_static/vineyard-logo-notext.png
new file mode 100644
index 0000000000..bd7069a19b
Binary files /dev/null and b/_static/vineyard-logo-notext.png differ
diff --git a/_static/vineyard-logo-rect.png b/_static/vineyard-logo-rect.png
new file mode 100644
index 0000000000..2c3ca4dae7
Binary files /dev/null and b/_static/vineyard-logo-rect.png differ
diff --git a/_static/vineyard-logo-v6d.png b/_static/vineyard-logo-v6d.png
new file mode 100644
index 0000000000..0cd2078d8d
Binary files /dev/null and b/_static/vineyard-logo-v6d.png differ
diff --git a/_static/vineyard-logo.png b/_static/vineyard-logo.png
new file mode 100644
index 0000000000..a1bc575baf
Binary files /dev/null and b/_static/vineyard-logo.png differ
diff --git a/_static/vineyard.ico b/_static/vineyard.ico
new file mode 100644
index 0000000000..8c8ace0f29
Binary files /dev/null and b/_static/vineyard.ico differ
diff --git a/_static/vineyard_arch.jpg b/_static/vineyard_arch.jpg
new file mode 100644
index 0000000000..813ab5d29e
Binary files /dev/null and b/_static/vineyard_arch.jpg differ
diff --git a/_static/vineyard_compare.png b/_static/vineyard_compare.png
new file mode 100644
index 0000000000..6756114099
Binary files /dev/null and b/_static/vineyard_compare.png differ
diff --git a/_static/vineyard_composable.jpg b/_static/vineyard_composable.jpg
new file mode 100644
index 0000000000..f4541b655d
Binary files /dev/null and b/_static/vineyard_composable.jpg differ
diff --git a/_static/vineyard_distributed_tensor.jpg b/_static/vineyard_distributed_tensor.jpg
new file mode 100644
index 0000000000..2b0ce68980
Binary files /dev/null and b/_static/vineyard_distributed_tensor.jpg differ
diff --git a/_static/vineyard_logo.png b/_static/vineyard_logo.png
new file mode 100644
index 0000000000..a1bc575baf
Binary files /dev/null and b/_static/vineyard_logo.png differ
diff --git a/_static/vineyard_operator_arch.png b/_static/vineyard_operator_arch.png
new file mode 100644
index 0000000000..68283ed017
Binary files /dev/null and b/_static/vineyard_operator_arch.png differ
diff --git a/_static/webfonts/fa-brands-400.ttf b/_static/webfonts/fa-brands-400.ttf
new file mode 100644
index 0000000000..430a02edc6
Binary files /dev/null and b/_static/webfonts/fa-brands-400.ttf differ
diff --git a/_static/webfonts/fa-brands-400.woff2 b/_static/webfonts/fa-brands-400.woff2
new file mode 100644
index 0000000000..4d904aab4f
Binary files /dev/null and b/_static/webfonts/fa-brands-400.woff2 differ
diff --git a/cncf/2022-vineyard-annual.html b/cncf/2022-vineyard-annual.html
new file mode 100644
index 0000000000..29c36e22ac
--- /dev/null
+++ b/cncf/2022-vineyard-annual.html
@@ -0,0 +1,723 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vineyard 2022 Annual Review - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Vineyard 2022 Annual Review
+
+Background
+Vineyard is an in-memory immutable data manager that provides
+out-of-the-box high-level abstraction and zero-copy in-memory sharing for
+distributed data in big data tasks, such as graph analytics, numerical computing, and
+machine learning.
+Vineyard provides :
+
+Efficient in-memory data management and zero-copy sharing across different systems.
+Out-of-the-box high-level data abstraction for distributed objects (e.g., tensors, tables,
+graphs) and efficient polyglot support (currently including C++, Python, and Java).
+Built-in streaming support for data accessing and across system pipelining.
+An extensible driver framework and a set of efficient built-in drivers for eliminating
+the boilerplate part in computation engines, e.g., I/O, serialization, and checkpointing.
+
+Alignment with CNCF :
+
+Vineyard builds on Kubernetes for deploying and scaling and the objects are observable
+in Kubernetes as CRDs.
+Vineyard makes efficient zero-copy sharing possible for data-intensive workflows on
+cloud-native infrastructure by a data-aware Kubernetes scheduler plugin.
+Vineyard adopts a immutable object design, which aligns with the immutable infrastructure
+of the cloud-native environment.
+
+Vineyard was accepted as a CNCF sandbox project on Apr 28th, 2021.
+
+
+DevStats
+
+Include a link to your project’s devstats page. We will be looking for signs of consistent
+or increasing contribution activity. Please feel free to add commentary to add colour to
+the numbers and graphs we will see on devstats.
+
+
+The vineyard community has grown since the project entered the CNCF sandbox.
+
+Number of contributors: 11 -> 26
+Github stars: 300+ -> 600+
+Github forks: 20+ -> 80+
+Contributing organizations: 1 -> 12
+
+
+
+Maintainers
+
+How many maintainers do you have, and which organisations are they from? (Feel free
+to link to an existing MAINTAINERS file if appropriate.)
+
+We currently have 7 maintainers and 2 committers and have a maintainer list on Github .
+
+
+
+Adoption
+
+What do you know about adoption, and how has this changed since your last review / since
+you joined Sandbox? If you can list companies that are end-users of your project, please
+do so. (Feel free to link to an existing ADOPTERS file if appropriate.)
+
+We know several cases where vineyard has been adopted in both testing and production environments.
+
+We have also integrated with the apache-airflow project, which is a workflow orchestration engine
+and has been widely adopted. We have published airflow-vineyard-provider on Astronomer Registry
+and received much feedback from end-users, but we haven’t tracked the actual adoption yet.
+
+
+Project Goals
+
+How has the project performed against its goals since the last review? (We won’t penalize you
+if your goals changed for good reasons.)
+
+Vineyard has successfully archived the goal of bringing value to big data analytical workflows
+on Kubernetes. We have shown the gain in an internal project which involves both ETL, graph
+computation, and machine learning jobs.
+Our goal hasn’t changed since becoming CNCF sandbox project and we are still aiming at supporting
+a more efficient big data analytical workflow on the cloud-native infrastructure. Specifically,
+we’ll keep moving towards following goals in the next year:
+
+Providing efficient cross-engine data sharing for data-intensive workflows in Kubernetes
+Integrating with projects in the cloud-native community for orchestration and scheduling
+and integrating with more big data computing engines to improve the end-to-end efficiency.
+Building a new cloud-native paradigm for big data applications working together. By
+integrating Vineyard, Kubernetes can help orchestrating data and workloads together for
+better alignment and efficiency.
+
+We still need to do more to engage end-users to show the value-added of the vineyard project.
+
+
+CNCF membership
+
+How can the CNCF help you achieve your upcoming goals?
+
+Vineyard has incredibly benefited from CNCF since accepted as a sandbox project. We believe
+the end-users in the CNCF community are critical for Vineyard to become successful. We have
+submitted proposals for the KubeCon and CNCF Conferences in the past year but got rejected.
+We hope we could have more opportunities to introduce our project to border end-users in the
+CNCF community to increase adoption.
+
+
+Incubation
+
+
+We think our project vineyard still needs further exploration to get border adoption in the
+production environment and we are looking forward to meeting the incubation criteria in near
+future.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cncf/2023-vineyard-annual.html b/cncf/2023-vineyard-annual.html
new file mode 100644
index 0000000000..0a41b61aba
--- /dev/null
+++ b/cncf/2023-vineyard-annual.html
@@ -0,0 +1,797 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vineyard 2023 Annual Review - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Vineyard 2023 Annual Review
+
+Background
+Vineyard is an in-memory immutable data manager that provides
+out-of-the-box high-level abstraction and zero-copy in-memory sharing for
+distributed data in big data tasks, such as graph analytics, numerical computing, and
+machine learning. Vineyard is design to address the inefficiency of data sharing in
+big data analytical workflows on Kubernetes.
+Vineyard provides :
+
+Efficient in-memory data management and zero-copy sharing across different systems.
+Out-of-the-box high-level data abstraction for distributed objects (e.g., tensors, tables,
+graphs, and distributed datasets) and efficient polyglot support (currently including C++,
+Python, Go, Rust and Java).
+Seamless integration with Kubernetes for cluster deployment and management, workloads
+orchestration, and observability.
+Out-of-the-box integration with workflow orchestration engines (including
+Apache Airflow ,
+Flyte
+and Kubeflow Pipelines ),
+providing end-users with a unified and intrusive experience to leverage Vineyard in
+their data-intensive workflows to improving performance.
+
+Alignment with CNCF :
+
+Vineyard builds on Kubernetes for deploying and scaling, and the objects are observable
+in Kubernetes as CRDs.
+Vineyard makes efficient zero-copy sharing possible for data-intensive workflows on
+cloud-native infrastructure by a data-aware Kubernetes scheduler plugin.
+Vineyard adopts an immutable object design, which aligns with the immutable infrastructure
+of the cloud-native environment.
+Vineyard aligns with the CNCF effort on helping migrate batching system workflows to cloud
+native environments.
+
+
+
+Development
+
+DevStats
+
+Include a link to your project’s devstats page. We will be looking for signs of consistent
+or increasing contribution activity. Please feel free to add commentary to add colour to
+the numbers and graphs we will see on devstats.
+
+
+The vineyard community has grown since the project entered the CNCF sandbox.
+
+Number of contributors: 26 -> 40
+Github stars: 600+ -> ~750
+Github forks: 80+ -> 110+
+
+
+
+Highlights of new features
+Vineyard published 8 release (one release about per 1.5 month) since the last annual review.
+The major new features and improvements include:
+
+Language SDKs in Rust and Go, where the Rust SDK was a collaboration with our external
+end-user, and enabled users seamlessly and efficiently interoperating their data between
+Python and Rust.
+Integration with the workflow engine Kedro, and gained attention in the Kedro community.
+Vineyard supports the Apache Hive data processing engine,
+letting users can easily connect traditional data processing pipelines built with the
+Hadoop ecosystem with emerging big-data and AI applications (e.g., applications in the
+PyData community).
+A initial version of CSI driver, which helped Vineyard aligned with the Kubernetes platform
+and enables users to leverage Vineyard in their Kubeflow pipelines to optimize the data
+sharing between steps with only minor changes to their existing source code.
+
+
+
+Academic Research
+We have conducted a series of research work around Vineyard and published the paper
+Vineyard: Optimizing Data Sharing in Data-Intensive Analytics in SIGMOD 2023, a top-tier
+conference in the data management community.
+
+Wenyuan Yu, Tao He, Lei Wang, Ke Meng, Ye Cao, Diwen Zhu, Sanhong Li, Jingren Zhou.
+Vineyard: Optimizing Data Sharing in Data-Intensive Analytics. ACM SIG Conference on
+Management of Data (SIGMOD), industry, 2023. https://dl.acm.org/doi/10.1145/3589780 .
+
+
+
+
+Maintainers
+
+How many maintainers do you have, and which organisations are they from? (Feel free
+to link to an existing MAINTAINERS file if appropriate.)
+
+We currently have 10 maintainers and 2 committers and have a maintainer list on Github .
+
+
+
+Adoption
+
+What do you know about adoption, and how has this changed since your last review / since
+you joined Sandbox? If you can list companies that are end-users of your project, please
+do so. (Feel free to link to an existing ADOPTERS file if appropriate.)
+
+We have tracked the following two major adoption since our last annual review
+
+Besides these two major companies, since our last annual review, we have also noticed some other
+questions about using Vineyard in machine learning inference scenarios, but we haven’t tracked
+the actual adoption yet.
+
+
+Project Goals
+
+How has the project performed against its goals since the last review? (We won’t penalize you
+if your goals changed for good reasons.)
+
+Vineyard has successfully archived the goals about easing the getting started process for
+end-users from three aspects:
+
+Out-of-the-box integration with data processing systems, especially Spark and Hive,
+the most popular data processing engines in the big data community;
+Data processing pipeline orchestration: providing non-intrusive interfaces to help users
+migrate their existing data processing pipelines to Vineyard on Kubernetes and finally
+benefit from the efficient data sharing;
+Seamless inter-operability with other systems in the cloud-native environments: we invest
+a lot of effort in the Vineyard operator to help use deploy vineyard along with their
+workloads in a non-intrusive, declarative way and has tested the functionality with
+GraphScope in end-users production environments.
+
+Besides, Vineyard has successfully attracted new end-users from the big data community to
+adopt Vineyard in their own data processing platform, and the feedback from the Kedro
+community is also positive.
+
+What are the current goals of the project? For example, are you working on major new features? Or are you concentrating on adoption or documentation?
+
+Our current goals are mainly focused on the attracting more end-user to adopt Vineyard in
+their scenarios from different domains. Specifically, we are keeping moving towards the
+following goals in the next year:
+
+Optimizing our current Kubeflow integration and find more opportunities to evaluate
+and deploy Vineyard in production machine learning applications;
+Publish our integration with the big data processing systems to their end-user
+community and gather feedback for further improvements;
+Seeking more opportunities to evaluate Vineyard in the emerging LLM applications,
+for both data preprocessing, training, and inference serving to see if Vineyard
+can bring added value to these applications as where the data cost is usually high;
+Getting engaged with the Batch System WG in CNCF to seek opportunities about
+further collaboration with other projects in CNCF.
+
+
+
+CNCF membership
+
+How can the CNCF help you achieve your upcoming goals?
+
+Vineyard has incredibly benefited from CNCF since accepted as a sandbox project. We believe
+the end-users in the CNCF community are critical for Vineyard to become successful. With
+the help of CNCF service desk, we have successfully built a new website for Vineyard, which
+is more friendly to end-users. We are also working on components like CSI driver and hope
+that could make the inter-operation with other projects in the CNCF community easier.
+We will host a Project Kiosk in this KubeCon China and hope to get more feedback from the
+community, and hope to get more feedback from the community. Furthermore, we hope we could have
+more opportunities to introduce our project to border end-users in the CNCF community to
+increase adoption.
+
+
+Incubation
+
+
+We think our project vineyard still needs further exploration to get border adoption in the
+end-user’s production deployment and gather more feedback, and we are looking forward to
+meeting the incubation criteria in the near future.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs.html b/docs.html
new file mode 100644
index 0000000000..8c00a3e491
--- /dev/null
+++ b/docs.html
@@ -0,0 +1,647 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+
+
+an in-memory immutable data manager
+
+
+
+
+Why bother?
+Sharing intermediate data between systems in modern big data and AI workflows
+can be challenging, often causing significant bottlenecks in such jobs. Let’s
+consider the following fraud detection pipeline:
+
+
+
+A real-life fraud detection job
+
+
+From the pipeline, we observed:
+
+Users usually prefer to program with dedicated computing systems for different tasks in the
+same applications, such as SQL and Python.
+Integrating a new computing system into production environments demands high technical
+effort to align with existing production environments in terms of I/O, failover, etc.
+
+Data could be polymorphic. Non-relational data, such as tensors, dataframes (in Pandas) and
+graphs/networks (in GraphScope ) are becoming increasingly prevalent. Tables and SQL may
+not be the best way to store, exchange, or process them.
+Transforming the data back and forth between different systems as “tables” could
+result in a significant overhead.
+
+Saving/loading the data to/from the external storage requires numerous memory copies and
+incurs high IO costs.
+
+
+
+What is Vineyard?
+Vineyard (v6d) is an in-memory immutable data manager that offers out-of-the-box high-level
+abstraction and zero-copy sharing for distributed data in big data tasks, such as
+graph analytics (e.g., GraphScope ), numerical computing (e.g., Mars ), and machine learning.
+
+Features
+
+Efficient data sharing
+Vineyard shares immutable data across different systems using shared memory without extra overheads,
+eliminating the overhead of serialization/deserialization and IO when exchanging immutable
+data between systems.
+
+
+Out-of-the-box data abstraction
+Vineyard defines a metadata-payload separated data model to capture the payload commonalities and
+method commonalities between sharable objects in different programming languages and different
+computing systems in a unified way.
+The Code Generation for Boilerplate (Vineyard Component Description Language) is specifically designed to annotate
+sharable members and methods, enabling automatic generation of boilerplate code for minimal
+integration effort.
+
+
+Pluggable I/O routines
+In many big data analytical tasks, a substantial portion of the workload consists of boilerplate
+routines that are unrelated to the core computation. These routines include various IO adapters,
+data partition strategies, and migration jobs. Due to different data structure abstractions across
+systems, these routines are often not easily reusable, leading to increased complexity and redundancy.
+Vineyard provides common manipulation routines for immutable data as drivers, which extend
+the capabilities of data structures by registering appropriate drivers. This enables out-of-the-box
+reuse of boilerplate components across diverse computation jobs.
+
+
+Data orchestration on Kubernetes
+Vineyard provides efficient distributed data sharing in cloud-native environments by embracing
+cloud-native big data processing. Kubernetes helps Vineyard leverage the scale-in/out and
+scheduling abilities of Kubernetes.
+
+
+
+Use cases
+
+
+
+
+
+
Object manager
+
Put and get arbitrary objects using Vineyard, in a zero-copy way!
+
+
+
+
+
+
+
+
Data orchestration
+
Vineyard coordinates the flow of objects and jobs on Kubernetes based on data-aware scheduling.
+
+
+
+
+
+
+
+
+Get started now!
+
+
+
+
+
+
+
Get started with Vineyard.
+
+
+
+
+
+
+
+
Deploy Vineyard on Kubernetes and accelerate big-data analytical workflows on cloud-native
+infrastructures.
+
+
+
+
+
+
+
+
Explore use cases and tutorials where Vineyard can bring added value.
+
+
+
+
+
+
+
+
Get involved and become part of the Vineyard community.
+
+
+
+
+
+
+
+
Frequently asked questions and discussions during the adoption of Vineyard.
+
+
+
+
+
+
+
+Read the Paper
+
+Vineyard is a CNCF sandbox project and is made successful by its community.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/genindex.html b/genindex.html
new file mode 100644
index 0000000000..f4221a0292
--- /dev/null
+++ b/genindex.html
@@ -0,0 +1,2043 @@
+
+
+
+
+
+
+ Index - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ V
+
+
+ version (vineyard.Client property)
+
+
+ vineyard::Array (C++ class)
+
+ vineyard::Array::Construct (C++ function)
+
+ vineyard::Array::Create (C++ function)
+
+ vineyard::Array::data (C++ function)
+
+ vineyard::Array::operator[] (C++ function)
+
+ vineyard::Array::size (C++ function)
+
+ vineyard::ArrayBuilder (C++ class)
+
+ vineyard::ArrayBuilder::ArrayBuilder (C++ function) , [1] , [2]
+
+ vineyard::ArrayBuilder::Build (C++ function)
+
+ vineyard::ArrayBuilder::data (C++ function) , [1]
+
+ vineyard::ArrayBuilder::operator[] (C++ function)
+
+ vineyard::ArrayBuilder::size (C++ function)
+
+ vineyard::ArrayBuilder::~ArrayBuilder (C++ function)
+
+ vineyard::Blob (C++ class)
+
+ vineyard::Blob::allocated_size (C++ function)
+
+ vineyard::Blob::ArrowBuffer (C++ function)
+
+ vineyard::Blob::ArrowBufferOrEmpty (C++ function)
+
+ vineyard::Blob::Buffer (C++ function)
+
+ vineyard::Blob::BufferOrEmpty (C++ function)
+
+ vineyard::Blob::Construct (C++ function)
+
+ vineyard::Blob::Create (C++ function)
+
+ vineyard::Blob::data (C++ function)
+
+ vineyard::Blob::Dump (C++ function)
+
+ vineyard::Blob::FromAllocator (C++ function)
+
+ vineyard::Blob::FromPointer (C++ function)
+
+ vineyard::Blob::MakeEmpty (C++ function)
+
+ vineyard::Blob::size (C++ function)
+
+ vineyard::BlobWriter (C++ class)
+
+ vineyard::BlobWriter::Abort (C++ function)
+
+ vineyard::BlobWriter::AddKeyValue (C++ function) , [1]
+
+ vineyard::BlobWriter::Buffer (C++ function)
+
+ vineyard::BlobWriter::Build (C++ function)
+
+ vineyard::BlobWriter::data (C++ function) , [1]
+
+ vineyard::BlobWriter::Dump (C++ function)
+
+ vineyard::BlobWriter::id (C++ function)
+
+ vineyard::BlobWriter::Shrink (C++ function)
+
+ vineyard::BlobWriter::size (C++ function)
+
+ vineyard::ByteStream (C++ class)
+
+ vineyard::ByteStream::Create (C++ function)
+
+ vineyard::ByteStream::FlushBuffer (C++ function)
+
+ vineyard::ByteStream::ReadLine (C++ function)
+
+ vineyard::ByteStream::SetBufferSizeLimit (C++ function)
+
+ vineyard::ByteStream::WriteBytes (C++ function)
+
+ vineyard::ByteStream::WriteLine (C++ function)
+
+ vineyard::Client (C++ class)
+
+ vineyard::Client::AllocatedSize (C++ function)
+
+ vineyard::Client::Client (C++ function)
+
+ vineyard::Client::Connect (C++ function) , [1] , [2] , [3]
+
+ vineyard::Client::CreateArena (C++ function)
+
+ vineyard::Client::CreateBlob (C++ function)
+
+ vineyard::Client::CreateBlobs (C++ function)
+
+ vineyard::Client::CreateBuffer (C++ function)
+
+ vineyard::Client::CreateBuffers (C++ function)
+
+ vineyard::Client::CreateDiskBlob (C++ function)
+
+ vineyard::Client::CreateGPUBuffer (C++ function)
+
+ vineyard::Client::Default (C++ function)
+
+ vineyard::Client::DelData (C++ function) , [1] , [2] , [3]
+
+ vineyard::Client::Disconnect (C++ function)
+
+ vineyard::Client::DropBuffer (C++ function)
+
+ vineyard::Client::FetchAndGetMetaData (C++ function)
+
+ vineyard::Client::FetchAndGetObject (C++ function) , [1] , [2] , [3]
+
+ vineyard::Client::Fork (C++ function)
+
+ vineyard::Client::GetBlob (C++ function) , [1]
+
+ vineyard::Client::GetBlobs (C++ function) , [1]
+
+ vineyard::Client::GetBuffer (C++ function)
+
+ vineyard::Client::GetBuffers (C++ function)
+
+ vineyard::Client::GetBufferSizes (C++ function)
+
+ vineyard::Client::GetDependency (C++ function)
+
+ vineyard::Client::GetGPUBuffer (C++ function)
+
+ vineyard::Client::GetGPUBuffers (C++ function)
+
+ vineyard::Client::GetMetaData (C++ function) , [1]
+
+ vineyard::Client::GetNextStreamChunk (C++ function)
+
+ vineyard::Client::GetObject (C++ function) , [1] , [2] , [3]
+
+ vineyard::Client::GetObjects (C++ function)
+
+ vineyard::Client::IsInUse (C++ function)
+
+ vineyard::Client::IsIPC (C++ function)
+
+ vineyard::Client::IsSharedMemory (C++ function) , [1] , [2] , [3]
+
+ vineyard::Client::IsSpilled (C++ function)
+
+ vineyard::Client::ListObjectMeta (C++ function)
+
+ vineyard::Client::ListObjects (C++ function)
+
+ vineyard::Client::OnDelete (C++ function)
+
+ vineyard::Client::OnRelease (C++ function)
+
+ vineyard::Client::Open (C++ function) , [1]
+
+ vineyard::Client::PostSeal (C++ function)
+
+ vineyard::Client::PullNextStreamChunk (C++ function) , [1] , [2] , [3]
+
+ vineyard::Client::Release (C++ function) , [1]
+
+ vineyard::Client::ReleaseArena (C++ function)
+
+ vineyard::Client::Seal (C++ function)
+
+ vineyard::Client::ShallowCopy (C++ function) , [1]
+
+ vineyard::Client::ShrinkBuffer (C++ function)
+
+ vineyard::Client::TryAcquireLock (C++ function)
+
+ vineyard::Client::TryReleaseLock (C++ function)
+
+ vineyard::Client::~Client (C++ function)
+
+ vineyard::ClientBase (C++ class)
+
+ vineyard::ClientBase::Clear (C++ function)
+
+ vineyard::ClientBase::client_mutex_ (C++ member)
+
+ vineyard::ClientBase::ClientBase (C++ function) , [1] , [2]
+
+ vineyard::ClientBase::CloseSession (C++ function)
+
+ vineyard::ClientBase::ClusterInfo (C++ function)
+
+ vineyard::ClientBase::compression_enabled (C++ function)
+
+ vineyard::ClientBase::compression_enabled_ (C++ member)
+
+ vineyard::ClientBase::Connected (C++ function)
+
+ vineyard::ClientBase::connected_ (C++ member)
+
+ vineyard::ClientBase::CreateData (C++ function) , [1]
+
+ vineyard::ClientBase::CreateMetaData (C++ function) , [1] , [2] , [3]
+
+ vineyard::ClientBase::CreateStream (C++ function)
+
+ vineyard::ClientBase::Debug (C++ function)
+
+ vineyard::ClientBase::DelData (C++ function) , [1] , [2] , [3]
+
+ vineyard::ClientBase::Disconnect (C++ function)
+
+ vineyard::ClientBase::doRead (C++ function) , [1]
+
+ vineyard::ClientBase::doWrite (C++ function)
+
+ vineyard::ClientBase::DropName (C++ function)
+
+ vineyard::ClientBase::DropStream (C++ function)
+
+ vineyard::ClientBase::Evict (C++ function)
+
+ vineyard::ClientBase::Exists (C++ function)
+
+ vineyard::ClientBase::GetData (C++ function) , [1]
+
+ vineyard::ClientBase::GetMetaData (C++ function)
+
+ vineyard::ClientBase::GetName (C++ function)
+
+ vineyard::ClientBase::IfPersist (C++ function)
+
+ vineyard::ClientBase::instance_id (C++ function)
+
+ vineyard::ClientBase::instance_id_ (C++ member)
+
+ vineyard::ClientBase::Instances (C++ function)
+
+ vineyard::ClientBase::InstanceStatus (C++ function)
+
+ vineyard::ClientBase::ipc_socket_ (C++ member)
+
+ vineyard::ClientBase::IPCSocket (C++ function)
+
+ vineyard::ClientBase::IsIPC (C++ function)
+
+ vineyard::ClientBase::IsRPC (C++ function)
+
+ vineyard::ClientBase::Label (C++ function) , [1]
+
+ vineyard::ClientBase::ListData (C++ function)
+
+ vineyard::ClientBase::ListNames (C++ function)
+
+ vineyard::ClientBase::Load (C++ function)
+
+ vineyard::ClientBase::MemoryTrim (C++ function)
+
+ vineyard::ClientBase::MigrateObject (C++ function)
+
+ vineyard::ClientBase::Open (C++ function)
+
+ vineyard::ClientBase::OpenStream (C++ function)
+
+ vineyard::ClientBase::operator= (C++ function) , [1]
+
+ vineyard::ClientBase::Persist (C++ function)
+
+ vineyard::ClientBase::PullNextStreamChunk (C++ function) , [1] , [2]
+
+ vineyard::ClientBase::PushNextStreamChunk (C++ function)
+
+ vineyard::ClientBase::PutName (C++ function)
+
+ vineyard::ClientBase::Release (C++ function)
+
+ vineyard::ClientBase::remote_instance_id (C++ function)
+
+ vineyard::ClientBase::rpc_endpoint_ (C++ member)
+
+ vineyard::ClientBase::RPCEndpoint (C++ function)
+
+ vineyard::ClientBase::server_version_ (C++ member)
+
+ vineyard::ClientBase::session_id (C++ function)
+
+ vineyard::ClientBase::session_id_ (C++ member)
+
+ vineyard::ClientBase::set_compression_enabled (C++ function)
+
+ vineyard::ClientBase::ShallowCopy (C++ function) , [1]
+
+ vineyard::ClientBase::StopStream (C++ function)
+
+ vineyard::ClientBase::support_rpc_compression_ (C++ member)
+
+ vineyard::ClientBase::SyncMetaData (C++ function)
+
+ vineyard::ClientBase::TryAcquireLock (C++ function)
+
+ vineyard::ClientBase::TryReleaseLock (C++ function)
+
+ vineyard::ClientBase::Unpin (C++ function)
+
+ vineyard::ClientBase::Version (C++ function)
+
+ vineyard::ClientBase::vineyard_conn_ (C++ member)
+
+ vineyard::ClientBase::~ClientBase (C++ function)
+
+ vineyard::DataFrame (C++ class)
+
+ vineyard::DataFrame::AsBatch (C++ function)
+
+ vineyard::DataFrame::Column (C++ function)
+
+ vineyard::DataFrame::Columns (C++ function)
+
+ vineyard::DataFrame::Construct (C++ function)
+
+ vineyard::DataFrame::Create (C++ function)
+
+ vineyard::DataFrame::Index (C++ function)
+
+ vineyard::DataFrame::partition_index (C++ function)
+
+ vineyard::DataFrame::shape (C++ function)
+
+ vineyard::DataFrameBuilder (C++ class)
+
+ vineyard::DataFrameBuilder::AddColumn (C++ function)
+
+ vineyard::DataFrameBuilder::Build (C++ function)
+
+ vineyard::DataFrameBuilder::Column (C++ function)
+
+ vineyard::DataFrameBuilder::DataFrameBuilder (C++ function)
+
+ vineyard::DataFrameBuilder::DropColumn (C++ function)
+
+ vineyard::DataFrameBuilder::partition_index (C++ function)
+
+ vineyard::DataFrameBuilder::set_index (C++ function)
+
+ vineyard::DataFrameBuilder::set_partition_index (C++ function)
+
+ vineyard::DataFrameBuilder::set_row_batch_index (C++ function)
+
+ vineyard::GlobalDataFrame (C++ class)
+
+ vineyard::GlobalDataFrame::Create (C++ function)
+
+ vineyard::GlobalDataFrame::LocalPartitions (C++ function)
+
+ vineyard::GlobalDataFrame::partition_shape (C++ function)
+
+ vineyard::GlobalDataFrame::PostConstruct (C++ function)
+
+ vineyard::GlobalDataFrameBuilder (C++ class)
+
+ vineyard::GlobalDataFrameBuilder::AddPartition (C++ function)
+
+ vineyard::GlobalDataFrameBuilder::AddPartitions (C++ function)
+
+ vineyard::GlobalDataFrameBuilder::GlobalDataFrameBuilder (C++ function)
+
+ vineyard::GlobalDataFrameBuilder::partition_shape (C++ function)
+
+ vineyard::GlobalDataFrameBuilder::set_partition_shape (C++ function)
+
+ vineyard::GlobalTensor (C++ class)
+
+ vineyard::GlobalTensor::Create (C++ function)
+
+ vineyard::GlobalTensor::LocalPartitions (C++ function)
+
+ vineyard::GlobalTensor::partition_shape (C++ function)
+
+ vineyard::GlobalTensor::PostConstruct (C++ function)
+
+ vineyard::GlobalTensor::shape (C++ function)
+
+ vineyard::GlobalTensorBuilder (C++ class)
+
+ vineyard::GlobalTensorBuilder::AddPartition (C++ function)
+
+ vineyard::GlobalTensorBuilder::AddPartitions (C++ function)
+
+ vineyard::GlobalTensorBuilder::GlobalTensorBuilder (C++ function)
+
+ vineyard::GlobalTensorBuilder::partition_shape (C++ function)
+
+ vineyard::GlobalTensorBuilder::set_partition_shape (C++ function)
+
+ vineyard::GlobalTensorBuilder::set_shape (C++ function)
+
+ vineyard::GlobalTensorBuilder::shape (C++ function)
+
+ vineyard::Hashmap (C++ class)
+
+ vineyard::Hashmap::at (C++ function)
+
+ vineyard::Hashmap::begin (C++ function)
+
+
+
+ vineyard::Hashmap::bucket_count (C++ function)
+
+ vineyard::Hashmap::const_pointer (C++ type)
+
+ vineyard::Hashmap::const_reference (C++ type)
+
+ vineyard::Hashmap::Construct (C++ function)
+
+ vineyard::Hashmap::count (C++ function)
+
+ vineyard::Hashmap::Create (C++ function)
+
+ vineyard::Hashmap::difference_type (C++ type)
+
+ vineyard::Hashmap::empty (C++ function)
+
+ vineyard::Hashmap::end (C++ function)
+
+ vineyard::Hashmap::Entry (C++ type)
+
+ vineyard::Hashmap::EntryPointer (C++ type)
+
+ vineyard::Hashmap::Equal (C++ type)
+
+ vineyard::Hashmap::find (C++ function) , [1]
+
+ vineyard::Hashmap::flat_hash_table_type (C++ type)
+
+ vineyard::Hashmap::Hasher (C++ type)
+
+ vineyard::Hashmap::hasher (C++ type)
+
+ vineyard::Hashmap::iterator (C++ struct)
+
+ vineyard::Hashmap::iterator::current (C++ member)
+
+ vineyard::Hashmap::iterator::iterator (C++ function) , [1]
+
+ vineyard::Hashmap::iterator::operator!= (C++ function)
+
+ vineyard::Hashmap::iterator::operator* (C++ function)
+
+ vineyard::Hashmap::iterator::operator++ (C++ function) , [1]
+
+ vineyard::Hashmap::iterator::operator-> (C++ function)
+
+ vineyard::Hashmap::iterator::operator== (C++ function)
+
+ vineyard::Hashmap::key_equal (C++ type)
+
+ vineyard::Hashmap::KeyEqual (C++ type)
+
+ vineyard::Hashmap::KeyHash (C++ type)
+
+ vineyard::Hashmap::load_factor (C++ function)
+
+ vineyard::Hashmap::pointer (C++ type)
+
+ vineyard::Hashmap::PostConstruct (C++ function)
+
+ vineyard::Hashmap::reference (C++ type)
+
+ vineyard::Hashmap::size (C++ function)
+
+ vineyard::Hashmap::size_type (C++ type)
+
+ vineyard::Hashmap::T (C++ type)
+
+ vineyard::Hashmap::value_type (C++ type)
+
+ vineyard::HashmapBuilder (C++ class)
+
+ vineyard::HashmapBuilder::AssociateDataBuffer (C++ function)
+
+ vineyard::HashmapBuilder::at (C++ function) , [1]
+
+ vineyard::HashmapBuilder::begin (C++ function) , [1]
+
+ vineyard::HashmapBuilder::bucket_count (C++ function)
+
+ vineyard::HashmapBuilder::Build (C++ function)
+
+ vineyard::HashmapBuilder::cbegin (C++ function)
+
+ vineyard::HashmapBuilder::cend (C++ function)
+
+ vineyard::HashmapBuilder::emplace (C++ function)
+
+ vineyard::HashmapBuilder::empty (C++ function)
+
+ vineyard::HashmapBuilder::end (C++ function) , [1]
+
+ vineyard::HashmapBuilder::find (C++ function)
+
+ vineyard::HashmapBuilder::HashmapBuilder (C++ function) , [1]
+
+ vineyard::HashmapBuilder::load_factor (C++ function)
+
+ vineyard::HashmapBuilder::operator[] (C++ function) , [1]
+
+ vineyard::HashmapBuilder::reserve (C++ function)
+
+ vineyard::HashmapBuilder::size (C++ function)
+
+ vineyard::InstanceStatus (C++ struct)
+
+ vineyard::InstanceStatus::deferred_requests (C++ member)
+
+ vineyard::InstanceStatus::deployment (C++ member)
+
+ vineyard::InstanceStatus::instance_id (C++ member)
+
+ vineyard::InstanceStatus::InstanceStatus (C++ function)
+
+ vineyard::InstanceStatus::ipc_connections (C++ member)
+
+ vineyard::InstanceStatus::memory_limit (C++ member)
+
+ vineyard::InstanceStatus::memory_usage (C++ member)
+
+ vineyard::InstanceStatus::rpc_connections (C++ member)
+
+ vineyard::Object (C++ class)
+
+ vineyard::Object::_Seal (C++ function)
+
+ vineyard::Object::Build (C++ function)
+
+ vineyard::Object::Construct (C++ function)
+
+ vineyard::Object::id (C++ function)
+
+ vineyard::Object::id_ (C++ member)
+
+ vineyard::Object::IsGlobal (C++ function)
+
+ vineyard::Object::IsLocal (C++ function)
+
+ vineyard::Object::IsPersist (C++ function)
+
+ vineyard::Object::meta (C++ function)
+
+ vineyard::Object::meta_ (C++ member)
+
+ vineyard::Object::nbytes (C++ function)
+
+ vineyard::Object::Object (C++ function)
+
+ vineyard::Object::Persist (C++ function)
+
+ vineyard::Object::PostConstruct (C++ function)
+
+ vineyard::Object::~Object (C++ function)
+
+ vineyard::ObjectBase (C++ class)
+
+ vineyard::ObjectBase::_Seal (C++ function)
+
+ vineyard::ObjectBase::Build (C++ function)
+
+ vineyard::ObjectBuilder (C++ class)
+
+ vineyard::ObjectBuilder::_Seal (C++ function) , [1]
+
+ vineyard::ObjectBuilder::Build (C++ function)
+
+ vineyard::ObjectBuilder::Seal (C++ function) , [1]
+
+ vineyard::ObjectBuilder::sealed (C++ function)
+
+ vineyard::ObjectBuilder::set_sealed (C++ function)
+
+ vineyard::ObjectBuilder::~ObjectBuilder (C++ function)
+
+ vineyard::ObjectID (C++ type)
+
+ vineyard::ObjectMeta (C++ class)
+
+ vineyard::ObjectMeta::AddKeyValue (C++ function) , [1] , [2] , [3] , [4] , [5] , [6] , [7] , [8] , [9] , [10] , [11] , [12] , [13]
+
+ vineyard::ObjectMeta::AddMember (C++ function) , [1] , [2] , [3] , [4]
+
+ vineyard::ObjectMeta::AddRemoteBlob (C++ function)
+
+ vineyard::ObjectMeta::begin (C++ function)
+
+ vineyard::ObjectMeta::const_iterator (C++ type)
+
+ vineyard::ObjectMeta::end (C++ function)
+
+ vineyard::ObjectMeta::ForceLocal (C++ function)
+
+ vineyard::ObjectMeta::GetBuffer (C++ function)
+
+ vineyard::ObjectMeta::GetBufferSet (C++ function)
+
+ vineyard::ObjectMeta::GetClient (C++ function)
+
+ vineyard::ObjectMeta::GetId (C++ function)
+
+ vineyard::ObjectMeta::GetInstanceId (C++ function)
+
+ vineyard::ObjectMeta::GetKeyValue (C++ function) , [1] , [2] , [3] , [4] , [5] , [6] , [7] , [8] , [9] , [10] , [11] , [12] , [13] , [14] , [15] , [16]
+
+ vineyard::ObjectMeta::GetMember (C++ function) , [1] , [2] , [3]
+
+ vineyard::ObjectMeta::GetMemberMeta (C++ function) , [1]
+
+ vineyard::ObjectMeta::GetNBytes (C++ function)
+
+ vineyard::ObjectMeta::GetSignature (C++ function)
+
+ vineyard::ObjectMeta::GetTypeName (C++ function)
+
+ vineyard::ObjectMeta::HasKey (C++ function)
+
+ vineyard::ObjectMeta::Haskey (C++ function)
+
+ vineyard::ObjectMeta::incomplete (C++ function)
+
+ vineyard::ObjectMeta::IsGlobal (C++ function)
+
+ vineyard::ObjectMeta::IsLocal (C++ function)
+
+ vineyard::ObjectMeta::Label (C++ function)
+
+ vineyard::ObjectMeta::Labels (C++ function)
+
+ vineyard::ObjectMeta::MemoryUsage (C++ function) , [1]
+
+ vineyard::ObjectMeta::MetaData (C++ function)
+
+ vineyard::ObjectMeta::MutMetaData (C++ function)
+
+ vineyard::ObjectMeta::ObjectMeta (C++ function) , [1]
+
+ vineyard::ObjectMeta::operator= (C++ function)
+
+ vineyard::ObjectMeta::PrintMeta (C++ function)
+
+ vineyard::ObjectMeta::Reset (C++ function)
+
+ vineyard::ObjectMeta::ResetKey (C++ function)
+
+ vineyard::ObjectMeta::ResetSignature (C++ function)
+
+ vineyard::ObjectMeta::SetBuffer (C++ function)
+
+ vineyard::ObjectMeta::SetClient (C++ function)
+
+ vineyard::ObjectMeta::SetGlobal (C++ function)
+
+ vineyard::ObjectMeta::SetId (C++ function)
+
+ vineyard::ObjectMeta::SetMetaData (C++ function)
+
+ vineyard::ObjectMeta::SetNBytes (C++ function)
+
+ vineyard::ObjectMeta::SetTypeName (C++ function)
+
+ vineyard::ObjectMeta::Timestamp (C++ function)
+
+ vineyard::ObjectMeta::ToString (C++ function)
+
+ vineyard::ObjectMeta::Unsafe (C++ function) , [1]
+
+ vineyard::ObjectMeta::~ObjectMeta (C++ function)
+
+ vineyard::RPCClient (C++ class)
+
+ vineyard::RPCClient::Connect (C++ function) , [1] , [2] , [3] , [4] , [5] , [6] , [7]
+
+ vineyard::RPCClient::CreateRemoteBlob (C++ function)
+
+ vineyard::RPCClient::CreateRemoteBlobs (C++ function)
+
+ vineyard::RPCClient::Fork (C++ function)
+
+ vineyard::RPCClient::GetMetaData (C++ function) , [1]
+
+ vineyard::RPCClient::GetObject (C++ function) , [1] , [2] , [3]
+
+ vineyard::RPCClient::GetObjects (C++ function)
+
+ vineyard::RPCClient::GetRemoteBlob (C++ function) , [1]
+
+ vineyard::RPCClient::GetRemoteBlobs (C++ function) , [1] , [2] , [3]
+
+ vineyard::RPCClient::IsFetchable (C++ function)
+
+ vineyard::RPCClient::IsRPC (C++ function)
+
+ vineyard::RPCClient::ListObjectMeta (C++ function)
+
+ vineyard::RPCClient::ListObjects (C++ function)
+
+ vineyard::RPCClient::remote_instance_id (C++ function)
+
+ vineyard::RPCClient::TryAcquireLock (C++ function)
+
+ vineyard::RPCClient::TryReleaseLock (C++ function)
+
+ vineyard::RPCClient::~RPCClient (C++ function)
+
+ vineyard::Scalar (C++ class)
+
+ vineyard::Scalar::Construct (C++ function)
+
+ vineyard::Scalar::Create (C++ function)
+
+ vineyard::Scalar::Type (C++ function)
+
+ vineyard::Scalar::Value (C++ function)
+
+ vineyard::ScalarBuilder (C++ class)
+
+ vineyard::ScalarBuilder::ScalarBuilder (C++ function) , [1]
+
+ vineyard::ScalarBuilder::SetValue (C++ function)
+
+ vineyard::Sequence (C++ class)
+
+ vineyard::Sequence::At (C++ function)
+
+ vineyard::Sequence::begin (C++ function)
+
+ vineyard::Sequence::Construct (C++ function)
+
+ vineyard::Sequence::Create (C++ function)
+
+ vineyard::Sequence::end (C++ function)
+
+ vineyard::Sequence::First (C++ function)
+
+ vineyard::Sequence::iterator (C++ class)
+
+ vineyard::Sequence::iterator::iterator (C++ function)
+
+ vineyard::Sequence::iterator::operator!= (C++ function)
+
+ vineyard::Sequence::iterator::operator* (C++ function)
+
+ vineyard::Sequence::iterator::operator++ (C++ function)
+
+ vineyard::Sequence::iterator::operator== (C++ function)
+
+ vineyard::Sequence::Second (C++ function)
+
+ vineyard::Sequence::Size (C++ function)
+
+ vineyard::SequenceBuilder (C++ class)
+
+ vineyard::SequenceBuilder::At (C++ function)
+
+ vineyard::SequenceBuilder::SequenceBuilder (C++ function) , [1]
+
+ vineyard::SequenceBuilder::SetSize (C++ function)
+
+ vineyard::SequenceBuilder::SetValue (C++ function) , [1]
+
+ vineyard::SequenceBuilder::Size (C++ function)
+
+ vineyard::Tensor (C++ class)
+
+ vineyard::Tensor::ArrowTensor (C++ function)
+
+ vineyard::Tensor::ArrowTensorT (C++ type)
+
+ vineyard::Tensor::auxiliary_buffer (C++ function)
+
+ vineyard::Tensor::buffer (C++ function)
+
+ vineyard::Tensor::Construct (C++ function)
+
+ vineyard::Tensor::Create (C++ function)
+
+ vineyard::Tensor::data (C++ function)
+
+ vineyard::Tensor::operator[] (C++ function)
+
+ vineyard::Tensor::partition_index (C++ function)
+
+ vineyard::Tensor::shape (C++ function)
+
+ vineyard::Tensor::strides (C++ function)
+
+ vineyard::Tensor::value_const_pointer_t (C++ type)
+
+ vineyard::Tensor::value_pointer_t (C++ type)
+
+ vineyard::Tensor::value_t (C++ type)
+
+ vineyard::Tensor::value_type (C++ function)
+
+ vineyard::TensorBuilder (C++ class)
+
+ vineyard::TensorBuilder::Build (C++ function)
+
+ vineyard::TensorBuilder::data (C++ function)
+
+ vineyard::TensorBuilder::partition_index (C++ function)
+
+ vineyard::TensorBuilder::set_partition_index (C++ function)
+
+ vineyard::TensorBuilder::set_shape (C++ function)
+
+ vineyard::TensorBuilder::shape (C++ function)
+
+ vineyard::TensorBuilder::strides (C++ function)
+
+ vineyard::TensorBuilder::TensorBuilder (C++ function) , [1]
+
+ vineyard::TensorBuilder::value_const_pointer_t (C++ type)
+
+ vineyard::TensorBuilder::value_pointer_t (C++ type)
+
+ vineyard::TensorBuilder::value_t (C++ type)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000000..7f647f2239
--- /dev/null
+++ b/index.html
@@ -0,0 +1,306 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vineyard: an In-Memory Data Manager for Data-Intensive Analytics
+
+
+
+
+
+
+
+
+ Vineyard: an In-Memory Data Manager for Data-Intensive Analytics
+
+
+ An innovative cloud-native in-memory immutable data manager that offers
+ out-of-the-box high-level abstractions and zero-copy in-memory sharing
+ for distributed data in various big data tasks.
+
+
+
+ pip install vineyard
+
+ Successfully installed vineyard
+ python
+ client = vineyard.connect()
+ object_id = client.put('Hello, vineyard!')
+ client.get(object_id)
+ 'Hello, vineyard!'
+
+
+
+
+
+
+
Efficient data sharing
+
+ Vineyard shares immutable data across different systems using shared
+ memory without extra overheads, eliminating the overhead of
+ serialization and deserialization.
+
+
Learn More
+
+
+
+ Out-of-the-box data abstraction
+
+
+ Vineyard defines a metadata-payload separated data model to capture
+ the payload commonalities and method commonalities between sharable
+ objects.
+
+
Learn More
+
+
+
+
+
+ Pluggable I/O
+ routines
+
+
+ Vineyard provides common manipulation routines for immutable data as
+ drivers, which extend the capabilities of data structures by
+ registering appropriate drivers.
+
+
Learn More
+
+
+
+ Data orchestration on
+ Kubernetes
+
+
+ Vineyard provides efficient distributed data sharing in cloud-native
+ environments by embracing cloud-native big data processing.
+
+
Learn More
+
+
+
+
+ Use Cases
+
+
+
Object store for all
+
+ Putting and getting arbitrary objects using Vineyard, in a zero-copy way!
+
+
Learn More
+
+
+
Data sharing in Kedro pipelines
+
Sharing intermediate data between tasks in Kedro pipelines.
+
Learn More
+
+
+
Data processing for machine learning
+
+ Sharing large objects between different systems in data preprocessing pipelines in machine learning applications.
+
+
Learn More
+
+
+
Data sharing on Kubernetes
+
+ Coordinating the flow of objects and jobs on Kubernetes
+ with the data-aware scheduler plugin.
+
+
Learn More
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/architecture.html b/notes/architecture.html
new file mode 100644
index 0000000000..68f31980e9
--- /dev/null
+++ b/notes/architecture.html
@@ -0,0 +1,688 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Architecture - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Architecture
+
+Overview
+The following figure illustrates the architecture of Vineyard.
+
+
+
+Architecture of Vineyard
+
+
+
+Server side
+On the server (daemon) side (i.e., the aforementioned Vineyard instance), there are
+three primary components:
+
+The shared memory is the memory space in Vineyard that is shared with Vineyard
+clients via the UNIX domain socket through memory mapping.
+As previously mentioned, the partitions of the distributed data reside in the
+shared memory of the corresponding Vineyard instance in the cluster.
+
+The metadata manager is responsible for managing the metadata of the data stored
+in Vineyard.
+The metadata manager maintains the metadata (structures, layouts, and properties) of
+the data to provide high-level abstractions (e.g., graphs, tensors, dataframes).
+The metadata managers in a Vineyard cluster communicate with each other through
+the backend key-value store, such as etcd server, to ensure the consistency of the
+distributed data stored in Vineyard.
+
+The IPC/RPC servers manage the IPC/RPC connections from Vineyard
+clients for data sharing.
+Specifically, the client can retrieve both metadata and data partitions stored in
+Vineyard via IPC and RPC connections. However, when both connection types are available,
+IPC connections are prioritized due to the greater efficiency of memory mapping for data
+sharing.
+
+
+
+
+Client side
+On the client side, the core component is the Vineyard client . The client side
+includes both low-level APIs for accessing Vineyard instances in a precise
+manner and high-level APIs for data structure sharing, manipulation, and
+routine reuse (e.g., I/O drivers). More specifically,
+
+The IPC client communicates with local Vineyard instances by connecting
+to the UNIX domain socket.
+The IPC client is used to establish an IPC connection between the Vineyard server and
+the client, enabling memory-sharing (by mmap
and transferring the file descriptor)
+between the Vineyard server and the computing engines.
+
+The RPC client communicates with remote Vineyard instances by connecting
+to the TCP port that the Vineyard daemon is bound to.
+Unlike the IPC client, the RPC client doesn’t allow memory sharing between processes
+and is less efficient in that regard. However, it is still useful for retrieving both
+metadata and payloads from the Vineyard cluster via TCP or RDMA.
+
+The builders and resolvers for out-of-the-box high-level data abstractions
+offer a convenient way for applications to consume objects in Vineyard and
+produce result objects into Vineyard.
+The builders and resolvers adopt an extensible design where users can register
+their own builders and resolvers for their newly defined data types, as well as
+new builders and resolvers that build ad-hoc engine-specific data structures
+as Vineyard objects and wrap Vineyard objects as engine-specific data types
+at a low cost.
+The builders, resolvers, and the registry are part of the language-specific
+SDKs of Vineyard. Currently, Python and C++ are officially supported, and the Rust
+and Go SDKs are under heavy development.
+
+The pluggable drivers assign specific functionalities to certain types of data
+in Vineyard.
+In particular, I/O drivers synchronize with external storages such as databases and file
+systems to read data into and write data from Vineyard, while partition and
+re-partition drivers reorganize the distributed graphs stored in Vineyard to
+balance the workload.
+
+
Note
+
The drivers typically employ the low-level APIs for precise operations.
+
+
+Object migration is the mechanism implemented on the client side to
+migrate objects between Vineyard instances in a cluster. Object migration
+is usually needed when the computing engines cannot be scheduled to co-locate
+with the data required by the jobs.
+Object migration is implemented on the client side as a process pair where the
+sender and receiver are both connected to (different) Vineyard instances and
+communicate with each other using TCP to move objects between Vineyard instances.
+We don’t put the object migration on the server side to decouple the functionalities
+and allow users to register a more efficient object migration implemented on
+their own deployment infrastructures, e.g.,leveraging RDMA and other high-performance
+network technologies.
+
+
+
+
+
+Core features
+
+Zero-cost in-memory data sharing
+Vineyard provides zero-cost data sharing through memory-mapping, as data objects
+in Vineyard are immutable. When an object is created, we allocate blobs in
+Vineyard to store the data payload. On the other hand, when retrieving the object,
+we map the blob from the Vineyard instance into the application process using
+inter-process memory mapping techniques, ensuring that no memory copy is involved
+in sharing the data payload.
+
+
+Distributed data sharing in big data tasks
+By examining the practices of big data tasks such as numeric computing, machine learning,
+and graph analysis, we have identified four key properties of the data involved:
+
+Distributed and each partitioned fragment usually fits into memory;
+Immutable, i.e., never modified after creation;
+With complex structure, e.g., graph in CSR format;
+Required to share between different computation systems and programming languages.
+
+Vineyard is designed to address these challenges with:
+
+Composable design for Vineyard objects;
+Immutable zero-cost in-memory data sharing via memory mapping;
+Out-of-the-box high-level data abstraction for complex data structures;
+Extensible design for builder/resolver/driver, enabling flexible cross-system and
+cross-language data sharing.
+
+In general, Vineyard’s design choices are fully determined by addressing
+the difficulties in handling large-scale distributed data in practice.
+
+
+Out-of-the-box high-level data abstraction
+Vineyard objects are stored with structures and high-level abstractions.
+For instance, a graph with CSR format in Vineyard stores the index along with
+the vertices and edges, enabling operations like edge iteration based on the
+index. This means users don’t have to implement the index-building
+function and edge iterators themselves, which is often required in
+existing big data practices.
+
+
+Convenient data integration
+The extensible design of builder/resolver/driver allows for convenient extension
+of existing Vineyard objects to different programming languages. Moreover,
+with codegen tools in Vineyard, users can easily transplant their
+data structures into Vineyard with only a few annotations.
+
+
+Data orchestration in a Python notebook
+Using Vineyard as the common data orchestration engine throughout the end-to-end
+big data processing, users can hold large-scale distributed data as variables
+of Vineyard objects in Python. As long as the computation modules
+involved provide Python APIs, users can write down the entire processing
+pipeline in a Python notebook. By running the Python script, users can
+manage trillions of data and different computation systems in the background
+distributedly across the cluster.
+
+
+
+Non-goals and limitations
+
+NO mutable objects
+Once a Vineyard object is created and sealed in the Vineyard instance, it
+becomes immutable and can NOT be modified anymore. Thus, Vineyard is not
+suitable for use as a data cache to store mutable data that changes
+rapidly along the processing pipeline.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/cloud-native/deploy-kubernetes.html b/notes/cloud-native/deploy-kubernetes.html
new file mode 100644
index 0000000000..dab3d58ef3
--- /dev/null
+++ b/notes/cloud-native/deploy-kubernetes.html
@@ -0,0 +1,704 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Deploy on Kubernetes - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Deploy on Kubernetes
+Vineyard is managed by the Vineyard Operator on Kubernetes.
+
+Quick start
+If you want to install vineyard cluster quickly, you can
+use the following command.
+Install vineyardctl as follows.
+
+Use the vineyardctl to install vineyard cluster.
+ python3 -m vineyard.ctl deploy vineyard-cluster --create-namespace
+
+
+Also, you could follow the next guide to install vineyard cluster steps
+by steps.
+
+
+Install vineyard-operator
+There are two recommended methods for installing the vineyard operator: using Helm (preferred) or
+installing directly from the source code.
+
+
Note
+
Prior to installing the vineyard operator, ensure that you have a Kubernetes cluster and kubectl
+installed. In this guide, we will use kind to create a cluster.
+
+
+Option #1: Install from helm chart (recommended)
+ $ helm repo add vineyard https://vineyard.oss-ap-southeast-1.aliyuncs.com/charts/
+$ helm repo update
+$ helm install vineyard-operator vineyard/vineyard-operator \
+ --namespace vineyard-system \
+ --create-namespace
+
+
+Wait for the vineyard operator until ready.
+
+
+
+Wait vineyard-operator ready
+Once the operator is installed, its deployment can be checked using kubectl
:
+ $ kubectl get all -n vineyard-system
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+pod/vineyard-controller-manager-5c6f4bc454-8xm8q 2 /2 Running 0 62m
+
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
+service/vineyard-controller-manager-metrics-service ClusterIP 10 .96.240.173 <none> 8443 /TCP 62m
+service/vineyard-webhook-service ClusterIP 10 .96.41.132 <none> 443 /TCP 62m
+
+NAME READY UP-TO-DATE AVAILABLE AGE
+deployment.apps/vineyard-controller-manager 1 /1 1 1 62m
+
+NAME DESIRED CURRENT READY AGE
+replicaset.apps/vineyard-controller-manager-5c6f4bc454 1 1 1 62m
+
+
+
+
+
+
+
+Create vineyard cluster
+Once the vineyard operator becomes ready, you can create a vineyard cluster by creating a
+Vineyardd
CRD . The following is an example of creating a vineyard cluster with 3 daemon
+replicas:
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Vineyardd
+metadata :
+ name : vineyardd-sample
+ # don't use default namespace
+ namespace : vineyard-system
+spec :
+ replicas : 3
+ service :
+ type : ClusterIP
+ port : 9600
+ vineyard :
+ image : vineyardcloudnative/vineyardd:latest
+ imagePullPolicy : IfNotPresent
+EOF
+
+
+The vineyard-operator efficiently creates the necessary dependencies, such as etcd, and establishes a
+Deployment
for a 3-replica vineyard server configuration. Once the setup is complete, you can
+conveniently inspect the components created and managed by the vineyard operator using the kubectl
+command.
+ $ kubectl get all -n vineyard-system
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+pod/etcd0 1 /1 Running 0 48s
+pod/etcd1 1 /1 Running 0 48s
+pod/etcd2 1 /1 Running 0 48s
+pod/vineyard-controller-manager-5c6f4bc454-8xm8q 2 /2 Running 0 72s
+pod/vineyardd-sample-5cc797668f-9ggr9 1 /1 Running 0 48s
+pod/vineyardd-sample-5cc797668f-nhw7p 1 /1 Running 0 48s
+pod/vineyardd-sample-5cc797668f-r56h7 1 /1 Running 0 48s
+
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
+service/etcd-for-vineyard ClusterIP 10 .96.174.41 <none> 2379 /TCP 48s
+service/etcd0 ClusterIP 10 .96.128.87 <none> 2379 /TCP,2380/TCP 48s
+service/etcd1 ClusterIP 10 .96.72.116 <none> 2379 /TCP,2380/TCP 48s
+service/etcd2 ClusterIP 10 .96.99.182 <none> 2379 /TCP,2380/TCP 48s
+service/vineyard-controller-manager-metrics-service ClusterIP 10 .96.240.173 <none> 8443 /TCP 72s
+service/vineyard-webhook-service ClusterIP 10 .96.41.132 <none> 443 /TCP 72s
+service/vineyardd-sample-rpc ClusterIP 10 .96.102.183 <none> 9600 /TCP 48s
+
+NAME READY UP-TO-DATE AVAILABLE AGE
+deployment.apps/vineyard-controller-manager 1 /1 1 1 72s
+deployment.apps/vineyardd-sample 3 /3 3 3 48s
+
+NAME DESIRED CURRENT READY AGE
+replicaset.apps/vineyard-controller-manager-5c6f4bc454 1 1 1 72s
+replicaset.apps/vineyardd-sample-5cc797668f 3 3 3 48s
+
+
+
+
+
+
+References
+In addition to deploying and managing the vineyard cluster, the operator plays a crucial role in scheduling
+workloads on vineyard. This optimizes data sharing between tasks in workflows and triggers necessary data
+movement or transformation tasks. Detailed references and examples can be found in vineyard-operator
.
+To simplify interactions with vineyard on Kubernetes, we offer a command-line tool, vineyardctl
, which
+automates much of the boilerplate configuration required when deploying workflows with vineyard on Kubernetes.
+
+
+
+
+
+
+
Vineyard operator manages vineyard cluster and orchestrates shared objects on Kubernetes.
+
+
+
+
+
+
+
+
vineyardctl
is the command-line tool for working with the Vineyard Operator.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/cloud-native/vineyard-operator.html b/notes/cloud-native/vineyard-operator.html
new file mode 100644
index 0000000000..a8ba25878f
--- /dev/null
+++ b/notes/cloud-native/vineyard-operator.html
@@ -0,0 +1,1850 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vineyard Operator - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Vineyard Operator
+
+Architecture
+The following figure demonstrates the architecture of vineyard operator.
+
+
+
+Architecture of vineyard operator
+
+
+
+
+Create a vineyard Cluster
+After successfully installing the vineyard operator (refer to Deploy on Kubernetes
+for installation details), you can effortlessly create a vineyard cluster by utilizing
+the Vineyardd
CRD. The following example demonstrates the creation of a vineyard
+cluster with 3 daemon replicas:
+
+
Note
+
The namespace of the vineyard cluster must be the same as the namespace of the
+vineyard operator, as the vineyard cluster will use the vineyard operator’s
+service account.
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Vineyardd
+metadata :
+ name : vineyardd-sample
+ # use the same namespace as the vineyard operator
+ namespace : vineyard-system
+EOF
+
+
+The vineyard-operator orchestrates the creation of a deployment for the required metadata
+service backend (etcd
), sets up appropriate services, and ultimately establishes a
+deployment for 3-replica vineyard servers. Upon successful deployment, the following
+components will be created and managed by the vineyard operator:
+ $ kubectl get all -n vineyard-system
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+pod/etcd0 1 /1 Running 0 48s
+pod/etcd1 1 /1 Running 0 48s
+pod/etcd2 1 /1 Running 0 48s
+pod/vineyard-controller-manager-5c6f4bc454-8xm8q 2 /2 Running 0 72s
+pod/vineyardd-sample-5cc797668f-9ggr9 1 /1 Running 0 48s
+pod/vineyardd-sample-5cc797668f-nhw7p 1 /1 Running 0 48s
+pod/vineyardd-sample-5cc797668f-r56h7 1 /1 Running 0 48s
+
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
+service/etcd-for-vineyard ClusterIP 10 .96.174.41 <none> 2379 /TCP 48s
+service/etcd0 ClusterIP 10 .96.128.87 <none> 2379 /TCP,2380/TCP 48s
+service/etcd1 ClusterIP 10 .96.72.116 <none> 2379 /TCP,2380/TCP 48s
+service/etcd2 ClusterIP 10 .96.99.182 <none> 2379 /TCP,2380/TCP 48s
+service/vineyard-controller-manager-metrics-service ClusterIP 10 .96.240.173 <none> 8443 /TCP 72s
+service/vineyard-webhook-service ClusterIP 10 .96.41.132 <none> 443 /TCP 72s
+service/vineyardd-sample-rpc ClusterIP 10 .96.102.183 <none> 9600 /TCP 48s
+
+NAME READY UP-TO-DATE AVAILABLE AGE
+deployment.apps/vineyard-controller-manager 1 /1 1 1 72s
+deployment.apps/vineyardd-sample 3 /3 3 3 48s
+
+NAME DESIRED CURRENT READY AGE
+replicaset.apps/vineyard-controller-manager-5c6f4bc454 1 1 1 72s
+replicaset.apps/vineyardd-sample-5cc797668f 3 3 3 48s
+
+
+
+
+Also, if you want to use the custom vineyard socket path and mount something like /dev to the
+vineyard container, you could use the following YAML file:
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Vineyardd
+metadata :
+ name : vineyardd-sample
+spec :
+ vineyard :
+ # only for host path
+ socket : /your/vineyard/socket/path
+ # you should set the securityContext.privileged to true
+ # if you want to mount /dev to the vineyard container
+ securityContext :
+ privileged : true
+ volumes :
+ - name : dev-volumes
+ hostPath :
+ path : /dev
+ volumeMounts :
+ - name : dev-volumes
+ mountPath : /dev
+EOF
+
+
+For detailed configuration entries of vineyardd, please refer to vineyardd CRD .
+
+
+Installing vineyard as sidecar
+Vineyard can be seamlessly integrated as a sidecar container within a pod. We offer the Sidecar
+Custom Resource Definition (CRD) for configuring and managing the sidecar container. The Sidecar
+CRD shares many similarities with the Vineyardd CRD, and all available configurations can be found
+in the Sidecar CRD .
+Besides, We provide some labels and annotations to help users to use the sidecar in vineyard operator.
+The following are all labels that we provide:
+
+
+Sidecar Configurations
+
+
+
+
+
+
+Name
+Yaml Fields
+Description
+
+
+
+“sidecar.v6d.io/enabled”
+labels
+Enable the sidecar.
+
+“sidecar.v6d.io/name”
+annotations
+The name of sidecar cr. If the name is default , the default sidecar cr will be created.
+
+
+
+
+There are two methods to install vineyard as a sidecar:
+
+Utilize the default sidecar configuration . Users should add two annotations,
+sidecar.v6d.io/enabled: true and sidecar.v6d.io/name: default , to their app’s YAML.
+This will create a default sidecar Custom Resource (CR) for observation.
+Employ the custom sidecar configuration . Users must first create a custom sidecar CR,
+such as sidecar-demo , and then add two annotations, sidecar.v6d.io/enabled: true and
+sidecar.v6d.io/name: sidecar-demo , to their app’s YAML.
+
+The following example demonstrates how to install vineyard as a sidecar container within a
+pod. First, install the vineyard operator according to the previous steps, and then create
+a namespace with the specific label sidecar-injection: enabled to enable the sidecar.
+ $ kubectl create namespace vineyard-job
+$ kubectl label namespace vineyard-job sidecar-injection= enabled
+
+
+Next, use the following YAML to inject the default sidecar into the pod.
+
+
Note
+
Please configure the command field of your app container to be in the format
+[“/bin/sh” or “/bin/bash”, “-c”, (your app command)] . After injecting the vineyard
+sidecar, the command field will be modified to [“/bin/sh” or “/bin/bash”, “-c”,
+while [ ! -e /var/run/vineyard.sock ]; do sleep 1; done;” + (your app command)] to
+ensure that the vineyard sidecar is ready before the app container starts.
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : job-deployment
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : job-deployment
+ replicas : 2
+ template :
+ metadata :
+ annotations :
+ sidecar.v6d.io/name : "default"
+ labels :
+ app : job-deployment
+ sidecar.v6d.io/enabled : "true"
+ spec :
+ containers :
+ - name : job
+ image : ghcr.io/v6d-io/v6d/sidecar-job
+ imagePullPolicy : IfNotPresent
+ command : [ "/bin/sh" , "-c" , "python3 /job.py" ]
+ env :
+ - name : JOB_NAME
+ value : v6d-workflow-demo-job
+EOF
+
+
+Next, you could see the sidecar container injected into the pod.
+# get the default sidecar cr
+$ kubectl get sidecar app-job-deployment-default-sidecar -n vineyard-job -o yaml
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Sidecar
+metadata :
+ # the default sidecar's name is your label selector + "-default-sidecar"
+ name : app-job-deployment-default-sidecar
+ namespace : vineyard-job
+spec :
+ metric :
+ enable : false
+ image : vineyardcloudnative/vineyard-grok-exporter:latest
+ imagePullPolicy : IfNotPresent
+ replicas : 2
+ selector : app=job-deployment
+ service :
+ port : 9600
+ selector : rpc.vineyardd.v6d.io/rpc=vineyard-rpc
+ type : ClusterIP
+ vineyard :
+ image : vineyardcloudnative/vineyardd:latest
+ imagePullPolicy : IfNotPresent
+ size : ""
+ socket : /var/run/vineyard.sock
+ spill :
+ name : ""
+ path : ""
+ persistentVolumeClaimSpec :
+ resources : {}
+ persistentVolumeSpec : {}
+ spillLowerRate : "0.3"
+ spillUpperRate : "0.8"
+ streamThreshold : 80
+ syncCRDs : true
+# get the injected Pod, here we only show the important part of the Pod
+$ kubectl get pod -l app=job-deployment -n vineyard-job -o yaml
+apiVersion : v1
+kind : Pod
+metadata :
+ name : job-deployment-55664458f8-h4jzk
+ namespace : vineyard-job
+spec :
+ containers :
+ - command :
+ - /bin/sh
+ - -c
+ - while [ ! -e /var/run/vineyard.sock ]; do sleep 1; done;python3 /job.py
+ env :
+ - name : JOB_NAME
+ value : v6d-workflow-demo-job
+ image : ghcr.io/v6d-io/v6d/sidecar-job
+ imagePullPolicy : IfNotPresent
+ name : job
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-socket
+ - command :
+ - /bin/bash
+ - -c
+ - |
+ /usr/local/bin/vineyardd --sync_crds true --socket /var/run/vineyard.sock
+ --stream_threshold 80 --etcd_cmd etcd --etcd_prefix /vineyard
+ --etcd_endpoint http://etcd-for-vineyard:2379
+ env :
+ - name : VINEYARDD_UID
+ value : 7b0c2ec8-49f3-4f8f-9e5f-8576a4dc4321
+ - name : VINEYARDD_NAME
+ value : app-job-deployment-with-default-sidecar-default-sidecar
+ - name : VINEYARDD_NAMESPACE
+ value : vineyard-job
+ image : vineyardcloudnative/vineyardd:latest
+ imagePullPolicy : IfNotPresent
+ name : vineyard-sidecar
+ ports :
+ - containerPort : 9600
+ name : vineyard-rpc
+ protocol : TCP
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-socket
+ volumes :
+ - emptyDir : {}
+ name : vineyard-socket
+# get the number of injected sidecar
+$ kubectl get sidecar -A
+NAMESPACE NAME CURRENT DESIRED
+vineyard-job app-job-deployment-with-default-sidecar-default-sidecar 2 2
+
+
+If you don’t want to use the default sidecar configuration, you could create a custom
+sidecar cr as follows:
+
+
Note
+
Please make sure your custom sidecar cr is created before deploying your app workload
+and keep the same namespace with your app workload.
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Sidecar
+metadata :
+ name : sidecar-sample
+ namespace : vineyard-job
+spec :
+ replicas : 2
+ selector : app=job-deployment-with-custom-sidecar
+ vineyard :
+ socket : /var/run/vineyard.sock
+ size : 1024Mi
+---
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : job-deployment-with-custom-sidecar
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : job-deployment-with-custom-sidecar
+ replicas : 2
+ template :
+ metadata :
+ annotations :
+ sidecar.v6d.io/name : "sidecar-sample"
+ labels :
+ app : job-deployment-with-custom-sidecar
+ sidecar.v6d.io/enabled : "true"
+ spec :
+ containers :
+ - name : job
+ image : ghcr.io/v6d-io/v6d/sidecar-job
+ imagePullPolicy : IfNotPresent
+ command : [ "/bin/sh" , "-c" , "python3 /job.py" ]
+ env :
+ - name : JOB_NAME
+ value : v6d-workflow-demo-job
+EOF
+
+
+Also, if you want to use the custom vineyard socket path and mount something like /dev to the
+vineyard container, you could use the following YAML file:
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Sidecar
+metadata :
+ name : sidecar-sample
+ namespace : vineyard-job
+spec :
+ replicas : 2
+ selector : app=job-deployment-with-custom-sidecar
+ vineyard :
+ socket : /var/run/vineyard.sock
+ size : 1024Mi
+ # you should set the securityContext.privileged to true
+ # if you want to mount /dev to the vineyard container
+ securityContext :
+ privileged : true
+ volumes :
+ - name : dev-volumes
+ hostPath :
+ path : /dev
+ volumeMounts :
+ - name : dev-volumes
+ mountPath : /dev
+---
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : job-deployment-with-custom-sidecar
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : job-deployment-with-custom-sidecar
+ replicas : 2
+ template :
+ metadata :
+ annotations :
+ sidecar.v6d.io/name : "sidecar-sample"
+ labels :
+ app : job-deployment-with-custom-sidecar
+ sidecar.v6d.io/enabled : "true"
+ spec :
+ containers :
+ - name : job
+ image : ghcr.io/v6d-io/v6d/sidecar-job
+ imagePullPolicy : IfNotPresent
+ command : [ "/bin/sh" , "-c" , "python3 /job.py" ]
+ env :
+ - name : JOB_NAME
+ value : v6d-workflow-demo-job
+EOF
+
+
+For more details about how to use the sidecar, please refer to the sidecar e2e test for
+more inspiration.
+
+
+Objects in Vineyard
+Vineyard objects are exposed to the Kubernetes control panel as Custom Resource Definitions (CRDs).
+In vineyard, objects are abstracted as global objects and local objects (refer to Objects ),
+which are represented by the GlobalObject and LocalObject CRDs in the vineyard operator:
+
+GlobalObject
+The GlobalObject custom resource definition (CRD) declaratively defines a global object
+within a vineyard cluster, and all configurations can be found in the
+GlobalObject CRD .
+In general, the GlobalObjects are created as intermediate objects when deploying
+users’ applications. You could get them as follows.
+ $ kubectl get globalobjects -A
+NAMESPACE NAME ID NAME SIGNATURE TYPENAME
+vineyard-system o001bcbcea406acd0 o001bcbcea406acd0 s001bcbcea4069f60 vineyard::GlobalDataFrame
+vineyard-system o001bcc19dbfc9c34 o001bcc19dbfc9c34 s001bcc19dbfc8d7a vineyard::GlobalDataFrame
+
+
+
+
+LocalObject
+The LocalObject custom resource definition (CRD) declaratively defines the local object
+in a Kubernetes cluster, and you can find all configurations in the LocalObject CRD .
+The LocalObjects are also intermediate objects just like the GlobalObjects, and you could
+get them as follows.
+ $ kubectl get localobjects -A
+
+
+
+
Expected output
+
+ NAMESPACE NAME ID NAME SIGNATURE TYPENAME INSTANCE HOSTNAME
+vineyard-system o001bcbce202ab390 o001bcbce202ab390 s001bcbce202aa6f6 vineyard::DataFrame 0 kind-worker2
+vineyard-system o001bcbce21d273e4 o001bcbce21d273e4 s001bcbce21d269c2 vineyard::DataFrame 1 kind-worker
+vineyard-system o001bcbce24606f6a o001bcbce24606f6a s001bcbce246067fc vineyard::DataFrame 2 kind-worker3
+
+
+
+
+
+
+
+Vineyard Scheduler
+The Vineyard operator includes a scheduler plugin designed to efficiently schedule workloads
+on Vineyard by placing them as close as possible to their input data, thereby reducing data
+migration costs. The Vineyard scheduler plugin is developed based on the Kubernetes Scheduling
+Framework , and its overall scheduling strategy can be summarized as follows:
+
+All Vineyard workloads can only be deployed on nodes where the Vineyard daemon server is
+present.
+If a workload does not depend on any other workload, it will be scheduled using a
+round-robin approach. For example, if a workload has 3 replicas and there are 3 nodes
+with Vineyard daemon servers, the first replica will be scheduled on the first node, the
+second replica on the second node, and so on.
+If a workload depends on other workloads, it will be scheduled using a best-effort policy.
+Assuming a workload produces N chunks during its lifecycle, and there are M nodes with
+Vineyard daemon servers, the best-effort policy will attempt to make the next workload
+consume M/N
: chunks. For instance, imagine a workload produces 12 chunks with the
+following distribution:
+node1 : 0 - 8
+node2 : 9 - 11
+node3 : 12
+
+
+The next workload has 3 replicas, and the best-effort policy will schedule it as follows:
+replica1 -> node1 ( consume 0 - 3 chunks )
+replica2 -> node1 ( consume 4 - 7 chunks )
+replica3 -> node2 ( consume 9 - 11 chunks , the other chunks will be migrated to the node )
+
+
+
+
+
+Utilizing the Vineyard Scheduler
+The Vineyard scheduler is integrated into the Vineyard operator and deployed alongside it.
+This scheduler plugin relies on specific annotations and labels to provide necessary input
+information. The required configurations are listed below in a clear and comprehensive manner:
+
+
Scheduler Plugin Configurations
+
+
+
+
+
+
+
+
+
+Name
+Yaml Fields
+Description
+
+
+
+“scheduling.k8s.v6d.io/required”
+annotations
+All jobs required by the job. If there are
+more than two tasks, use the concatenator ‘,’
+to concatenate them into a string.
+E.g. job1,job2,job3 .
+If there is no required jobs, set none .
+
+“scheduling.k8s.v6d.io/vineyardd”
+labels
+The name or namespaced name of vineyardd. e.g.,
+vineyard-sample or
+vineyard-system/vineyard-sample .
+
+“scheduling.k8s.v6d.io/job “”
+labels
+The job name.
+
+“schedulerName”
+spec
+The vineyard scheduler’s name, and the
+default value is vineyard-scheduler .
+
+
+
+
+
+
+In this section, we will demonstrate a comprehensive example of utilizing the Vineyard
+scheduler. To begin, ensure that the Vineyard operator and Vineyard daemon server are
+installed by following the steps outlined earlier. Then, proceed to deploy workflow-job1
+as shown below.
+ $ kubectl create ns vineyard-job
+
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : v6d-workflow-demo-job1-deployment
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : v6d-workflow-demo-job1
+ replicas : 2
+ template :
+ metadata :
+ labels :
+ app : v6d-workflow-demo-job1
+ # vineyardd's name
+ scheduling.k8s.v6d.io/vineyardd-namespace : vineyard-system
+ scheduling.k8s.v6d.io/vineyardd : vineyardd-sample
+ # job name
+ scheduling.k8s.v6d.io/job : v6d-workflow-demo-job1
+ spec :
+ # vineyard scheduler name
+ schedulerName : vineyard-scheduler
+ containers :
+ - name : job1
+ image : ghcr.io/v6d-io/v6d/workflow-job1
+ # please set the JOB_NAME env, it will be used by vineyard scheduler
+ env :
+ - name : JOB_NAME
+ value : v6d-workflow-demo-job1
+ imagePullPolicy : IfNotPresent
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-sock
+ volumes :
+ - name : vineyard-sock
+ hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+EOF
+
+
+We can see the created job and the objects produced by it:
+ $ kubectl get all -n vineyard-job
+NAME READY STATUS RESTARTS AGE
+pod/v6d-workflow-demo-job1-deployment-6f479d695b-698xb 1 /1 Running 0 3m16s
+pod/v6d-workflow-demo-job1-deployment-6f479d695b-7zrw6 1 /1 Running 0 3m16s
+
+NAME READY UP-TO-DATE AVAILABLE AGE
+deployment.apps/v6d-workflow-demo-job1-deployment 2 /2 2 2 3m16s
+
+NAME DESIRED CURRENT READY AGE
+replicaset.apps/v6d-workflow-demo-job1-deployment-6f479d695b 2 2 2 3m16s
+
+$ kubectl get globalobjects -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME
+o001c87014cf03c70 o001c87014cf03c70 s001c87014cf03262 vineyard::Sequence
+o001c8729e49e06b8 o001c8729e49e06b8 s001c8729e49dfbb4 vineyard::Sequence
+
+$ kubectl get localobjects -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME INSTANCE HOSTNAME
+o001c87014ca81924 o001c87014ca81924 s001c87014ca80acc vineyard::Tensor<int64> 1 kind-worker2
+o001c8729e4590626 o001c8729e4590626 s001c8729e458f47a vineyard::Tensor<int64> 2 kind-worker3
+
+# when a job is scheduled, the scheduler will create a configmap to record the globalobject id
+# that the next job will consume.
+$ kubectl get configmap v6d-workflow-demo-job1 -n vineyard-job -o yaml
+apiVersion: v1
+data:
+ kind-worker3: o001c8729e4590626
+ v6d-workflow-demo-job1: o001c8729e49e06b8
+kind: ConfigMap
+...
+
+
+Then deploy the workflow-job2 as follows.
+$ cat <<EOF | kubectl apply -f -
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : v6d-workflow-demo-job2-deployment
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : v6d-workflow-demo-job2
+replicas : 3
+template :
+ metadata :
+ annotations :
+ # required jobs
+ scheduling.k8s.v6d.io/required : v6d-workflow-demo-job1
+ labels :
+ app : v6d-workflow-demo-job2
+ # vineyardd's name
+ scheduling.k8s.v6d.io/vineyardd-namespace : vineyard-system
+ scheduling.k8s.v6d.io/vineyardd : vineyardd-sample
+ # job name
+ scheduling.k8s.v6d.io/job : v6d-workflow-demo-job2
+ spec :
+ # vineyard scheduler name
+ schedulerName : vineyard-scheduler
+ containers :
+ - name : job2
+ image : ghcr.io/v6d-io/v6d/workflow-job2
+ imagePullPolicy : IfNotPresent
+ env :
+ - name : JOB_NAME
+ value : v6d-workflow-demo-job2
+ # pass node name to the environment
+ - name : NODENAME
+ valueFrom :
+ fieldRef :
+ fieldPath : spec.nodeName
+ # Notice, vineyard operator will create a configmap to pass the global object id produced by the previous job.
+ # Please set the configMapRef, it's name is the same as the job name.
+ envFrom :
+ - configMapRef :
+ name : v6d-workflow-demo-job1
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-sock
+ volumes :
+ - name : vineyard-sock
+ hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+EOF
+
+
+Now you can see that both jobs have been scheduled and become running:
+ $ kubectl get all -n vineyard-job
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+pod/v6d-workflow-demo-job1-deployment-6f479d695b-698xb 1 /1 Running 0 8m12s
+pod/v6d-workflow-demo-job1-deployment-6f479d695b-7zrw6 1 /1 Running 0 8m12s
+pod/v6d-workflow-demo-job2-deployment-b5b58cbdc-4s7b2 1 /1 Running 0 6m24s
+pod/v6d-workflow-demo-job2-deployment-b5b58cbdc-cd5v2 1 /1 Running 0 6m24s
+pod/v6d-workflow-demo-job2-deployment-b5b58cbdc-n6zvm 1 /1 Running 0 6m24s
+
+NAME READY UP-TO-DATE AVAILABLE AGE
+deployment.apps/v6d-workflow-demo-job1-deployment 2 /2 2 2 8m12s
+deployment.apps/v6d-workflow-demo-job2-deployment 3 /3 3 3 6m24s
+
+NAME DESIRED CURRENT READY AGE
+replicaset.apps/v6d-workflow-demo-job1-deployment-6f479d695b 2 2 2 8m12s
+replicaset.apps/v6d-workflow-demo-job2-deployment-b5b58cbdc 3 3 3 6m24s
+
+
+
+
+The above is the process of running the workload based on the vineyard scheduler, and it’s same
+as the workflow e2e test . What’s more, you could refer to the
+workflow demo to dig into what happens in the container.
+
+
+
+Operations and drivers
+The Operation custom resource definition (CRD) elegantly defines the configurable
+pluggable drivers, primarily assembly and repartition , within a Kubernetes cluster.
+You could refer the Operation CRD to get more details.
+The Operation Custom Resource (CR) is created by the vineyard scheduler while scheduling vineyard jobs.
+You can retrieve the created Operation CRs as follows:
+ $ kubectl get operation -A
+NAMESPACE NAME OPERATION TYPE STATE
+vineyard-job dask-repartition-job2-bbf596bf4-985vc repartition dask
+
+
+Currently, the vineyard operator includes three pluggable drivers: checkpoint , assembly , and
+repartition . The following sections provide a brief introduction to each of these drivers.
+
+Checkpoint
+Vineyard currently supports two types of checkpoint drivers:
+
+Active checkpoint - Serialization : Users can store data in temporary or persistent storage
+for checkpoint purposes using the API (vineyard.io.serialize/deserialize ). Note that the
+serialization process is triggered by the user within the application image, and the volume is
+also created by the user. Therefore, it is not managed by the vineyard operator.
+Passive checkpoint - Spill : Vineyard now supports spilling data from memory to storage
+when the data size exceeds the available memory capacity. There are two watermarks for memory
+spilling: the low watermark and the high watermark. When the data size surpasses the high watermark,
+vineyardd will spill the excess data to storage until it reaches the low watermark.
+
+
+Triggering a checkpoint job
+Now, the checkpoint driver (Spill ) is configured within the vineyardd Custom Resource
+Definition (CRD). To create a default vineyardd daemon server with the spill mechanism enabled,
+use the following YAML file:
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Vineyardd
+metadata :
+ name : vineyardd-sample
+ # use the same namespace as the vineyard operator
+ namespace : vineyard-system
+spec :
+ vineyard :
+ # spill configuration
+ spill :
+ name : spill-path
+ # please make sure the path exists
+ path : /var/vineyard/spill
+ spillLowerRate : "0.3"
+ spillUpperRate : "0.8"
+ persistentVolumeSpec :
+ storageClassName : manual
+ capacity :
+ storage : 1Gi
+ accessModes :
+ - ReadWriteOnce
+ hostPath :
+ path : /var/vineyard/spill
+ persistentVolumeClaimSpec :
+ storageClassName : manual
+ accessModes :
+ - ReadWriteOnce
+ resources :
+ requests :
+ storage : 512Mi
+EOF
+
+
+For a comprehensive understanding of the checkpoint mechanism in the vineyard operator,
+please refer to the checkpoint examples . Additionally, the serialize e2e test and
+the spill e2e test can provide valuable insights on how to effectively utilize the
+checkpoint mechanism within a workflow.
+
+
+
+Assembly
+In real-world scenarios, workloads often involve various computing engines. Some of these
+engines support stream types to accelerate data processing, while others do not. To ensure
+the seamless operation of the workload, an assembly mechanism is required to convert the
+stream type into a chunk type. This conversion enables subsequent computing engines that
+do not support stream types to read the metadata generated by the previous engine.
+
+Triggering an assembly job
+To reduce the load on the Kubernetes API Server, we offer a namespace selector for assembly.
+The assembly driver will only be applied to namespaces with the specific label
+operation-injection: enabled . Therefore, ensure that the application’s namespace has
+this label before using the assembly mechanism.
+We provide several labels to assist users in utilizing the assembly mechanism in the
+vineyard operator. The following are the available labels:
+
+
Assembly Drivers Configurations
+
+
+
+
+
+
+
+
+
+Name
+Yaml Fields
+Description
+
+
+
+“assembly.v6d.io/enabled”
+labels
+If the job needs an assembly operation
+before deploying it, then set true .
+
+“assembly.v6d.io/type”
+labels
+There are two types in assembly operation,
+local only for localobject(stream on the same node),
+distributed for globalobject(stream on different nodes).
+
+
+
+
+
+
+In this example, we demonstrate how to utilize the assembly mechanism in the
+vineyard operator. We have a workflow consisting of two workloads: the first
+workload processes a stream, and the second workload processes a chunk. The
+assembly mechanism is used to convert the stream output from the first workload
+into a chunk format that can be consumed by the second workload. The following
+YAML file represents the assembly workload1 :
+
+
Note
+
Ensure that the vineyard operator and vineyardd are installed before
+executing the following YAML file.
+
+ $ kubectl create namespace vineyard-job
+
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : assembly-job1
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : assembly-job1
+ replicas : 1
+ template :
+ metadata :
+ labels :
+ app : assembly-job1
+ # this label represents the vineyardd's name that need to be used
+ scheduling.k8s.v6d.io/vineyardd-namespace : vineyard-system
+ scheduling.k8s.v6d.io/vineyardd : vineyardd-sample
+ scheduling.k8s.v6d.io/job : assembly-job1
+ spec :
+ schedulerName : vineyard-scheduler
+ containers :
+ - name : assembly-job1
+ image : ghcr.io/v6d-io/v6d/assembly-job1
+ env :
+ - name : JOB_NAME
+ value : assembly-job1
+ imagePullPolicy : IfNotPresent
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-sock
+ volumes :
+ - name : vineyard-sock
+ hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+EOF
+# we can get the localobjects produced by the first workload, it's a stream type.
+$ kubectl get localobjects -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME INSTANCE HOSTNAME
+o001d1b280049b146 o001d1b280049b146 s001d1b280049a4d4 vineyard::RecordBatchStream 0 kind-worker2
+
+
+From the output above, it is evident that the localobjects generated by the first
+workload are of the stream type. Next, we will deploy the second workload utilizing
+the assembly mechanism. The following YAML file represents the assembly workload2 :
+# remember label the namespace with the label `operation-injection: enabled` to
+# enable pluggable drivers.
+$ kubectl label namespace vineyard-job operation-injection= enabled
+
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : assembly-job2
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : assembly-job2
+ replicas : 1
+ template :
+ metadata :
+ annotations :
+ scheduling.k8s.v6d.io/required : assembly-job1
+ labels :
+ app : assembly-job2
+ assembly.v6d.io/enabled : "true"
+ assembly.v6d.io/type : "local"
+ # this label represents the vineyardd's name that need to be used
+ scheduling.k8s.v6d.io/vineyardd-namespace : vineyard-system
+ scheduling.k8s.v6d.io/vineyardd : vineyardd-sample
+ scheduling.k8s.v6d.io/job : assembly-job2
+ spec :
+ schedulerName : vineyard-scheduler
+ containers :
+ - name : assembly-job2
+ image : ghcr.io/v6d-io/v6d/assembly-job2
+ env :
+ - name : JOB_NAME
+ value : assembly-job2
+ - name : REQUIRED_JOB_NAME
+ value : assembly-job1
+ envFrom :
+ - configMapRef :
+ name : assembly-job1
+ imagePullPolicy : IfNotPresent
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-sock
+ volumes :
+ - name : vineyard-sock
+ hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+EOF
+
+
+Upon deploying the second workload, it remains in a pending state. This indicates that the scheduler
+has identified the need for an assembly operation, and consequently, the corresponding assembly
+operation Custom Resource (CR) will be created.
+# get all workloads, the job2 is pending as it needs an assembly operation.
+$ kubectl get pod -n vineyard-job
+NAME READY STATUS RESTARTS AGE
+assembly-job1-86c99c995f-nzns8 1 /1 Running 0 2m
+assembly-job2-646b78f494-cvz2w 0 /1 Pending 0 53s
+
+# the assembly operation CR is created by the scheduler.
+$ kubectl get operation -A
+NAMESPACE NAME OPERATION TYPE STATE
+vineyard-job assembly-job2-646b78f494-cvz2w assembly local
+
+
+During the assembly operation, the Operation Controller will create a job to run assembly
+operation. We can get the objects produced by the job.
+# get the assembly operation job
+$ kubectl get job -n vineyard-job
+NAMESPACE NAME COMPLETIONS DURATION AGE
+vineyard-job assemble-o001d1b280049b146 1 /1 26s 119s
+# get the pod
+$ kubectl get pod -n vineyard-job
+NAME READY STATUS RESTARTS AGE
+assemble-o001d1b280049b146-fzws7 0 /1 Completed 0 5m55s
+assembly-job1-86c99c995f-nzns8 1 /1 Running 0 4m
+assembly-job2-646b78f494-cvz2w 0 /1 Pending 0 5m
+
+# get the localobjects produced by the job
+$ kubectl get localobjects -l k8s.v6d.io/created-podname= assemble-o001d1b280049b146-fzws7 -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME INSTANCE HOSTNAME
+o001d1b56f0ec01f8 o001d1b56f0ec01f8 s001d1b56f0ebf578 vineyard::DataFrame 0 kind-worker2
+o001d1b5707c74e62 o001d1b5707c74e62 s001d1b5707c742e0 vineyard::DataFrame 0 kind-worker2
+o001d1b571f47cfe2 o001d1b571f47cfe2 s001d1b571f47c3c0 vineyard::DataFrame 0 kind-worker2
+o001d1b5736a6fd6c o001d1b5736a6fd6c s001d1b5736a6f1cc vineyard::DataFrame 0 kind-worker2
+o001d1b574d9b94ae o001d1b574d9b94ae s001d1b574d9b8a9e vineyard::DataFrame 0 kind-worker2
+o001d1b5765629cbc o001d1b5765629cbc s001d1b57656290a8 vineyard::DataFrame 0 kind-worker2
+o001d1b57809911ce o001d1b57809911ce s001d1b57809904e0 vineyard::DataFrame 0 kind-worker2
+o001d1b5797a9f958 o001d1b5797a9f958 s001d1b5797a9ee82 vineyard::DataFrame 0 kind-worker2
+o001d1b57add9581c o001d1b57add9581c s001d1b57add94e62 vineyard::DataFrame 0 kind-worker2
+o001d1b57c53875ae o001d1b57c53875ae s001d1b57c5386a22 vineyard::DataFrame 0 kind-worker2
+
+# get the globalobjects produced by the job
+$ kubectl get globalobjects -l k8s.v6d.io/created-podname= assemble-o001d1b280049b146-fzws7 -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME
+o001d1b57dc2c74ee o001d1b57dc2c74ee s001d1b57dc2c6a4a vineyard::Sequence
+
+
+Each stream will be transformed into a globalobject. To make the second workload obtain the
+globalobject generated by the assembly operation, the vineyard scheduler will create a configmap
+to store the globalobject id as follows.
+ $ kubectl get configmap assembly-job1 -n vineyard-job -o yaml
+apiVersion: v1
+data:
+ assembly-job1: o001d1b57dc2c74ee
+kind: ConfigMap
+...
+
+
+Upon completion of the assembly operation, the scheduler will reschedule the second workload,
+allowing it to be successfully deployed as shown below:
+ $ kubectl get pod -n vineyard-job
+NAME READY STATUS RESTARTS AGE
+assemble-o001d1b280049b146-fzws7 0 /1 Completed 0 9m55s
+assembly-job1-86c99c995f-nzns8 1 /1 Running 0 8m
+assembly-job2-646b78f494-cvz2w 1 /1 Running 0 9m
+
+
+The assembly operation process is demonstrated in the local assembly e2e test . For more
+details, please refer to the assembly demo and local assembly operation .
+Additionally, we also support distributed assembly operation . You can explore the
+distributed assembly e2e test for further insights.
+
+
+
+Repartitioning
+Repartitioning is a mechanism that adjusts the distribution of data across the Vineyard
+cluster. It is particularly useful when the number of workers cannot accommodate the required
+number of partitions. For example, if a workload creates 4 partitions, but the subsequent
+workload has only 3 workers, the repartitioning mechanism will redistribute the partitions
+from 4 to 3, allowing the next workload to function as expected. Currently, the Vineyard
+operator supports repartitioning based on dask .
+
+Initiating a Repartition Job
+For workloads based on Dask, we provide several annotations and labels to help users
+utilize the repartitioning mechanism in the Vineyard operator. The following list contains
+all the labels and annotations we offer:
+
+
Dask Repartition Drivers Configurations
+
+
+
+
+
+
+
+
+
+Name
+Yaml Fields
+Description
+
+
+
+“scheduling.k8s.v6d.io/dask-scheduler”
+annotations
+The service of dask scheduler.
+
+“scheduling.k8s.v6d.io/dask-worker-selector”
+annotations
+The label selector of dask worker pod.
+
+“repartition.v6d.io/enabled”
+labels
+Enable the repartition.
+
+“repartition.v6d.io/type”
+labels
+The type of repartition, at present,
+only support dask .
+
+“scheduling.k8s.v6d.io/replicas”
+labels
+The replicas of the workload.
+
+
+
+
+
+
+The following is a demo of repartition based on dask. At first, we create a dask cluster
+with 3 workers.
+
+
Note
+
Please make sure you have installed the vineyard operator and vineyardd before
+running the following yaml file.
+
+# install dask scheduler and dask worker.
+$ helm repo add dask https://helm.dask.org/
+$ helm repo update
+
+
+# the dask-worker's image is built with vineyard, please refer
+# https://github.com/v6d-io/v6d/blob/main/k8s/test/e2e/repartition-demo/Dockerfile.dask-worker-with-vineyard.
+$ cat <<EOF | helm install dask-cluster dask/dask --values -
+scheduler :
+ image :
+ tag : "2022.8.1"
+
+jupyter :
+ enabled : false
+
+worker :
+ # worker numbers
+ replicas : 3
+ image :
+ repository : ghcr.io/v6d-io/v6d/dask-worker-with-vineyard
+ tag : latest
+ env :
+ - name : VINEYARD_IPC_SOCKET
+ value : /var/run/vineyard.sock
+ - name : VINEYARD_RPC_SOCKET
+ value : vineyardd-sample-rpc.vineyard-system:9600
+ mounts :
+ volumes :
+ - name : vineyard-sock
+ hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-sock
+EOF
+
+
+Deploy the repartition workload1 as follows:
+ $ kubectl create namespace vineyard-job
+
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : dask-repartition-job1
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : dask-repartition-job1
+ replicas : 1
+ template :
+ metadata :
+ annotations :
+ scheduling.k8s.v6d.io/dask-scheduler : "tcp://my-release-dask-scheduler.default:8786"
+ # use ',' to separate the different labels here
+ scheduling.k8s.v6d.io/dask-worker-selector : "app:dask,component:worker"
+ labels :
+ app : dask-repartition-job1
+ repartition.v6d.io/type : "dask"
+ scheduling.k8s.v6d.io/replicas : "1"
+ # this label represents the vineyardd's name that need to be used
+ scheduling.k8s.v6d.io/vineyardd-namespace : vineyard-system
+ scheduling.k8s.v6d.io/vineyardd : vineyardd-sample
+ scheduling.k8s.v6d.io/job : dask-repartition-job1
+ spec :
+ schedulerName : vineyard-scheduler
+ containers :
+ - name : dask-repartition-job1
+ image : ghcr.io/v6d-io/v6d/dask-repartition-job1
+ imagePullPolicy : IfNotPresent
+ env :
+ - name : JOB_NAME
+ value : dask-repartition-job1
+ - name : DASK_SCHEDULER
+ value : tcp://my-release-dask-scheduler.default:8786
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-sock
+ volumes :
+ - name : vineyard-sock
+ hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+EOF
+
+
+The first workload will create 4 partitions (each partition as a localobject):
+ $ kubectl get globalobjects -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME
+o001d2a6ae6c6e2e8 o001d2a6ae6c6e2e8 s001d2a6ae6c6d4f4 vineyard::GlobalDataFrame
+$ kubectl get localobjects -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME INSTANCE HOSTNAME
+o001d2a6a6483ac44 o001d2a6a6483ac44 s001d2a6a6483a3ce vineyard::DataFrame 1 kind-worker3
+o001d2a6a64a29cf4 o001d2a6a64a29cf4 s001d2a6a64a28f2e vineyard::DataFrame 0 kind-worker
+o001d2a6a66709f20 o001d2a6a66709f20 s001d2a6a667092a2 vineyard::DataFrame 2 kind-worker2
+o001d2a6ace0f6e30 o001d2a6ace0f6e30 s001d2a6ace0f65b8 vineyard::DataFrame 2 kind-worker2
+
+
+Deploy the repartition workload2 as follows:
+ $ kubectl label namespace vineyard-job operation-injection= enabled
+
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : dask-repartition-job2
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : dask-repartition-job2
+ replicas : 1
+ template :
+ metadata :
+ annotations :
+ scheduling.k8s.v6d.io/required : "dask-repartition-job1"
+ scheduling.k8s.v6d.io/dask-scheduler : "tcp://my-release-dask-scheduler.default:8786"
+ # use ',' to separate the different labels here
+ scheduling.k8s.v6d.io/dask-worker-selector : "app:dask,component:worker"
+ labels :
+ app : dask-repartition-job2
+ repartition.v6d.io/enabled : "true"
+ repartition.v6d.io/type : "dask"
+ scheduling.k8s.v6d.io/replicas : "1"
+ # this label represents the vineyardd's name that need to be used
+ scheduling.k8s.v6d.io/vineyardd-namespace : vineyard-system
+ scheduling.k8s.v6d.io/vineyardd : vineyardd-sample
+ scheduling.k8s.v6d.io/job : dask-repartition-job2
+ spec :
+ schedulerName : vineyard-scheduler
+ containers :
+ - name : dask-repartition-job2
+ image : ghcr.io/v6d-io/v6d/dask-repartition-job2
+ imagePullPolicy : IfNotPresent
+ env :
+ - name : JOB_NAME
+ value : dask-repartition-job2
+ - name : DASK_SCHEDULER
+ value : tcp://my-release-dask-scheduler.default:8786
+ - name : REQUIRED_JOB_NAME
+ value : dask-repartition-job1
+ envFrom :
+ - configMapRef :
+ name : dask-repartition-job1
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-sock
+ volumes :
+ - name : vineyard-sock
+ hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+EOF
+
+
+The second workload waits for the repartition operation to finish:
+# check all workloads
+$ kubectl get pod -n vineyard-job
+NAME READY STATUS RESTARTS AGE
+dask-repartition-job1-5dbfc54997-7kghk 1 /1 Running 0 92s
+dask-repartition-job2-bbf596bf4-cvrt2 0 /1 Pending 0 49s
+
+# check the repartition operation
+$ kubectl get operation -A
+NAMESPACE NAME OPERATION TYPE STATE
+vineyard-job dask-repartition-job2-bbf596bf4-cvrt2 repartition dask
+
+# check the job
+$ kubectl get job -n vineyard-job
+NAME COMPLETIONS DURATION AGE
+repartition-o001d2a6ae6c6e2e8 0 /1 8s 8s
+
+
+After the repartition job finishes, the second workload will be scheduled:
+# check all workloads
+$ kubectl get pod -n vineyard-job
+NAME READY STATUS RESTARTS AGE
+dask-repartition-job1-5dbfc54997-7kghk 1 /1 Running 0 5m43s
+dask-repartition-job2-bbf596bf4-cvrt2 0 /1 Pending 0 4m30s
+repartition-o001d2a6ae6c6e2e8-79wcm 0 /1 Completed 0 3m30s
+
+# check the repartition operation
+# as the second workload only has 1 replica, the repartition operation will repartitioned
+# the global object into 1 partition
+$ kubectl get globalobjects -n vineyard-system
+NAME ID NAME SIGNATURE TYPENAME
+o001d2ab523e3fbd0 o001d2ab523e3fbd0 s001d2ab523e3f0e6 vineyard::GlobalDataFrame
+
+# the repartition operation will create a new local object(only 1 partition)
+$ kubectl get localobjects -n vineyard-system
+NAMESPACE NAME ID NAME SIGNATURE TYPENAME INSTANCE HOSTNAME
+vineyard-system o001d2dc18d72a47e o001d2dc18d72a47e s001d2dc18d729ab6 vineyard::DataFrame 2 kind-worker2
+
+
+The whole workflow can be found in dask repartition e2e test . What’s more,
+please refer the repartition directory to get more details.
+
+
+
+
+Failover mechanism of vineyard cluster
+If you want to back up data for the current vineyard cluster, you can create a Backup CR to
+perform a backup operation. As the Backup CR will use the default service account of the
+namespace the vineyard operator is deployed, you need to set up the same namespace as
+the vineyard operator. Please refer the Backup CRD
+for more details.
+After data backup, you can create a Recover CR to restore a certain vineyard backup data.
+Please refer the Recover CRD for more details.
+Next, we will show how to use the failover mechanism in vineyard operator. Assuming that
+we have a vineyard cluster that contains some objects, then we create a backup cr to back
+up the data. The following is the yaml file of the backup:
+
+
Note
+
Please make sure you have installed the vineyard operator and vineyardd before
+running the following yaml file.
+
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Backup
+metadata :
+ name : backup-sample
+ namespace : vineyard-system
+spec :
+ vineyarddName : vineyardd-sample
+ vineyarddNamespace : vineyard-system
+ backupPath : /var/vineyard/dump
+ persistentVolumeSpec :
+ storageClassName : manual
+ capacity :
+ storage : 1Gi
+ accessModes :
+ - ReadWriteOnce
+ hostPath :
+ path : /var/vineyard/dump
+ persistentVolumeClaimSpec :
+ storageClassName : manual
+ accessModes :
+ - ReadWriteOnce
+ resources :
+ requests :
+ storage : 1Gi
+EOF
+
+
+Assuming that the vineyard cluster crashes at some point, we create Recover
CR to
+restore the data in the vineyard cluster, and the recover yaml file is as follows:
+$ cat <<EOF | kubectl apply -f -
+apiVersion : k8s.v6d.io/v1alpha1
+kind : Recover
+metadata :
+ name : recover-sample
+ namespace : vineyard-system
+spec :
+ backupName : backup-sample
+ backupNamespace : vineyard-system
+EOF
+
+
+Then you could get the Recover’s status to get the mapping relationship between the
+object ID during backup and the object ID during recovery as follows:
+ $ kubectl get recover -A
+NAMESPACE NAME MAPPING STATE
+vineyard-system recover-sample { "o000ef92379fd8850" :"o000ef9ea5189718d" ,"o000ef9237a3a5432" :"o000ef9eb5d26ad5e" ,"o000ef97a8289973f" :"o000ef9ed586ef1d3" } Succeed
+
+
+If you want to get more details about the failover mechanism of vineyard cluster, please refer
+the failover e2e test .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/cloud-native/vineyardctl.html b/notes/cloud-native/vineyardctl.html
new file mode 100644
index 0000000000..5c2c524a90
--- /dev/null
+++ b/notes/cloud-native/vineyardctl.html
@@ -0,0 +1,3213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ vineyardctl - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+vineyardctl
+vineyardctl is the command-line tool for interact with the Vineyard Operator.
+
+Synopsis
+vineyardctl is the command-line tool for working with the
+Vineyard Operator. It supports creating, deleting and checking
+status of Vineyard Operator. It also supports managing the
+vineyard relevant components such as vineyardd and pluggable
+drivers.
+SEE ALSO
+
+
+
+Options
+ -- create - namespace create the namespace if it does not exist , default false
+ - j , -- dump - usage Dump usage in JSON
+ - g , -- gen - doc Generate reference docs , e . g . , "./cmd/README.md"
+ - h , -- help help for vineyardctl
+ -- kubeconfig string kubeconfig path for the kubernetes cluster ( default "$HOME/.kube/config" )
+ - n , -- namespace string the namespace for operation ( default "vineyard-system" )
+ -- verbose print verbose log , default false
+ - v , -- version version for vineyardctl
+ -- wait wait for the kubernetes resource to be ready , default true ( default true )
+
+
+
+
+vineyardctl create
+Create a vineyard jobs on kubernetes
+SEE ALSO
+
+
+Examples
+ # create the backup job on kubernetes
+ vineyardctl create backup --vineyardd-name vineyardd-sample --vineyardd-namespace vineyard-system
+
+ # create the recover job on kubernetes
+ vineyardctl create recover --backup-name vineyardd-sample -n vineyard-system
+
+ # create the operation job on kubernetes
+ vineyardctl create operation --name assembly \
+ --type local \
+ --require job1 \
+ --target job2 \
+ --timeoutSeconds 600
+
+
+
+
+Options
+ - h , -- help help for create
+
+
+
+
+
+vineyardctl create backup
+Create a backup cr to backup the current vineyard cluster on kubernetes
+
+Synopsis
+Backup the current vineyard cluster on kubernetes. You could
+backup all objects of the current vineyard cluster quickly.
+For persistent storage, you could specify the pv spec and pv
+spec.
+Notice, the command is used to create a backup cr for the
+vineyard operator and you must deploy the vineyard operator
+and vineyard cluster before using it.
+vineyardctl create backup [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # create a backup cr for the vineyard cluster on kubernetes
+ # you could define the pv and pvc spec from json string as follows
+ vineyardctl create backup \
+ --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-system \
+ --limit 1000 \
+ --path /var/vineyard/dump \
+ --pv-pvc-spec '{
+ "pv-spec": {
+ "capacity": {
+ "storage": "1Gi"
+ },
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "storageClassName": "manual",
+ "hostPath": {
+ "path": "/var/vineyard/dump"
+ }
+ },
+ "pvc-spec": {
+ "storageClassName": "manual",
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "1Gi"
+ }
+ }
+ }
+ }'
+
+ # create a backup cr for the vineyard cluster on kubernetes
+ # you could define the pv and pvc spec from yaml string as follows
+ vineyardctl create backup \
+ --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-system \
+ --limit 1000 --path /var/vineyard/dump \
+ --pv-pvc-spec \
+ '
+ pv-spec:
+ capacity:
+ storage: 1Gi
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: manual
+ hostPath:
+ path: "/var/vineyard/dump"
+ pvc-spec:
+ storageClassName: manual
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ '
+
+ # create a backup cr for the vineyard cluster on kubernetes
+ # you could define the pv and pvc spec from json file as follows
+ # also you could use yaml file instead of json file
+ cat pv-pvc.json | vineyardctl create backup \
+ --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-system \
+ --limit 1000 --path /var/vineyard/dump \
+ -
+
+
+
+
+Options
+ -- backup - name string the name of backup job ( default "vineyard-backup" )
+ - h , -- help help for backup
+ -- objectIDs strings the specific objects to be backed up
+ -- path string the path of the backup data
+ -- pv - pvc - spec string the PersistentVolume and PersistentVolumeClaim of the backup data
+ -- vineyardd - name string the name of vineyardd
+ -- vineyardd - namespace string the namespace of vineyardd
+
+
+
+
+
+vineyardctl create operation
+Insert an operation in a workflow based on vineyard cluster
+
+Synopsis
+Insert an operation in a workflow based on vineyard cluster.
+You could create a assembly or repartition operation in a
+workflow. Usually, the operation should be created between
+the workloads: job1 -> operation -> job2.
+vineyardctl create operation [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # create a local assembly operation between job1 and job2
+ vineyardctl create operation --name assembly \
+ --type local \
+ --require job1 \
+ --target job2 \
+ --timeoutSeconds 600
+
+ # create a distributed assembly operation between job1 and job2
+ vineyardctl create operation --name assembly \
+ --type distributed \
+ --require job1 \
+ --target job2 \
+ --timeoutSeconds 600
+
+ # create a dask repartition operation between job1 and job2
+ vineyardctl create operation --name repartition \
+ --type dask \
+ --require job1 \
+ --target job2 \
+ --timeoutSeconds 600
+
+
+
+
+Options
+ - h , -- help help for operation
+ -- kind string the kind of operation , including "assembly" and "repartition"
+ -- name string the name of operation
+ -- require string the job that need an operation to be executed
+ -- target string the job that need to be executed before this operation
+ -- timeoutSeconds int the timeout seconds of operation ( default 600 )
+ -- type string the type of operation : for assembly , it can be "local" or "distributed" ; for repartition , it can be "dask"
+
+
+
+
+
+vineyardctl create recover
+Create a recover cr to recover the current vineyard cluster on kubernetes
+
+Synopsis
+Recover the current vineyard cluster on kubernetes. You could
+recover all objects from a backup of vineyard cluster. Usually,
+the recover crd should be created in the same namespace of
+the backup job.
+Notice, the command is used to create a recover cr for the
+vineyard operator and you must deploy the vineyard operator
+and vineyard cluster before using it.
+vineyardctl create recover [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # create a recover cr for a backup job in the same namespace
+ vineyardctl create recover --backup-name vineyardd-sample -n vineyard-system
+
+
+
+
+Options
+ -- backup - name string the name of backup job ( default "vineyard-backup" )
+ - h , -- help help for recover
+ -- recover - name string the name of recover job ( default "vineyard-recover" )
+
+
+
+
+
+vineyardctl csi
+Start the vineyard csi driver
+vineyardctl csi [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # start the csi with the specific endpoint and node id
+ vineyardctl csi --endpoint= unix:///csi/csi.sock --nodeid= csinode1
+
+
+
+
+Options
+ - f , -- endpoint string the endpoint of vineyard csi driver
+ - h , -- help help for csi
+ -- nodeid string the node id of vineyard csi driver
+ -- state - file - path string the path of state file ( default "/csi/state" )
+
+
+
+
+
+vineyardctl delete
+Delete the vineyard components from kubernetes
+SEE ALSO
+
+
+Examples
+ # delete the default vineyard cluster on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config delete
+
+ # delete the default vineyard operator on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config delete operator
+
+ # delete the default vineyardd on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config delete vineyardd
+
+
+
+
+Options
+ - h , -- help help for delete
+
+
+
+
+
+vineyardctl delete backup
+Delete the backup job on kubernetes
+
+Synopsis
+Delete the backup job on kubernetes.
+vineyardctl delete backup [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # delete the default backup job
+ vineyardctl delete backup
+
+
+
+
+Options
+ -- backup - name string the name of backup job ( default "vineyard-backup" )
+ - h , -- help help for backup
+
+
+
+
+
+vineyardctl delete csidriver
+Delete the vineyard csi driver on kubernetes
+vineyardctl delete csidriver [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # delete the csi driver named "csidriver-test"
+ vineyardctl delete csidriver --name csidriver-test
+
+
+
+
+Options
+ - h , -- help help for csidriver
+ -- name string The name of the csi driver cr . ( default "csidriver-sample" )
+
+
+
+
+
+vineyardctl delete operation
+Delete the operation from kubernetes
+vineyardctl delete operation [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # delete the operation named "assembly-test" in the "vineyard-system" namespace
+ vineyardctl delete operation --name assembly-test
+
+
+
+
+Options
+ - h , -- help help for operation
+ -- name string the name of operation
+
+
+
+
+
+vineyardctl delete operator
+Delete the vineyard operator from kubernetes
+vineyardctl delete operator [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # delete the default vineyard operator in the vineyard-system namespace
+ vineyardctl delete operator
+
+ # delete the vineyard operator in a specific namespace
+ vineyardctl delete operator -n <namespace>
+
+
+
+
+Options
+ - h , -- help help for operator
+
+
+
+
+
+vineyardctl delete recover
+Delete the recover job from kubernetes
+vineyardctl delete recover [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # delete the default recover job on kubernetes
+ vineyardctl delete recover
+
+
+
+
+Options
+ - h , -- help help for recover
+ -- recover - name string the name of recover job ( default "vineyard-recover" )
+
+
+
+
+
+vineyardctl delete vineyard-cluster
+Delete the vineyard cluster from kubernetes
+vineyardctl delete vineyard - cluster [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # delete the default vineyard cluster on kubernetes
+ vineyardctl delete vineyard-cluster
+
+
+
+
+Options
+ - h , -- help help for vineyard - cluster
+
+
+
+
+
+vineyardctl delete vineyard-deployment
+delete vineyard-deployment will delete the vineyard deployment without vineyard operator
+vineyardctl delete vineyard - deployment [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # delete the default vineyard deployment in the vineyard-system namespace
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config delete vineyard-deployment
+
+ # delete the vineyard deployment with specific name in the vineyard-system namespace
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config delete vineyard-deployment \
+ --name vineyardd-0
+
+
+
+
+Options
+ - h , -- help help for vineyard - deployment
+ -- name string the name of vineyardd ( default "vineyardd-sample" )
+
+
+
+
+
+vineyardctl delete vineyardd
+Delete the vineyardd cluster from kubernetes
+vineyardctl delete vineyardd [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # delete the default vineyardd cluster(vineyardd-sample) in the default namespace
+ vineyardctl delete vineyardd
+
+ # delete the specific vineyardd cluster in the vineyard-system namespace
+ vineyardctl -n vineyard-system delete vineyardd --name vineyardd-test
+
+
+
+
+Options
+ - h , -- help help for vineyardd
+ -- name string the name of vineyardd ( default "vineyardd-sample" )
+
+
+
+
+
+vineyardctl deploy
+Deploy the vineyard components on kubernetes
+SEE ALSO
+
+
+Examples
+ # deploy the default vineyard cluster on kubernetes
+ vineyardctl --kubeconfig $HOME /.kube/config deploy vineyard-cluster
+
+ # deploy the vineyard operator on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy operator
+
+ # deploy the vineyardd on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy vineyardd
+
+ # deploy the vineyard csi driver on kubernetes
+ vineyardctl deploy csidriver --name vineyard-csi-sample \
+ --clusters vineyard-system/vineyardd-sample,default/vineyardd-sample
+
+
+
+
+Options
+ - h , -- help help for deploy
+
+
+
+
+
+vineyardctl deploy backup-job
+Deploy a backup job of vineyard cluster on kubernetes
+
+Synopsis
+Deploy the backup job for the vineyard cluster on kubernetes,
+which will backup all objects of the current vineyard cluster
+quickly. For persistent storage, you could specify the pv spec
+and pv spec and the related pv and pvc will be created automatically.
+Also, you could also specify the existing pv and pvc name to use
+vineyardctl deploy backup - job [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # deploy a backup job for all vineyard objects of the vineyard
+ # cluster on kubernetes and you could define the pv and pvc
+ # spec from json string as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --path /var/vineyard/dump \
+ --pv-pvc-spec '{
+ "pv-spec": {
+ "capacity": {
+ "storage": "1Gi"
+ },
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "storageClassName": "manual",
+ "hostPath": {
+ "path": "/var/vineyard/dump"
+ }
+ },
+ "pvc-spec": {
+ "storageClassName": "manual",
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "1Gi"
+ }
+ }
+ }
+ }'
+
+ # deploy a backup job for the vineyard cluster on kubernetes
+ # you could define the pv and pvc spec from yaml string as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --path /var/vineyard/dump \
+ --pv-pvc-spec \
+ '
+ pv-spec:
+ capacity:
+ storage: 1Gi
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: manual
+ hostPath:
+ path: "/var/vineyard/dump"
+ pvc-spec:
+ storageClassName: manual
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ '
+
+ # deploy a backup job for specific vineyard objects of the vineyard
+ # cluster on kubernetes.
+ cat pv-pvc.json | vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --objectIDs "o000018d29207fd01,o000018d80d264010" \
+ --path /var/vineyard/dump
+
+ # Assume you have already deployed a pvc named "pvc-sample", you
+ # could use them as the backend storage for the backup job as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --path /var/vineyard/dump \
+ --pvc-name pvc-sample
+
+ # The namespace to deploy the backup and recover job must be the same
+ # as the vineyard cluster namespace.
+ # Assume the vineyard cluster is deployed in the namespace "test", you
+ # could deploy the backup job as follows
+ vineyardctl deploy backup-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace test \
+ --namespace test \
+ --path /var/vineyard/dump \
+ --pvc-name pvc-sample
+
+
+
+
+Options
+ -- backup - name string the name of backup job ( default "vineyard-backup" )
+ - h , -- help help for backup - job
+ -- objectIDs strings the specific objects to be backed up
+ -- path string the path of the backup data
+ -- pv - pvc - spec string the PersistentVolume and PersistentVolumeClaim of the backup data
+ -- pvc - name string the name of an existing PersistentVolumeClaim
+ -- vineyard - deployment - name string the name of vineyard deployment
+ -- vineyard - deployment - namespace string the namespace of vineyard deployment
+
+
+
+
+
+vineyardctl deploy csidriver
+Deploy the vineyard csi driver on kubernetes
+
+Synopsis
+Deploy the Vineyard CSI Driver on kubernetes.
+The CR is a cluster-scoped resource, and can only be created once.
+vineyardctl deploy csidriver [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # deploy the Vineyard CSI Driver named vineyard-csi-sample on kubernetes
+ # Notice, the clusters are built as {vineyard-deployment-namespace}/{vineyard-deployment-name}
+ # and sperated by comma, e.g. vineyard-system/vineyardd-sample, default/vineyardd-sample
+ # They must be created before deploying the Vineyard CSI Driver.
+ vineyardctl deploy csidriver --name vineyard-csi-sample \
+ --clusters vineyard-system/vineyardd-sample,default/vineyardd-sample
+
+
+
+
+Options
+ -- attacherImage string The image of csi attacher . ( default "registry.k8s.io/sig-storage/csi-attacher:v4.0.0" )
+ -- clusters strings The list of vineyard clusters .
+ -- enableToleration Enable toleration for vineyard csi driver .
+ - h , -- help help for csidriver
+ - i , -- image string The image of vineyard csi driver . ( default "vineyardcloudnative/vineyard-operator" )
+ -- imagePullPolicy string The image pull policy of vineyard csi driver . ( default "IfNotPresent" )
+ -- livenessProbeImage string The image of livenessProbe . ( default "registry.k8s.io/sig-storage/livenessprobe:v2.8.0" )
+ -- name string The name of the csi driver cr . ( default "csidriver-sample" )
+ -- nodeRegistrarImage string The image of csi nodeRegistrar . ( default "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.6.0" )
+ -- provisionerImage string The image of csi provisioner . ( default "registry.k8s.io/sig-storage/csi-provisioner:v3.3.0" )
+ -- sidecar . enableTopology Enable topology for the csi driver .
+ -- sidecar . imagePullPolicy string The image pull policy of all sidecar containers . ( default "Always" )
+ - s , -- storageClassName string The name of storage class . ( default "vineyard-csi" )
+ - m , -- volumeBindingMode string The volume binding mode of the storage class . ( default "WaitForFirstConsumer" )
+
+
+
+
+
+vineyardctl deploy operator
+Deploy the vineyard operator on kubernetes
+
+Synopsis
+Deploy the vineyard operator on kubernetes.
+vineyardctl deploy operator [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # deploy the vineyard operator on the 'vineyard-system' namespace
+ vineyardctl deploy operator
+
+ # deploy the vineyard operator on the existing namespace
+ vineyardctl deploy operator -n my-custom-namespace
+
+ # deploy the vineyard operator on the new namespace
+ vineyardctl deploy operator -n a-new-namespace-name --create-namespace
+
+
+
+
+Options
+ - h , -- help help for operator
+
+
+
+
+
+vineyardctl deploy recover-job
+Deploy a recover job to recover a backup of current vineyard cluster on kubernetes
+
+Synopsis
+Deploy the recover job for vineyard cluster on kubernetes, which
+will recover all objects from a backup of vineyard cluster. Usually,
+the recover job should be created in the same namespace of
+the backup job.
+vineyardctl deploy recover - job [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # Deploy a recover job for the vineyard deployment in the same namespace.
+ # After the recover job finished, the command will create a kubernetes
+ # configmap named [recover-name]+"-mapping-table" that contains the
+ # mapping table from the old vineyard objects to the new ones.
+ #
+ # If you create the recover job as follows, you can get the mapping table via
+ # "kubectl get configmap vineyard-recover-mapping-table -n vineyard-system -o yaml"
+ # the left column is the old object id, and the right column is the new object id.
+ vineyardctl deploy recover-job \
+ --vineyard-deployment-name vineyardd-sample \
+ --vineyard-deployment-namespace vineyard-system \
+ --recover-path /var/vineyard/dump \
+ --pvc-name vineyard-backup
+
+
+
+
+Options
+ - h , -- help help for recover - job
+ -- pvc - name string the name of an existing PersistentVolumeClaim
+ -- recover - name string the name of recover job ( default "vineyard-recover" )
+ -- recover - path string the path of recover job
+ -- vineyard - deployment - name string the name of vineyard deployment
+ -- vineyard - deployment - namespace string the namespace of vineyard deployment
+
+
+
+
+
+vineyardctl deploy vineyard-cluster
+Deploy the vineyard cluster from kubernetes
+vineyardctl deploy vineyard - cluster [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # deploy the default vineyard cluster on kubernetes
+ vineyardctl deploy vineyard-cluster
+
+
+
+
+Options
+ - h , -- help help for vineyard - cluster
+
+
+
+
+
+vineyardctl deploy vineyard-deployment
+DeployVineyardDeployment builds and deploy the yaml file of vineyardd without vineyard operator
+
+Synopsis
+Builds and deploy the yaml file of vineyardd the vineyardd
+without vineyard operator. You could deploy a customized
+vineyardd from stdin or file.
+vineyardctl deploy vineyard - deployment [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # deploy the default vineyard deployment on kubernetes
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config \
+ deploy vineyard-deployment
+
+ # deploy the vineyard deployment with customized image
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config \
+ deploy vineyard-deployment --image vineyardcloudnative/vineyardd:v0.12.2
+
+
+
+
+Options
+ -- etcd . replicas int the number of etcd replicas in a vineyard cluster ( default 1 )
+ - f , -- file string the path of vineyardd
+ - h , -- help help for vineyard - deployment
+ -- name string the name of vineyardd ( default "vineyardd-sample" )
+ -- owner - references string The owner reference of all vineyard deployment resources
+ -- pluginImage . backupImage string the backup image of vineyardd ( default "ghcr.io/v6d-io/v6d/backup-job" )
+ -- pluginImage . daskRepartitionImage string the dask repartition image of vineyardd workflow ( default "ghcr.io/v6d-io/v6d/dask-repartition" )
+ -- pluginImage . distributedAssemblyImage string the distributed image of vineyard workflow ( default "ghcr.io/v6d-io/v6d/distributed-assembly" )
+ -- pluginImage . localAssemblyImage string the local assembly image of vineyardd workflow ( default "ghcr.io/v6d-io/v6d/local-assembly" )
+ -- pluginImage . recoverImage string the recover image of vineyardd ( default "ghcr.io/v6d-io/v6d/recover-job" )
+ -- replicas int the number of vineyardd replicas ( default 3 )
+ -- securityContext string the json string of security context of vineyardd
+ -- vineyardd . cpu string the cpu requests and limits of vineyard container
+ -- vineyardd . envs strings The environment variables of vineyardd
+ -- vineyardd . image string the image of vineyardd ( default "vineyardcloudnative/vineyardd:latest" )
+ -- vineyardd . imagePullPolicy string the imagePullPolicy of vineyardd ( default "IfNotPresent" )
+ -- vineyardd . memory string the memory requests and limits of vineyard container
+ -- vineyardd . metric . enable enable metrics of vineyardd
+ -- vineyardd . metric . image string the metic image of vineyardd ( default "vineyardcloudnative/vineyard-grok-exporter:latest" )
+ -- vineyardd . metric . imagePullPolicy string the imagePullPolicy of the metric image ( default "IfNotPresent" )
+ -- vineyardd . reserve_memory Reserving enough physical memory pages for vineyardd
+ -- vineyardd . service . port int the service port of vineyard service ( default 9600 )
+ -- vineyardd . service . type string the service type of vineyard service ( default "ClusterIP" )
+ -- vineyardd . size string The size of vineyardd . You can use the power - of - two equivalents : Ei , Pi , Ti , Gi , Mi , Ki . Defaults "" , means not limited
+ -- vineyardd . socket string The directory on host for the IPC socket file . The namespace and name will be replaced with your vineyard config ( default "/var/run/vineyard-kubernetes/{{.Namespace}}/{{.Name}}" )
+ -- vineyardd . spill . config string If you want to enable the spill mechanism , please set the name of spill config
+ -- vineyardd . spill . path string The path of spill config
+ -- vineyardd . spill . pv - pvc - spec string the json string of the persistent volume and persistent volume claim
+ -- vineyardd . spill . spillLowerRate string The low watermark of spilling memory ( default "0.3" )
+ -- vineyardd . spill . spillUpperRate string The high watermark of spilling memory ( default "0.8" )
+ -- vineyardd . streamThreshold int memory threshold of streams ( percentage of total memory ) ( default 80 )
+ -- vineyardd . syncCRDs enable metrics of vineyardd ( default true )
+ -- vineyardd . volume . mountPath string Set the mount path for the pvc
+ -- vineyardd . volume . pvcname string Set the pvc name for storing the vineyard objects persistently
+ -- volume string the json string of vineyardd volume
+ -- volumeMount string the json string of vineyardd volume mount
+
+
+
+
+
+vineyardctl deploy vineyardd
+Deploy the vineyardd on kubernetes
+
+Synopsis
+Deploy the vineyardd on kubernetes. You could deploy a
+customized vineyardd from stdin or file.
+vineyardctl deploy vineyardd [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # deploy the default vineyard on kubernetes
+ # wait for the vineyardd to be ready(default option)
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy vineyardd
+
+ # not to wait for the vineyardd to be ready
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy vineyardd \
+ --wait= false
+
+ # deploy the vineyardd from a yaml file
+ vineyardctl --kubeconfig $HOME /.kube/config deploy vineyardd --file vineyardd.yaml
+
+ # deploy the vineyardd with customized image
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy vineyardd \
+ --image vineyardd:v0.12.2
+
+ # deploy the vineyardd with spill mechanism on persistent storage from json string
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy vineyardd \
+ --vineyardd.spill.config spill-path \
+ --vineyardd.spill.path /var/vineyard/spill \
+ --vineyardd.spill.pv-pvc-spec '{
+ "pv-spec": {
+ "capacity": {
+ "storage": "1Gi"
+ },
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "storageClassName": "manual",
+ "hostPath": {
+ "path": "/var/vineyard/spill"
+ }
+ },
+ "pvc-spec": {
+ "storageClassName": "manual",
+ "accessModes": [
+ "ReadWriteOnce"
+ ],
+ "resources": {
+ "requests": {
+ "storage": "512Mi"
+ }
+ }
+ }
+ }'
+
+ # deploy the vineyardd with spill mechanism on persistent storage from yaml string
+ vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy vineyardd \
+ --vineyardd.spill.config spill-path \
+ --vineyardd.spill.path /var/vineyard/spill \
+ --vineyardd.spill.pv-pvc-spec \
+ '
+ pv-spec:
+ capacity:
+ storage: 1Gi
+ accessModes:
+ - ReadWriteOnce
+ storageClassName: manual
+ hostPath:
+ path: "/var/vineyard/spill"
+ pvc-spec:
+ storageClassName: manual
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 512Mi
+ '
+
+# deploy the vineyardd with spill mechanism on persistent storage from json file
+ # also you could use the yaml file
+ cat pv-pvc.json | vineyardctl -n vineyard-system --kubeconfig $HOME /.kube/config deploy vineyardd \
+ --vineyardd.spill.config spill-path \
+ --vineyardd.spill.path /var/vineyard/spill \
+ -
+
+
+
+
+Options
+ -- etcd . replicas int the number of etcd replicas in a vineyard cluster ( default 1 )
+ - f , -- file string the path of vineyardd
+ - h , -- help help for vineyardd
+ -- name string the name of vineyardd ( default "vineyardd-sample" )
+ -- pluginImage . backupImage string the backup image of vineyardd ( default "ghcr.io/v6d-io/v6d/backup-job" )
+ -- pluginImage . daskRepartitionImage string the dask repartition image of vineyardd workflow ( default "ghcr.io/v6d-io/v6d/dask-repartition" )
+ -- pluginImage . distributedAssemblyImage string the distributed image of vineyard workflow ( default "ghcr.io/v6d-io/v6d/distributed-assembly" )
+ -- pluginImage . localAssemblyImage string the local assembly image of vineyardd workflow ( default "ghcr.io/v6d-io/v6d/local-assembly" )
+ -- pluginImage . recoverImage string the recover image of vineyardd ( default "ghcr.io/v6d-io/v6d/recover-job" )
+ -- replicas int the number of vineyardd replicas ( default 3 )
+ -- securityContext string the json string of security context of vineyardd
+ -- vineyardd . cpu string the cpu requests and limits of vineyard container
+ -- vineyardd . envs strings The environment variables of vineyardd
+ -- vineyardd . image string the image of vineyardd ( default "vineyardcloudnative/vineyardd:latest" )
+ -- vineyardd . imagePullPolicy string the imagePullPolicy of vineyardd ( default "IfNotPresent" )
+ -- vineyardd . memory string the memory requests and limits of vineyard container
+ -- vineyardd . metric . enable enable metrics of vineyardd
+ -- vineyardd . metric . image string the metic image of vineyardd ( default "vineyardcloudnative/vineyard-grok-exporter:latest" )
+ -- vineyardd . metric . imagePullPolicy string the imagePullPolicy of the metric image ( default "IfNotPresent" )
+ -- vineyardd . reserve_memory Reserving enough physical memory pages for vineyardd
+ -- vineyardd . service . port int the service port of vineyard service ( default 9600 )
+ -- vineyardd . service . type string the service type of vineyard service ( default "ClusterIP" )
+ -- vineyardd . size string The size of vineyardd . You can use the power - of - two equivalents : Ei , Pi , Ti , Gi , Mi , Ki . Defaults "" , means not limited
+ -- vineyardd . socket string The directory on host for the IPC socket file . The namespace and name will be replaced with your vineyard config ( default "/var/run/vineyard-kubernetes/{{.Namespace}}/{{.Name}}" )
+ -- vineyardd . spill . config string If you want to enable the spill mechanism , please set the name of spill config
+ -- vineyardd . spill . path string The path of spill config
+ -- vineyardd . spill . pv - pvc - spec string the json string of the persistent volume and persistent volume claim
+ -- vineyardd . spill . spillLowerRate string The low watermark of spilling memory ( default "0.3" )
+ -- vineyardd . spill . spillUpperRate string The high watermark of spilling memory ( default "0.8" )
+ -- vineyardd . streamThreshold int memory threshold of streams ( percentage of total memory ) ( default 80 )
+ -- vineyardd . syncCRDs enable metrics of vineyardd ( default true )
+ -- vineyardd . volume . mountPath string Set the mount path for the pvc
+ -- vineyardd . volume . pvcname string Set the pvc name for storing the vineyard objects persistently
+ -- volume string the json string of vineyardd volume
+ -- volumeMount string the json string of vineyardd volume mount
+
+
+
+
+
+vineyardctl get
+Get vineyard object, metadata, blob or cluster-info
+SEE ALSO
+
+
+Examples
+ # Connect the vineyardd deployment with IPC client
+ # Get the cluster info and output as table
+ vineyardctl get cluster-info --deployment-name vineyardd-sample -n vineyard-system
+
+
+
+
+Options
+ - h , -- help help for get
+
+
+
+
+
+vineyardctl get blob
+Get vineyard blob
+
+Synopsis
+Get vineyard blob and only support IPC socket.
+If you don’t specify the ipc socket every time, you can set it as the
+environment variable VINEYARD_IPC_SOCKET.
+vineyardctl get blob [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # Get vineyard blob with the given vineyard object_id and the ipc socket
+ vineyardctl get blob --object_id xxxxxxxx --ipc-socket /var/run/vineyard.sock
+
+ # Get vineyard blob with the given vineyard object_id and the ipc socket
+ # and set the unsafe to be true
+ vineyardctl get blob --object_id xxxxxxxx --unsafe --ipc-socket /var/run/vineyard.sock
+
+ # If you set the environment variable VINEYARD_IPC_SOCKET
+ # you can use the following command to get vineyard blob
+ vineyardctl get blob --object_id xxxxxxxx
+
+
+
+
+Options
+ -- deployment - name string the name of vineyard deployment
+ - o , -- format string the output format , support table or json , default is table ( default "table" )
+ -- forward - port int the forward port of vineyard deployment ( default 9600 )
+ - h , -- help help for blob
+ -- ipc - socket string vineyard IPC socket path
+ -- object_id string The object id to get
+ -- port int the port of vineyard deployment ( default 9600 )
+ -- rpc - socket string vineyard RPC socket path
+ -- syncRemote If the target object is a remote object , code_remote = True will force a meta synchronization on the vineyard server .
+ -- unsafe unsafe means getting the blob even the blob is not sealed yet . Default is False .
+
+
+
+
+
+vineyardctl get cluster-info
+Get vineyard cluster info
+
+Synopsis
+Get vineyard cluster info, including
+the instanceId, hostName, node name and so on.
+vineyardctl get cluster - info [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # Get the cluster info of vineyard deployment and output as table
+ vineyardctl get cluster-info --deployment-name vineyardd-sample -n vineyard-system
+
+ # Get the cluster info of vineyard deployment and output as json
+ vineyardctl get cluster-info --deployment-name vineyardd-sample -n vineyard-system -o json
+
+ # Get the cluster info via IPC socket
+ vineyardctl get cluster-info --ipc-socket /var/run/vineyard.sock
+
+
+
+
+Options
+ -- deployment - name string the name of vineyard deployment
+ - o , -- format string the output format , support table or json , default is table ( default "table" )
+ -- forward - port int the forward port of vineyard deployment ( default 9600 )
+ - h , -- help help for cluster - info
+ -- ipc - socket string vineyard IPC socket path
+ -- port int the port of vineyard deployment ( default 9600 )
+ -- rpc - socket string vineyard RPC socket path
+
+
+
+
+
+
+vineyardctl get object
+Get vineyard object
+
+Synopsis
+Get vineyard object and support IPC socket,
+RPC socket and vineyard deployment. If you don’t specify the ipc socket or rpc socket
+every time, you can set it as the environment variable VINEYARD_IPC_SOCKET or
+VINEYARD_RPC_SOCKET.
+vineyardctl get object [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # Get vineyard object with the given vineyard object_id and the ipc socket
+ vineyardctl get object --object_id xxxxxxxx --ipc-socket /var/run/vineyard.sock
+
+ # Get vineyard object with the given vineyard object_id and the rpc socket
+ vineyardctl get object --object_id xxxxxxxx --rpc-socket 127 .0.0.1:9600
+
+
+
+
+Options
+ -- deployment - name string the name of vineyard deployment
+ - o , -- format string the output format , support table or json , default is table ( default "table" )
+ -- forward - port int the forward port of vineyard deployment ( default 9600 )
+ - h , -- help help for object
+ -- ipc - socket string vineyard IPC socket path
+ -- object_id string The object id to get
+ -- port int the port of vineyard deployment ( default 9600 )
+ -- rpc - socket string vineyard RPC socket path
+ -- syncRemote If the target object is a remote object , code_remote = True will force a meta synchronization on the vineyard server .
+ -- unsafe unsafe means getting the blob even the blob is not sealed yet . Default is False .
+
+
+
+
+
+vineyardctl inject
+Inject the vineyard sidecar container into a workload
+
+Synopsis
+Inject the vineyard sidecar container into a workload. You can
+input a workload yaml or a workload json and then get the injected
+workload and some etcd manifests from the output. The workload can
+be a pod or a deployment or a statefulset, etc.
+The output is a set of manifests that includes the injected workload,
+the rpc service, the etcd service and the etcd cluster(e.g. several
+pods and services).
+If you have a pod yaml:
+apiVersion : v1
+kind : Pod
+metadata :
+ name : python
+spec :
+ containers :
+ - name : python
+ image : python:3.10
+ command : [ "python" , "-c" , "import time; time.sleep(100000)" ]
+
+
+Then, you can use the following command to inject the vineyard sidecar
+$ vineyardctl inject -f pod.yaml
+After running the command, the output is as follows:
+apiVersion : v1
+kind : Pod
+metadata :
+ labels :
+ app.vineyard.io/name : vineyard-sidecar
+ app.vineyard.io/role : etcd
+ etcd_node : vineyard-sidecar-etcd-0
+ name : vineyard-sidecar-etcd-0
+ namespace : null
+ ownerReferences : []
+spec :
+ containers :
+ - command :
+ - etcd
+ - --name
+ - vineyard-sidecar-etcd-0
+ - --initial-advertise-peer-urls
+ - http://vineyard-sidecar-etcd-0:2380
+ - --advertise-client-urls
+ - http://vineyard-sidecar-etcd-0:2379
+ - --listen-peer-urls
+ - http://0.0.0.0:2380
+ - --listen-client-urls
+ - http://0.0.0.0:2379
+ - --initial-cluster
+ - vineyard-sidecar-etcd-0=http://vineyard-sidecar-etcd-0:2380
+ - --initial-cluster-state
+ - new
+ image : vineyardcloudnative/vineyardd:latest
+ name : etcd
+ ports :
+ - containerPort : 2379
+ name : client
+ protocol : TCP
+ - containerPort : 2380
+ name : server
+ protocol : TCP
+ restartPolicy : Always
+---
+apiVersion : v1
+kind : Service
+metadata :
+ labels :
+ etcd_node : vineyard-sidecar-etcd-0
+ name : vineyard-sidecar-etcd-0
+ namespace : null
+ ownerReferences : []
+spec :
+ ports :
+ - name : client
+ port : 2379
+ protocol : TCP
+ targetPort : 2379
+ - name : server
+ port : 2380
+ protocol : TCP
+ targetPort : 2380
+ selector :
+ app.vineyard.io/role : etcd
+ etcd_node : vineyard-sidecar-etcd-0
+---
+apiVersion : v1
+kind : Service
+metadata :
+ name : vineyard-sidecar-etcd-service
+ namespace : null
+ ownerReferences : []
+spec :
+ ports :
+ - name : etcd-for-vineyard-port
+ port : 2379
+ protocol : TCP
+ targetPort : 2379
+ selector :
+ app.vineyard.io/name : vineyard-sidecar
+ app.vineyard.io/role : etcd
+---
+apiVersion : v1
+kind : Service
+metadata :
+ labels :
+ app.vineyard.io/name : vineyard-sidecar
+ name : vineyard-sidecar-rpc
+ namespace : null
+ ownerReferences : []
+spec :
+ ports :
+ - name : vineyard-rpc
+ port : 9600
+ protocol : TCP
+ selector :
+ app.vineyard.io/name : vineyard-sidecar
+ app.vineyard.io/role : vineyardd
+ type : ClusterIP
+---
+apiVersion : v1
+kind : Pod
+metadata :
+ creationTimestamp : null
+ labels :
+ app.vineyard.io/name : vineyard-sidecar
+ app.vineyard.io/role : vineyardd
+ name : python
+ ownerReferences : []
+spec :
+ containers :
+ - command :
+ - python
+ - -c
+ - while [ ! -e /var/run/vineyard.sock ]; do sleep 1; done;import time; time.sleep(100000)
+ env :
+ - name : VINEYARD_IPC_SOCKET
+ value : /var/run/vineyard.sock
+ image : python:3.10
+ name : python
+ resources : {}
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-socket
+ - command :
+ - /bin/bash
+ - -c
+ - |
+ /usr/local/bin/vineyardd --sync_crds true --socket /var/run/vineyard.sock --size \
+ --stream_threshold 80 --etcd_cmd etcd --etcd_prefix /vineyard --etcd_endpoint http://vineyard-sidecar-etcd-service:2379
+ env :
+ - name : VINEYARDD_UID
+ value : null
+ - name : VINEYARDD_NAME
+ value : vineyard-sidecar
+ - name : VINEYARDD_NAMESPACE
+ value : null
+ image : vineyardcloudnative/vineyardd:latest
+ imagePullPolicy : IfNotPresent
+ name : vineyard-sidecar
+ ports :
+ - containerPort : 9600
+ name : vineyard-rpc
+ protocol : TCP
+ resources :
+ limits : null
+ requests : null
+ securityContext : {}
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-socket
+ volumes :
+ - emptyDir : {}
+ name : vineyard-socket
+status : {}
+
+
+Next, we will introduce a simple example to show the injection with
+the apply-resources flag.
+Assume you have the following workload yaml:
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : nginx-deployment
+ # Notice, you must set the namespace here
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : nginx
+ template :
+ metadata :
+ labels :
+ app : nginx
+ spec :
+ containers :
+ - name : nginx
+ image : nginx:1.14.2
+ ports :
+ - containerPort : 80
+
+
+Then, you can use the following command to inject the vineyard sidecar
+which means that all resources will be created during the injection except
+the workload itself. The workload should be created by users.
+$ vineyardctl inject -f workload.yaml –apply-resources
+After running the command, the main output(removed some unnecessary fields)
+is as follows:
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ creationTimestamp : null
+ name : nginx-deployment
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : nginx
+template :
+ metadata :
+ labels :
+ app : nginx
+ # the default sidecar name is vineyard-sidecar
+ app.vineyard.io/name : vineyard-sidecar
+ spec :
+ containers :
+ - command : null
+ image : nginx:1.14.2
+ name : nginx
+ ports :
+ - containerPort : 80
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-socket
+ - command :
+ - /bin/bash
+ - -c
+ - |
+ /usr/local/bin/vineyardd --sync_crds true --socket /var/run/vineyard.sock \
+ --stream_threshold 80 --etcd_cmd etcd --etcd_prefix /vineyard \
+ --etcd_endpoint http://vineyard-sidecar-etcd-service:2379
+ env :
+ - name : VINEYARDD_UID
+ value : null
+ - name : VINEYARDD_NAME
+ value : vineyard-sidecar
+ - name : VINEYARDD_NAMESPACE
+ value : vineyard-job
+ image : vineyardcloudnative/vineyardd:latest
+ imagePullPolicy : IfNotPresent
+ name : vineyard-sidecar
+ ports :
+ - containerPort : 9600
+ name : vineyard-rpc
+ protocol : TCP
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-socket
+ volumes :
+ - emptyDir : {}
+ name : vineyard-socket
+
+
+The sidecar template can be accessed from the following link:
+https://github.com/v6d-io/v6d/blob/main/k8s/pkg/templates/sidecar/injection-template.yaml
+also you can get some inspiration from the doc link:
+https://v6d.io/notes/cloud-native/vineyard-operator.html#installing-vineyard-as-sidecar
+vineyardctl inject [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # use json format to output the injected workload
+ # notice that the output is a json string of all manifests
+ # it looks like:
+ # {
+ # "workload": "workload json string",
+ # "rpc_service": "rpc service json string",
+ # "etcd_service": "etcd service json string",
+ # "etcd_internal_service": [
+ # "etcd internal service json string 1",
+ # "etcd internal service json string 2",
+ # "etcd internal service json string 3"
+ # ],
+ # "etcd_pod": [
+ # "etcd pod json string 1",
+ # "etcd pod json string 2",
+ # "etcd pod json string 3"
+ # ]
+ # }
+ vineyardctl inject -f workload.yaml -o json
+
+ # inject the default vineyard sidecar container into a workload
+ # output all injected manifests and then deploy them
+ vineyardctl inject -f workload.yaml | kubectl apply -f -
+
+ # if you only want to get the injected workload yaml rather than
+ # all manifests that includes the etcd cluster and the rpc service,
+ # you can enable the apply-resources and then the manifests will be
+ # created during the injection, finally you will get the injected
+ # workload yaml
+ vineyardctl inject -f workload.yaml --apply-resources
+
+
+
+
+Options
+ -- apply - resources Whether to apply the resources including the etcd cluster and the rpc service if you enable this flag , the etcd cluster and the rpc service will be created during the injection
+ -- etcd - replicas int The number of etcd replicas ( default 1 )
+ - f , -- file string The yaml of workload
+ - h , -- help help for inject
+ -- name string The name of sidecar ( default "vineyard-sidecar" )
+ - o , -- output string The output format of the command , support yaml and json ( default "yaml" )
+ -- owner - references string The owner reference of all injectied resources
+ -- resource string The resource of workload
+ -- securityContext string the json string of security context of vineyard sidecar container
+ -- sidecar . cpu string the cpu requests and limits of vineyard container
+ -- sidecar . envs strings The environment variables of vineyardd
+ -- sidecar . image string the image of vineyardd ( default "vineyardcloudnative/vineyardd:latest" )
+ -- sidecar . imagePullPolicy string the imagePullPolicy of vineyardd ( default "IfNotPresent" )
+ -- sidecar . memory string the memory requests and limits of vineyard container
+ -- sidecar . metric . enable enable metrics of vineyardd
+ -- sidecar . metric . image string the metic image of vineyardd ( default "vineyardcloudnative/vineyard-grok-exporter:latest" )
+ -- sidecar . metric . imagePullPolicy string the imagePullPolicy of the metric image ( default "IfNotPresent" )
+ -- sidecar . reserve_memory Reserving enough physical memory pages for vineyardd
+ -- sidecar . service . port int the service port of vineyard service ( default 9600 )
+ -- sidecar . service . type string the service type of vineyard service ( default "ClusterIP" )
+ -- sidecar . size string The size of vineyardd . You can use the power - of - two equivalents : Ei , Pi , Ti , Gi , Mi , Ki . Defaults "" , means not limited
+ -- sidecar . socket string The directory on host for the IPC socket file . The namespace and name will be replaced with your vineyard config ( default "/var/run/vineyard-kubernetes/{{.Namespace}}/{{.Name}}" )
+ -- sidecar . spill . config string If you want to enable the spill mechanism , please set the name of spill config
+ -- sidecar . spill . path string The path of spill config
+ -- sidecar . spill . pv - pvc - spec string the json string of the persistent volume and persistent volume claim
+ -- sidecar . spill . spillLowerRate string The low watermark of spilling memory ( default "0.3" )
+ -- sidecar . spill . spillUpperRate string The high watermark of spilling memory ( default "0.8" )
+ -- sidecar . streamThreshold int memory threshold of streams ( percentage of total memory ) ( default 80 )
+ -- sidecar . syncCRDs enable metrics of vineyardd ( default true )
+ -- sidecar . volume . mountPath string Set the mount path for the pvc
+ -- sidecar . volume . pvcname string Set the pvc name for storing the vineyard objects persistently
+ -- volume string the json string of vineyard sidecar container volume
+ -- volumeMount string the json string of vineyard sidecar container volume mount
+
+
+
+
+
+vineyardctl inject argo-workflow
+Inject the vineyard volumes into the argo workflow
+
+Synopsis
+Inject the vineyard volumes into the argo workflow DAGs. You can input
+the workflow manifest file and the injected manifest file with
+vineyard volume will be output to the file with the suffix
+“_with_vineyard”, such as “workflow_with_vineyard.yaml”.
+Suppose the workflow manifest named “workflow.yaml” is as follows:
+apiVersion : argoproj.io/v1alpha1
+kind : Workflow
+metadata :
+ generateName : mlops-
+spec :
+ entrypoint : dag
+ templates :
+ - name : producer
+ container :
+ image : producer:latest
+ command : [ python ]
+ args : [ "/producer.py" ]
+ - name : consumer
+ container :
+ image : consumer:latest
+ command : [ python ]
+ args : [ "/consumer.py" ]
+ - name : dag
+ dag :
+ tasks :
+ - name : producer
+ template : producer
+ - name : consumer
+ template : consumer
+ dependencies :
+ - producer
+
+
+Assume the ‘producer’ and ‘consumer’ task all need to use vineyard
+volume, you can inject the vineyard volume into the workflow manifest
+with the following command:
+$ vineyardctl inject argo-workflow -f workflow.yaml
+–templates=“producer,consumer”
+–vineyard-cluster=“vineyard-system/vineyardd-sample”
+–mount-path=“/vineyard/data”
+–dag=“dag”
+–tasks=“producer,consumer”
+–output-as-file
+The injected manifest will be output to the file named “workflow_with_vineyard.yaml”.
+$ cat workflow_with_vineyard.yaml
+apiVersion : argoproj.io/v1alpha1
+kind : Workflow
+metadata :
+ generateName : mlops-
+spec :
+ entrypoint : dag
+ templates :
+ - name : producer
+ container :
+ image : producer:latest
+ command : [ python ]
+ args : [ "/producer.py" ]
+ ################## Injected #################
+ volumeMounts :
+ - name : vineyard-objects
+ mountPath : /vineyard/data
+ #############################################
+ ######################## Injected #######################
+ volumes :
+ - name : vineyard-objects
+ persistentVolumeClaim :
+ claimName : '{{inputs.parameters.vineyard-objects-name}}'
+ #########################################################
+ ############## Injected #############
+ inputs :
+ parameters :
+ - { name : vineyard-objects-name }
+ #####################################
+ - name : consumer
+ container :
+ image : consumer:latest
+ command : [ python ]
+ args : [ "/consumer.py" ]
+ ################## Injected #################
+ volumeMounts :
+ - name : vineyard-objects
+ mountPath : /vineyard/data
+ #############################################
+ ######################## Injected #######################
+ volumes :
+ - name : vineyard-objects
+ persistentVolumeClaim :
+ claimName : '{{inputs.parameters.vineyard-objects-name}}'
+ #########################################################
+ ############## Injected #############
+ inputs :
+ parameters :
+ - { name : vineyard-objects-name }
+ #####################################
+ - name : dag
+ dag :
+ tasks :
+ - name : producer
+ template : producer
+ arguments :
+ parameters :
+ ################################# Injected ################################
+ - name : vineyard-objects-name
+ value : '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ###########################################################################
+ dependencies :
+ ########### Injected ##########
+ - vineyard-objects
+ ###############################
+ - name : consumer
+ template : consumer
+ arguments :
+ parameters :
+ ################################# Injected ################################
+ - name : vineyard-objects-name
+ value : '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ###########################################################################
+ dependencies :
+ - producer
+ ########### Injected ##########
+ - vineyard-objects
+ ###############################
+ ########## Injected #########
+ - name : vineyard-objects
+ template : vineyard-objects
+ #############################
+############################# Injected ##########################
+ - name : vineyard-objects
+ resource :
+ action : create
+ setOwnerReference : true
+ manifest : |
+ apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: '{{workflow.name}}-vineyard-objects-pvc'
+ spec:
+ accessModes:
+ - ReadWriteMany
+ resources:
+ requests:
+ storage: 1Mi
+ storageClassName: vineyard-system.vineyardd-sample.csi
+ outputs :
+ parameters :
+ - name : vineyard-objects-name
+ valueFrom :
+ jsonPath : '{.metadata.name}'
+##############################################################
+
+
+Suppose your workflow YAML only has a single template as follows.
+$ cat workflow.yaml
+apiVersion : argoproj.io/v1alpha1
+kind : Workflow
+metadata :
+ generateName : mlops-
+spec :
+ entrypoint : dag
+ templates :
+ - name : MLops
+ inputs :
+ parameters :
+ - name : functions
+ container :
+ imagePullPolicy : IfNotPresent
+ image : mlops-benchmark:latest
+ command : [ python ]
+ args : [ "-m" , "{{inputs.parameters.functions}}" ]
+ - name : dag
+ dag :
+ tasks :
+ - name : producer
+ template : MLops
+ arguments :
+ parameters :
+ - name : functions
+ value : producer.py
+ - name : consumer
+ template : MLops
+ dependencies :
+ - producer
+ arguments :
+ parameters :
+ - name : functions
+ value : consumer.py
+
+
+Suppose only the ‘consumer’ task need to use vineyard volume,
+you can inject the vineyard volume into the workflow manifest
+with the following command:
+$ vineyardctl inject argo-workflow -f workflow.yaml
+–templates=“MLops”
+–vineyard-cluster=“vineyard-system/vineyardd-sample”
+–mount-path=“/vineyard/data”
+–dag=“dag”
+–tasks=“consumer”
+Then the injected manifest will be as follows:
+apiVersion : argoproj.io/v1alpha1
+kind : Workflow
+metadata :
+ generateName : mlops-
+spec :
+ entrypoint : dag
+ templates :
+ - container :
+ args :
+ - -m
+ - '{{inputs.parameters.functions}}'
+ command :
+ - python
+ image : mlops-benchmark:latest
+ imagePullPolicy : IfNotPresent
+ ############# Injected ############
+ volumeMounts :
+ - name : vineyard-objects
+ mountPath : /vineyard/data
+ ###################################
+ inputs :
+ parameters :
+ - name : functions
+ ############# Injected ############
+ - name : vineyard-objects-name
+ ###################################
+ name : MLops
+ ######################### Injected ########################
+ volumes :
+ - name : vineyard-objects
+ persistentVolumeClaim :
+ claimName : '{{inputs.parameters.vineyard-objects-name}}'
+ ###########################################################
+ - dag :
+ tasks :
+ - arguments :
+ parameters :
+ - name : functions
+ value : producer.py
+ ################################# Injected #################################
+ - name : vineyard-objects-name
+ value : '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ############################################################################
+ dependencies :
+ ##### Injected #####
+ - vineyard-objects
+ ####################
+ name : producer
+ template : MLops
+ - arguments :
+ parameters :
+ - name : functions
+ value : consumer.py
+ ################################# Injected #################################
+ - name : vineyard-objects-name
+ value : '{{tasks.vineyard-objects.outputs.parameters.vineyard-objects-name}}'
+ ############################################################################
+ dependencies :
+ - producer
+ ##### Injected #####
+ - vineyard-objects
+ ####################
+ name : consumer
+ template : MLops
+ ########### Injected ###########
+ - name : vineyard-objects
+ template : vineyard-objects
+ ################################
+ name : dag
+ ################################# Injected #################################
+ - name : vineyard-objects
+ outputs :
+ parameters :
+ - name : vineyard-objects-name
+ valueFrom :
+ jsonPath : '{.metadata.name}'
+ resource :
+ action : create
+ manifest : |-
+ apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: '{{workflow.name}}-vineyard-objects-pvc'
+ spec:
+ accessModes:
+ - ReadWriteMany
+ resources:
+ requests:
+ storage: 1Mi
+ storageClassName: vineyard-system.vineyardd-sample.csi
+ setOwnerReference : true
+ ############################################################################
+
+
+vineyardctl inject argo - workflow [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # Inject the vineyard volumes into the argo workflow
+ $ vineyardctl inject argo-workflow -f workflow.yaml \
+ --templates= "preprocess-data,train-data" \
+ --vineyard-cluster= "vineyard-system/vineyardd-sample" \
+ --mount-path= "/vineyard/data" \
+ --dag= "dag" \
+ --tasks= "preprocess-data,train-data"
+
+ # Suppose you only have a single template in the workflow
+ # you could set only one template name in the --templates flag
+ $ vineyardctl inject argo-workflow -f workflow.yaml \
+--templates= "mlops" \
+ --vineyard-cluster= "vineyard-system/vineyardd-sample" \
+ --mount-path= "/vineyard/data" \
+ --dag= "dag" \
+ --tasks= "preprocess-data,test-data"
+
+
+
+
+Options
+ -- dag string The name of dag which will be injected with vineyard volumes
+ - f , -- file string The file name of argo workflow
+ - h , -- help help for argo - workflow
+ -- mount - path string The mount path of vineyard volumes
+ -- output - as - file Whether to output the injected workflow as a file , default is falseThe output file name will add a suffix '_with_vineyard' to the original file name
+ -- tasks strings The set of task names under the dag
+ - t , -- templates strings The name of workflow template which will be injected with vineyard volumes
+ -- vineyard - cluster string The name of vineyard cluster which the argo workflow will use
+
+
+
+
+
+vineyardctl ls
+List vineyard objects, metadatas or blobs
+SEE ALSO
+
+
+Examples
+ # Connect the vineyardd server with IPC client
+ # List the vineyard objects no more than 10
+ vineyardctl ls objects --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List the vineyard blobs no more than 10
+ vineyardctl ls blobs --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List the vineyard objects with the specified pattern
+ vineyardctl ls objects --pattern "vineyard::Tensor<.*>" --regex --ipc-socket /var/run/vineyard.sock
+
+ # Connect the vineyardd server with RPC client
+ # List the vineyard metadatas no more than 1000
+ vineyardctl ls metadatas --rpc-socket 127 .0.0.1:9600 --limit 1000
+
+ # Connect the vineyard deployment with PRC client
+ # List the vineyard objects no more than 1000
+ vineyardctl ls objects --deployment-name vineyardd-sample -n vineyard-system
+
+
+
+
+
+
+vineyardctl ls blobs
+List vineyard blobs
+
+Synopsis
+List vineyard blobs and only support IPC socket.
+If you don’t specify the ipc socket every time, you can set it as the
+environment variable VINEYARD_IPC_SOCKET.
+vineyardctl ls blobs [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # List no more than 10 vineyard blobs
+ vineyardctl ls blobs --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List no more than 1000 vineyard blobs
+ vineyardctl ls blobs --ipc-socket /var/run/vineyard.sock --limit 1000
+
+ # List vineyard blobs with the name matching
+ vineyardctl ls blobs --pattern "vineyard::Tensor<.*>" --regex --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard blobs with the regex pattern
+ vineyardctl ls blobs --pattern "*DataFrame*" --ipc-socket /var/run/vineyard.sock
+
+ # If you set the environment variable VINEYARD_IPC_SOCKET
+ # you can use the following command to list vineyard blobs
+ vineyardctl ls blobs --limit 1000
+
+
+
+
+Options
+ -- deployment - name string the name of vineyard deployment
+ - o , -- format string the output format , support table or json , default is table ( default "table" )
+ -- forward - port int the forward port of vineyard deployment ( default 9600 )
+ - h , -- help help for blobs
+ -- ipc - socket string vineyard IPC socket path
+ - l , -- limit int maximum number of objects to return ( default 5 )
+ -- port int the port of vineyard deployment ( default 9600 )
+ -- rpc - socket string vineyard RPC socket path
+
+
+
+
+
+
+vineyardctl ls objects
+List vineyard objects
+
+Synopsis
+List vineyard objects and support IPC socket,
+RPC socket and vineyard deployment. If you don’t specify the ipc socket or rpc socket
+every time, you can set it as the environment variable VINEYARD_IPC_SOCKET or
+VINEYARD_RPC_SOCKET.
+vineyardctl ls objects [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # List no more than 10 vineyard objects
+ vineyardctl ls objects --limit 10 --ipc-socket /var/run/vineyard.sock
+
+ # List any vineyard objects and no more than 1000 objects
+ vineyardctl ls objects --pattern "*" --ipc-socket /var/run/vineyard.sock --limit 1000
+
+ # List vineyard objects with the name matching the regex pattern
+ vineyardctl ls objects --pattern "vineyard::Tensor<.*>" --regex --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard objects and output as json format
+ vineyardctl ls objects --format json --ipc-socket /var/run/vineyard.sock
+
+ # List vineyard objects sorted by the typename
+ vineyardctl ls objects --sorted-key typename --limit 1000 --ipc-socket /var/run/vineyard.sock
+
+
+
+
+Options
+ --deployment-name string the name of vineyard deployment
+ -o, --format string the output format, support table or json, default is table (default "table")
+ --forward-port int the forward port of vineyard deployment (default 9600)
+ -h, --help help for objects
+ --ipc-socket string vineyard IPC socket path
+ -l, --limit int maximum number of objects to return (default 5)
+ -p, --pattern string string that will be matched against the object’s typenames (default "*")
+ --port int the port of vineyard deployment (default 9600)
+ -r, --regex regex pattern to match the object’s typenames
+ --rpc-socket string vineyard RPC socket path
+ -k, --sorted-key string key to sort the objects, support:
+ - id: object id, the default value.
+ - typename: object typename, e.g. tensor, dataframe, etc.
+ - type: object type, e.g. global, local, etc.
+ - instance_id: object instance id. (default "id")
+
+
+
+
+
+vineyardctl manager
+Start the manager of vineyard operator
+vineyardctl manager [ flags ]
+
+
+SEE ALSO
+
+
+Examples
+ # start the manager of vineyard operator with default configuration
+ # (Enable the controller, webhooks and scheduler)
+ vineyardctl manager
+
+ # start the manager of vineyard operator without webhooks
+ vineyardctl manager --enable-webhook= false
+
+ # start the manager of vineyard operator without scheduler
+ vineyardctl manager --enable-scheduler= false
+
+ # only start the controller
+ vineyardctl manager --enable-webhook= false --enable-scheduler= false
+
+
+
+
+Options
+ -- enable - scheduler Enable scheduler for controller manager . ( default true )
+ -- enable - webhook Enable webhook for controller manager . ( default true )
+ -- health - probe - bind - address string The address the probe endpoint binds to . ( default ":8081" )
+ - h , -- help help for manager
+ -- leader - elect Enable leader election for controller manager . Enabling this will ensure there is only one active controller manager .
+ -- metrics - bind - address string The address the metric endpoint binds to . ( default "127.0.0.1:8080" )
+ -- scheduler - config - file string The location of scheduler plugin 's configuration file. (default "/etc/kubernetes/scheduler.yaml")
+ -- webhook - cert - dir string The directory to store the generated certificates . ( default "/etc/webhook/certs" )
+
+
+
+
+
+vineyardctl put
+Put basic data type into vineyard
+
+Synopsis
+Put basic data type into vineyard and only support IPC socket.
+It receives the flag –value as string and will print object id if succeed.
+If you don’t specify the ipc socket every time, you can set it as the
+environment variable VINEYARD_IPC_SOCKET.
+vineyardctl put [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # put value into vineyard with the given ipc socket
+ vineyardctl put --value 12345 --ipc-socket /var/run/vineyard.sock
+ vineyardctl put --value hello,world --ipc-socket /var/run/vineyard.sock
+
+ # If you set the environment variable VINEYARD_IPC_SOCKET
+ # you can use the following command to get vineyard blob
+ vineyardctl put --value 12345
+
+
+
+
+Options
+ -- deployment - name string the name of vineyard deployment
+ - o , -- format string the output format , support table or json , default is table ( default "table" )
+ -- forward - port int the forward port of vineyard deployment ( default 9600 )
+ - h , -- help help for put
+ -- ipc - socket string vineyard IPC socket path
+ -- port int the port of vineyard deployment ( default 9600 )
+ -- rpc - socket string vineyard RPC socket path
+ -- value string vineyard blob value
+
+
+
+
+
+vineyardctl schedule
+Schedule a workload or a workflow to existing vineyard cluster.
+SEE ALSO
+
+
+Examples
+ # Schedule a workload to a vineyard cluster
+ # it will add PodAffinity to the workload
+ vineyardctl schedule workload --resource '{kubernetes workload json string}'
+
+ # schedule a workflow to the vineyard cluster
+ # it will use the best-effort scheduling strategy
+ vineyardctl schedule workflow --file workflow.yaml
+
+
+
+
+Options
+ - h , -- help help for schedule
+
+
+
+
+
+vineyardctl schedule workflow
+Schedule a workflow based on the vineyard cluster
+
+Synopsis
+Schedule a workflow based on the vineyard cluster.
+It will apply the workflow to kubernetes cluster and deploy the workload
+of the workflow on the vineyard cluster with the best-fit strategy.
+vineyardctl schedule workflow [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # schedule a workflow to the vineyard cluster with the best-fit strategy
+ vineyardctl schedule workflow --file workflow.yaml
+
+ # schedule a workflow without CRD installed
+ # Notice, it only works for the workflow built by pods
+ vineyardctl schedule workflow --file pod-workflow.yaml --without-crd
+
+
+
+
+Options
+ - f , -- file string the path of workflow file
+ - h , -- help help for workflow
+ -- without - crd whether the CRD ( especially for GlobalObject and LocalObject ) is installed
+
+
+
+
+
+vineyardctl schedule workload
+Schedule the workload to a vineyard cluster
+
+Synopsis
+Schedule the workload to a vineyard cluster.
+It will add the podAffinity to the workload so that the workload
+will be scheduled to the vineyard cluster. Besides, if the workload
+does not have the socket volumeMount and volume, it will add one.
+Assume you have the following workload yaml:
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ name : python-client
+ # Notice, you must set the namespace here
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : python
+ template :
+ metadata :
+ labels :
+ app : python
+ spec :
+ containers :
+ - name : python
+ image : python:3.10
+ command : [ "python" , "-c" , "import time; time.sleep(100000)" ]
+
+
+Then you can run the following command to add the podAffinity and socket volume
+to the workload yaml:
+$ vineyard schedule workload -f workload.yaml -o yaml
+After that, you will get the following workload yaml:
+apiVersion : apps/v1
+kind : Deployment
+metadata :
+ creationTimestamp : null
+ name : python-client
+ namespace : vineyard-job
+spec :
+ selector :
+ matchLabels :
+ app : python
+ strategy : {}
+ template :
+ metadata :
+ creationTimestamp : null
+ labels :
+ app : python
+ spec :
+ affinity :
+ podAffinity :
+ requiredDuringSchedulingIgnoredDuringExecution :
+ - labelSelector :
+ matchExpressions :
+ - key : app.kubernetes.io/instance
+ operator : In
+ values :
+ - vineyard-system-vineyardd-sample
+ namespaces :
+ - vineyard-system
+ topologyKey : kubernetes.io/hostname
+
+ containers :
+ - command :
+ - python
+ - -c
+ - import time; time.sleep(100000)
+ env :
+ - name : VINEYARD_IPC_SOCKET
+ value : /var/run/vineyard.sock
+ image : python:3.10
+ name : python
+ resources : {}
+ volumeMounts :
+ - mountPath : /var/run
+ name : vineyard-socket
+ volumes :
+ - hostPath :
+ path : /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+ name : vineyard-socket
+
+
+vineyardctl schedule workload [ flags ]
+
+
+SEE ALSO
+
+
+
+Examples
+ # Add the podAffinity to the workload yaml
+ vineyardctl schedule workload -f workload.yaml \
+ --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-system
+
+ # Add the podAffinity to the workload for the specific vineyard cluster
+ vineyardctl schedule workload --resource '{
+ "apiVersion": "apps/v1",
+ "kind": "Deployment",
+ "metadata": {
+ "name": "web-server"
+ },
+ "spec": {
+ "selector": {
+ "matchLabels": {
+ "app": "web-store"
+ }
+ },
+ "replicas": 3,
+ "template": {
+ "metadata": {
+ "labels": {
+ "app": "web-store"
+ }
+ },
+ "spec": {
+ "affinity": {
+ "podAntiAffinity": {
+ "requiredDuringSchedulingIgnoredDuringExecution": [
+ {
+ "labelSelector": {
+ "matchExpressions": [
+ {
+ "key": "app",
+ "operator": "In",
+ "values": [
+ "web-store"
+ ]
+ }
+ ]
+ },
+ "topologyKey": "kubernetes.io/hostname"
+ }
+ ]
+ },
+ "podAffinity": {
+ "requiredDuringSchedulingIgnoredDuringExecution": [
+ {
+ "labelSelector": {
+ "matchExpressions": [
+ {
+ "key": "app",
+ "operator": "In",
+ "values": [
+ "store"
+ ]
+ }
+ ]
+ },
+ "topologyKey": "kubernetes.io/hostname"
+ }
+ ]
+ }
+ },
+ "containers": [
+ {
+ "name": "web-app",
+ "image": "nginx:1.16-alpine"
+ }
+ ]
+ }
+ }
+ }
+ }' \
+ --vineyardd-name vineyardd-sample \
+ --vineyardd-namespace vineyard-system
+
+
+
+
+Options
+ - f , -- file string the file path of workload
+ - h , -- help help for workload
+ - o , -- output string the output format for vineyardctl schedule workload command ( default "json" )
+ -- resource string the json string of kubernetes workload
+ -- vineyardd - name string the namespace of vineyard cluster ( default "vineyardd-sample" )
+ -- vineyardd - namespace string the namespace of vineyard cluster ( default "vineyard-system" )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/developers.html b/notes/developers.html
new file mode 100644
index 0000000000..3476bdf094
--- /dev/null
+++ b/notes/developers.html
@@ -0,0 +1,561 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Getting Involved - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Getting Involved
+
+
+Vineyard is an open-source project that was accepted into the CNCF sandbox in April 2021.
+It has been successfully developed and maintained by the open-source community. We are
+committed to engaging community members to help us improve Vineyard. You will find our
+community welcoming and responsive by joining our Github discussions or Slack channel:
+
+To modify the Vineyard source code, you will need to set up the development environment
+and build the project from source. Follow the instructions below:
+
+If you encounter any issues during your journey with Vineyard, you may find solutions in:
+
+We also have a public roadmap that outlines our future goals and highlights our ongoing efforts:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/developers/build-from-source.html b/notes/developers/build-from-source.html
new file mode 100644
index 0000000000..4e0e20fa9a
--- /dev/null
+++ b/notes/developers/build-from-source.html
@@ -0,0 +1,667 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Building from source - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Building from source
+
+Install vineyard
+Vineyard is distributed as a python package
+and can be easily installed with pip
:
+
+
+
+Install etcd
+Vineyard is based on etcd , please refer the doc to install it.
+
+
+Install from source
+Vineyard is open source on Github: https://github.com/v6d-io/v6d .
+You can obtain the source code using git
:
+git clone https://github.com/v6d-io/v6d
+cd v6d
+git submodule update --init
+
+
+
+Prepare dependencies
+Vineyard can be built and deployed on common Unix-like systems. Vineyard has been
+fully tests with C++ compilers that supports C++ 14.
+
+Dependencies
+Vineyard requires the following software as dependencies to build and run:
+
+If you want to build the vineyard server, the following additional libraries are needed:
+
+And the following python packages are required:
+
+
+
+Install on Ubuntu (or Debian)
+Vineyard has been fully tested on Ubuntu 20.04. The dependencies can be installed by
+ apt-get install -y ca-certificates \
+ cmake \
+ doxygen \
+ libboost-all-dev \
+ libcurl4-openssl-dev \
+ libgflags-dev \
+ libgoogle-glog-dev \
+ libgrpc-dev \
+ libgrpc++-dev \
+ libmpich-dev \
+ libprotobuf-dev \
+ libssl-dev \
+ libunwind-dev \
+ libz-dev \
+ protobuf-compiler-grpc \
+ python3-pip \
+ wget
+
+
+Then install the apache-arrow (see also https://arrow.apache.org/install ):
+ wget https://apache.jfrog.io/artifactory/arrow/$( lsb_release --id --short | tr 'A-Z' 'a-z' ) /apache-arrow-apt-source-latest-$( lsb_release --codename --short) .deb \
+ -O /tmp/apache-arrow-apt-source-latest-$( lsb_release --codename --short) .deb
+apt install -y -V /tmp/apache-arrow-apt-source-latest-$( lsb_release --codename --short) .deb
+apt update -y
+apt install -y libarrow-dev
+
+
+
+
+Dependencies on MacOS
+Vineyard has been tested on MacOS as well, the dependencies can be installed using brew
:
+ brew install apache-arrow boost gflags glog grpc protobuf llvm mpich openssl zlib autoconf
+
+
+
+
+
+Building vineyard
+After the required dependencies are installed, you do an out-of-source build using CMake :
+
+
Tip
+
We recommend to use the brew installed LLVM as the compiler for building vineyard on MacOS,
+which can be accomplished by setting the environment variable CC
and CXX
:
+
export CC=$(brew --prefix llvm)/bin/clang
+export CXX=$(brew --prefix llvm)/bin/clang++
+
+
+
+ mkdir build
+cd build
+cmake ..
+make -j$( nproc)
+sudo make install # optionally
+
+
+You will see vineyard server binary under the bin
directory, and static or shared linked
+libraries will be placed under the lib-shared
folder.
+
+
+Building python wheels
+After building the vineyard library successfully, you can package an install wheel distribution by
+ python3 setup.py bdist_wheel
+
+
+
+
+
+Building the documentation
+Vineyard documentation is organized and generated by sphinx. There are other packages that
+help us build the documentation, which can be easily installed using pip
:
+ pip3 install -r requirements.txt -r requirements-dev.txt
+
+
+Once installed, you could go to the docs/ directory and build the documentation by
+cd docs/ # skip if you are already there
+make html
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/developers/contributing.html b/notes/developers/contributing.html
new file mode 100644
index 0000000000..fe0ad40392
--- /dev/null
+++ b/notes/developers/contributing.html
@@ -0,0 +1,719 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contributing to vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Contributing to vineyard
+Vineyard is the product of a dedicated team of software engineers and
+researchers. We warmly welcome contributions from the open-source community to
+enhance and refine this project!
+Vineyard is licensed under the Apache License 2.0 .
+
+Install development dependencies
+Vineyard requires the following C++ packages for development:
+
+apache-arrow >= 0.17.1
+gflags
+glog
+boost
+protobuf
+grpc
+
+and the following python packages that can be easily installed using pip :
+
+
+
+Developing Vineyard Using Docker
+To streamline the dependency installation process, we offer a pre-built Docker
+image containing all necessary requirements. You can find this image at
+vineyardcloudnative/vineyard-dev .
+ docker pull vineyardcloudnative/vineyard-dev:latest
+
+
+
+
+Build the source
+You can do an out-of-source build using CMake:
+ mkdir build
+cd build
+cmake ..
+make -j$( nproc)
+
+
+The vineyardd target will be generated under the bin directory.
+You may find building and installation instructions for other platforms from our CI:
+
+
+
+Running Unit Tests
+Vineyard incorporates a comprehensive set of unit tests within its continuous integration
+process. To build these test cases, execute the following command:
+cd build
+make vineyard_tests -j$( nproc)
+
+
+Before running the test cases, ensure that etcd is properly installed by executing
+brew install etcd
on macOS or pip3 install etcd_distro
on Linux distributions.
+A dedicated script is provided to set up the required environments and execute the test cases:
+ ./test/runner.py --help
+usage: runner.py [ -h] [ --with-cpp] [ --with-python] [ --with-io] [ --with-deployment] [ --with-migration] [ --with-contrib] [ --tests [ TESTS [ TESTS ...]]]
+
+optional arguments:
+ -h, --help show this help message and exit
+ --with-cpp Whether to run C++ tests
+ --with-python Whether to run python tests
+ --with-io Whether to run IO adaptors tests
+ --with-deployment Whether to run deployment and scaling in /out tests
+ --with-migration Whether to run object migration tests
+ --with-contrib Whether to run python contrib tests
+ --tests [ TESTS [ TESTS ...]]
+ Specify tests cases ro run
+
+
+As shown above, you could run C++ unittests by
+ ./test/runner --with-cpp
+
+
+You could only run specified test case as well:
+ ./test/runner --with-cpp --tests array_test dataframe_test
+
+
+
+
+Documentation
+Vineyard’s documentation is generated using Doxygen and Sphinx. To build the
+documentation locally, navigate to the docs/
directory and execute the
+following commands:
+
+Upon successful completion, the HTML documentation will be available under the
+docs/_build/html
directory:
+ open _build/html/index.html
+
+
+For the most up-to-date version of the documentation, visit https://v6d.io .
+Vineyard offers comprehensive documentation that delves into the design and
+implementation details of the project. The documentation adheres to the syntax
+conventions of Doxygen and Sphinx markup. If you identify areas for improvement
+or wish to contribute, feel free to submit a pull request. We appreciate your
+enthusiasm and support!
+
+
+Reporting Bugs
+Vineyard is hosted on GitHub and utilizes GitHub issues as its bug tracker.
+If you encounter any issues or unexpected behavior while using Vineyard, please file an issue .
+Before creating a new bug report, we recommend that you first search among existing
+Vineyard bugs to check if the issue has already been addressed.
+When submitting a new bug report, kindly provide essential information regarding your
+problem in the description, such as the operating system version, Vineyard version,
+and any relevant system configurations. This will greatly assist us in diagnosing
+and resolving the issue.
+
+
+Submitting Pull Requests
+We greatly appreciate contributions from the community, including bug fixes and new
+features. To submit a pull request to Vineyard, please follow the guidelines in this
+section:
+
+Install Pre-commit
+Vineyard uses pre-commit to prevent accidental inclusion of secrets in the Git
+repository. To install pre-commit , run:
+ pip3 install pre-commit
+
+
+Next, configure the necessary pre-commit hooks with:
+
+
+
+Sign Off Your Commits
+Vineyard has enabled the DCO , which requires you to sign-off your commits included
+in pull requests. Git provides a -s
command line option to sign-off your
+commit automatically:
+ git commit -s -m 'This is my commit message'
+
+
+
+
+
+Open a Pull Request
+When opening issues or submitting pull requests, please prefix the pull request title
+with the issue number and the type of patch (BUGFIX or FEATURE ) in brackets. For
+example, [BUGFIX-1234] Fix crash in sealing vector to vineyard or [FEATURE-2345]
+Support seamless operability with PyTorch's tensors
.
+
+
+Git Workflow for Newcomers
+Generally, you do NOT need to rebase your pull requests unless there are merge conflicts
+with the main branch. If GitHub indicates “Can’t automatically merge” on your pull
+request, you will be asked to rebase your pull request on top of the latest main branch
+using the following commands:
+
+First, rebase to the most recent main:
+ git remote add upstream https://github.com/v6d-io/v6d.git
+git fetch upstream
+git rebase upstream/main
+
+
+
+If Git shows conflicts, such as in conflict.cpp ,you need to:
+- Manually modify the file to resolve the conflicts
+- After resolving, mark it as resolved by
+
+
+Then, continue rebasing with:
+
+
+Finally, push to your fork, and the pull request will be updated:
+
+
+
+
+
+
+Creating a Release
+The Vineyard Python package is built using the manylinux2014 environment. To create
+a release version, we utilize Docker for a consistent and reliable build process.
+The base image’s details can be found in the docker/pypa/Dockerfile.manylinux1 file.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/developers/faq.html b/notes/developers/faq.html
new file mode 100644
index 0000000000..23186d50a6
--- /dev/null
+++ b/notes/developers/faq.html
@@ -0,0 +1,617 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Frequently Asked Questions - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Frequently Asked Questions
+This FAQ page compiles questions frequently asked by our end users to provide
+informative and concise answers. If the following sections do not address your
+concerns, please feel free to open an issue or post it to discussions .
+
+What are the objects in vineyard?
+
+
+A global object is composed of multiple local objects distributed across the cluster,
+with each local object stored in a single vineyard daemon (ensuring that a local object
+can always fit into the memory of a single machine).
+
These local objects represent partitions of the global object (e.g., partitioned dataframes
+within a large dataframe, graph fragments within a vast graph). Generally, a global object
+serves as an abstraction for the input or output of a parallel-processing workload, while
+a local object corresponds to the input or output of an individual worker within that workload.
+
+
+Can multiple readers access the same data simultaneously in vineyard?
+
+
+Absolutely. Vineyard stores objects as immutable entities, which are shared
+among readers’ processes through memory mapping. This ensures safe and concurrent
+access to objects by multiple readers without any conflicts.
+
+
+How can I launch a cluster with multiple vineyardd instances?
+
+
+A vineyard daemon server represents a single vineyard instance within a vineyard cluster. To
+initiate a vineyard cluster, simply start the vineyardd
process on all the
+machines within the cluster, ensuring that these vineyard instances can register with
+the same etcd_endpoint
. The default value for etcd_endpoint
is
+http://127.0.0.1:2379
, and if the etcd servers are not already running on the cluster,
+vineyard
will automatically launch the etcd_endpoint
.
+
For additional parameter settings, refer to the help documentation by running
+python3 -m vineyard --help
.
+
+
+Is Kubernetes a necessity for vineyard?
+
+
+No, Kubernetes is not a necessity for vineyard. However, deploying vineyard on Kubernetes
+allows users to benefit from the flexible resource management offered by cloud-native
+deployments for their application workloads. Additionally, the scheduler plugin assists
+in co-locating worker pods with the data for improved data-work alignment.
+
+
+How does vineyard achieve IPC and memory sharing (i.e., zero-copy sharing) on Kubernetes?
+
+
+Inter-process memory sharing can be challenging in Kubernetes, but it is achievable. When
+deployed on Kubernetes, vineyard exposes its UNIX-domain socket as a PersistentVolume
.
+This volume can be mounted into the job’s pod, allowing the socket to be used for IPC
+connections to the vineyard daemon. Memory sharing is accomplished by mounting a volume of
+medium Memory
into both the vineyard daemon’s pod and the job’s pod.
+
+
+How does vineyard’s stream differ from similar systems, such as Kafka?
+
+
+Vineyard’s stream is an abstraction of a sequence of objects, where each object typically
+represents a small portion of the entire object (e.g., a mini-batch of a tensor). This
+abstraction is designed to support cross-engine pipelining between consecutive workers in
+a data analytics pipeline (e.g., a dataframe engine generating training data while the
+subsequent machine learning engine consumes the data and trains the model simultaneously).
+
The primary distinction between vineyard’s stream and traditional stream frameworks like
+Kafka is that data in vineyard’s stream is still abstracted as (high-level) objects and
+can be consumed in a zero-copy manner, similar to normal objects in vineyard. In contrast,
+Kafka is designed for stream processing applications and abstracts data as (low-level)
+messages. Utilizing Kafka in the aforementioned scenario would still incur (de)serialization
+and memory copy costs.
+
+
+Does vineyard support accessing remote objects?
+
+
+Yes, vineyard’s RPC client can access the metadata of an object, regardless of whether
+the object is local or remote. This capability enables users and internal operators to
+examine essential information (e.g., chunk axis, size) about an object, assisting in
+decision-making processes related to object management (e.g., determining the need for
+repartitioning, planning the next workload). With this capability, the vineyard client
+connects to the Vineyard daemon that stores the object’s payloads, retrieves these payloads,
+and assembles the objects locally.
+
+
+How does migration work in vineyard? Is it automatically triggered?
+
+
+Consider a scenario where workload A produces a global object O , and the subsequent
+workload B consumes O as input. In a Kubernetes cluster with multiple hosts (e.g.,
+h1 , h2 , h3 , h4 ), if A has two worker pods on h1 and h2 , the local objects
+(i.e., O1 and O2 ) of O are stored on h1 and h2 , respectively.
+
If the two worker pods of B (i.e., B1 and B2 ) are placed on h1 and h3 , B1
+can access O1 locally via memory mapping. However, B2 (on h3 ) cannot access O2
+since it resides on h2 . In this situation, a utility program distributed with vineyard
+in the initContainer
of B2 triggers the migration of O2 from h2 to h3 ,
+enabling pod B2 to access O2 locally.
+
Although data migration incurs a cost, the scheduler plugin has been developed to
+prioritize h2 when launching B2 , minimizing the need for migration whenever possible.
+
+
+What’s the minimal Kubernetes version requirement for vineyard operator?
+
+
+At present, we only test the vineyard operator based on Kubernetes 1.24.0.
+So we highly recommend using Kubernetes 1.24.0 or above.
+
+
+Why the vineyard operator can’t be deployed on Kubernetes?
+
+
+If you use the helm to deploy the vineyard operator, you may find the vineyard operator
+can’t be deployed successfully after a long time. In this case, you should check whether
+the command contains the flag –wait . If so, you should remove the flag –wait and
+try to install the operator again.
+
+
+How to connect to the vineyard cluster deployed by the vineyard operator?
+
+
+There are two ways to connect to the vineyard cluster deployed by the vineyard operator:
+
+Through IPC . Create a pod with the specific labels so that the pod can be scheduled
+to the node where the vineyard cluster is deployed.
+Through RPC . Connect to the vineyard cluster through the RPC service exposed by the
+vineyard operator. You could refer to the guide for more details.
+
+
+
+Is there a way to install the vineyard cluster on Kubernetes quickly?
+
+
+To reduce the complexity of the installation, we provide a command line tool
+to install the vineyard cluster on Kubernetes quickly.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/developers/roadmap.html b/notes/developers/roadmap.html
new file mode 100644
index 0000000000..dd7dd21e10
--- /dev/null
+++ b/notes/developers/roadmap.html
@@ -0,0 +1,633 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Roadmap - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Roadmap
+Vineyard aims to serve as an open-source in-memory immutable data manager. We
+cut a major release once a year, a minor release for about every two months,
+and a patch release every one or two weeks.
+The roadmap for major vineyard releases are listed as follows:
+
+v0.8.0
+Vineyard v0.8.0 will deliver the first implementation of the following
+important features and will be hopefully release in the later Aug, 2022:
+
+Filesystem view of vineyard objects: vineyard objects can be accessed like
+files on a filesystem in a high-performance fashion. Such a feature would
+greatly ease the integration of computing processes with vineyard.
+Copy-on-realloc and data lineage: the mutation support would be extended
+from blobs to general objects with a carefully concurrency-control design.
+Transparent object spilling: objects in vineyard can be spilled to disk
+when they are too large to fit in memory.
+Sharing GPU memory between processes of different compute engines: we are
+working on shared memory on devices to enable boarder applications that
+can benefit from the shared vineyard store, especially for deep learning
+frameworks and GNN frameworks.
+
+
+
+v0.7.0
+Vineyard v0.7.0 will be released in later July, 2022. Vineyard v0.7.0 will
+introduces the following experimental features to ease the integration of
+various kinds of workloads with Vineyard:
+
+Limited mutation support on blobs: starts from vineyard v0.7.0 , unsealed
+blobs can be get by other clients with an unsafe
flag to ease the
+integration of some online storage engines.
+Limited support for remote data accessing using the RPC client: vineyard
+v0.7.0 will bring the feature about creating and accessing remote blobs
+using the RPC client. It would be greatly helpful for some specific deployment
+and the cost of remote data sourcing to vineyard is tolerable.
+
+
+
+v0.6.0
+We plan to release the v0.6.0 version before tne end of June, 2022. The v0.6.0
+release will include the following enhancement:
+
+Better compatibility on various platforms (e.g., CentOS and ArchLinux), and process
+platform-specific features like LD_LIBRARY_PATH and libunwind dependency
+carefully.
+Ensure the backwards compatibility with various third-party integrations, e.g.,
+apache-airflow.
+Vineyard v0.6.0 will be available from homebrew .
+
+
+
+v0.5.0
+We plan to release the first preliminary version for the Rust SDK and Go SDK
+in vineyard v0.5.0 , that is expected to be delivered in later May, 2022.
+In vineyard v0.5.0 , we will investigate the opportunity about code generation
+based on the metadata of vineyard objects, i.e., we could generate the data
+structure definition based on the structure of metadata in runtime (for Python)
+and in compile time (even maybe in runtime) for C++ and Rust.
+The integration with Kubernetes (especially the CSI part) will be another key
+improvement for v0.5.0 .
+Further details about release for v0.5.0 will be added later.
+
+
+v0.4.0
+The release of vineyard v0.4.0 , will be hopefully released before April, 2022, will
+be a follow-up bugfix releases after v0.3.0 . The version v0.4.0 makes the
+kubernetes related components better.
+
+Improve the robustness of the scheduler plugin.
+Refine the definition of CRDs.
+Distribute the vineyard operator to artifact hub as a chart, to make it available for more users.
+
+
+
+v0.3.0
+We plan to release v0.3.0 by the end of 2021. vineyard v0.3.0 will be the first major
+stable releases with fully kubernetes support, which will include:
+
+A stable CRD definition for LocalObject
and GlobalObject
to represents vineyard objects
+as kubernetes resources.
+A full-features scheduler plugin for kubernetes, as well as a custom controller that manages
+objects (custom resources) in vineyard cluster.
+A refined version of Helm integration.
+Application-aware far memory will be included in v0.3.0 as an experimental feature.
+
+
+
+v0.2.0
+Vineyard v0.2.0 will address the issue about Python ecosystem compatibility, I/O, and
+the kubernetes integration. Vineyard v0.2.0 will take about half of a year with several bugfix
+release to testing the design and APIs to reach a stable stable state.
+
+Vineyard v0.2.0 will support any filesystem-spec -compatible data source/sink as well as file
+format.
+Vineyard v0.2.0 will support Python ecosystem (especially numpy and pandas) better.
+Vineyard v0.2.0 will include basic Helm integration for deploying on Kubernetes as a DaemonSet
.
+A prototype of scheduler plugin to do data locality scheduling will be included into vineyard v0.2.0
+to demonstrates the capability about co-scheduling job and data in kubernetes brought by vineyard.
+Match the criterion of CNCF sandbox project.
+
+
+
+v0.1.0
+Vineyard v0.1.0 is the first release after open source. This version includes:
+
+
+
+Release Notes
+For more details about what changes happened for every version, please refer to
+our releases notes as well.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/developers/troubleshooting.html b/notes/developers/troubleshooting.html
new file mode 100644
index 0000000000..3577d53fd0
--- /dev/null
+++ b/notes/developers/troubleshooting.html
@@ -0,0 +1,560 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Troubleshooting - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Troubleshooting
+This page provides guidance for addressing common issues that may arise when
+working with Vineyard.
+
+Vineyard Fails to Start
+
+Improper Etcd Configuration
+
+If you encounter the following error when sending requests to Vineyard:
+
Etcd error : etcdserver : too many operations in txn request , error code : 3
+
+
+
This indicates that your Etcd configuration is not set up correctly and does not support
+more than 128 operations within a single transaction. To resolve this issue, check your Etcd
+startup parameters and increase the --max-txn-ops
value, for example, to 102400
.
+
+
+bind: Permission Denied Error When Launching vineyardd
+
+The Vineyard server uses a UNIX-domain socket for IPC connections and memory sharing with clients.
+By default, the UNIX-domain socket is located at /var/run/vineyard.sock
, which typically
+requires root permission.
+
To launch vineyardd, you can either:
+
+Run the vineyardd
command with sudo
,
+Or, specify a different location for the UNIX-domain socket that does not require root permission
+using the --socket
command line argument, e.g.,
+.. code:: bash
+
+python3 -m vineyard –socket=/tmp/vineyard.sock
+
+
+
+
+
+
+
+
+Vineyard Issues on Kubernetes
+
+Etcd Pod Resource Limitations in Kubernetes Deployment
+
+We have observed that etcd performance may degrade when a Vineyard client persists a large
+object, particularly in Kubernetes deployments where the CPU cores of the etcd pod are limited by
+cgroups. In such cases, users should increase the CPU resources allocated to the etcd pod. For
+more information on etcd tuning, please refer to the Hardware recommendations section in the etcd documentation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/getting-started.html b/notes/getting-started.html
new file mode 100644
index 0000000000..c51b52b17e
--- /dev/null
+++ b/notes/getting-started.html
@@ -0,0 +1,728 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Getting Started - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Getting Started
+
+Installing vineyard
+Vineyard is distributed as a Python package and can be effortlessly installed using pip
:
+$ pip3 install vineyard
+
+
+
+
+Launching vineyard server
+
+A vineyard daemon server will be launched with default settings. By default, /var/run/vineyard.sock
+will be used by vineyardd to listen for incoming IPC connections.
+To stop the running vineyardd instance, simply press Ctrl-C
in the terminal.
+
+
Tip
+
If you encounter errors like cannot launch vineyardd on '/var/run/vineyard.sock':
+Permission denied,
, it means you don’t have the permission to create a UNIX-domain
+socket at /var/run/vineyard.sock
. You can either:
+
+Run vineyard as root, using sudo
:
+$ sudo -E python3 -m vineyard
+
+
+
+Or, change the socket path to a writable location with the --socket
command
+line option:
+$ python3 -m vineyard --socket /tmp/vineyard.sock
+
+
+
+
+
+
+
+Connecting to vineyard
+Once launched, you can call vineyard.connect
with the socket name to initiate a vineyard client
+from Python:
+>>> import vineyard
+>>> client = vineyard . connect ( '/var/run/vineyard.sock' )
+
+
+
+
+Storing and Retrieving Python Objects
+Vineyard is designed as an in-memory object store and offers two high-level APIs put
and
+get
for creating and accessing shared objects, enabling seamless interoperability with the Python
+ecosystem. The former returns a vineyard.ObjectID
upon success, which can be used
+to retrieve shared objects from vineyard using the latter.
+In the following example, we use client.put()
to build a vineyard object from the numpy
+ndarray arr
, which returns the object_id
- a unique identifier in vineyard representing
+the object. Given the object_id
, we can obtain a shared-memory object from vineyard with the
+client.get()
method.
+>>> import numpy as np
+>>>
+>>> object_id = client . put ( np . random . rand ( 2 , 4 ))
+>>> object_id
+o0015c78883eddf1c
+>>>
+>>> shared_array = client . get ( object_id )
+>>> shared_array
+ndarray([[0.39736989, 0.38047846, 0.01948815, 0.38332264],
+ [0.61671189, 0.48903213, 0.03875045, 0.5873005 ]])
+
+
+
+
Note
+
shared_array
does not allocate extra memory in the Python process; instead, it shares memory
+with the vineyard server via mmap in a zero-copy process.
+
+The sharable objects can be complex and nested. Like numpy ndarray, the pandas dataframe df
can
+be seamlessly stored in vineyard and retrieved with the .put()
and .get()
methods as follows:
+>>> import pandas as pd
+>>>
+>>> df = pd . DataFrame ({ 'u' : [ 0 , 0 , 1 , 2 , 2 , 3 ],
+>>> 'v' : [ 1 , 2 , 3 , 3 , 4 , 4 ],
+>>> 'weight' : [ 1.5 , 3.2 , 4.7 , 0.3 , 0.8 , 2.5 ]})
+>>> object_id = client . put ( df )
+>>>
+>>> shared_dataframe = client . get ( object_id )
+>>> shared_dataframe
+ u v weight
+0 0 1 1.5
+1 0 2 3.2
+2 1 3 4.7
+3 2 3 0.3
+4 2 4 0.8
+5 3 4 2.5
+
+
+Under the hood, vineyard implements a builder/resolver mechanism to represent arbitrary
+data structures as vineyard objects and resolve them back to native values in the corresponding
+programming languages and computing systems. See also I/O Drivers for more information.
+
+
+Sharing objects between tasks
+Vineyard is designed for sharing intermediate data between tasks. The following example
+demonstrates how a dataframe can be passed between two processes using vineyard, namely
+the producer and consumer in the example below:
+import multiprocessing as mp
+import vineyard
+
+import numpy as np
+import pandas as pd
+
+socket = '/var/run/vineyard.sock'
+
+def produce ( name ):
+ client = vineyard . connect ( socket )
+ client . put ( pd . DataFrame ( np . random . randn ( 100 , 4 ), columns = list ( 'ABCD' )),
+ persist = True , name = name )
+
+def consume ( name ):
+ client = vineyard . connect ( socket )
+ print ( client . get ( name = name ) . sum ())
+
+if __name__ == '__main__' :
+ name = 'dataset'
+
+ producer = mp . Process ( target = produce , args = ( name ,))
+ producer . start ()
+ consumer = mp . Process ( target = consume , args = ( name ,))
+ consumer . start ()
+
+ producer . join ()
+ consumer . join ()
+
+
+Running the code above, you should see the following output:
+ A -4.529080
+B -2.969152
+C -7.067356
+D 4.003676
+dtype: float64
+
+
+
+
+Next steps
+Beyond the core functionality of sharing objects between tasks, vineyard also provides:
+
+Distributed objects and stream abstraction over immutable chunks;
+An IDL (Code Generation for Boilerplate ) that helps integrate vineyard with other systems at minimal cost;
+A mechanism of pluggable drivers for various tasks that serve as the glue
+between the core compute engine and the external world, e.g., data sources, data
+sinks;
+Integration with Kubernetes for sharing between tasks in workflows deployed
+on cloud-native infrastructures.
+
+
+Learn more about vineyard’s key concepts from the following user guides:
+
+
+
+
+
+
+
VCDL
+
Discover how vineyard integrates with other computing systems.
+
+
+
+
+
+
+
I/O Drivers
+
Understand the design and implementation of pluggable routines for I/O, repartition,
+migration, and more.
+
+
+
+
+
+Vineyard is a natural fit for cloud-native computing, where it can be deployed and
+managed by the vineyard operator , providing data-aware scheduling for data analytical
+workflows to achieve efficient data sharing on Kubernetes. More details about vineyard
+on Kubernetes can be found here:
+
+
+
+
+
+
+
Deploy vineyard on Kubernetes and accelerate your big-data workflows.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/integration-bigdata.html b/notes/integration-bigdata.html
new file mode 100644
index 0000000000..f0356e045c
--- /dev/null
+++ b/notes/integration-bigdata.html
@@ -0,0 +1,520 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Big-data on Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Big-data on Vineyard
+
+
+Vineyard serves as a powerful data-sharing engine, seamlessly integrating with
+a variety of big-data computing platforms. This includes machine learning
+frameworks and the distributed data processing engine, Dask.
+
+
+
+
+
+
+
Executing machine learning workflows on top of vineyard.
+
+
+
+
+
+
+
+
Using vineyard as the data source / sink of dask computations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/integration-orchestration.html b/notes/integration-orchestration.html
new file mode 100644
index 0000000000..7c9e46feae
--- /dev/null
+++ b/notes/integration-orchestration.html
@@ -0,0 +1,532 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Workflow orchestration - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Workflow orchestration
+
+
+Vineyard seamlessly integrates with the workflow orchestration engines, e.g.,
+Apache Airflow and Kedro, enabling users to effortlessly incorporate Vineyard
+into their workflows for enhanced performance.
+Moreover, the Airflow integration empowers users to work with large Python objects
+featuring complex data types (e.g., pandas.DataFrame
) at minimal cost, while
+eliminating the need for cumbersome pickle.dump/loads
operations.
+
+
+
+
+
+
+
Airflow uses vineyard as the XCom backend to efficiently handle complex data in Python.
+
+
+
+
+
+The Kedro integration enables users to easily share large data objects across
+nodes in a pipeline and eliminates the high cost of (de)serialization and I/O
+compared with alternatives like AWS S3 or Minio, without the need to modify
+the pipeline code intrusively, and provides seamless user experience when scaling
+pipelines to Kubernetes.
+
+
+
+
+
+
+
Kedro uses vineyard as a DataSet implementation for efficient intermediate data sharing.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/integration/airflow.html b/notes/integration/airflow.html
new file mode 100644
index 0000000000..ce55df3c78
--- /dev/null
+++ b/notes/integration/airflow.html
@@ -0,0 +1,713 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Airflow on Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Airflow on Vineyard
+Big data analytical pipelines often involve various types of workloads, each
+requiring a dedicated computing system to complete the task. Intermediate
+data flows between tasks in the pipeline, and the additional cost of transferring data
+accounts for a significant portion of the end-to-end performance in real-world deployments,
+making optimization a challenging task.
+Integrating Vineyard with Airflow presents opportunities to alleviate this problem.
+
+Introducing Airflow
+Airflow is a platform that enables users to programmatically author, schedule, and
+monitor workflows. Users organize tasks in a Directed Acyclic Graph (DAG), and the
+Airflow scheduler executes the tasks on workflows while adhering to the specified
+dependencies.
+Consider the following ETL workflow as an example ,
+@dag ( schedule_interval = None , start_date = days_ago ( 2 ), tags = [ 'example' ])
+def tutorial_taskflow_api_etl ():
+ @task ()
+ def extract ():
+ data_string = '{"1001": 301.27, "1002": 433.21, "1003": 502.22}'
+
+ order_data_dict = json . loads ( data_string )
+ return order_data_dict
+
+ @task ( multiple_outputs = True )
+ def transform ( order_data_dict : dict ):
+ return { "total_order_value" : total_order_value }
+
+ @task ()
+ def load ( total_order_value : float ):
+ print ( f "Total order value is: { total_order_value : .2f } " )
+
+ order_data = extract ()
+ order_summary = transform ( order_data )
+
+
+tutorial_etl_dag = tutorial_taskflow_api_etl ()
+
+
+It forms the following DAG, including three individual tasks as the nodes, and
+runs the tasks sequentially based on their data This forms a DAG, including
+three individual tasks as nodes, and edges between nodes that describe the
+data dependency relations. The Airflow scheduler runs the tasks sequentially
+based on their data dependencies.dependencies. Airflow ETL Workflow
+
+
+Airflow on Vineyard
+
+The Rationale for Airflow on Vineyard
+Airflow excels at defining and orchestrating complex workflows. However, managing
+data flow within the pipeline remains a challenge. Airflow relies on database
+backends such as SQLite, MySQL, and PostgreSQL to store intermediate data between
+tasks. In real-world scenarios, large-scale data, such as large tensors, dataframes,
+and distributed graphs, cannot fit into these databases. As a result, external
+storage systems like HDFS and S3 are used to store intermediate data, with only
+an identifier stored in the database.
+Utilizing external storage systems to share intermediate data among tasks in big
+data analytical pipelines incurs performance costs due to data copying,
+serialization/deserialization, and network data transfer.
+Vineyard is designed to efficiently share intermediate in-memory data for big data
+analytical pipelines, making it a natural fit for workloads on Airflow.
+
+
+How Vineyard Enhances Airflow
+Airflow allows users to register an external XCom backend, which is precisely
+what Vineyard is designed for.
+Vineyard serves as an XCom backend for Airflow workers, enabling the transfer of
+large-scale data objects between tasks without relying on Airflow’s database backend
+or external storage systems like HDFS. The Vineyard XCom backend also handles object
+migration when the required inputs are not located where the task is scheduled to
+execute.
+Vineyard’s XCom backend achieves its functionality by injecting hooks into the
+processes of saving values to the backend and fetching values from the backend,
+as described below:
+class VineyardXCom ( BaseXCom ):
+
+ @staticmethod
+ def serialize_value ( value : Any ):
+ """ Store the value to vineyard server, and serialized the result
+ Object ID to save it into the backend database later.
+ """
+
+ @staticmethod
+ def deserialize_value ( result : "XCom" ) -> Any :
+ """ Obtain the Object ID after deserialization, and fetching the
+ underlying value from vineyard.
+
+ This value is resolved from vineyard objects in a zero-copy
+ fashion.
+ """
+
+
+
+
+Addressing Distributed Deployment Challenges
+Airflow supports parallel task execution across multiple workers to efficiently
+process complex workflows. In a distributed deployment (using the CeleryExecutor ),
+tasks sharing intermediate data might be scheduled on different workers, necessitating
+remote data access.
+Vineyard seamlessly handles object migration for various data types. In the XCom backend,
+when the IPC client encounters remote objects, it triggers a migration action to move
+the objects to the local worker, ensuring input data is readily available before task
+execution.
+This transparent object migration simplifies complex data operations and movement,
+allowing data scientists to focus on computational logic when developing big data
+applications on Airflow.
+
+
+
+Running Vineyard + Airflow
+Users can try Airflow provider for Vineyard by the following steps:
+
+Install required packages:
+ pip3 install airflow-provider-vineyard
+
+
+
+Configure Vineyard locally
+The vineyard server can be easier launched locally with the following command:
+ python -m vineyard --socket= /tmp/vineyard.sock
+
+
+See also our documentation about launching vineyard .
+
+Configure Airflow to use the vineyard XCom backend by specifying the environment
+variable
+export AIRFLOW__CORE__XCOM_BACKEND = vineyard.contrib.airflow.xcom.VineyardXCom
+
+
+and configure the location of UNIX-domain IPC socket for vineyard client by
+export AIRFLOW__VINEYARD__IPC_SOCKET = /tmp/vineyard.sock
+
+
+or
+export VINEYARD_IPC_SOCKET = /tmp/vineyard.sock
+
+
+
+Launching your airflow scheduler and workers, and run the following DAG as example,
+import numpy as np
+import pandas as pd
+
+from airflow.decorators import dag , task
+from airflow.utils.dates import days_ago
+
+default_args = {
+ 'owner' : 'airflow' ,
+}
+
+@dag ( default_args = default_args , schedule_interval = None , start_date = days_ago ( 2 ), tags = [ 'example' ])
+def taskflow_etl_pandas ():
+ @task ()
+ def extract ():
+ order_data_dict = pd . DataFrame ({
+ 'a' : np . random . rand ( 100000 ),
+ 'b' : np . random . rand ( 100000 ),
+ })
+ return order_data_dict
+
+ @task ( multiple_outputs = True )
+ def transform ( order_data_dict : dict ):
+ return { "total_order_value" : order_data_dict [ "a" ] . sum ()}
+
+ @task ()
+ def load ( total_order_value : float ):
+ print ( f "Total order value is: { total_order_value : .2f } " )
+
+ order_data = extract ()
+ order_summary = transform ( order_data )
+ load ( order_summary [ "total_order_value" ])
+
+taskflow_etl_pandas_dag = taskflow_etl_pandas ()
+
+
+
+
+In the example above, the extract and transform tasks share a pandas.DataFrame as
+intermediate data. This presents a challenge, as the DataFrame cannot be pickled, and when
+dealing with large data, it cannot fit into the backend databases of Airflow.
+This example is adapted from the Airflow documentation. For more information, refer to the
+Tutorial on the Taskflow API .
+
+
+Further Ahead
+The Airflow provider for Vineyard, currently in its experimental stage, demonstrates
+significant potential for efficiently and flexibly sharing large-scale intermediate data
+in big data analytical workflows within Airflow.
+The Airflow community is actively working to enhance support for modern big data and AI
+applications. We believe that the integration of Vineyard, Airflow, and other cloud-native
+infrastructures can provide a more effective and efficient solution for data scientists.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/integration/dask.html b/notes/integration/dask.html
new file mode 100644
index 0000000000..4fa871a28a
--- /dev/null
+++ b/notes/integration/dask.html
@@ -0,0 +1,642 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dask on Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Dask on Vineyard
+The integration with Dask enables dask.array and dask.dataframe to be seamlessly persisted in
+and retrieved from Vineyard. In the following sections, we demonstrate how Vineyard simplifies
+the implementation of an example that utilizes Dask for data preprocessing and TensorFlow for
+distributed learning, as previously showcased in the blog .
+
+The Deployment
+
+As illustrated in the figure above, we employ two machines for the distributed tasks for
+demonstration purposes. The Vineyard daemon processes are launched on both machines, along
+with the Dask workers. The Dask scheduler is initiated on the first machine, where we also
+run the Dask preprocessing program in the first step, as the Dask scheduler manages the
+distribution of computation tasks among its workers.
+In the second step, we execute the training program on both machines with different TF_CONFIG
+settings. For details on configuring the setup, please refer to the documentation .
+
+
+Preprocessing in Dask
+In this step, we load the mnist data and duplicate it to simulate the parallel processing as same as the blog .
+from vineyard.core.builder import builder_context
+from vineyard.contrib.dask.dask import dask_context
+
+def dask_preprocess ( dask_scheduler ):
+ def get_mnist ():
+ ( x_train , y_train ), _ = tf . keras . datasets . mnist . load_data ()
+ # The `x` arrays are in uint8 and have values in the [0, 255] range.
+ # You need to convert them to float64 with values in the [0, 1] range.
+ x_train = x_train / np . float64 ( 255 )
+ y_train = y_train . astype ( np . int64 )
+ return pd . DataFrame ({ 'x' : list ( x_train ), 'y' : y_train })
+
+ with dask_context ():
+ datasets = [ delayed ( get_mnist )() for i in range ( 20 )]
+ dfs = [ dd . from_delayed ( ds ) for ds in datasets ]
+ gdf = dd . concat ( dfs )
+ gdf_id = vineyard . connect () . put ( gdf , dask_scheduler = dask_scheduler )
+
+ return gdf_id
+
+
+Here the returned gdf_id is the ObjectID of a vineyard::GlobalDataFrame
+which consists of 20 partitions (10 partitions on each machine).
+
+
+Training in Tensorflow
+In this step, we use the preprocessed data gdf_id to train a model distributedly
+in keras of Tensorflow.
+from vineyard.contrib.ml.tensorflow import register_tf_types
+from vineyard.core.resolver import resolver_context
+
+def mnist_dataset ( gdf_id , batch_size ):
+ with resolver_context () as resolver :
+ # register the resolver for tensorflow Dataset to the resolver_context
+ register_tf_types ( None , resolver )
+ train_datasets = vineyard . connect () . get ( gdf_id , data = 'x' , label = 'y' )
+ train_datasets = train_datasets . repeat () . batch ( batch_size )
+
+ options = tf . data . Options ()
+ options . experimental_distribute . auto_shard_policy = tf . data . experimental . AutoShardPolicy . OFF
+ train_datasets_no_auto_shard = train_datasets . with_options ( options )
+ return train_datasets_no_auto_shard
+
+def build_and_compile_cnn_model ():
+ model = tf . keras . Sequential ([
+ tf . keras . layers . InputLayer ( input_shape = ( 28 , 28 )),
+ tf . keras . layers . Reshape ( target_shape = ( 28 , 28 , 1 )),
+ tf . keras . layers . Conv2D ( 32 , 3 , activation = 'relu' ),
+ tf . keras . layers . Flatten (),
+ tf . keras . layers . Dense ( 128 , activation = 'relu' ),
+ tf . keras . layers . Dense ( 10 )
+ ])
+ model . compile (
+ loss = tf . keras . losses . SparseCategoricalCrossentropy ( from_logits = True ),
+ optimizer = tf . keras . optimizers . SGD ( learning_rate = 0.001 ),
+ metrics = [ 'accuracy' ])
+ return model
+
+def train ( gdf_id ):
+ per_worker_batch_size = 64
+ strategy = tf . distribute . MultiWorkerMirroredStrategy ()
+ train_dataset = mnist_dataset ( gdf_id , per_worker_batch_size )
+
+ with strategy . scope ():
+ multi_worker_model = mnist . build_and_compile_cnn_model ()
+
+ multi_worker_model . fit ( train_dataset , epochs = 3 , steps_per_epoch = 70 )
+
+
+To utilize the preprocessed data, we first register the resolvers capable of resolving a
+vineyard::GlobalDataFrame distributed across multiple workers within the resolver_context.
+Subsequently, we can directly obtain the tf.data.Dataset from Vineyard using the get
+method.
+
+
Note
+
It is essential to specify the column names for the data and label, as they were set in
+the previous step.
+
+
+
+Transfer Learning
+In this section, we demonstrate how the dask-vineyard integration can be effectively utilized
+in transfer learning scenarios. Transfer learning is a technique where a pre-trained deep
+learning model is used to compute features for downstream models. Storing these features in
+memory is advantageous, as it eliminates the need to recompute features or incur significant
+I/O costs by repeatedly reading them from disk. We will refer to the featurization example
+and use the tf_flowers dataset as a dask.array . We will employ the pre-trained ResNet50
+model to generate features and subsequently store them in Vineyard. The resulting global
+tensor in Vineyard will consist of 8 partitions, each containing 400 data slots.
+def get_images ( idx , num ):
+ paths = list ( Path ( "flower_photos" ) . rglob ( "*.jpg" ))[ idx :: num ]
+ data = []
+ for p in paths :
+ with open ( p , 'rb' ) as f :
+ img = Image . open ( io . BytesIO ( f . read ())) . resize ([ 224 , 224 ])
+ arr = preprocess_input ( img_to_array ( img ))
+ data . append ( arr )
+ return np . array ( data )
+
+def featurize ( v , block_id = None ):
+ model = ResNet50 ( include_top = False )
+ preds = model . predict ( np . stack ( v ))
+ return preds . reshape ( 400 , 100352 )
+
+imgs = [ da . from_delayed ( delayed ( get_images )( i , 8 ), shape = ( 400 , 244 , 244 , 3 ), dtype = 'float' ) for i in range ( 8 )]
+imgs = da . concatenate ( imgs , axis = 0 )
+res = imgs . map_blocks ( featurize , chunks = ( 400 , 100352 ), drop_axis = [ 2 , 3 ], dtype = float )
+global_tensor_id = vineyard . connect () . put ( res , dask_scheduler = dask_scheduler )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/integration/kedro.html b/notes/integration/kedro.html
new file mode 100644
index 0000000000..192c414296
--- /dev/null
+++ b/notes/integration/kedro.html
@@ -0,0 +1,750 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Kedro Vineyard Plugin - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Kedro Vineyard Plugin
+The Kedro vineyard plugin contains components (e.g., DataSet
and Runner
)
+to share intermediate data among nodes in Kedro pipelines using vineyard.
+
+Kedro on Vineyard
+Vineyard works as the DataSet provider for kedro workers to allow transferring
+large-scale data objects between tasks that cannot be efficiently serialized and
+is not suitable for pickle
, without involving external storage systems like
+AWS S3 (or Minio as an alternative). The Kedro vineyard plugin handles object migration
+as well when the required inputs are not located where the task is scheduled to execute.
+
+
+Requirements
+The following packages are needed to run Kedro on vineyard,
+
+kedro >= 0.18
+vineyard >= 0.14.5
+
+
+
+Configuration
+
+Install required packages:
+ pip3 install vineyard-kedro
+
+
+
+Configure Vineyard locally
+The vineyard server can be easier launched locally with the following command:
+ python3 -m vineyard --socket=/tmp/vineyard.sock
+
+
+See also our documentation about Launching Vineyard .
+
+Configure the environment variable to tell Kedro vineyard plugin how to connect to the
+vineyardd server:
+ export VINEYARD_IPC_SOCKET=/tmp/vineyard.sock
+
+
+
+
+
+
+Usage
+After installing the dependencies and preparing the vineyard server, you can execute the
+Kedro workflows as usual and benefits from vineyard for intermediate data sharing.
+We take the Iris example as an example,
+ $ kedro new --starter= pandas-iris
+
+
+The nodes in this pipeline look like
+def split_data (
+ data : pd . DataFrame , parameters : Dict [ str , Any ]
+) -> Tuple [ pd . DataFrame , pd . DataFrame , pd . Series , pd . Series ]:
+ data_train = data . sample (
+ frac = parameters [ "train_fraction" ], random_state = parameters [ "random_state" ]
+ )
+ data_test = data . drop ( data_train . index )
+
+ X_train = data_train . drop ( columns = parameters [ "target_column" ])
+ X_test = data_test . drop ( columns = parameters [ "target_column" ])
+ y_train = data_train [ parameters [ "target_column" ]]
+ y_test = data_test [ parameters [ "target_column" ]]
+
+ return X_train , X_test , y_train , y_test
+
+
+def make_predictions (
+ X_train : pd . DataFrame , X_test : pd . DataFrame , y_train : pd . Series
+) -> pd . Series :
+ X_train_numpy = X_train . to_numpy ()
+ X_test_numpy = X_test . to_numpy ()
+
+ squared_distances = np . sum (
+ ( X_train_numpy [:, None , :] - X_test_numpy [ None , :, :]) ** 2 , axis =- 1
+ )
+ nearest_neighbour = squared_distances . argmin ( axis = 0 )
+ y_pred = y_train . iloc [ nearest_neighbour ]
+ y_pred . index = X_test . index
+
+ return y_pred
+
+
+You can see that the intermediate data between split_data
and make_predictions
is some pandas
+dataframes and series.
+Try running the pipeline without vineyard,
+ $ cd iris
+$ kedro run
+[ 05 /25/23 11 :38:56] INFO Kedro project iris session.py:355
+[ 05 /25/23 11 :38:57] INFO Loading data from 'example_iris_data' ( CSVDataSet) ... data_catalog.py:343
+ INFO Loading data from 'parameters' ( MemoryDataSet) ... data_catalog.py:343
+ INFO Running node: split: split_data([ example_iris_data,parameters]) -> [ X_train,X_test,y_train,y_test] node.py:329
+ INFO Saving data to 'X_train' ( MemoryDataSet) ... data_catalog.py:382
+ INFO Saving data to 'X_test' ( MemoryDataSet) ... data_catalog.py:382
+ INFO Saving data to 'y_train' ( MemoryDataSet) ... data_catalog.py:382
+ INFO Saving data to 'y_test' ( MemoryDataSet) ... data_catalog.py:382
+ INFO Completed 1 out of 3 tasks sequential_runner.py:85
+ INFO Loading data from 'X_train' ( MemoryDataSet) ... data_catalog.py:343
+ INFO Loading data from 'X_test' ( MemoryDataSet) ... data_catalog.py:343
+ INFO Loading data from 'y_train' ( MemoryDataSet) ... data_catalog.py:343
+ INFO Running node: make_predictions: make_predictions([ X_train,X_test,y_train]) -> [ y_pred] node.py:329
+...
+
+
+You can see that the intermediate data is shared with memory. When kedro is deploy to a cluster, e.g.,
+to argo workflow , the MemoryDataSet
is not applicable anymore and you will need to setup the
+AWS S3 or Minio service and sharing those intermediate data as CSV files.
+X_train :
+ type : pandas.CSVDataSet
+ filepath : s3://testing/data/02_intermediate/X_train.csv
+ credentials : minio
+
+X_test :
+ type : pandas.CSVDataSet
+ filepath : s3://testing/data/02_intermediate/X_test.csv
+ credentials : minio
+
+y_train :
+ type : pandas.CSVDataSet
+ filepath : s3://testing/data/02_intermediate/y_train.csv
+ credentials : minio
+
+
+It might be inefficient for pickling pandas dataframes when data become larger. With the kedro
+vineyard plugin, you can run the pipeline with vineyard as the intermediate data medium by
+ $ kedro run --runner vineyard.contrib.kedro.runner.SequentialRunner
+[ 05 /25/23 11 :45:34] INFO Kedro project iris session.py:355
+ INFO Loading data from 'example_iris_data' ( CSVDataSet) ... data_catalog.py:343
+ INFO Loading data from 'parameters' ( MemoryDataSet) ... data_catalog.py:343
+ INFO Running node: split: split_data([ example_iris_data,parameters]) -> [ X_train,X_test,y_train,y_test] node.py:329
+ INFO Saving data to 'X_train' ( VineyardDataSet) ... data_catalog.py:382
+ INFO Saving data to 'X_test' ( VineyardDataSet) ... data_catalog.py:382
+ INFO Saving data to 'y_train' ( VineyardDataSet) ... data_catalog.py:382
+ INFO Saving data to 'y_test' ( VineyardDataSet) ... data_catalog.py:382
+ INFO Loading data from 'X_train' ( VineyardDataSet) ... data_catalog.py:343
+ INFO Loading data from 'X_test' ( VineyardDataSet) ... data_catalog.py:343
+ INFO Loading data from 'y_train' ( VineyardDataSet) ... data_catalog.py:343
+ INFO Running node: make_predictions: make_predictions([ X_train,X_test,y_train]) -> [ y_pred] node.py:329
+...
+
+
+Without any modification to your pipeline code, you can see that the intermediate data is shared
+with vineyard using the VineyardDataSet
and no longer suffers from the overhead of (de)serialization
+and the I/O cost between external AWS S3 or Minio services.
+Like kedro catalog create
, the Kedro vineyard plugin provides a command-line interface to generate
+the catalog configuration for given pipeline, which will rewrite the unspecified intermediate data
+to VineyardDataSet
, e.g.,
+ $ kedro vineyard catalog create -p __default__
+
+
+You will get
+X_test :
+ ds_name : X_test
+ type : vineyard.contrib.kedro.io.dataset.VineyardDataSet
+X_train :
+ ds_name : X_train
+ type : vineyard.contrib.kedro.io.dataset.VineyardDataSet
+y_pred :
+ ds_name : y_pred
+ type : vineyard.contrib.kedro.io.dataset.VineyardDataSet
+y_test :
+ ds_name : y_test
+ type : vineyard.contrib.kedro.io.dataset.VineyardDataSet
+y_train :
+ ds_name : y_train
+ type : vineyard.contrib.kedro.io.dataset.VineyardDataSet
+
+
+
+
+Deploy to Kubernetes
+When the pipeline scales to Kubernetes, the interaction with the Kedro vineyard plugin is
+still simple and non-intrusive. The plugin provides tools to prepare the docker image and
+generate Argo workflow specification file for the Kedro pipeline. Next, we’ll demonstrate
+how to deploy pipelines to Kubernetes while leverage Vineyard for efficient intermediate
+sharing between tasks step-by-step.
+
+Prepare the vineyard cluster (see also Deploy on Kubernetes ):
+# export your kubeconfig path here
+$ export KUBECONFIG = /path/to/your/kubeconfig
+
+# install the vineyard operator
+$ go run k8s/cmd/main.go deploy vineyard-cluster --create-namespace
+
+
+
+Install the argo server:
+# install the argo server
+$ kubectl create namespace argo
+$ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.4.8/install.yaml
+
+
+
+Generate the iris demo project from the official template:
+ $ kedro new --starter= pandas-iris
+
+
+
+Build the Docker image for this iris demo project:
+# walk to the iris demo root directory
+$ cd iris
+$ kedro vineyard docker build
+
+
+A Docker image named iris
will be built successfully. The docker image
+need to be pushed to your image registry, or loaded to the kind/minikube cluster, to be
+available in Kubernetes.
+ $ docker images | grep iris
+iris latest 3c92da8241c6 About a minute ago 690MB
+
+
+
+Next, generate the Argo workflow YAML file from the iris demo project:
+ $ kedro vineyard argo generate -i iris
+
+# check the generated Argo workflow YAML file, you can see the Argo workflow YAML file named `iris.yaml`
+# is generated successfully.
+$ ls -l argo-iris.yml
+-rw-rw-r-- 1 root root 3685 Jun 12 23 :55 argo-iris.yml
+
+
+
+Finally, submit the Argo workflow to Kubernetes:
+ $ argo submit -n argo argo-iris.yml
+
+
+You can interact with the Argo workflow using the argo
command-line tool, e.g.,
+ $ argo list workflows -n argo
+NAME STATUS AGE DURATION PRIORITY MESSAGE
+iris-sg6qf Succeeded 18m 30s 0
+
+
+
+
+We have prepared a benchmark to evaluate the performance gain brought by vineyard for data
+sharing when data scales, for more details, please refer to this report .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/integration/ml.html b/notes/integration/ml.html
new file mode 100644
index 0000000000..e09b91f359
--- /dev/null
+++ b/notes/integration/ml.html
@@ -0,0 +1,788 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Machine Learning with Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Machine Learning with Vineyard
+Vineyard-ML : A Vineyard package that integrates Machine Learning Frameworks to Vineyard.
+
+TensorFlow
+
+Using Numpy Data
+>>> import tensorflow as tf
+>>> from vineyard.contrib.ml import tensorflow
+>>> dataset = tf . data . Dataset . from_tensor_slices (( data , label ))
+>>> data_id = vineyard_client . put ( dataset )
+>>> vin_data = vineyard_client . get ( data_id )
+
+
+Vineyard supports the tf.data.Dataset
. The vin_data
will be a shared-memory object
+from the vineyard.
+
+
+Using Dataframe
+>>> import pandas as pd
+>>> df = pd . DataFrame ({ 'a' : [ 1 , 2 , 3 , 4 ], 'b' : [ 5 , 6 , 7 , 8 ], 'target' : [ 1.0 , 2.0 , 3.0 , 4.0 ]})
+>>> label = df . pop ( 'target' )
+>>> dataset = tf . data . Dataset . from_tensor_slices (( dict ( df ), label ))
+>>> data_id = vineyard_client . put ( dataset )
+>>> vin_data = vineyard_client . get ( data_id )
+
+
+Wrap the dataframe with tf.data.Dataset
. This enables the use of feature columns as a
+bridge to map from the columns in Pandas Dataframe to features in Dataset. The
+dataset should return a dictionary of column names (from the dataframe) that maps
+to column values. The dataset should only contain numerical data
.
+
+
+Using RecordBatch of Pyarrow
+>>> import pyarrow as pa
+>>> arrays = [ pa . array ([ 1 , 2 , 3 , 4 ]), pa . array ([ 3.0 , 4.0 , 5.0 , 6.0 ]), pa . array ([ 0 , 1 , 0 , 1 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'f1' , 'label' ])
+>>> data_id = vineyard_client . put ( batch )
+>>> vin_data = vineyard_client . get ( data_id )
+
+
+Vineyard supports direct integration of RecordBatch. The vin_data
object will
+be a TensorFlow Dataset, i.e. tf.data.Dataset
. Here the label
row should be named as label
.
+
+
+Using Tables of Pyarrow
+>>> arrays = [ pa . array ([ 1 , 2 , 3 , 4 ]), pa . array ([ 3.0 , 4.0 , 5.0 , 6.0 ]), pa . array ([ 0 , 1 , 0 , 1 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'f1' , 'label' ])
+>>> batches = [ batch ] * 3
+>>> table = pa . Table . from_batches ( batches )
+>>> data_id = vineyard_client . put ( table )
+>>> vin_data = vineyard_client . get ( data_id )
+
+
+Vineyard supports direct integration of Tables as well. Here, the vin_data
+object will be of type TensorFlow Dataset, i.e. tf.data.Dataset
. Here the label
row
+should be named as label
.
+
+
+
+PyTorch
+
+Using Numpy Data
+Vineyard supports Custom Datasets
inherited from the PyTorch Dataset.
+>>> import torch
+>>> from vineyard.contrib.ml import pytorch
+>>> data_id = vineyard_client . put ( dataset , typename = 'Tensor' )
+>>> vin_data = vineyard_client . get ( data_id )
+
+
+The dataset object should be an object of the type CustomDataset class which is inherited
+from torch.utils.data.Dataset
class. Adding the typename as Tensor
is important.
+The vin_data
will be of type torch.utils.data.TensorDataset
.
+
+
+Using Dataframe
+>>> df = pd . DataFrame ({ 'a' : [ 1 , 2 , 3 , 4 ], 'b' : [ 5 , 6 , 7 , 8 ], 'c' : [ 1.0 , 2.0 , 3.0 , 4.0 ]})
+>>> label = torch . from_numpy ( df [ 'c' ] . values . astype ( np . float32 ))
+>>> data = torch . from_numpy ( df . drop ( 'c' , axis = 1 ) . values . astype ( np . float32 ))
+>>> dataset = torch . utils . data . TensorDataset ( data , label )
+>>> data_id = vineyard_client . put ( dataset , typename = 'Dataframe' , cols = [ 'a' , 'b' , 'c' ], label = 'c' )
+>>> vin_data = vineyard_client . get ( data_id , label = 'c)
+
+
+While using the PyTorch form of the dataframe with vineyard, it is important to mention
+the typename as Dataframe
, a list of column names in cols
and the label
+name in label tag. The vin_data
will be of the form TensorDataset
with
+the label as mentioned with the label tag. If no value is passed to the label tag
+vineyard will consider the default value which is the value of label passed in while
+calling the put
method
+
+
+Using RecordBatch of Pyarrow
+>>> import pyarrow as pa
+>>> arrays = [ pa . array ([ 1 , 2 , 3 , 4 ]), pa . array ([ 3.0 , 4.0 , 5.0 , 6.0 ]), pa . array ([ 0 , 1 , 0 , 1 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'f1' , 'f2' ])
+>>> data_id = vineyard_client . put ( batch )
+>>> vin_data = vineyard_client . get ( data_id , label = 'f2' )
+
+
+The vin_data
will be of the form TensorDataset
with the label as mentioned
+with the label tag. In this case it is important to mention the label tag.
+
+
+Using Tables of Pyarrow
+>>> arrays = [ pa . array ([ 1 , 2 , 3 , 4 ]), pa . array ([ 3.0 , 4.0 , 5.0 , 6.0 ]), pa . array ([ 0 , 1 , 0 , 1 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'f1' , 'f2' ])
+>>> batches = [ batch ] * 3
+>>> table = pa . Table . from_batches ( batches )
+>>> data_id = vineyard_client . put ( table )
+>>> vin_data = vineyard_client . get ( data_id , label = 'f2' )
+
+
+The vin_data
object will be of the form TensorDataset
with the label as mentioned
+with the label tag. In this case, it is important to mention the label tag.
+
+
+
+MxNet
+
+Using Numpy Data
+Vineyard supports Array Datasets
from the gluon.data of MxNet.
+>>> import mxnet as mx
+>>> from vineyard.contrib.ml import mxnet
+>>> dataset = mx . gluon . data . ArrayDataset (( data , label ))
+>>> data_id = vineyard_client . put ( dataset , typename = 'Tensor' )
+>>> vin_data = vineyard_client . get ( data_id )
+
+
+The dataset object should be an object of the type ArrayDataset from mxnet.gluon.data
+class. Here, Adding the typename as Tensor
is important. The vin_data
will be
+of type mxnet.gluon.data.ArrayDataset
.
+
+
+Using Dataframe
+>>> df = pd . DataFrame ({ 'a' : [ 1 , 2 , 3 , 4 ], 'b' : [ 5 , 6 , 7 , 8 ], 'c' : [ 1.0 , 2.0 , 3.0 , 4.0 ]})
+>>> label = df [ 'c' ] . values . astype ( np . float32 )
+>>> data = df . drop ( 'c' , axis = 1 ) . values . astype ( np . float32 )
+>>> dataset = mx . gluon . data . ArrayDataset (( data , label ))
+>>> data_id = vineyard_client . put ( dataset , typename = 'Dataframe' , cols = [ 'a' , 'b' , 'c' ], label = 'c' )
+>>> vin_data = vineyard_client . get ( data_id , label = 'c)
+
+
+While using the MxNet form of the dataframe with vineyard, it is important to mention
+the typename as Dataframe
, a list of column names in cols
and the label
+name in label tag. The vin_data
will be of the form ArrayDataset
with
+the label as mentioned with the label tag. If no value is passed to the label tag
+vineyard will consider the default value which is the value of label passed in while
+calling the put
method
+
+
+Using RecordBatch of Pyarrow
+>>> import pyarrow as pa
+>>> arrays = [ pa . array ([ 1 , 2 , 3 , 4 ]), pa . array ([ 3.0 , 4.0 , 5.0 , 6.0 ]), pa . array ([ 0 , 1 , 0 , 1 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'f1' , 'f2' ])
+>>> data_id = vineyard_client . put ( batch )
+>>> vin_data = vineyard_client . get ( data_id , label = 'f2' )
+
+
+The vin_data
will be of the form ArrayDataset
with the label as mentioned
+with the label tag. In this case, it is important to mention the label tag.
+
+
+Using Tables of Pyarrow
+>>> arrays = [ pa . array ([ 1 , 2 , 3 , 4 ]), pa . array ([ 3.0 , 4.0 , 5.0 , 6.0 ]), pa . array ([ 0 , 1 , 0 , 1 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'f1' , 'f2' ])
+>>> batches = [ batch ] * 3
+>>> table = pa . Table . from_batches ( batches )
+>>> data_id = vineyard_client . put ( table )
+>>> vin_data = vineyard_client . get ( data_id , label = 'f2' )
+
+
+The vin_data
object will be of the form ArrayDataset
with the label as mentioned
+with the label tag. In this case, it is important to mention the label tag.
+
+
+
+XGBoost
+Vineyard supports resolving XGBoost::DMatrix
from various kinds of vineyard data types.
+
+From Vineyard::Tensor
+>>> arr = np . random . rand ( 4 , 5 )
+>>> vin_tensor_id = vineyard_client . put ( arr )
+>>> dmatrix = vineyard_client . get ( vin_tensor_id )
+
+
+The dmatrix
will be a DMatrix
instance with the same shape (4, 5)
resolved from the Vineyard::Tensor
+object with the id vin_tensor_id
.
+
+
+From Vineyard::DataFrame
+>>> df = pd . DataFrame ({ 'a' : [ 1 , 2 , 3 , 4 ], 'b' : [ 5 , 6 , 7 , 8 ], 'c' : [ 1.0 , 2.0 , 3.0 , 4.0 ]})
+>>> vin_df_id = vineyard_client . put ( df )
+>>> dmatrix = vineyard_client . get ( vin_df_id , label = 'a' )
+
+
+The dmatrix
will be a DMatrix
instance with shape of (4, 2)
and feature_names
of ['b', 'c']
.
+While the label of dmatrix
is the values of column a
.
+Sometimes the dataframe is a complex data structure and only one
column will be used as the features
.
+We support this case by providing the data
kwarg.
+>>> df = pd . DataFrame ({ 'a' : [ 1 , 2 , 3 , 4 ],
+>>> 'b' : [[ 5 , 1.0 , 4 ], [ 6 , 2.0 , 3 ], [ 7 , 3.0 , 2 ], [ 8 , 9.0 , 1 ]]})
+>>> vin_df_id = vineyard_client . put ( df )
+>>> dmatrix = vineyard_client . get ( vin_df_id , data = 'b' , label = 'a' )
+
+
+The dmatrix
will have the shape of (4, 3)
corresponding to the values of column b
.
+While the label is the values of column a
.
+
+
+From Vineyard::RecordBatch
+>>> import pyarrow as pa
+>>> arrays = [ pa . array ([ 1 , 2 , 3 , 4 ]), pa . array ([ 3.0 , 4.0 , 5.0 , 6.0 ]), pa . array ([ 0 , 1 , 0 , 1 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'f1' , 'target' ])
+>>> vin_rb_id = vineyard_client . put ( batch )
+>>> dmatrix = vineyard_client . get ( vin_rb_id , label = 'target' )
+
+
+The dmatrix
will have the shape of (4, 2)
and feature_names
of ['f0', 'f1']
.
+While the label is the values of column target
.
+
+
+From Vineyard::Table
+>>> arrays = [ pa . array ([ 1 , 2 ]), pa . array ([ 0 , 1 ]), pa . array ([ 0.1 , 0.2 ])]
+>>> batch = pa . RecordBatch . from_arrays ( arrays , [ 'f0' , 'label' , 'f2' ])
+>>> batches = [ batch ] * 3
+>>> table = pa . Table . from_batches ( batches )
+>>> vin_tab_id = vineyard_client . put ( table )
+>>> dmatrix = vineyard_client . get ( vin_tab_id , label = 'label' )
+
+
+The dmatrix
will have the shape of (6, 2)
and feature_names
of ['f0', 'f2']
.
+While the label is the values of column label
.
+
+
+
+Nvidia-DALI
+Vineyard supports integration of Dali Pipelines
.
+>>> from nvidia.dali import pipeline_def
+>>> pipeline = pipe ( device_id = device_id , num_threads = num_threads , batch_size = batch_size )
+>>> pipeline . build ()
+>>> pipe_out = pipeline . run ()
+>>> data_id = vineyard_client . put ( pipe_out )
+>>> vin_pipe = vineyard_client . get ( data_id )
+
+
+In this case, the pipe is a pipeline_def
function. The data received after executing pipe.run() can
+be stored into vineyard. The Pipeline should only return two values, namely data and label. The return
+type of the data and label values should be of type TensorList
. The vin_pipe
object will be the
+output of a simple in-built pipeline after executing the pipeline.build() and pipeline.run(). It will
+simply return two values of type Pipeline.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/integration/ray.html b/notes/integration/ray.html
new file mode 100644
index 0000000000..b6d61fd019
--- /dev/null
+++ b/notes/integration/ray.html
@@ -0,0 +1,453 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Ray on Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/key-concepts.html b/notes/key-concepts.html
new file mode 100644
index 0000000000..3692fd5f3d
--- /dev/null
+++ b/notes/key-concepts.html
@@ -0,0 +1,581 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Key Concepts - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Key Concepts
+
+
+The User Guide section offers an in-depth understanding of vineyard’s design
+and implementation. It covers detailed environment setup instructions, the
+architecture, and the core features within the vineyard engine.
+Additional information on vineyard’s internals will be provided soon .
+
+
Tip
+
If you are new to vineyard, we recommend starting with the
+Getting Started page for a smoother
+introduction.
+
+
+Concepts
+
+
+
+
+
+
+
The design space of vineyard objects.
+
+
+
+
+
+
+
+
VCDL and how to integration vineyard with computing systems.
+
+
+
+
+
+
+
+
The approaches that can be used to access various kinds of objects stored in
+vineyard.
+
+
+
+
+
+
+
+
The stream abstraction upon the immutable data sharing storage and its usages.
+
+
+
+
+
+
+
+
Design and implementation of the builtin I/O drivers that eases the integration
+of computing engines to existing infrastructure.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/key-concepts/data-accessing.html b/notes/key-concepts/data-accessing.html
new file mode 100644
index 0000000000..eb85bbb9f2
--- /dev/null
+++ b/notes/key-concepts/data-accessing.html
@@ -0,0 +1,834 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Data Accessing - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Data Accessing
+Vineyard is designed to support distributed object sharing and offers both IPCClient
+and RPCClient for efficient data access. This section will guide you through various
+methods of accessing objects within vineyard. For more information on vineyard object
+basics, please refer to Object = metadata + payloads and Distributed objects .
+
+IPCClient vs. RPCClient
+As depicted in the above figure, data is partitioned across different vineyard
+instances. The concept of zero-copy sharing was explained in Architecture .
+Memory mapping is only available for clients on the same instance, while metadata
+is globally synchronized and accessible from clients connected to instances on other hosts.
+Vineyard provides two clients to support IPC and RPC scenarios:
+
+IPC Client
+
+
+RPC Client
+
+
+
+
+Local vs. Remote
+Distributed shared objects are typically partitioned, with each vineyard instance managing
+some chunks of the entire object. As shown in Distributed objects , a GlobalTensor
+is partitioned into three chunks, and each instance holds one chunk of type Tensor
.
+From the perspective of computing engines , distributed computing engines launch
+workers on vineyard instances. Each worker connects to the co-located local instance and
+is responsible for processing chunks in that local instance. For example, when starting a Dask
+cluster on a vineyard cluster as illustrated in the picture above, each Dask worker is responsible
+for executing computations on its local chunks. Some computing tasks require communication between
+workers, such as aggregation. In these cases, the communication is performed by the computing
+engine itself (in this case, the Dask cluster).
+
+
Tip
+
We assume that the computing engines built upon vineyard are responsible for scheduling
+tasks based on their awareness of the underlying data partitioning within the vineyard
+cluster.
+
This design is well-suited for commonly-used modern computing engines,such as GraphScope,
+Spark, Presto, Dask, Mars, and Ray.
+
+
+
+
+Local Objects
+Creating and accessing local objects in vineyard can be easily achieved using put
and get
methods (see
+vineyard.IPCClient.put()
and vineyard.IPCClient.get()
).
+
+
Effortlessly create and access local objects using put
and get
+
>>> import pandas as pd
+ >>> import vineyard
+ >>> import numpy as np
+ >>>
+ >>> vineyard_ipc_client = vineyard . connect ( "/tmp/vineyard.sock" )
+ >>>
+ >>> df = pd . DataFrame ( np . random . rand ( 10 , 2 ))
+ >>>
+ >>> # put object into vineyard
+ >>> r = vineyard_ipc_client . put ( df )
+ >>> r , type ( r )
+ ( o00053008257020f8 , vineyard . _C . ObjectID )
+ >>>
+ >>> # get object from vineyard using object id
+ >>> data = vineyard_ipc_client . get ( r )
+ >>> data
+ 0 1
+ 0 0.534487 0.261941
+ 1 0.901056 0.441583
+ 2 0.687568 0.671564
+ ...
+
+
+
+Vineyard provides low-level APIs to operate on metadatas and raw blobs as well.
+
+
+Using blobs
+Vineyard offers low-level APIs for creating and accessing local blobs with enhanced efficiency:
+
+
+
Creating local blobs
+
>>> import vineyard
+ >>> vineyard_ipc_client = vineyard . connect ( "/tmp/vineyard.sock" )
+ >>>
+ >>> # mock a data
+ >>> payload = b 'abcdefgh1234567890uvwxyz'
+ >>>
+ >>> # create a blob builder
+ >>> buffer_builder = vineyard_ipc_client . create_blob ( len ( payload ))
+ >>>
+ >>> # copy the mocked data into the builder
+ >>> buffer_builder . copy ( 0 , payload )
+ >>>
+ >>> # seal the builder then we will get a blob
+ >>> blob = buffer_builder . seal ( vineyard_ipc_client )
+
+
+
+
+
Accessing local blobs
+
>>> # get the blob from vineyard using object id
+ >>> blob = vineyard_ipc_client . get_blob ( blob . id )
+ >>> blob , type ( blob )
+ ( Object < "o800532e4ab1f2087" : vineyard :: Blob > , vineyard . _C . Blob )
+ >>>
+ >>> # inspect the value
+ >>> bytes ( memoryview ( blob ))
+ b 'abcdefgh1234567890uvwxyz'
+
+
+
+
+
+
+Remote Objects
+Creating and accessing remote objects in vineyard can be easily achieved using put
and get
methods (see
+vineyard.RPCClient.put()
and vineyard.RPCClient.get()
).
+
+
Effortlessly create and access remote objects using put
and get
+
>>> import pandas as pd
+ >>> import vineyard
+ >>> import numpy as np
+ >>>
+ >>> vineyard_rpc_client = vineyard . connect ( "localhost" , 9600 )
+ >>>
+ >>> df = pd . DataFrame ( np . random . rand ( 10 , 2 ))
+ >>>
+ >>> # put object into vineyard
+ >>> r = vineyard_rpc_client . put ( df )
+ >>> r , type ( r )
+ ( o000a45730a85f8fe , vineyard . _C . ObjectID )
+ >>>
+ >>> # get object from vineyard using object id
+ >>> data = vineyard_rpc_client . get ( r )
+ >>> data
+ 0 1
+ 0 0.884227 0.576031
+ 1 0.863040 0.069815
+ 2 0.297906 0.911874
+ ...
+
+
+
+The RPC client enables inspection of remote object metadata and facilitates operations on blobs
+within the remote cluster, while taking into account the associated network transfer costs.
+
+
+Using remote blobs
+However, due to the absence of memory sharing between hosts, zero-copy data sharing is not feasible when
+connecting to a vineyard instance that is not deployed on the same host as the client. Transferring data
+over the network incurs significant costs, and vineyard requires users to explicitly issue a migrate
+command to move data from the remote instance to the local instance. For more details, please refer to
+Object Migration in Vineyard .
+For added convenience, we also provide APIs to fetch remote blobs to the local client by transferring
+payloads over the network.
+
+
+
Warning
+
Note that the remote
in the above APIs means the blob will be transferred using
+TCP network. For large blobs, it implies a significant cost of time.
+
+
+
Creating remote blobs
+
>>> import vineyard
+ >>> vineyard_rpc_client = vineyard . connect ( "localhost" , 9600 )
+ >>>
+ >>> # mock a data
+ >>> payload = b 'abcdefgh1234567890uvwxyz'
+ >>>
+ >>> # create an empty blob builder
+ >>> remote_buffer_builder = vineyard . RemoteBlobBuilder ( len ( payload ))
+ >>>
+ >>> # copy the mocked data into the builder
+ >>> remote_buffer_builder . copy ( 0 , payload )
+ >>>
+ >>> # create the remote blob using the RPCClient, with the `remote_buffer_builder` as argument
+ >>> remote_blob_meta = vineyard_rpc_client . create_remote_blob ( remote_buffer_builder )
+
+
+
+
+
Accessing remote blobs
+
>>> # get the remote blob from vineyard using object id
+ >>> remote_blob = vineyard_rpc_client . get_remote_blob ( remote_blob_meta . id )
+ >>> remote_blob , type ( remote_blob )
+ ( < vineyard . _C . RemoteBlob at 0x142204870 > , vineyard . _C . RemoteBlob )
+ >>>
+ >>> # inspect the value of remote blob
+ >>> bytes ( memoryview ( remote_blob ))
+ b 'abcdefgh1234567890uvwxyz'
+
+
+
+
+
+
+
+Utilizing Distributed Objects
+In the illustration at the beginning of this section, we demonstrate that vineyard is capable of sharing
+distributed objects partitioned across multiple hosts. Accessing these distributed objects
+in vineyard can be achieved through two distinct approaches:
+
+Inspecting metadata of global.
+The metadata of global objects can be examined using the vineyard.RPCClient
. This allows
+computing engines to understand the distribution of partitions of global tensors using the
+RPCClient, and subsequently schedule jobs over those chunks based on the distribution information.
+Mars employs this method to consume distributed tensors and dataframes in vineyard.
+Additionally, by leveraging the metadata of global objects and the server metadata accessible
+via vineyard.Client.meta()
, multiple RPC clients can connect to retrieve the corresponding
+blobs from different nodes. These blobs are then assembled locally into a single object. This approach
+is also the default method for vineyard.client
.
+
+Accessing local partitions of global objects using the IPCClient
:
+Another prevalent pattern for accessing shared global objects involves launching a worker on each
+instance where the global object is partitioned. Then, using the vineyard.IPCClient
,
+workers can obtain the local partitions of the global object. Each worker is responsible for
+processing its local partitions.
+This pattern is commonly utilized in many computing engines that have been integrated with
+vineyard, such as GraphScope and Presto.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/key-concepts/io-drivers.html b/notes/key-concepts/io-drivers.html
new file mode 100644
index 0000000000..6ce7daf775
--- /dev/null
+++ b/notes/key-concepts/io-drivers.html
@@ -0,0 +1,518 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ I/O Drivers - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+I/O Drivers
+As we have shown in the getting-started, the open
function in vineyard can open a local
+file as a stream for consuming, and we notice that the path of the local file is headed
+with the scheme file://
.
+Actually, vineyard supports several different types of data source, e.g., kafka://
+for kafka topics. The functional methods to open different data sources as vineyard
+streams are called drivers
in vineyard. They are registered to open
for
+specific schemes, so that when open
is invoked, it will dispatch the corresponding
+driver to handle the specific data source according to the scheme of the path.
+The following sample code demonstrates the dispatching logic in open
, and the
+registration examples.
+>>> @registerize
+>>> def open ( path , * args , ** kwargs ):
+>>> scheme = urlparse ( path ) . scheme
+
+>>> for reader in open . _factory [ scheme ][:: - 1 ]:
+>>> r = reader ( path , * args , ** kwargs )
+>>> if r is not None :
+>>> return r
+>>> raise RuntimeError ( 'Unable to find a proper IO driver for %s ' % path )
+>>>
+>>> # different driver functions are registered as follows
+>>> open . register ( 'file' , local_driver )
+
+
+Most importantly, the registration design allows users to register their own drivers
+to registerized
vineyard methods using .register
, which prevents major revisions
+on the processing code to fulfill customized computation requirements.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/key-concepts/objects.html b/notes/key-concepts/objects.html
new file mode 100644
index 0000000000..91369c59fa
--- /dev/null
+++ b/notes/key-concepts/objects.html
@@ -0,0 +1,781 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Objects - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Objects
+Vineyard represents various data types as vineyard objects. It employs a
+metadata-payloads decoupled design, where an object in vineyard comprises:
+
+A collection of blobs containing the actual data payload;
+A hierarchical meta tree that describes the data’s type, layout, and properties.
+
+
+
+
+Data model
+
+Composable
+The composition mechanism in vineyard is based on the hierarchical tree structure of
+the metadata of its objects. The root metadata of a complex object stores references
+to the root metadata of its components. By recursively traversing these references,
+a complete metadata tree is constructed for the complex object.
+
+
+
+Vineyard objects are composable
+
+
+For instance, a distributed dataframe consists of partitioned dataframe chunks, while
+a dataframe is composed of column vectors. Considering the decoupling design of payload
+and layout in vineyard objects, the blobs are stored in the corresponding vineyard
+instance’s memory for each partition, and the metadata (e.g., chunk index, shape,
+column data types) are stored in the key-value store behind the metadata service.
+To store a distributed graph, we first save the partitioned fragments in each vineyard
+instance and share their metadata in the backend key-value store. Then, we can create
+the distributed graph by generating the root metadata containing links to the root
+metadata of the fragments in an efficient manner.
+
+
+Distributed objects
+Vineyard is designed to store large objects across multiple nodes in a cluster, enabling
+user programs to seamlessly interact with these objects as a single entity. Data is
+sharded across multiple machines without replication.
+
+
+
+Distributed objects in vineyard
+
+
+For example, consider a “Tensor” object that contains billions of columns and rows, making
+it too large to fit into a single machine. In such cases, the tensor can be split along
+the index or column axis, with each vineyard node holding a subset of chunks. Vineyard
+provides a logical view of the complete tensor, allowing distributed computation engines
+like Mars and GraphScope to process the data structure as a whole.
+.. TODO: add the collection APIs
+
+
Tip
+
See also the concepts of persistent objects in the following subsection. Refer to
+the following subsection for more information on the concept of persistent objects .
+
+
+
+Transient vs. Persistent
+As previously mentioned, vineyard objects’ metadata and payloads are managed separately
+by different components of the vineyard server. Payloads are designed to be shared with
+computing engines using local memory mapping. However, metadata may need to be inspected
+by clients connected to other vineyard instances, such as when forming a distributed object.
+In this case, the distributed object consists of a set of chunks placed on different
+vineyard instances. When retrieving the distributed objects from vineyard, computing engines
+may need to inspect the metadata of non-local pieces to understand the distribution of the
+entire dataset.
+This requirement implies that metadata must be globally synchronized and accessible from
+clients connected to other vineyard instances. However, global synchronization is a costly
+operation, and numerous small key-value pairs can significantly increase the burden on the
+key-value store backend of our metadata services. To address this issue, we categorize
+objects as transient or persistent.
+
+Transient objects are designed for cases where the object is known not to be part of a
+distributed object and will never need to be inspected by clients on other vineyard instances.
+Transient objects are useful for short-lived immediate values within the progress of a
+single computing engine.
+Persistent objects are designed for cases where the object chunk will be used to form
+a larger distributed object, and the metadata is needed when applications inspect the
+distributed object. Persistent objects and distributed objects are commonly used to pass
+intermediate data between two distributed engines.
+
+
+
Caution
+
By default, objects are transient . We provide an API client.persist()
that
+can explicitly persist the metadata of the target object to etcd, ensuring its visibility
+by clients connected to other instances in the cluster.
+
+
+
+Builders and resolvers
+Vineyard utilizes an extensible registry mechanism to enable users to easily integrate their
+data structures into the system. This design, which includes builders, resolvers, and drivers,
+allows users to create, resolve, and share their data structures across different systems and
+paradigms. Notably, even the core data structures and drivers in Vineyard follow this design.
+
+
Note
+
What is the registry mechanism?
+
The registry mechanism decouples methods from the definition of Vineyard data types. For
+builders and resolvers, this means users can flexibly register different implementations
+in various languages to build and resolve the same Vineyard data type. This enables data
+sharing between different systems and paradigms and allows for native language optimizations.
+
For drivers, the registry mechanism permits users to flexibly plug in functionality methods
+in different languages for Vineyard data types, providing the necessary capabilities for
+data types during the data analysis process.
+
Moreover, the registered methods can be implemented and optimized according to specific
+data analysis tasks, further enhancing efficiency.
+
+Refer to Define Data Types in Python and Defining Custom Data Types in C++ for examples of how builders
+and resolvers are implemented in Python and C++, respectively.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/key-concepts/streams.html b/notes/key-concepts/streams.html
new file mode 100644
index 0000000000..2b2ee61a99
--- /dev/null
+++ b/notes/key-concepts/streams.html
@@ -0,0 +1,624 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Streams in Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Streams in Vineyard
+Streams in Vineyard serve as an abstraction over the immutable data sharing storage,
+facilitating seamless pipelining between computing engines. Similar to
+pipe , Vineyard’s streams enable
+efficient inter-engine communication while minimizing the overhead associated with
+data serialization/deserialization and copying.
+A typical use case for streams in Vineyard involves one process continuously producing
+data chunks (e.g., an IO reader) while another process performs scan computations
+on the data (e.g., filtering and aggregation operations). A stream consists of a
+sequence of immutable data chunks, produced by the former engine and consumed by the
+latter engine.
+This section will explore the utilization of streams in Vineyard.
+
+Using streams
+We first import required packages:
+import threading
+import time
+from typing import List
+
+import numpy as np
+import pandas as pd
+
+import vineyard
+from vineyard.io.recordbatch import RecordBatchStream
+
+
+
+
+
+Producer and consumer
+We define a producer that generates random dataframe chunks and inserts them
+into the stream:
+
+
A producer of RecordBatchStream
+
def generate_random_dataframe ( dtypes , size ):
+ columns = dict ()
+ for k , v in dtypes . items ():
+ columns [ k ] = np . random . random ( size ) . astype ( v )
+ return pd . DataFrame ( columns )
+
+ def producer ( stream : RecordBatchStream , total_chunks , dtypes , produced : List ):
+ writer = stream . writer
+ for idx in range ( total_chunks ):
+ time . sleep ( idx )
+ chunk = generate_random_dataframe ( dtypes , 2 ) # np.random.randint(10, 100))
+ chunk_id = vineyard_client . put ( chunk )
+ writer . append ( chunk_id )
+ produced . append (( chunk_id , chunk ))
+ writer . finish ()
+
+
+
+Additionally, we create a consumer that retrieves the chunks from the stream in a
+loop, continuing until it encounters a StopIteration
exception:
+
+
A consumer of RecordBatchStream
+
def consumer ( stream : RecordBatchStream , total_chunks , produced : List ):
+ reader = stream . reader
+ index = 0
+ while True :
+ try :
+ chunk = reader . next ()
+ print ( 'reader receive chunk:' , type ( chunk ), chunk )
+ pd . testing . assert_frame_equal ( produced [ index ][ 1 ], chunk )
+ except StopIteration :
+ break
+ index += 1
+
+
+
+
+
+Streams between processes
+Finally, we can test the producer and consumer using two threads:
+
+
Connect the producer and consumer threads using vineyard stream
+
def test_recordbatch_stream ( vineyard_client , total_chunks ):
+ stream = RecordBatchStream . new ( vineyard_client )
+ dtypes = {
+ 'a' : np . dtype ( 'int' ),
+ 'b' : np . dtype ( 'float' ),
+ 'c' : np . dtype ( 'bool' ),
+ }
+
+ client1 = vineyard_client . fork ()
+ client2 = vineyard_client . fork ()
+ stream1 = client1 . get ( stream . id )
+ stream2 = client2 . get ( stream . id )
+
+ produced = []
+
+ thread1 = threading . Thread ( target = consumer , args = ( stream1 , total_chunks , produced ))
+ thread1 . start ()
+
+ thread2 = threading . Thread ( target = producer , args = ( stream2 , total_chunks , dtypes , produced ))
+ thread2 . start ()
+
+ thread1 . join ()
+ thread2 . join ()
+
+ if __name__ == '__main__' :
+ vineyard_client = vineyard . connect ( "/tmp/vineyard.sock" )
+ test_recordbatch_stream ( vineyard_client , total_chunks = 10 )
+
+
+
+For more detailed API about the streams, please refer to Streams .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/key-concepts/vcdl.html b/notes/key-concepts/vcdl.html
new file mode 100644
index 0000000000..7427749d5b
--- /dev/null
+++ b/notes/key-concepts/vcdl.html
@@ -0,0 +1,522 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Code Generation for Boilerplate - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Code Generation for Boilerplate
+The process of sharing objects between engines involves two fundamental steps: defining
+the data structure and establishing the protocol to represent the data type
+as Objects . To alleviate the integration burden with custom data types,
+Vineyard offers an auto-generation mechanism.
+This mechanism, known as VCDL , relies on the custom annotation [[shared]]
+applied to C++ classes.
+Consider the following C++ class Array
as an example:
+template < typename T >
+class [[ vineyard ]] Array {
+ public :
+ [[ shared ]] const T & operator []( size_t loc ) const { return data ()[ loc ]; }
+ [[ shared ]] size_t size () const { return size_ ; }
+ [[ shared ]] const T * data () const {
+ return reinterpret_cast < const T *> ( buffer_ -> data ());
+ }
+
+ private :
+ [[ shared ]] size_t size_ ;
+ [[ shared ]] std :: shared_ptr < Blob > buffer_ ;
+};
+
+
+
+When applied to classes: the class itself is identified as a shared vineyard
+object, and a builder and resolver (see also Builders and resolvers ) are
+automatically synthesized.
+When applied to data members: the data member is treated as a metadata
+field or a sub-member.
+When applied to method members: the method member is deemed
+cross-language sharable, and FFI wrappers are automatically synthesized.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/references.html b/notes/references.html
new file mode 100644
index 0000000000..fe3689eee2
--- /dev/null
+++ b/notes/references.html
@@ -0,0 +1,535 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ API Reference - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+API Reference
+
+
+Vineyard offers a comprehensive suite of SDKs, including Python and C++ versions.
+For detailed API references, please explore the following pages:
+
+
+
+
+
+
+
API reference for vineyard Python SDK.
+
+
+
+
+
+
+
+
API reference for vineyard C++ SDK.
+
+
+
+
+
+All terms in the documentation site can use search from the following
+indexing page:
+
+
+
+
+
+
+
Term indexes for the vineyard documentation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/references/cpp-api.html b/notes/references/cpp-api.html
new file mode 100644
index 0000000000..c3f0051d5b
--- /dev/null
+++ b/notes/references/cpp-api.html
@@ -0,0 +1,5865 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C++ API Reference - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+C++ API Reference
+
+Objects
+
+
+using vineyard :: ObjectID = uint64_t
+ObjectID is an opaque type for vineyard’s object id. The object ID is generated by vineyard server, the underlying type of ObjectID is a 64-bit unsigned integer.
+
+
+
+
+class Object : public vineyard :: ObjectBase , public std :: enable_shared_from_this < Object >
+Object is the core concept in vineyard. Object can be a scalar, a tuple, a vector, a tensor, or even a distributed graph in vineyard. Objects are stored in vineyard, and can be shared to process that connects to the same vineyard cluster.
+Every object in vineyard has a unique identifier ObjectID
that can be passed back and forth in the computation pipeline. An object is composed by a metadata, and a set of blobs.
+Object in vineyard is by-design to be hierarchical, and can have other Object as members. For example, a tensor object may has a vector as its payload, and a distributed dataframe has many dataframe objects as its chunks, and a dataframe is composed by an array of tensors as columns.
+Subclassed by vineyard::Registered< Array< Entry > >, vineyard::Registered< Array< T > >, vineyard::Registered< ArrowFragmentGroup >, vineyard::Registered< BaseBinaryArray< ArrayType > >, vineyard::Registered< BaseListArray< ArrayType > >, vineyard::Registered< Blob >, vineyard::Registered< BooleanArray >, vineyard::Registered< DataFrame >, vineyard::Registered< FixedSizeBinaryArray >, vineyard::Registered< FixedSizeListArray >, vineyard::Registered< Hashmap< K, V, prime_number_hash_wy< K >, std::equal_to< K > > >, vineyard::Registered< HDataFrame< T > >, vineyard::Registered< KVCache >, vineyard::Registered< KVCacheBlock >, vineyard::Registered< NullArray >, vineyard::Registered< NumericArray< T > >, vineyard::Registered< ParallelStream >, vineyard::Registered< PerfectHashmap< K, V > >, vineyard::Registered< RecordBatch >, vineyard::Registered< RefcntMapObject >, vineyard::Registered< RemoteBlob >, vineyard::Registered< Scalar< T > >, vineyard::Registered< SchemaProxy >, vineyard::Registered< Sequence >, vineyard::ArrowFragmentBase, vineyard::ITensor, vineyard::KVTensor, vineyard::Registered< T >
+
+
Public Functions
+
+
+virtual ~Object ( )
+
+
+
+
+const ObjectID id ( ) const
+The object id of this object.
+
+
+
+
+const ObjectMeta & meta ( ) const
+The metadata of this object.
+
+
+
+
+const size_t nbytes ( ) const
+The nbytes of this object, can be treated as the memory usage of this object.
+
+
+
+
+virtual void Construct ( const ObjectMeta & meta )
+Construct an object from metadata. The metadata meta
should come from client’s GetMetaData method.
+The implementation of Construct
method is usually boilerplate. Vineyard provides a code generator to help developers code their own data structures and can be shared via vineyard.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+inline virtual void PostConstruct ( const ObjectMeta & meta )
+PostConstruct
is called at the end of Construct
to perform user-specific constructions that the code generator cannot handle.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+inline virtual Status Build ( Client & client ) final
+Object is also a kind of ObjectBase , and can be used as a member to construct new objects. The Object type also has a Build
method but it does nothing, though.
+
+
+
+
+virtual std :: shared_ptr < Object > _Seal ( Client & client ) final
+Object is also a kind of ObjectBase , and can be used as a member to construct new objects. The Object type also has a _Seal
method but it does nothing, though.
+
+
+
+
+Status Persist ( ClientBase & client ) const
+Persist the object to make it visible for clients that connected to other vineyardd instances in the cluster.
+
+Parameters:
+client – The client that to be used to perform the Persist
request.
+
+
+
+
+
+
+const bool IsLocal ( ) const
+The verb “local” means it is a local object to the client. A local object’s blob can be accessed by the client in a zero-copy fashion. Otherwise only the metadata is accessible.
+
+Returns:
+True iff the object is a local object.
+
+
+
+
+
+
+const bool IsPersist ( ) const
+The verb “persist” means it is visible for client that connected to other vineyardd instances in the cluster. After Persist
the object becomes persistent.
+
+Returns:
+True iff the object is a persistent object.
+
+
+
+
+
+
+const bool IsGlobal ( ) const
+The verb “global” means it is a global object and only refers some local objects.
+
+Returns:
+True iff the object is a global object.
+
+
+
+
+
+
+
Protected Functions
+
+
+inline Object ( )
+
+
+
+
+
+
Friends
+
+
+friend class ClientBase
+
+
+
+
+friend class Client
+
+
+
+
+friend class PlasmaClient
+
+
+
+
+friend class RPCClient
+
+
+
+
+friend class ObjectMeta
+
+
+
+
+friend class ObjectFactory
+
+
+
+
+
+
+
+class ObjectBuilder : public vineyard :: ObjectBase
+Subclassed by vineyard::CollectionBuilder< DataFrame >, vineyard::CollectionBuilder< ITensor >, vineyard::CollectionBuilder< RecordBatch >, vineyard::ArrowFragmentGroupBuilder, vineyard::BlobWriter , vineyard::BooleanArrayBaseBuilder, vineyard::CollectionBuilder< T >, vineyard::DataFrameBaseBuilder, vineyard::FixedSizeBinaryArrayBaseBuilder, vineyard::FixedSizeListArrayBaseBuilder, vineyard::KVCacheBlockBuilder, vineyard::KVCacheBuilder, vineyard::KVTensorBuilder, vineyard::NullArrayBaseBuilder, vineyard::ParallelStreamBaseBuilder, vineyard::RecordBatchBaseBuilder, vineyard::RefcntMapObjectBuilder, vineyard::SchemaProxyBaseBuilder, vineyard::SequenceBaseBuilder, vineyard::TensorBaseBuilder< std::string >
+
+
Public Functions
+
+
+inline virtual ~ObjectBuilder ( )
+
+
+
+
+virtual Status Build ( Client & client ) override = 0
+Building the object means construct all blobs of this object to vineyard server.
+
+Parameters:
+client – The vineyard client that been used to create blobs in the connected vineyard server.
+
+
+
+
+
+
+virtual std :: shared_ptr < Object > Seal ( Client & client )
+
+
+
+
+virtual Status Seal ( Client & client , std :: shared_ptr < Object > & object )
+
+
+
+
+virtual std :: shared_ptr < Object > _Seal ( Client & client ) override
+Sealing the object means construct the metadata for the object and create metadata in vineyard server.
+
+Parameters:
+client – The vineyard client that been used to create metadata in the connected vineyard server.
+
+
+
+
+
+
+virtual Status _Seal ( Client & client , std :: shared_ptr < Object > & object )
+
+
+
+
+inline bool sealed ( ) const
+
+
+
+
+
Protected Functions
+
+
+inline void set_sealed ( bool const sealed = true )
+
+
+
+
+
+
+
+class ObjectBase
+ObjectBase is the most base class for vineyard’s Object and ObjectBuilder .
+An ObjectBase instance is a build-able value that it’s Build
method put blobs * into vineyard server, and it’s _Seal
method is responsible for creating metadata in vineyard server for the object.
+Subclassed by vineyard::Object , vineyard::ObjectBuilder
+
+
Public Functions
+
+
+virtual Status Build ( Client & client ) = 0
+Building the object means construct all blobs of this object to vineyard server.
+
+Parameters:
+client – The vineyard client that been used to create blobs in the connected vineyard server.
+
+
+
+
+
+
+virtual std :: shared_ptr < Object > _Seal ( Client & client ) = 0
+Sealing the object means construct the metadata for the object and create metadata in vineyard server.
+
+Parameters:
+client – The vineyard client that been used to create metadata in the connected vineyard server.
+
+
+
+
+
+
+
+
+
+
+Vineyard Clients
+
+
+class ClientBase
+ClientBase is the base class for vineyard IPC and RPC client.
+ClientBase implements common communication stuffs, and leave the IPC and RPC specific functionalities to Client and RPCClient .
+Vineyard’s Client and RPCClient is non-copyable.
+Subclassed by vineyard::BasicIPCClient, vineyard::RPCClient
+
+
Public Functions
+
+
+ClientBase ( )
+
+
+
+
+inline virtual ~ClientBase ( )
+
+
+
+
+inline virtual Status Release ( ObjectID const & id )
+
+
+
+
+ClientBase ( const ClientBase & ) = delete
+
+
+
+
+ClientBase ( ClientBase & & ) = delete
+
+
+
+
+ClientBase & operator = ( const ClientBase & ) = delete
+
+
+
+
+ClientBase & operator = ( ClientBase & & ) = delete
+
+
+
+
+Status GetData ( const ObjectID id , json & tree , const bool sync_remote = false , const bool wait = false )
+Get object metadata from vineyard using given object ID.
+
+Parameters:
+
+id – The ID of the requested object.
+tree – The returned metadata tree of the requested object.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific metadata. Default is false.
+wait – The request could be blocked util the object with given id has been created on vineyard by other clients. Default is false.
+
+
+Returns:
+Status that indicates whether the get action succeeds.
+
+
+
+
+
+
+Status GetData ( const std :: vector < ObjectID > & ids , std :: vector < json > & trees , const bool sync_remote = false , const bool wait = false )
+Get multiple object metadatas from vineyard using given object IDs.
+
+Parameters:
+
+ids – The IDs of the requested objects
+trees – The returned metadata trees of the requested objects
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific metadata. Default is false.
+wait – The request could be blocked util the object with given id has been created on vineyard by other clients. Default is false.
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status CreateData ( const json & tree , ObjectID & id , Signature & signature , InstanceID & instance_id )
+Create the metadata in the vineyard server.
+
+Parameters:
+
+tree – The metadata that will be created in vineyard.
+id – The returned object ID of the created data.
+instance_id – The vineyard instance ID where this object is created. at.
+
+
+Returns:
+Status that indicates whether the create action has succeeded.
+
+
+
+
+
+
+Status CreateData ( const std :: vector < json > & trees , std :: vector < ObjectID > & ids , std :: vector < Signature > & signatures , std :: vector < InstanceID > & instance_ids )
+
+
+
+
+Status CreateMetaData ( ObjectMeta & meta_data , ObjectID & id )
+Create the metadata in the vineyard server, after created, the resulted object id in the meta_data
will be filled.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the create action has succeeded.
+
+
+
+
+
+
+Status CreateMetaData ( std :: vector < ObjectMeta > & meta_datas , std :: vector < ObjectID > & ids )
+
+
+
+
+Status CreateMetaData ( ObjectMeta & meta_data , InstanceID const & instance_id , ObjectID & id )
+Create the metadata in the vineyard server with specified instance id, after created, the resulted object id in the meta_data
will be filled.
+The specified instance id is required that the metadata can be created using the RPC client on the specified instance as a placeholder.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the create action has succeeded.
+
+
+
+
+
+
+Status CreateMetaData ( std :: vector < ObjectMeta > & meta_datas , InstanceID const & instance_id , std :: vector < ObjectID > & ids )
+
+
+
+
+virtual Status GetMetaData ( const ObjectID id , ObjectMeta & meta_data , const bool sync_remote = false ) = 0
+Get the meta-data of the requested object.
+
+Parameters:
+
+id – The ID of the requested object
+meta_data – The returned metadata of the requested object
+sync_remote – Whether trigger remote sync
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status SyncMetaData ( )
+Sync remote metadata from etcd to the connected vineyardd.
+
+Returns:
+Status that indicates whether the sync action has succeeded.
+
+
+
+
+
+
+Status DelData ( const ObjectID id , const bool force = false , const bool deep = true )
+Delete metadata in vineyard. When the object is a used by other object, it will be deleted only when the force
parameter is specified.
+
+Parameters:
+
+id – The ID to delete.
+force – Whether to delete the object forcely. Forcely delete an object means the object and objects which use this object will be delete. Default is false.
+deep – Whether to delete the member of this object. Default is true. Note that when deleting object which has direct blob members, the processing on those blobs yields a “deep” behavior.
+memory_trim – Whether to trim the memory pool inside the shared memory allocator to return the unused physical memory back to the OS.
+
+
+Returns:
+Status that indicates whether the delete action has succeeded.
+
+
+
+
+
+
+Status DelData ( const ObjectID id , const bool force , const bool deep , const bool memory_trim )
+
+
+
+
+Status DelData ( const std :: vector < ObjectID > & ids , const bool force = false , const bool deep = true )
+Delete multiple metadatas in vineyard.
+
+Parameters:
+
+ids – The IDs to delete.
+force – Whether to delete the object forcely. Forcely delete an object means the object and objects which use this object will be delete. Default is false.
+deep – Whether to delete the member of this object. Default is true. Note that when deleting objects which have direct blob members, the processing on those blobs yields a “deep” behavior.
+memory_trim – Whether to trim the memory pool inside the shared memory allocator to return the unused physical memory back to the OS.
+
+
+Returns:
+Status that indicates whether the delete action has succeeded.
+
+
+
+
+
+
+Status DelData ( const std :: vector < ObjectID > & ids , const bool force , const bool deep , const bool memory_trim )
+
+
+
+
+Status ListData ( std :: string const & pattern , bool const regex , size_t const limit , std :: unordered_map < ObjectID , json > & meta_trees )
+List objectmetas in vineyard, using the given typename patterns.
+
+Parameters:
+
+pattern – The pattern string that will be used to matched against objects’ typename
.
+regex – Whether the pattern is a regular expression pattern. Default is false. When regex
is false, the pattern will be treated as a glob pattern.
+limit – The number limit for how many objects will be returned at most.
+meta_trees – An map that contains the returned object metadatas.
+
+
+Returns:
+Status that indicates whether the list action has succeeded.
+
+
+
+
+
+
+Status ListNames ( std :: string const & pattern , bool const regex , size_t const limit , std :: map < std :: string , ObjectID > & names )
+List names in vineyard, using the given name patterns.
+
+Parameters:
+
+pattern – The pattern string that will be used to matched against objects’ name
.
+regex – Whether the pattern is a regular expression pattern. Default is false. When regex
is false, the pattern will be treated as a glob pattern.
+limit – The number limit for how many objects will be returned at most.
+names – An map that contains the returned names and corresponding object ids.
+
+
+Returns:
+Status that indicates whether the list action has succeeded.
+
+
+
+
+
+
+Status CreateStream ( const ObjectID & id )
+Allocate a stream on vineyard. The metadata of parameter id
must has already been created on vineyard.
+
+Parameters:
+id – The id of metadata that will be used to create stream.
+
+Returns:
+Status that indicates whether the create action has succeeded.
+
+
+
+
+
+
+Status OpenStream ( const ObjectID & id , StreamOpenMode mode )
+open a stream on vineyard. Failed if the stream is already opened on the given mode.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the open action has succeeded.
+
+
+
+
+
+
+Status PushNextStreamChunk ( ObjectID const id , ObjectID const chunk )
+Push a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+Status PullNextStreamChunk ( ObjectID const id , ObjectID & chunk )
+Pull a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+Status PullNextStreamChunk ( ObjectID const id , ObjectMeta & chunk )
+Pull a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+Status PullNextStreamChunk ( ObjectID const id , std :: shared_ptr < Object > & chunk )
+Pull a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+Status StopStream ( ObjectID const id , bool failed )
+Stop a stream, mark it as finished or aborted.
+
+Parameters:
+
+id – The id of the stream.
+failed – Whether the stream is stopped at a successful state. True means the stream has been exited normally, otherwise false.
+
+
+Returns:
+Status that indicates whether the request has succeeded.
+
+
+
+
+
+
+Status DropStream ( ObjectID const id )
+Close a stream, mark it as aborted if it is not finished yet.
+
+Parameters:
+id – The id of the stream.
+
+Returns:
+Status that indicates whether the request has succeeded.
+
+
+
+
+
+
+Status Persist ( const ObjectID id )
+Persist the given object to etcd to make it visible to clients that been connected to vineyard servers in the cluster.
+
+Parameters:
+id – The object id of object that will be persisted.
+
+Returns:
+Status that indicates whether the persist action has succeeded.
+
+
+
+
+
+
+Status IfPersist ( const ObjectID id , bool & persist )
+Check if the given object has been persist to etcd.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the check has succeeded.
+
+
+
+
+
+
+Status Exists ( const ObjectID id , bool & exists )
+Check if the given object exists in vineyard server.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the check has succeeded.
+
+
+
+
+
+
+Status ShallowCopy ( const ObjectID id , ObjectID & target_id )
+Make a shallow copy on the given object. A “shallow copy” means the result object has the same type with the source object and they shares all member objects.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the shallow copy has succeeded.
+
+
+
+
+
+
+Status ShallowCopy ( const ObjectID id , json const & extra_metadata , ObjectID & target_id )
+Make a shallow copy on the given object. A “shallow copy” means the result object has the same type with the source object and they share all member objects.
+
+Parameters:
+
+id – The object id to shallow copy.
+extra_metadata – Feed extra metadata when shallow copying.
+target_id – The result object id will be stored in target_id
as return value.
+
+
+Returns:
+Status that indicates whether the shallow copy has succeeded.
+
+
+
+
+
+
+Status PutName ( const ObjectID id , std :: string const & name )
+Vineyard support associating a user-specific name with an object. PutName registers a name entry in vineyard server. An object can be assoiciated with more than one names.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the request has succeeded.
+
+
+
+
+
+
+Status GetName ( const std :: string & name , ObjectID & id , const bool wait = false )
+Retrieve the object ID by associated name.
+
+Parameters:
+
+name – The name of the requested object.
+id – The returned object ID.
+wait – If wait is specified, the request will be blocked util the given name has been registered on vineyard by other clients.
+
+
+Returns:
+Status that indicates whether the query has succeeded.
+
+
+
+
+
+
+Status DropName ( const std :: string & name )
+Deregister a name entry. The associated object will be kept and won’t be deleted.
+
+Parameters:
+name – The name that will be deregistered.
+
+Returns:
+Status that indicates whether the query has succeeded.
+
+
+
+
+
+
+Status MigrateObject ( const ObjectID object_id , ObjectID & result_id )
+Migrate remote object to connected instance.
+
+Parameters:
+
+
+Returns:
+Status that indicates if the migration success.
+
+
+
+
+
+
+Status Clear ( )
+Clear all objects that are visible to current instances in the cluster.
+
+
+
+
+Status MemoryTrim ( bool & trimmed )
+Trim the memory pool inside the shared memory allocator to return the unused physical memory back to the OS kernel, like the malloc_trim
API from glibc.
+
+
+
+
+Status Label ( const ObjectID object , std :: string const & key , std :: string const & value )
+Associate given labels to an existing object.
+
+Parameters:
+object – Object to be labeled.
+
+
+
+
+
+
+Status Label ( const ObjectID object , std :: map < std :: string , std :: string > const & labels )
+Associate given labels to an existing object.
+
+Parameters:
+object – Object to be labeled.
+
+
+
+
+
+
+Status Evict ( std :: vector < ObjectID > const & objects )
+Evict objects from the vineyardd server.
+
+Parameters:
+objects – Objects to be evicted.
+
+
+
+
+
+
+Status Load ( std :: vector < ObjectID > const & objects , const bool pin = false )
+Load objects to ensure they resident in vineyardd server’s memory, with an optional arguments to pin these objects to prevent from being spilled.
+
+Parameters:
+objects – Objects to be reloaded, and possibly pinned.
+
+
+
+
+
+
+Status Unpin ( std :: vector < ObjectID > const & objects )
+Unpin objects from the vineyardd server’s memory.
+
+Parameters:
+objects – Objects to be unpinned.
+
+
+
+
+
+
+bool Connected ( ) const
+Check if the client still connects to the vineyard server.
+
+Returns:
+True when the connection is still alive, otherwise false.
+
+
+
+
+
+
+void Disconnect ( )
+Disconnect this client.
+
+
+
+
+Status Open ( std :: string const & ipc_socket )
+Create a new anonymous session in vineyardd and connect to it .
+
+Parameters:
+ipc_socket – Location of the UNIX domain socket.
+
+Returns:
+Status that indicates whether the connection of has succeeded.
+
+
+
+
+
+
+void CloseSession ( )
+Close the session that the client is connecting to.
+
+
+
+
+inline std :: string const & IPCSocket ( )
+Get the UNIX domain socket location of the connected vineyardd server.
+
+Returns:
+Location of the IPC socket.
+
+
+
+
+
+
+inline std :: string const & RPCEndpoint ( )
+The RPC endpoint of the connected vineyardd server.
+
+Returns:
+The RPC endpoint.
+
+
+
+
+
+
+inline virtual bool IsIPC ( ) const
+Check if the client is an IPC client.
+
+Returns:
+True if the client is an IPC client, otherwise false.
+
+
+
+
+
+
+inline virtual bool IsRPC ( ) const
+Check if the client is a RPC client.
+
+Returns:
+True if the client is a RPC client, otherwise false.
+
+
+
+
+
+
+inline const InstanceID instance_id ( ) const
+Get the instance id of the connected vineyard server.
+Note that for RPC client the instance id is not available.
+
+Returns:
+The vineyard server’s instance id.
+
+
+
+
+
+
+inline virtual const InstanceID remote_instance_id ( ) const
+Get the remote instance id of the connected vineyard server.
+Note that for RPC client the instance id is not available, thus we have the “remote instance id” to indicate which server we are connecting to.
+
+Returns:
+The vineyard server’s instance id.
+
+
+
+
+
+
+inline const SessionID session_id ( ) const
+Get the session id of the connected vineyard server.
+Note that for RPC client the instance id is not available.
+
+Returns:
+The vineyard server’s session id.
+
+
+
+
+
+
+Status ClusterInfo ( std :: map < InstanceID , json > & meta )
+Retrieve the cluster information of the connected vineyard server.
+The cluster information for every instance mainly includes the host address (i.e., ip address).
+
+Returns:
+Status that indicates whether the query has succeeded.
+
+
+
+
+
+
+Status InstanceStatus ( std :: shared_ptr < struct InstanceStatus > & status )
+Return the status of connected vineyard instance.
+If success, the status
parameter will be reset as an instance of InstanceStatus .
+
+Parameters:
+status – The result instance status.
+
+Returns:
+Status that indicates whether the query has succeeded.
+
+
+
+
+
+
+Status Instances ( std :: vector < InstanceID > & instances )
+List all instances in the connected vineyard cluster.
+
+Parameters:
+A – list of instance IDs will be stored in instances
.
+
+Returns:
+Status that indicates whether the query has succeeded.
+
+
+
+
+
+
+inline const std :: string & Version ( ) const
+Get the version of connected vineyard server.
+
+Returns:
+Return a version string MAJOR.MINOR.PATCH that follows the semver convention.
+
+
+
+
+
+
+virtual Status TryAcquireLock ( std :: string key , bool & result , std :: string & actural_key ) = 0
+Try to acquire a distributed lock.
+
+Parameters:
+key – The key of the lock.
+
+Returns:
+Status that indicates whether the lock process succeeds.
+
+
+
+
+
+
+virtual Status TryReleaseLock ( std :: string key , bool & result ) = 0
+Try to release a distributed lock.
+
+Parameters:
+key – The key of the lock.
+
+Returns:
+Status that indicates whether the unlock process succeeds.
+
+
+
+
+
+
+Status Debug ( const json & debug , json & tree )
+Issue a debug request.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the debug action succeeds.
+
+
+
+
+
+
+inline bool compression_enabled ( ) const
+
+
+
+
+inline void set_compression_enabled ( bool enabled = true )
+
+
+
+
+
Protected Functions
+
+
+Status doWrite ( const std :: string & message_out )
+
+
+
+
+Status doRead ( std :: string & message_in )
+
+
+
+
+Status doRead ( json & root )
+
+
+
+
+
Protected Attributes
+
+
+mutable bool connected_
+
+
+
+
+std :: string ipc_socket_
+
+
+
+
+std :: string rpc_endpoint_
+
+
+
+
+int vineyard_conn_
+
+
+
+
+SessionID session_id_
+
+
+
+
+InstanceID instance_id_
+
+
+
+
+std :: string server_version_
+
+
+
+
+bool support_rpc_compression_ = false
+
+
+
+
+mutable std :: recursive_mutex client_mutex_
+
+
+
+
+bool compression_enabled_ = false
+
+
+
+
+
+
+
+class Client : public vineyard :: BasicIPCClient , protected vineyard :: detail :: UsageTracker < ObjectID , Payload , Client >
+Vineyard’s IPC Client connects to to UNIX domain socket of the vineyard server. Vineyard’s IPC Client talks to vineyard server and manipulate objects in vineyard.
+
+
Public Functions
+
+
+inline Client ( )
+
+
+
+
+~Client ( ) override
+
+
+
+
+Status Connect ( )
+Connect to vineyard using the UNIX domain socket file specified by the environment variable VINEYARD_IPC_SOCKET
.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( std :: string const & username , std :: string const & password )
+Connect to vineyard using the UNIX domain socket file specified by the environment variable VINEYARD_IPC_SOCKET
.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & ipc_socket )
+Connect to vineyardd using the given UNIX domain socket ipc_socket
.
+
+Parameters:
+ipc_socket – Location of the UNIX domain socket.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & ipc_socket , std :: string const & username , std :: string const & password )
+Connect to vineyardd using the given UNIX domain socket ipc_socket
.
+
+Parameters:
+ipc_socket – Location of the UNIX domain socket.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+void Disconnect ( )
+Disconnect this client.
+
+
+
+
+Status Open ( std :: string const & ipc_socket )
+Create a new anonymous session in vineyardd and connect to it .
+
+Parameters:
+ipc_socket – Location of the UNIX domain socket.
+
+Returns:
+Status that indicates whether the connection of has succeeded.
+
+
+
+
+
+
+Status Open ( std :: string const & ipc_socket , std :: string const & username , std :: string const & password )
+Create a new anonymous session in vineyardd and connect to it .
+
+Parameters:
+ipc_socket – Location of the UNIX domain socket.
+
+Returns:
+Status that indicates whether the connection of has succeeded.
+
+
+
+
+
+
+Status Fork ( Client & client )
+Create a new client using self UNIX domain socket.
+
+
+
+
+virtual Status GetMetaData ( const ObjectID id , ObjectMeta & meta_data , const bool sync_remote = false ) override
+Obtain metadata from vineyard server.
+
+Parameters:
+
+id – The object id to get.
+meta_data – The result metadata will be store in meta_data
as return value.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific metadata. Default is false.
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status FetchAndGetMetaData ( const ObjectID id , ObjectMeta & meta_data , const bool sync_remote = false )
+Obtain metadata from vineyard server.
+
+Parameters:
+
+id – The object id to get.
+meta_data – The result metadata will be store in meta_data
as return value.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific metadata. Default is false.
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetMetaData ( const std :: vector < ObjectID > & ids , std :: vector < ObjectMeta > & , const bool sync_remote = false )
+Obtain multiple metadatas from vineyard server.
+
+Parameters:
+
+ids – The object ids to get.
+meta_data – The result metadata will be store in meta_data
as return value.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific metadata. Default is false.
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status CreateBlob ( size_t size , std :: unique_ptr < BlobWriter > & blob )
+Create a blob in vineyard server. When creating a blob, vineyard server’s bulk allocator will prepare a block of memory of the requested size, then map the memory to client’s process to share the allocated memory.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the create action has succeeded.
+
+
+
+
+
+
+Status CreateBlobs ( const std :: vector < size_t > & sizes , std :: vector < std :: unique_ptr < BlobWriter > > & blobs )
+Create blobs in vineyard server. When creating a blob, vineyard server’s bulk allocator will prepare a block of memory of the requested size, then map the memory to client’s process to share the allocated memory.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the create action has succeeded.
+
+
+
+
+
+
+Status GetBlob ( ObjectID const id , std :: shared_ptr < Blob > & blob )
+Get a blob from vineyard server.
+
+Parameters:
+id – the blob to get.
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetBlob ( ObjectID const id , bool unsafe , std :: shared_ptr < Blob > & blob )
+Get a blob from vineyard server, and optionally bypass the “sealed” check.
+
+Parameters:
+id – the blob to get.
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetBlobs ( std :: vector < ObjectID > const ids , std :: vector < std :: shared_ptr < Blob > > & blobs )
+Get a blob from vineyard server.
+
+Parameters:
+id – the blob to get.
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetBlobs ( std :: vector < ObjectID > const ids , const bool unsafe , std :: vector < std :: shared_ptr < Blob > > & blobs )
+Get a blob from vineyard server, and optionally bypass the “sealed” check.
+
+Parameters:
+id – the blob to get.
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status CreateDiskBlob ( size_t size , const std :: string & path , std :: unique_ptr < BlobWriter > & blob )
+Claim a shared blob that backed by a file on disk. Users need to provide either a filename to mmap, or an expected size to allocate the file on disk.
+When mapping existing file as a blob, if the existing file size is smaller than specified “size”, the file will be enlarged using ftruncate().
+Note that when deleting the blob that backed by files, the file won’t be automatically deleted by vineyard.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetNextStreamChunk ( ObjectID const id , size_t const size , std :: unique_ptr < MutableBuffer > & blob )
+Allocate a chunk of given size in vineyard for a stream. When the request cannot be satisfied immediately, e.g., vineyard doesn’t have enough memory or the specified has accumulated too many chunks, the request will be blocked until the request been processed.
+
+Parameters:
+
+id – The id of the stream.
+size – The size of the chunk to allocate.
+blob – The allocated mutable buffer will be set in blob
.
+
+
+Returns:
+Status that indicates whether the allocation has succeeded.
+
+
+
+
+
+
+Status PullNextStreamChunk ( ObjectID const id , std :: unique_ptr < Buffer > & chunk )
+Pull a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+std :: shared_ptr < Object > GetObject ( const ObjectID id , const bool sync_remote = true )
+Get an object from vineyard. The ObjectFactory will be used to resolve the constructor of the object.
+
+Parameters:
+
+
+Returns:
+A std::shared_ptr<Object> that can be safely cast to the underlying concrete object type. When the object doesn’t exists an std::runtime_error exception will be raised.
+
+
+
+
+
+
+std :: shared_ptr < Object > FetchAndGetObject ( const ObjectID id , const bool sync_remote = true )
+Get an object from vineyard. The ObjectFactory will be used to resolve the constructor of the object.
+
+Parameters:
+
+
+Returns:
+A std::shared_ptr<Object> that can be safely cast to the underlying concrete object type. When the object doesn’t exists an std::runtime_error exception will be raised.
+
+
+
+
+
+
+Status GetObject ( const ObjectID id , std :: shared_ptr < Object > & object , const bool sync_remote = true )
+Get an object from vineyard. The ObjectFactory will be used to resolve the constructor of the object.
+
+Parameters:
+
+id – The object id to get.
+object – The result object will be set in parameter object
.
+sync_remote – Whether to trigger an immediate remote metadata
+
+
+Returns:
+When errors occur during the request, this method won’t throw exceptions, rather, it results a status to represents the error.
+
+
+
+
+
+
+Status FetchAndGetObject ( const ObjectID id , std :: shared_ptr < Object > & object , const bool sync_remote = true )
+Get an object from vineyard. The ObjectFactory will be used to resolve the constructor of the object.
+
+Parameters:
+
+id – The object id to get.
+object – The result object will be set in parameter object
.
+sync_remote – Whether to trigger an immediate remote metadata
+
+
+Returns:
+When errors occur during the request, this method won’t throw exceptions, rather, it results a status to represents the error.
+
+
+
+
+
+
+template < typename T > inline std :: shared_ptr < T > GetObject ( const ObjectID id , const bool sync_remote = true )
+Get an object from vineyard. The type parameter T
will be used to resolve the constructor of the object.
+
+Parameters:
+
+
+Returns:
+A std::shared_ptr<Object> that can be safely cast to the underlying concrete object type. When the object doesn’t exists an std::runtime_error exception will be raised.
+
+
+
+
+
+
+template < typename T > inline std :: shared_ptr < T > FetchAndGetObject ( const ObjectID id , const bool sync_remote = true )
+Get an object from vineyard. The type parameter T
will be used to resolve the constructor of the object.
+
+Parameters:
+
+
+Returns:
+A std::shared_ptr<Object> that can be safely cast to the underlying concrete object type. When the object doesn’t exists an std::runtime_error exception will be raised.
+
+
+
+
+
+
+template < typename T > inline Status GetObject ( const ObjectID id , std :: shared_ptr < T > & object , const bool sync_remote = true )
+Get an object from vineyard. The type parameter T
will be used to resolve the constructor of the object.
+This method can be used to get concrete object from vineyard without explicitly dynamic_cast
, and the template type parameter can be deduced in many situations:
+std :: shared_ptr < Array < int >> int_array ;
+client . GetObject ( id , int_array );
+
+
+
+Parameters:
+
+id – The object id to get.
+object – The result object will be set in parameter object
.
+sync_remote – Whether to trigger an immediate remote metadata
+
+
+Returns:
+When errors occur during the request, this method won’t throw exceptions, rather, it results a status to represents the error.
+
+
+
+
+
+
+template < typename T > inline Status FetchAndGetObject ( const ObjectID id , std :: shared_ptr < T > & object , const bool sync_remote = true )
+Get an object from vineyard. The type parameter T
will be used to resolve the constructor of the object.
+This method can be used to get concrete object from vineyard without explicitly dynamic_cast
, and the template type parameter can be deduced in many situations:
+std :: shared_ptr < Array < int >> int_array ;
+client . FetchAndGetObject ( id , int_array );
+
+
+
+Parameters:
+
+id – The object id to get.
+object – The result object will be set in parameter object
.
+sync_remote – Whether to trigger an immediate remote metadata
+
+
+Returns:
+When errors occur during the request, this method won’t throw exceptions, rather, it results a status to represents the error.
+
+
+
+
+
+
+std :: vector < std :: shared_ptr < Object > > GetObjects ( const std :: vector < ObjectID > & ids , const bool sync_remote = true )
+Get multiple objects from vineyard.
+
+Parameters:
+
+
+Returns:
+A list of objects.
+
+
+
+
+
+
+std :: vector < ObjectMeta > ListObjectMeta ( std :: string const & pattern , const bool regex = false , size_t const limit = 5 , bool nobuffer = false )
+List object metadatas in vineyard, using the given typename patterns.
+
+Parameters:
+
+pattern – The pattern string that will be used to matched against objects’ typename
.
+regex – Whether the pattern is a regular expression pattern. Default is false. When regex
is false, the pattern will be treated as a glob pattern.
+limit – The number limit for how many objects will be returned at most.
+
+
+Returns:
+A vector of object metadatas that listed from vineyard server.
+
+
+
+
+
+
+std :: vector < std :: shared_ptr < Object > > ListObjects ( std :: string const & pattern , const bool regex = false , size_t const limit = 5 )
+List objects in vineyard, using the given typename patterns.
+
+Parameters:
+
+pattern – The pattern string that will be used to matched against objects’ typename
.
+regex – Whether the pattern is a regular expression pattern. Default is false. When regex
is false, the pattern will be treated as a glob pattern.
+limit – The number limit for how many objects will be returned at most.
+
+
+Returns:
+A vector of objects that listed from vineyard server.
+
+
+
+
+
+
+bool IsSharedMemory ( const void * target ) const
+Check if the given address belongs to the shared memory region.
+
+Return true if the address (client-side address) comes from the vineyard server.
+
+Parameters:
+target – The pointer that been queried.
+
+
+
+
+
+
+bool IsSharedMemory ( const uintptr_t target ) const
+Check if the given address belongs to the shared memory region.
+
+Return true if the address (client-side address) comes from the vineyard server.
+
+Parameters:
+target – The pointer that been queried.
+
+
+
+
+
+
+bool IsSharedMemory ( const void * target , ObjectID & object_id ) const
+Check if the given address belongs to the shared memory region.
+
+Return true if the address (client-side address) comes from the vineyard server.
+
+Parameters:
+
+target – The pointer that been queried.
+object_id – Return the object id of the queried pointer, if found.
+
+
+
+
+
+
+
+bool IsSharedMemory ( const uintptr_t target , ObjectID & object_id ) const
+Check if the given address belongs to the shared memory region.
+
+Return true if the address (client-side address) comes from the vineyard server.
+
+Parameters:
+
+target – The pointer that been queried.
+object_id – Return the object id of the queried pointer, if found.
+
+
+
+
+
+
+
+Status IsInUse ( ObjectID const & id , bool & is_in_use )
+Check if the blob is a cold blob (no client is using it).
+Return true if the the blob is in-use.
+
+
+
+
+Status IsSpilled ( ObjectID const & id , bool & is_spilled )
+Check if the blob is a spilled blob (those no client is using and be dumped on disk).
+Return true if the the blob is spilled.
+
+
+
+
+Status AllocatedSize ( const ObjectID id , size_t & size )
+Get the allocated size for the given object.
+
+
+
+
+Status CreateArena ( const size_t size , int & fd , size_t & available_size , uintptr_t & base , uintptr_t & space )
+
+
+
+
+Status ReleaseArena ( const int fd , std :: vector < size_t > const & offsets , std :: vector < size_t > const & sizes )
+
+
+
+
+Status ShallowCopy ( ObjectID const id , ObjectID & target_id , Client & source_client )
+Move the selected objects from the source session to the target.
+
+
+
+
+Status ShallowCopy ( PlasmaID const plasma_id , ObjectID & target_id , PlasmaClient & source_client )
+
+
+
+
+Status Release ( std :: vector < ObjectID > const & ids )
+Decrease the reference count of the object. It will trigger OnRelease
behavior when reference count reaches zero. See UsageTracker.
+
+
+
+
+virtual Status Release ( ObjectID const & id ) override
+
+
+
+
+Status DelData ( const ObjectID id , const bool force = false , const bool deep = true )
+Delete metadata in vineyard. When the object is a used by other object, it will be deleted only when the force
parameter is specified.
+
+Parameters:
+
+id – The ID to delete.
+force – Whether to delete the object forcely. Forcely delete an object means the object and objects which use this object will be delete. Default is false.
+deep – Whether to delete the member of this object. Default is true. Note that when deleting object which has direct blob members, the processing on those blobs yields a “deep” behavior.
+
+
+Returns:
+Status that indicates whether the delete action has succeeded.
+
+
+
+
+
+
+Status DelData ( const ObjectID id , const bool force , const bool deep , const bool memory_trim )
+
+
+
+
+Status DelData ( const std :: vector < ObjectID > & ids , const bool force = false , const bool deep = true )
+Delete multiple metadatas in vineyard.
+
+Parameters:
+
+ids – The IDs to delete.
+force – Whether to delete the object forcely. Forcely delete an object means the object and objects which use this object will be delete. Default is false.
+deep – Whether to delete the member of this object. Default is true. Note that when deleting objects which have direct blob members, the processing on those blobs yields a “deep” behavior.
+
+
+Returns:
+Status that indicates whether the delete action has succeeded.
+
+
+
+
+
+
+Status DelData ( const std :: vector < ObjectID > & ids , const bool force , const bool deep , const bool memory_trim )
+
+
+
+
+Status CreateGPUBuffer ( const size_t size , ObjectID & id , Payload & payload , std :: shared_ptr < MutableBuffer > & buffer )
+Create a GPU buffer on vineyard server. See also CreateBuffer
.
+
+Parameters:
+
+size – The size of requested GPU buffer.
+id – The result GPU buffer object id.
+payload – The result GPU buffer payload.
+buffer – The result mutable GPU buffer object related to the GPU blob.
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetGPUBuffers ( const std :: set < ObjectID > & ids , const bool unsafe , std :: map < ObjectID , std :: shared_ptr < Buffer > > & buffers )
+Get a set of blobs from vineyard server. See also GetBuffer
.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetGPUBuffer ( const ObjectID id , const bool unsafe , std :: shared_ptr < Buffer > & buffer )
+Get a single GPU blob from vineyard server. See also GetBuffer
.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+virtual Status TryAcquireLock ( std :: string key , bool & result , std :: string & actual_key ) override
+Try to acquire a distributed lock.
+
+Parameters:
+key – The key of the lock.
+
+Returns:
+Status that indicates whether the lock process succeeds.
+
+
+
+
+
+
+virtual Status TryReleaseLock ( std :: string key , bool & result ) override
+Try to release a distributed lock.
+
+Parameters:
+key – The key of the lock.
+
+Returns:
+Status that indicates whether the unlock process succeeds.
+
+
+
+
+
+
+Status PullNextStreamChunk ( ObjectID const id , ObjectID & chunk )
+Pull a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+Status PullNextStreamChunk ( ObjectID const id , ObjectMeta & chunk )
+Pull a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+Status PullNextStreamChunk ( ObjectID const id , std :: shared_ptr < Object > & chunk )
+Pull a chunk from a stream. When there’s no more chunk available in the stream, i.e., the stream has been stopped, a status code kStreamDrained
or kStreamFinish
will be returned, otherwise the reader will be blocked until writer creates a new chunk in the stream.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the polling has succeeded.
+
+
+
+
+
+
+
Public Static Functions
+
+
+static Client & Default ( )
+Get a default client reference, using the UNIX domain socket file specified by the environment variable VINEYARD_IPC_SOCKET
.
+
+Returns:
+A reference of the default Client instance.
+
+
+
+
+
+
+
Protected Functions
+
+
+Status OnRelease ( ObjectID const & id )
+Required by UsageTracker
. When reference count reaches zero, send the ReleaseRequest
to server.
+
+
+
+
+Status OnDelete ( ObjectID const & id )
+Required by UsageTracker
. Currently, the deletion does not respect the reference count, it will send the DelData to server and do the deletion forcely.
+
+
+
+
+Status PostSeal ( ObjectMeta const & meta_data )
+Increase reference count after a new object is sealed.
+
+
+
+
+Status GetDependency ( ObjectID const & id , std :: set < ObjectID > & bids )
+Send request to server to get all underlying blobs of a object.
+
+
+
+
+Status CreateBuffer ( const size_t size , ObjectID & id , Payload & payload , std :: shared_ptr < MutableBuffer > & buffer )
+
+
+
+
+Status CreateBuffers ( const std :: vector < size_t > & sizes , std :: vector < ObjectID > & ids , std :: vector < Payload > & payloads , std :: vector < std :: shared_ptr < MutableBuffer > > & buffers )
+
+
+
+
+Status GetBuffer ( const ObjectID id , std :: shared_ptr < Buffer > & buffer )
+Get a blob from vineyard server. When obtaining blobs from vineyard server, the memory address in the server process will be mmapped to the client’s process to share the memory.
+
+Parameters:
+
+id – Object id for the blob to get.
+buffer – The result immutable blob will be set in blob
. Note that blob is special, since it can be get as immutable object before sealing.
+
+
+Returns:
+Status that indicates whether the create action has succeeded.
+
+
+
+
+
+
+Status GetBuffers ( const std :: set < ObjectID > & ids , std :: map < ObjectID , std :: shared_ptr < Buffer > > & buffers )
+Get a set of blobs from vineyard server. See also GetBuffer
.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetBufferSizes ( const std :: set < ObjectID > & ids , std :: map < ObjectID , size_t > & sizes )
+Get the size of blobs from vineyard server.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status DropBuffer ( const ObjectID id , const int fd )
+An (unsafe) internal-usage method that drop the buffer, without checking the dependency. To achieve the “DeleteObject” semantic for blobs, use DelData
instead.
+Note that the target buffer could be both sealed and unsealed.
+
+
+
+
+Status ShrinkBuffer ( const ObjectID id , const size_t size )
+An (unsafe) internal-usage method that shrink the buffer, without allocating a new buffer and copying. The buffer to be shrink shouldn’t be sealed.
+In the underlying server-side implementation, madvise
is used.
+
+
+
+
+Status Seal ( ObjectID const & object_id )
+mark the blob as sealed to control the visibility of a blob, client can never Get
an unsealed blob.
+
+
+
+
+inline virtual bool IsIPC ( ) const override
+Check if the client is an IPC client.
+
+Returns:
+True means the client is an IPC client.
+
+
+
+
+
+
+
Friends
+
+
+friend class detail::UsageTracker< ObjectID, Payload, Client >
+
+
+
+
+
+
+
+class RPCClient : public vineyard :: ClientBase
+
+
Public Functions
+
+
+~RPCClient ( ) override
+
+
+
+
+Status Connect ( )
+Connect to vineyard using the TCP endpoint specified by the environment variable VINEYARD_RPC_ENDPOINT
.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( std :: string const & username , std :: string const & password )
+Connect to vineyard using the TCP endpoint specified by the environment variable VINEYARD_RPC_ENDPOINT
.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & rpc_endpoint )
+Connect to vineyardd using the given TCP endpoint rpc_endpoint
.
+
+Parameters:
+rpc_endpoint – The TPC endpoint of vineyard server, in the format of host:port
.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & rpc_endpoint , std :: string const & username , std :: string const & password )
+Connect to vineyardd using the given TCP endpoint rpc_endpoint
.
+
+Parameters:
+rpc_endpoint – The TPC endpoint of vineyard server, in the format of host:port
.
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & rpc_endpoint , const SessionID session_id , std :: string const & username = "" , std :: string const & password = "" )
+Connect to vineyardd using the given TCP endpoint rpc_endpoint
.
+
+Parameters:
+
+rpc_endpoint – The TPC endpoint of vineyard server, in the format of host:port
.
+session_id – Connect to specified session.
+
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & host , uint32_t port )
+Connect to vineyardd using the given TCP host
and port
.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & host , uint32_t port , std :: string const & username , std :: string const & password )
+Connect to vineyardd using the given TCP host
and port
.
+
+Parameters:
+
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Connect ( const std :: string & host , uint32_t port , const SessionID session_id , std :: string const & username = "" , std :: string const & password = "" )
+Connect to vineyardd using the given TCP host
and port
.
+
+Parameters:
+
+host – The host of vineyard server.
+port – The TCP port of vineyard server’s RPC service.
+session_id – Connect to specified session.
+
+
+Returns:
+Status that indicates whether the connect has succeeded.
+
+
+
+
+
+
+Status Fork ( RPCClient & client )
+Create a new client using self endpoint.
+
+
+
+
+virtual Status GetMetaData ( const ObjectID id , ObjectMeta & meta_data , const bool sync_remote = false ) override
+Obtain metadata from vineyard server. Note that unlike IPC client, RPC client doesn’t map shared memorys to the client’s process.
+
+Parameters:
+
+id – The object id to get.
+meta_data – The result metadata will be store in meta_data
as return value.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific metadata. Default is false.
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+Status GetMetaData ( const std :: vector < ObjectID > & id , std :: vector < ObjectMeta > & meta_data , const bool sync_remote = false )
+Obtain multiple metadatas from vineyard server.
+
+Parameters:
+
+ids – The object ids to get.
+meta_data – The result metadata will be store in meta_data
as return value.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific metadata. Default is false.
+
+
+Returns:
+Status that indicates whether the get action has succeeded.
+
+
+
+
+
+
+std :: shared_ptr < Object > GetObject ( const ObjectID id , const bool sync_remote = true )
+Get an object from vineyard. The ObjectFactory will be used to resolve the constructor of the object.
+In RPCClient , all blob fields in the result object are unaccessible, access those fields will trigger an std::runtime_error
.
+
+Parameters:
+
+
+Returns:
+A std::shared_ptr<Object> that can be safely cast to the underlying concrete object type. When the object doesn’t exists an std::runtime_error exception will be raised.
+
+
+
+
+
+
+Status GetObject ( const ObjectID id , std :: shared_ptr < Object > & object , const bool sync_remote = true )
+Get an object from vineyard. The ObjectFactory will be used to resolve the constructor of the object.
+
+Parameters:
+
+id – The object id to get.
+object – The result object will be set in parameter object
.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific object. Default is true.
+
+
+Returns:
+When errors occur during the request, this method won’t throw exceptions, rather, it results a status to represents the error.
+
+
+
+
+
+
+std :: vector < std :: shared_ptr < Object > > GetObjects ( const std :: vector < ObjectID > & ids , const bool sync_remote = true )
+Get multiple objects from vineyard.
+
+Parameters:
+
+
+Returns:
+A list of objects.
+
+
+
+
+
+
+template < typename T > inline std :: shared_ptr < T > GetObject ( const ObjectID id , const bool sync_remote = true )
+Get an object from vineyard. The type parameter T
will be used to resolve the constructor of the object.
+
+Parameters:
+
+
+Returns:
+A std::shared_ptr<Object> that can be safely cast to the underlying concrete object type. When the object doesn’t exists an std::runtime_error exception will be raised.
+
+
+
+
+
+
+template < typename T > inline Status GetObject ( const ObjectID id , std :: shared_ptr < T > & object , const bool sync_remote = true )
+Get an object from vineyard. The type parameter T
will be used to resolve the constructor of the object.
+This method can be used to get concrete object from vineyard without explicitly dynamic_cast
, and the template type parameter can be deduced in many situations:
+std :: shared_ptr < Array < int >> int_array ;
+client . GetObject ( id , int_array );
+
+
+
+Parameters:
+
+id – The object id to get.
+object – The result object will be set in parameter object
.
+sync_remote – Whether to trigger an immediate remote metadata synchronization before get specific object. Default is true.
+
+
+Returns:
+When errors occur during the request, this method won’t throw exceptions, rather, it results a status to represents the error.
+
+
+
+
+
+
+std :: vector < ObjectMeta > ListObjectMeta ( std :: string const & pattern , const bool regex = false , size_t const limit = 5 , bool nobuffer = false )
+List object metadatas in vineyard, using the given typename patterns.
+
+Parameters:
+
+pattern – The pattern string that will be used to matched against objects’ typename
.
+regex – Whether the pattern is a regular expression pattern. Default is false. When regex
is false, the pattern will be treated as a glob pattern.
+limit – The number limit for how many objects will be returned at most.
+
+
+Returns:
+A vector of object metadatas that listed from vineyard server.
+
+
+
+
+
+
+std :: vector < std :: shared_ptr < Object > > ListObjects ( std :: string const & pattern , const bool regex = false , size_t const limit = 5 )
+List objects in vineyard, using the given typename patterns.
+
+Parameters:
+
+pattern – The pattern string that will be used to matched against objects’ typename
.
+regex – Whether the pattern is a regular expression pattern. Default is false. When regex
is false, the pattern will be treated as a glob pattern.
+limit – The number limit for how many objects will be returned at most.
+
+
+Returns:
+A vector of objects that listed from vineyard server.
+
+
+
+
+
+
+inline virtual const InstanceID remote_instance_id ( ) const override
+Get the remote instance id of the connected vineyard server.
+Note that for RPC client the instance id is not available, thus we have the “remote instance id” to indicate which server we are connecting to.
+
+Returns:
+The vineyard server’s instance id.
+
+
+
+
+
+
+inline virtual bool IsRPC ( ) const override
+Check if the client is a RPC client.
+
+Returns:
+True means the client is a RPC client.
+
+
+
+
+
+
+bool IsFetchable ( const ObjectMeta & meta )
+Whether the instance connected by rpc client is the same as object metadata’s instance.
+
+Returns:
+True means the instance is the same as object metadata’s instance.
+
+
+
+
+
+
+Status CreateRemoteBlob ( std :: shared_ptr < RemoteBlobWriter > const & buffer , ObjectMeta & meta )
+Create a remote blob on the vineyard server.
+
+
+
+
+Status CreateRemoteBlobs ( std :: vector < std :: shared_ptr < RemoteBlobWriter > > const & buffers , std :: vector < ObjectMeta > & metas )
+Create remote blobs on the vineyard server.
+
+
+
+
+Status GetRemoteBlob ( const ObjectID & id , std :: shared_ptr < RemoteBlob > & buffer )
+Get the remote blob of the connected vineyard server, using the RPC socket.
+Note that getting remote blobs requires an expensive copy over network.
+
+
+
+
+Status GetRemoteBlob ( const ObjectID & id , const bool unsafe , std :: shared_ptr < RemoteBlob > & buffer )
+Get the remote blob of the connected vineyard server, using the RPC socket, and optionally bypass the “seal” check.
+Note that getting remote blobs requires an expensive copy over network.
+
+
+
+
+Status GetRemoteBlobs ( std :: vector < ObjectID > const & ids , std :: vector < std :: shared_ptr < RemoteBlob > > & remote_blobs )
+Get the remote blobs of the connected vineyard server, using the RPC socket.
+Note that getting remote blobs requires an expensive copy over network.
+
+
+
+
+Status GetRemoteBlobs ( std :: set < ObjectID > const & ids , std :: map < ObjectID , std :: shared_ptr < RemoteBlob > > & remote_blobs )
+
+
+
+
+Status GetRemoteBlobs ( std :: vector < ObjectID > const & ids , const bool unsafe , std :: vector < std :: shared_ptr < RemoteBlob > > & remote_blobs )
+Get the remote blobs of the connected vineyard server, using the RPC socket. and optionally bypass the “seal” check.
+Note that getting remote blobs requires an expensive copy over network.
+
+
+
+
+Status GetRemoteBlobs ( std :: set < ObjectID > const & ids , const bool unsafe , std :: map < ObjectID , std :: shared_ptr < RemoteBlob > > & remote_blobs )
+
+
+
+
+inline virtual Status TryAcquireLock ( std :: string key , bool & result , std :: string & actual_key ) override
+Try to acquire a distributed lock.
+
+Parameters:
+key – The key of the lock.
+
+Returns:
+Status that indicates whether the lock process succeeds.
+
+
+
+
+
+
+inline virtual Status TryReleaseLock ( std :: string key , bool & result ) override
+Try to release a distributed lock.
+
+Parameters:
+key – The key of the lock.
+
+Returns:
+Status that indicates whether the unlock process succeeds.
+
+
+
+
+
+
+
+
+
+Vineyard Server
+
+
+struct InstanceStatus
+
+
Public Functions
+
+
+explicit InstanceStatus ( const json & tree )
+Initialize the status value using a json returned from the vineyard server.
+
+Parameters:
+tree – JSON that returned from the vineyard server.
+
+
+
+
+
+
+
Public Members
+
+
+const InstanceID instance_id
+The connected instance id.
+
+
+
+
+const std :: string deployment
+The deployment manner, can be local or distributed.
+
+
+
+
+const size_t memory_usage
+The current memory usage in vineyard server, in bytes.
+
+
+
+
+const size_t memory_limit
+The memory upper bound of this vineyard server, in bytes.
+
+
+
+
+const size_t deferred_requests
+How many requests are deferred in the queue.
+
+
+
+
+const size_t ipc_connections
+How many Client connects to this vineyard server.
+
+
+
+
+const size_t rpc_connections
+How many RPCClient connects to this vineyard server.
+
+
+
+
+
+
+
+Blob
+
+
+class Blob : public vineyard :: Registered < Blob >
+The unit to store data payload in vineyard.
+When the client gets a blob from vineyard, the vineyard server maps a chunk of memory from its memory space to the client space in a zero-copy fashion.
+
+
Public Functions
+
+
+size_t size ( ) const
+Get the size of the blob, i.e., the number of bytes of the data payload in the blob.
+Note that the size of blob is the “allocated size” of the blob, and may (usually) not be the same value of the requested size.
+
+Returns:
+The (allocated) size of the blob.
+
+
+
+
+
+
+size_t allocated_size ( ) const
+Get the allocated size of the blob, i.e., the number of bytes of the data payload in the blob.
+
+Returns:
+The allocated size of the blob.
+
+
+
+
+
+
+const char * data ( ) const
+Get the const data pointer of the data payload in the blob.
+
+Returns:
+The const data pointer.
+
+
+
+
+
+
+const std :: shared_ptr < vineyard :: Buffer > & Buffer ( ) const
+Get the buffer of the blob.
+
+Returns:
+The buffer which holds the data payload of the blob.
+
+
+
+
+
+
+const std :: shared_ptr < arrow :: Buffer > ArrowBuffer ( ) const
+Get the arrow buffer of the blob.
+
+Returns:
+The buffer which holds the data payload of the blob.
+
+
+
+
+
+
+const std :: shared_ptr < vineyard :: Buffer > BufferOrEmpty ( ) const
+Get the buffer of the blob, ensure a valid shared_ptr been returned even the blob is empty (size == 0).
+
+Returns:
+The buffer which holds the data payload of the blob.
+
+
+
+
+
+
+const std :: shared_ptr < arrow :: Buffer > ArrowBufferOrEmpty ( ) const
+Get the arrow buffer of the blob, ensure a valid shared_ptr been returned even the blob is empty (size == 0).
+
+Returns:
+The buffer which holds the data payload of the blob.
+
+
+
+
+
+
+virtual void Construct ( ObjectMeta const & meta ) override
+Construct the blob locally for the given object meta.
+
+Parameters:
+meta – The given object meta.
+
+
+
+
+
+
+void Dump ( ) const
+Dump the buffer for debugging.
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+static std :: shared_ptr < Blob > MakeEmpty ( Client & client )
+Create an empty blob in the vineyard server.
+
+Parameters:
+client – The client connected to the vineyard server.
+
+
+
+
+
+
+static std :: shared_ptr < Blob > FromAllocator ( Client & client , const ObjectID object_id , const uintptr_t pointer , const size_t size )
+Create the blob from a buffer from the client-side allocator.
+
+Parameters:
+
+object_id – The object ID of this blob.
+pointer – The address of buffer in the client-side allocator.
+size – The estimated size of the buffer.
+
+
+
+
+
+
+
+static std :: shared_ptr < Blob > FromPointer ( Client & client , const uintptr_t pointer , const size_t size )
+Create the blob from a given buffer. If the buffer already lies in the vineyardd, it would return immediately without copying, otherwise a blob writer will be created and the content of the buffer will be copied into.
+
+Parameters:
+
+
+
+
+
+
+
+
+
+
+class BlobWriter : public vineyard :: ObjectBuilder
+The writer to write a blob in vineyard.
+The writer is initialized in the client with a local buffer and its size, and a blob in vineyard will be created when Build is invoked.
+
+
Public Functions
+
+
+ObjectID id ( ) const
+Return the object id of this blob builder. Note that before sealing the blob builder the object id cannot be used to get “Blob” objects.
+
+Returns:
+The ObjectID of the blob writer.
+
+
+
+
+
+
+size_t size ( ) const
+Get the size of the blob, i.e., the number of bytes of the data payload in the blob.
+
+Returns:
+The size of the blob.
+
+
+
+
+
+
+char * data ( )
+Get the data pointer of the data payload in the blob.
+
+Returns:
+The data pointer.
+
+
+
+
+
+
+const char * data ( ) const
+Get the const data pointer of the data payload in the blob.
+
+Returns:
+The const data pointer.
+
+
+
+
+
+
+const std :: shared_ptr < MutableBuffer > & Buffer ( ) const
+Get the mutable buffer of the blob.
+
+Returns:
+The mutable buffer of the blob, which can be modified to update the content in the blob.
+
+
+
+
+
+
+virtual Status Build ( Client & client ) override
+Build a blob in vineyard server.
+
+Parameters:
+client – The client connected to the vineyard server.
+
+
+
+
+
+
+Status Abort ( Client & client )
+Abort the blob builder.
+
+Parameters:
+client – Release the blob builder object if it is not sealed.
+
+
+
+
+
+
+Status Shrink ( Client & client , const size_t size )
+Shrink the blob builder to the given size without reallocating and copying.
+
+
+
+
+void AddKeyValue ( std :: string const & key , std :: string const & value )
+Add key-value metadata for the blob.
+
+Parameters:
+
+
+
+
+
+
+
+void AddKeyValue ( std :: string const & key , std :: string & & value )
+Add key-value metadata for the blob.
+
+Parameters:
+
+
+
+
+
+
+
+void Dump ( ) const
+Dump the buffer for debugging.
+
+
+
+
+
+
+
+Stream
+
+
+class ByteStream : public vineyard :: BareRegistered < ByteStream > , public vineyard :: Stream < Blob >
+
+
Public Functions
+
+
+inline void SetBufferSizeLimit ( size_t limit )
+
+
+
+
+Status WriteBytes ( const char * ptr , size_t len )
+
+
+
+
+Status WriteLine ( const std :: string & line )
+
+
+
+
+Status FlushBuffer ( )
+
+
+
+
+Status ReadLine ( std :: string & line )
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+
+
+Basic Data Types
+
+
+template < typename T > class Array : public vineyard :: Registered < Array < T > >
+The array type in vineyard.
+
+Template Parameters:
+T – The type for the elements.
+
+
+
+
Public Functions
+
+
+inline virtual void Construct ( const ObjectMeta & meta ) override
+Construct an object from metadata. The metadata meta
should come from client’s GetMetaData method.
+The implementation of Construct
method is usually boilerplate. Vineyard provides a code generator to help developers code their own data structures and can be shared via vineyard.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+inline const T & operator [] ( size_t loc ) const
+Get the element at the given location.
+
+Parameters:
+loc – The given location to get the element.
+
+
+
+
+
+
+inline size_t size ( ) const
+Get the size of the array.
+
+Returns:
+The size.
+
+
+
+
+
+
+inline const T * data ( ) const
+Get the pointer to the beginning of the data buffer.
+
+Parameters:
+The – pointer to the data buffer
+
+
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+
+
+template < typename T > class ArrayBuilder : public vineyard :: ArrayBaseBuilder < T >
+ArrayBuilder is designed for constructing arrays that supported by vineyard.
+
+Template Parameters:
+T – The type for the elements.
+
+
+
+
Public Functions
+
+
+inline ArrayBuilder ( Client & client , size_t size )
+
+
+
+
+inline ArrayBuilder ( Client & client , std :: vector < T > const & vec )
+Initialize the ArrayBuilder from an existing std::vector of type T.
+
+Parameters:
+
+
+
+
+
+
+
+inline ArrayBuilder ( Client & client , const T * data , size_t size )
+Initialize the ArrayBuilder from an existing C array of type T.
+
+Parameters:
+
+client – The client connected to the vineyard server.
+data – The pointer to the array.
+size – The size of the array.
+
+
+
+
+
+
+
+inline ~ArrayBuilder ( )
+
+
+
+
+inline const size_t size ( ) const
+Get the size of the array, i.e., number of elements in the array.
+
+Returns:
+The size.
+
+
+
+
+
+
+inline T & operator [] ( size_t idx )
+Get the element located in the given index of the array.
+
+Parameters:
+idx – The give index.
+
+Returns:
+The element at the given index.
+
+
+
+
+
+
+inline T * data ( ) noexcept
+Get the data pointer to the array.
+
+Returns:
+The data pointer.
+
+
+
+
+
+
+inline const T * data ( ) const noexcept
+Get the const data pointer to the array.
+
+Returns:
+The const data pointer.
+
+
+
+
+
+
+inline Status Build ( Client & client ) override
+Build the array object.
+
+Parameters:
+client – The client connected to the vineyard server.
+
+
+
+
+
+
+
+
+
+template < typename K , typename V , typename H = prime_number_hash_wy < K > , typename E = std :: equal_to < K > > class Hashmap : public vineyard :: Registered < Hashmap < K , V , prime_number_hash_wy < K > , std :: equal_to < K > > > , public vineyard :: prime_number_hash_wy < K > , public std :: equal_to < K >
+The hash map in vineyard.
+
+Template Parameters:
+
+K – The type for the key.
+V – The type for the value.
+std::hash<K> – The hash function for the key.
+std::equal_to<K> – The compare function for the key.
+
+
+
+
+
Public Types
+
+
+using KeyHash = H
+
+
+
+
+using KeyEqual = E
+
+
+
+
+using T = std :: pair < K , V >
+
+
+
+
+using Entry = ska :: detailv3 :: sherwood_v3_entry < T >
+
+
+
+
+using EntryPointer = const Entry *
+
+
+
+
+using Hasher = ska :: detailv3 :: KeyOrValueHasher < K , std :: pair < K , V > , H >
+
+
+
+
+using Equal = ska :: detailv3 :: KeyOrValueEquality < K , std :: pair < K , V > , E >
+
+
+
+
+using value_type = T
+
+
+
+
+using size_type = size_t
+
+
+
+
+using difference_type = std :: ptrdiff_t
+
+
+
+
+using hasher = H
+
+
+
+
+using key_equal = E
+
+
+
+
+using reference = value_type &
+
+
+
+
+using const_reference = const value_type &
+
+
+
+
+using pointer = value_type *
+
+
+
+
+using const_pointer = value_type *
+
+
+
+
+using flat_hash_table_type = ska :: detailv3 :: sherwood_v3_table < T , K , H , Hasher , E , Equal , std :: allocator < T > , typename std :: allocator_traits < std :: allocator < T > > :: template rebind_alloc < ska :: detailv3 :: sherwood_v3_entry < T > > >
+
+
+
+
+
Public Functions
+
+
+inline virtual void Construct ( const ObjectMeta & meta ) override
+Construct an object from metadata. The metadata meta
should come from client’s GetMetaData method.
+The implementation of Construct
method is usually boilerplate. Vineyard provides a code generator to help developers code their own data structures and can be shared via vineyard.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+inline virtual void PostConstruct ( const ObjectMeta & meta ) override
+Set the hash policy after the construction of the HashMap.
+
+
+
+
+inline iterator begin ( ) const
+The beginning iterator.
+
+
+
+
+inline iterator end ( ) const
+The ending iterator.
+
+
+
+
+inline iterator find ( const K & key )
+Find the iterator by key.
+
+
+
+
+inline const iterator find ( const K & key ) const
+Return the const iterator by key.
+
+
+
+
+inline size_t count ( const K & key ) const
+Return the number of occurancies of the key.
+
+
+
+
+inline size_t size ( ) const
+Return the size of the HashMap, i.e., the number of elements stored in the HashMap.
+
+
+
+
+inline size_t bucket_count ( ) const
+Return the max size of the HashMap, i.e., the number of allocated cells for elements stored in the HashMap.
+
+
+
+
+inline float load_factor ( ) const
+Return the load factor of the HashMap.
+
+
+
+
+inline bool empty ( ) const
+Check whether the HashMap is empty.
+
+
+
+
+inline const V & at ( const K & key ) const
+Get the value by key. Here the existence of the key is checked.
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+struct iterator
+The iterator to iterate key-value mappings in the HashMap.
+
+
Public Functions
+
+
+iterator ( ) = default
+
+
+
+
+inline explicit iterator ( EntryPointer current )
+
+
+
+
+inline iterator & operator ++ ( )
+
+
+
+
+inline iterator operator ++ ( int )
+
+
+
+
+inline const value_type & operator * ( ) const
+
+
+
+
+inline const value_type * operator -> ( ) const
+
+
+
+
+
+
Friends
+
+
+inline friend bool operator == ( const iterator & lhs , const iterator & rhs )
+
+
+
+
+inline friend bool operator != ( const iterator & lhs , const iterator & rhs )
+
+
+
+
+
+
+
+
+
+template < typename K , typename V , typename H = prime_number_hash_wy < K > , typename E = std :: equal_to < K > > class HashmapBuilder : public vineyard :: HashmapBaseBuilder < K , V , prime_number_hash_wy < K > , std :: equal_to < K > >
+HashmapBuilder is used for constructing hashmaps that supported by vineyard.
+
+Template Parameters:
+
+K – The type for the key.
+V – The type for the value.
+std::hash<K> – The hash function for the key.
+std::equal_to<K> – The compare function for the key.
+
+
+
+
+
Public Functions
+
+
+inline explicit HashmapBuilder ( Client & client )
+
+
+
+
+inline HashmapBuilder ( Client & client , ska :: flat_hash_map < K , V , H , E > & & hashmap )
+
+
+
+
+inline V & operator [] ( const K & key )
+Get the mapping value of the given key.
+
+
+
+
+inline V & operator [] ( K & & key )
+Get the mapping value of the given key.
+
+
+
+
+template < class ... Args > inline bool emplace ( Args & & ... args )
+Emplace key-value pair into the hashmap.
+
+
+
+
+inline V & at ( const K & key )
+Get the mapping value of the given key.
+
+
+
+
+inline const V & at ( const K & key ) const
+Get the const mapping value of the given key.
+
+
+
+
+inline size_t size ( ) const
+Get the size of the hashmap.
+
+
+
+
+inline void reserve ( size_t size )
+Reserve the size for the hashmap.
+
+
+
+
+inline size_t bucket_count ( ) const
+Return the maximum possible size of the HashMap, i.e., the number of elements that can be stored in the HashMap.
+
+
+
+
+inline float load_factor ( ) const
+Return the load factor of the HashMap.
+
+
+
+
+inline bool empty ( ) const
+Check whether the hashmap is empty.
+
+
+
+
+inline ska :: flat_hash_map < K , V , H , E > :: iterator begin ( )
+Return the beginning iterator.
+
+
+
+
+inline ska :: flat_hash_map < K , V , H , E > :: const_iterator begin ( ) const
+Return the const beginning iterator.
+
+
+
+
+inline ska :: flat_hash_map < K , V , H , E > :: const_iterator cbegin ( ) const
+Return the const beginning iterator.
+
+
+
+
+inline ska :: flat_hash_map < K , V , H , E > :: iterator end ( )
+Return the ending iterator.
+
+
+
+
+inline ska :: flat_hash_map < K , V , H , E > :: const_iterator end ( ) const
+Return the const ending iterator.
+
+
+
+
+inline ska :: flat_hash_map < K , V , H , E > :: const_iterator cend ( ) const
+Return the const ending iterator.
+
+
+
+
+inline ska :: flat_hash_map < K , V , H , E > :: iterator find ( const K & key )
+Find the value by key.
+
+
+
+
+inline void AssociateDataBuffer ( std :: shared_ptr < Blob > data_buffer )
+Associated with a given data buffer.
+
+
+
+
+inline Status Build ( Client & client ) override
+Build the hashmap object.
+
+
+
+
+
+
+
+template < typename T > class Tensor : public vineyard :: ITensor , public vineyard :: BareRegistered < Tensor < T > >
+
+
Public Types
+
+
+using value_t = T
+
+
+
+
+using value_pointer_t = T *
+
+
+
+
+using value_const_pointer_t = const T *
+
+
+
+
+using ArrowTensorT = typename detail :: ArrowTensorType < T > :: type
+
+
+
+
+
Public Functions
+
+
+inline virtual void Construct ( const ObjectMeta & meta ) override
+Construct an object from metadata. The metadata meta
should come from client’s GetMetaData method.
+The implementation of Construct
method is usually boilerplate. Vineyard provides a code generator to help developers code their own data structures and can be shared via vineyard.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+inline std :: vector < int64_t > strides ( ) const
+Get the strides of the tensor.
+
+Returns:
+The strides of the tensor. The definition of the tensor’s strides can be found in https://pytorch.org/docs/stable/tensor_attributes.html
+
+
+
+
+
+
+inline virtual std :: vector < int64_t > const & shape ( ) const override
+Get the shape of the tensor.
+
+Returns:
+The shape vector where the ith element represents the size of the ith axis.
+
+
+
+
+
+
+inline virtual std :: vector < int64_t > const & partition_index ( ) const override
+Get the index of this partition in the global tensor.
+
+Returns:
+The index vector where the ith element represents the index in the ith axis.
+
+
+
+
+
+
+inline virtual AnyType value_type ( ) const override
+Get the type of tensor’s elements.
+
+Returns:
+The type of the tensor’s elements.
+
+
+
+
+
+
+inline value_const_pointer_t data ( ) const
+Get the data pointer to the tensor’s data buffer.
+
+Returns:
+The data pointer.
+
+
+
+
+
+
+inline const value_t operator [] ( size_t index ) const
+Get the data in the tensor by index.
+
+Returns:
+The data reference.
+
+
+
+
+
+
+inline virtual const std :: shared_ptr < arrow :: Buffer > buffer ( ) const override
+Get the buffer of the tensor.
+
+Returns:
+The shared pointer to an arrow buffer which holds the data buffer of the tensor.
+
+
+
+
+
+
+inline virtual const std :: shared_ptr < arrow :: Buffer > auxiliary_buffer ( ) const override
+
+
+
+
+inline const std :: shared_ptr < ArrowTensorT > ArrowTensor ( )
+Return a view of the original tensor so that it can be used as arrow’s Tensor .
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+
+
+template < typename T > class TensorBuilder : public vineyard :: ITensorBuilder , public vineyard :: TensorBaseBuilder < T >
+TensorBuilder is used for building tensors that supported by vineyard.
+
+Template Parameters:
+T –
+
+
+
+
Public Types
+
+
+using value_t = T
+
+
+
+
+using value_pointer_t = T *
+
+
+
+
+using value_const_pointer_t = const T *
+
+
+
+
+
Public Functions
+
+
+inline TensorBuilder ( Client & client , std :: vector < int64_t > const & shape )
+Initialize the TensorBuilder with the tensor shape.
+
+Parameters:
+
+
+
+
+
+
+
+inline TensorBuilder ( Client & client , std :: vector < int64_t > const & shape , std :: vector < int64_t > const & partition_index )
+Initialize the TensorBuilder for a partition of a GlobalTensor .
+
+Parameters:
+
+client – The client connected to the vineyard server.
+shape – The shape of the partition.
+partition_index – The partition index in the global tensor.
+
+
+
+
+
+
+
+inline std :: vector < int64_t > const & shape ( ) const
+Get the shape of the tensor.
+
+Returns:
+The shape vector where the ith element represents the size of the ith axis.
+
+
+
+
+
+
+inline std :: vector < int64_t > const & partition_index ( ) const
+Get the index of this partition in the global tensor.
+
+Returns:
+The index vector where the ith element represents the index in the ith axis.
+
+
+
+
+
+
+inline void set_shape ( std :: vector < int64_t > const & shape )
+Set the shape of the tensor.
+
+Parameters:
+shape – The vector for the shape, where the ith element represents the size of the shape in the ith axis.
+
+
+
+
+
+
+inline void set_partition_index ( std :: vector < int64_t > const & partition_index )
+Set the index in the global tensor.
+
+Parameters:
+partition_index – The vector of indices, where the ith element represents the index in the ith axis.
+
+
+
+
+
+
+inline std :: vector < int64_t > strides ( ) const
+Get the strides of the tensor.
+
+Returns:
+The strides of the tensor. The definition of the tensor’s strides can be found in https://pytorch.org/docs/stable/tensor_attributes.html
+
+
+
+
+
+
+inline value_pointer_t data ( ) const
+Get the data pointer of the tensor.
+
+
+
+
+inline Status Build ( Client & client ) override
+Build the tensor.
+
+Parameters:
+client – The client connceted to the vineyard server.
+
+
+
+
+
+
+
+
+
+class DataFrame : public vineyard :: Registered < DataFrame >
+
+
Public Functions
+
+
+inline virtual void Construct ( const ObjectMeta & meta ) override
+Construct an object from metadata. The metadata meta
should come from client’s GetMetaData method.
+The implementation of Construct
method is usually boilerplate. Vineyard provides a code generator to help developers code their own data structures and can be shared via vineyard.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+const std :: vector < json > & Columns ( ) const
+Get the column names.
+
+Returns:
+The vector of column names.
+
+
+
+
+
+
+std :: shared_ptr < ITensor > Index ( ) const
+Get the index of dataframe.
+
+Returns:
+The shared pointer to the index tensor.
+
+
+
+
+
+
+std :: shared_ptr < ITensor > Column ( json const & column ) const
+Get the column of the given column name.
+
+Parameters:
+column – The given column name.
+
+Returns:
+The shared pointer to the column tensor.
+
+
+
+
+
+
+const std :: pair < size_t , size_t > partition_index ( ) const
+Get the partition index of the global dataframe.
+
+Returns:
+The pair of the partition_index on rows and the partition_index on columns.
+
+
+
+
+
+
+const std :: pair < size_t , size_t > shape ( ) const
+Get the shape of the dataframe.
+
+Returns:
+The pair of the number of rows and the number of columns.
+
+
+
+
+
+
+const std :: shared_ptr < arrow :: RecordBatch > AsBatch ( bool copy = false ) const
+Get a RecordBatch view for the dataframe.
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+
+
+class DataFrameBuilder : public vineyard :: DataFrameBaseBuilder
+DataFrameBuilder is used for constructing dataframes that supported by vineyard.
+
+
Public Functions
+
+
+explicit DataFrameBuilder ( Client & client )
+
+
+
+
+const std :: pair < size_t , size_t > partition_index ( ) const
+Get the partition index of the global dataframe.
+
+Returns:
+The pair of the partition_index on rows and the partition_index on columns.
+
+
+
+
+
+
+void set_partition_index ( size_t partition_index_row , size_t partition_index_column )
+Set the index in the global dataframe.
+
+Parameters:
+
+
+
+
+
+
+
+void set_row_batch_index ( size_t row_batch_index )
+Set the row batch index in the global dataframe. Note that the row batch index gives the order of batches on rows.
+
+Parameters:
+row_batch_index – The row batch index.
+
+
+
+
+
+
+void set_index ( std :: shared_ptr < ITensorBuilder > builder )
+Set the index of dataframe by add a index column to dataframe.
+
+Parameters:
+builder – The index tensor builder.
+
+
+
+
+
+
+std :: shared_ptr < ITensorBuilder > Column ( json const & column ) const
+Get the column of the given column name.
+
+Parameters:
+column – The given column name.
+
+Returns:
+The shared pointer to the column tensor.
+
+
+
+
+
+
+void AddColumn ( json const & column , std :: shared_ptr < ITensorBuilder > builder )
+Add a column to the dataframe by registering a tensor builder to the column name. When the dataframe is built, the tensor builder will be employed to build the column.
+
+Parameters:
+
+
+
+
+
+
+
+void DropColumn ( json const & column )
+Drop the column with the given column name.
+
+Parameters:
+column – The name of column to be dropped.
+
+
+
+
+
+
+virtual Status Build ( Client & client ) override
+Build the dataframe object.
+
+Parameters:
+client – The client connected to the vineyard server.
+
+
+
+
+
+
+
+
+
+class Sequence : public vineyard :: Registered < Sequence >
+The sequence type in vineyard.
+
+
Public Functions
+
+
+inline virtual void Construct ( const ObjectMeta & meta ) override
+Construct an object from metadata. The metadata meta
should come from client’s GetMetaData method.
+The implementation of Construct
method is usually boilerplate. Vineyard provides a code generator to help developers code their own data structures and can be shared via vineyard.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+inline const size_t Size ( ) const
+Get the size of the sequence, i.e., the number of elements it contains.
+
+Returns:
+The size of the sequence.
+
+
+
+
+
+
+inline const std :: shared_ptr < Object > At ( size_t index ) const
+Get the value at the given index.
+
+Parameters:
+index – The given index to get the value.
+
+
+
+
+
+
+inline const std :: shared_ptr < Object > First ( ) const
+Get the first element of the pair.
+
+Returns:
+The shared pointer to the first object.
+
+
+
+
+
+
+inline const std :: shared_ptr < Object > Second ( ) const
+Get the second element of the pair.
+
+Returns:
+The shared pointer to the second object.
+
+
+
+
+
+
+inline const iterator begin ( ) const
+Get the beginning iterator.
+
+Returns:
+The beginning iterator.
+
+
+
+
+
+
+inline const iterator end ( ) const
+Get the ending iterator.
+
+Returns:
+The ending iterator.
+
+
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+class iterator : public std :: iterator < std :: bidirectional_iterator_tag , std :: shared_ptr < Object > , size_t , const std :: shared_ptr < Object > * , std :: shared_ptr < Object > >
+The iterator for the sequence object to iterate from the first to the last element.
+
+
Public Functions
+
+
+inline explicit iterator ( Sequence const * sequence , size_t index = 0 )
+
+
+
+
+inline iterator & operator ++ ( )
+
+
+
+
+inline bool operator == ( iterator other ) const
+
+
+
+
+inline bool operator != ( iterator other ) const
+
+
+
+
+inline reference operator * ( ) const
+
+
+
+
+
+
+
+
+
+class SequenceBuilder : public vineyard :: SequenceBaseBuilder
+SequenceBuilder is designed for generating sequences.
+
+
Public Functions
+
+
+inline explicit SequenceBuilder ( Client & client )
+
+
+
+
+inline explicit SequenceBuilder ( Client & client , size_t const size )
+Initialize the SequenceBuilder with a given size.
+
+Parameters:
+
+
+
+
+
+
+
+inline const size_t Size ( ) const
+Get the size of the sequence, i.e., the number of elements it contains.
+
+Returns:
+The size of the sequence.
+
+
+
+
+
+
+inline void SetSize ( size_t size )
+Set the size for the sequence. Note that the size of a sequence can be set only once.
+
+Parameters:
+size – The size for the sequence.
+
+
+
+
+
+
+inline std :: shared_ptr < ObjectBuilder > At ( size_t index )
+Get the builder at the given index. Here the index is bound-checked.
+
+Parameters:
+index – The given index.
+
+Returns:
+The builder at the given index.
+
+
+
+
+
+
+inline void SetValue ( size_t idx , std :: shared_ptr < ObjectBuilder > const & value )
+Set the builder for the value at the given index. When building the sequence, the builder will be invoked to build the value.
+
+Parameters:
+
+
+
+
+
+
+
+inline void SetValue ( size_t idx , std :: shared_ptr < Object > const & value )
+Set the builder for the value at the given index. When building the sequence, the builder will be invoked to build the value.
+
+Parameters:
+
+
+
+
+
+
+
+
+
+
+template < typename T > class Scalar : public vineyard :: Registered < Scalar < T > >
+The scalar type in vineyard. Note that the value of the scalar is writing into the meta tree as a string
directly, instead of storing the value in the shared memory with a blob.
+
+Template Parameters:
+T – The type for the value.
+
+
+
+
Public Functions
+
+
+inline virtual void Construct ( const ObjectMeta & meta ) override
+Construct an object from metadata. The metadata meta
should come from client’s GetMetaData method.
+The implementation of Construct
method is usually boilerplate. Vineyard provides a code generator to help developers code their own data structures and can be shared via vineyard.
+
+Parameters:
+meta – The metadata that be used to construct the object.
+
+
+
+
+
+
+inline const T Value ( ) const
+Get the value of the scalar.
+
+Returns:
+The value of the scalar.
+
+
+
+
+
+
+inline AnyType Type ( ) const
+Get the type of the scalar.
+
+Returns:
+The type of the scalar.
+
+
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+
+
+template < typename T > class ScalarBuilder : public vineyard :: ScalarBaseBuilder < T >
+ScalarBuilder is used for building scalars that supported by vineyard.
+
+Template Parameters:
+T – The type for the scalar.
+
+
+
+
Public Functions
+
+
+inline explicit ScalarBuilder ( Client & client )
+
+
+
+
+inline explicit ScalarBuilder ( Client & client , T const & value )
+Initialize the scalar with the value.
+
+Parameters:
+
+
+
+
+
+
+
+inline void SetValue ( T const & value )
+Set the value of the scalar.
+
+Parameters:
+value – The value for the scalar.
+
+
+
+
+
+
+
+
+
+Distributed Data Types
+
+
+class GlobalTensor : public vineyard :: BareRegistered < GlobalTensor > , public vineyard :: Collection < ITensor >
+GlobalTensor is a holder for a set of tensor chunks that are distributed over many vineyard nodes.
+
+
Public Functions
+
+
+void PostConstruct ( const ObjectMeta & meta ) override
+
+
+
+
+std :: vector < int64_t > const & shape ( ) const
+
+
+
+
+std :: vector < int64_t > const & partition_shape ( ) const
+
+
+
+
+const std :: vector < std :: shared_ptr < ITensor > > LocalPartitions ( Client & client ) const
+backwards compatibility
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+
+
+class GlobalTensorBuilder : public vineyard :: CollectionBuilder < ITensor >
+GlobalTensorBuilder is designed for building global tensors.
+
+
Public Functions
+
+
+inline explicit GlobalTensorBuilder ( Client & client )
+
+
+
+
+std :: vector < int64_t > const & partition_shape ( ) const
+Get the partition shape of the global tensor. Here the ith element represents how many partitions are made on the ith axis.
+
+
+
+
+void set_partition_shape ( std :: vector < int64_t > const & partition_shape )
+Set the partition shape of the global tensor. Here the ith element represents how many partitions are made on the ith axis.
+
+
+
+
+std :: vector < int64_t > const & shape ( ) const
+Get the entire shape of the global tensor.
+
+
+
+
+void set_shape ( std :: vector < int64_t > const & shape )
+Set the entire shape of the global tensor.
+
+
+
+
+void AddPartition ( const ObjectID partition_id )
+Backwards compatibility.
+
+
+
+
+void AddPartitions ( const std :: vector < ObjectID > & partition_ids )
+
+
+
+
+
+
+
+class GlobalDataFrame : public vineyard :: BareRegistered < GlobalDataFrame > , public vineyard :: Collection < DataFrame >
+GlobalDataFrame is a DataFrame that refers a set of dataframe chunks in many vineyardd nodes.
+
+
Public Functions
+
+
+void PostConstruct ( const ObjectMeta & meta ) override
+
+
+
+
+const std :: pair < size_t , size_t > partition_shape ( ) const
+Set the partition shape of the global dataframe.
+
+Parameters:
+
+
+
+
+
+
+
+const std :: vector < std :: shared_ptr < DataFrame > > LocalPartitions ( Client & client ) const
+backwards compatibility
+
+
+
+
+
Public Static Functions
+
+
+static inline std :: unique_ptr < Object > Create ( )
+
+
+
+
+
+
+
+class GlobalDataFrameBuilder : public vineyard :: CollectionBuilder < DataFrame >
+GlobalDataFrameBuilder is designed for building global dataframes.
+
+
Public Functions
+
+
+inline explicit GlobalDataFrameBuilder ( Client & client )
+
+
+
+
+const std :: pair < size_t , size_t > partition_shape ( ) const
+Get the partition shape of the global dataframe.
+
+Returns:
+The pair of <number_of_partitions_on_rows, number_of_partitions_on_columns>.
+
+
+
+
+
+
+void set_partition_shape ( const size_t partition_shape_row , const size_t partition_shape_column )
+Set the partition shape of the global dataframe.
+
+Parameters:
+
+
+
+
+
+
+
+void AddPartition ( const ObjectID partition_id )
+Backwards compatibility.
+
+
+
+
+void AddPartitions ( const std :: vector < ObjectID > & partition_ids )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/references/crds.html b/notes/references/crds.html
new file mode 100644
index 0000000000..e5f735e093
--- /dev/null
+++ b/notes/references/crds.html
@@ -0,0 +1,1626 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ API Reference - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+API Reference
+
+
+
+Package v1alpha1 contains API Schema definitions for the k8s v1alpha1 API group
+
+Resource Types
+
+
+Backup
+Backup describes a backup operation of vineyard objects, which uses the Kubernetes PersistentVolume to store the backup data. Every backup operation will be binded with the name of Backup.
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+Backup
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
BackupSpec
+
+
+
+
+
+
+
+BackupList
+BackupList contains a list of Backup
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+BackupList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
Backup array
+
+
+
+
+
+
+
+BackupSpec
+BackupSpec defines the desired state of Backup
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+vineyarddName
string
+the name of the vineyard cluster
+
+vineyarddNamespace
string
+the namespace of the vineyard cluster
+
+objecIDs
string array
+the specific objects to be backed up if not specified, all objects will be backed up
+
+backupPath
string
+the path of backup data
+
+persistentVolumeSpec
PersistentVolumeSpec
+the PersistentVolumeSpec of the backup data
+
+persistentVolumeClaimSpec
PersistentVolumeClaimSpec
+the PersistentVolumeClaimSpec of the backup data
+
+
+
+
+
+
+CSIDriver
+CSIDriver is the Schema for the csidrivers API
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+CSIDriver
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
CSIDriverSpec
+
+
+
+
+
+
+
+CSIDriverList
+CSIDriverList contains a list of CSIDriver
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+CSIDriverList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
CSIDriver array
+
+
+
+
+
+
+
+CSIDriverSpec
+CSIDriverSpec defines the desired state of CSIDriver
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+image
string
+Image is the name of the csi driver image
+
+imagePullPolicy
string
+ImagePullPolicy is the image pull policy of the csi driver
+
+storageClassName
string
+StorageClassName is the name of the storage class
+
+volumeBindingMode
string
+VolumeBindingMode is the volume binding mode of the storage class
+
+sidecar
CSISidecar
+Sidecar is the configuration for the CSI sidecar container nolint: lll
+
+clusters
VineyardClusters array
+Clusters are the list of vineyard clusters
+
+enableToleration
boolean
+EnableToleration is the flag to enable toleration for the csi driver
+
+enableVerboseLog
boolean
+EnableVerboseLog is the flag to enable verbose log for the csi driver
+
+
+
+
+
+
+CSISidecar
+CSISidecar holds the configuration for the CSI sidecar container
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+provisionerImage
string
+ProvisionerImage is the image of the provisioner sidecar
+
+attacherImage
string
+AttacherImage is the image of the attacher sidecar
+
+nodeRegistrarImage
string
+NodeRegistrarImage is the image of the node registrar sidecar
+
+livenessProbeImage
string
+LivenessProbeImage is the image of the liveness probe sidecar
+
+imagePullPolicy
string
+ImagePullPolicy is the image pull policy of all sidecar containers
+
+enableTopology
boolean
+EnableTopology is the flag to enable topology for the csi driver
+
+
+
+
+
+
+GlobalObject
+GlobalObject describes a global object in vineyard, whose metadata will be stored in etcd.
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+GlobalObject
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
GlobalObjectSpec
+
+
+
+
+
+
+
+GlobalObjectList
+GlobalObjectList contains a list of GlobalObject
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+GlobalObjectList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
GlobalObject array
+
+
+
+
+
+
+
+GlobalObjectSpec
+GlobalObjectSpec defines the desired state of GlobalObject
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+id
string
+
+
+name
string
+
+
+signature
string
+
+
+typename
string
+
+
+members
string array
+
+
+metadata
string
+Refer to Kubernetes API documentation for fields of metadata
.
+
+
+
+
+
+
+LocalObject
+LocalObject describes a local object in vineyard, whose metadata will only be stored in local vineyard.
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+LocalObject
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
LocalObjectSpec
+
+
+
+
+
+
+
+LocalObjectList
+LocalObjectList contains a list of LocalObject
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+LocalObjectList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
LocalObject array
+
+
+
+
+
+
+
+LocalObjectSpec
+LocalObjectSpec defines the desired state of LocalObject
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+id
string
+
+
+name
string
+
+
+signature
string
+
+
+typename
string
+
+
+instance_id
integer
+
+
+hostname
string
+
+
+metadata
string
+Refer to Kubernetes API documentation for fields of metadata
.
+
+
+
+
+
+
+MetricConfig
+MetricConfig holds the configuration about metric container
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+enable
boolean
+Enable metrics
+
+image
string
+represent the metric’s image
+
+imagePullPolicy
string
+the policy about pulling image
+
+
+
+
+
+
+Operation
+Operation describes an operation between workloads, such as assembly and repartition.
+As for the assembly
operation, there are several kinds of computing engines, some may not support the stream data, so we need to insert an assembly
operation to assemble the stream data into a batch data, so that the next computing engines can process the data.
+As for the repartition
operation, the vineyard has integrated with the distributed computing engines, such as Dask. If you want to repartition the data to adapt the dask workers, then the repartition
operation is essential for such scenario.
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+Operation
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
OperationSpec
+
+
+
+
+
+
+
+OperationList
+OperationList contains a list of Operation
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+OperationList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
Operation array
+
+
+
+
+
+
+
+OperationSpec
+OperationSpec defines the desired state of Operation
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+name
string
+the name of vineyard pluggable drivers, including assembly and repartition.
+
+type
string
+the type of object, including local and distributed.
+
+require
string
+the required job’s name of the operation
+
+target
string
+the target job’s name of the operation
+
+timeoutSeconds
integer
+TimeoutSeconds is the timeout of the operation.
+
+
+
+
+
+
+PluginImageConfig
+PluginImageConfig holds all image configuration about pluggable drivers(backup, recover, local assembly, distributed assembly, repartition)
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+backupImage
string
+the image of backup operation
+
+recoverImage
string
+the image of recover operation
+
+daskRepartitionImage
string
+the image of dask repartition operation
+
+localAssemblyImage
string
+the image of local assembly operation
+
+distributedAssemblyImage
string
+the image of distributed assembly operation
+
+
+
+
+
+
+Recover
+Recover describes a recover operation of vineyard objects, which is used to recover a specific backup operation.
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+Recover
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
RecoverSpec
+
+
+
+
+
+
+
+RecoverList
+RecoverList contains a list of Recover
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+RecoverList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
Recover array
+
+
+
+
+
+
+
+RecoverSpec
+RecoverSpec defines the desired state of Recover
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+backupName
string
+the name of backup
+
+backupNamespace
string
+the namespace of backup
+
+
+
+
+
+
+ServiceConfig
+ServiceConfig holds all service configuration about vineyardd
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+type
string
+service type
+
+port
integer
+service port
+
+
+
+
+
+
+Sidecar
+Sidecar is used for configuring and managing the vineyard sidecar container.
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+Sidecar
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
SidecarSpec
+
+
+
+
+
+
+
+SidecarList
+SidecarList contains a list of Sidecar
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+SidecarList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
Sidecar array
+
+
+
+
+
+
+
+SidecarSpec
+SidecarSpec defines the desired state of Sidecar
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+selector
string
+the selector of pod
+
+replicas
integer
+the replicas of workload
+
+etcdReplicas
integer
+EtcdReplicas describe the etcd replicas
+
+vineyard
VineyardConfig
+vineyard container configuration nolint: lll
+
+metric
MetricConfig
+metric container configuration
+
+volume
VolumeConfig
+metric configurations
+
+service
ServiceConfig
+rpc service configuration
+
+securityContext
SecurityContext
+SecurityContext holds the security context settings for the vineyardd container.
+
+volumes
Volume array
+Volumes is the list of Kubernetes volumes that can be mounted by the vineyard container.
+
+volumeMounts
VolumeMount array
+VolumeMounts specifies the volumes listed in “.spec.volumes” to mount into the vineyard container.
+
+
+
+
+
+
+SpillConfig
+SpillConfig holds all configuration about spilling
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+name
string
+the name of the spill config
+
+path
string
+the path of spilling
+
+spillLowerRate
string
+low watermark of spilling memory
+
+spillUpperRate
string
+high watermark of triggering spilling
+
+persistentVolumeSpec
PersistentVolumeSpec
+the PersistentVolumeSpec of the spilling PV
+
+persistentVolumeClaimSpec
PersistentVolumeClaimSpec
+the PersistentVolumeClaimSpec of the spill file
+
+
+
+
+
+
+VineyardClusters
+VineyardClusters contains the list of vineyard clusters
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+namespace
string
+Namespace is the namespace of the vineyard cluster
+
+name
string
+Name is the name of the vineyard deployment
+
+
+
+
+
+
+VineyardConfig
+VineyardConfig holds all configuration about vineyard container
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+image
string
+represent the vineyardd’s image
+
+imagePullPolicy
string
+the policy about pulling image
+
+syncCRDs
boolean
+synchronize CRDs when persisting objects
+
+socket
string
+The directory on host for the IPC socket file. The UNIX-domain socket will be placed as ${Socket}/vineyard.sock
.
+
+size
string
+shared memory size for vineyardd
+
+reserveMemory
boolean
+reserve the shared memory for vineyardd
+
+streamThreshold
integer
+memory threshold of streams (percentage of total memory)
+
+spill
SpillConfig
+the configuration of spilling
+
+env
EnvVar array
+vineyard environment configuration
+
+memory
string
+the memory resources of vineyard container
+
+cpu
string
+the cpu resources of vineyard container
+
+
+
+
+
+
+Vineyardd
+Vineyardd is used to deploy a vineyard cluster on kubernetes, which can simplify the configurations of the vineyard binary, the external etcd cluster and the vineyard Deployment . As vineyard is bound to a specific socket on the hostpath by default, the vineyard pod cannot be deployed on the same node. Before deploying vineyardd, you should know how many nodes are available for vineyard pod to deploy on and make sure the vineyardd pod number is less than the number of available nodes.
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+Vineyardd
+
+metadata
ObjectMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+spec
VineyarddSpec
+
+
+
+
+
+
+
+VineyarddList
+VineyarddList contains a list of Vineyardd
+
+
+
+Field
+Description
+
+
+
+apiVersion
string
+k8s.v6d.io/v1alpha1
+
+kind
string
+VineyarddList
+
+metadata
ListMeta
+Refer to Kubernetes API documentation for fields of metadata
.
+
+items
Vineyardd array
+
+
+
+
+
+
+
+VineyarddSpec
+VineyarddSpec holds all configuration about vineyardd
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+replicas
integer
+Replicas is the number of vineyardd pods to deploy
+
+etcdReplicas
integer
+EtcdReplicas describe the etcd replicas
+
+service
ServiceConfig
+vineyardd’s service
+
+vineyard
VineyardConfig
+vineyard container configuration nolint: lll
+
+pluginImage
PluginImageConfig
+operation container configuration nolint: lll
+
+metric
MetricConfig
+metric container configuration
+
+volume
VolumeConfig
+Volume configuration
+
+securityContext
SecurityContext
+SecurityContext holds the security context settings for the vineyardd container.
+
+volumes
Volume array
+Volumes is the list of Kubernetes volumes that can be mounted by the vineyard deployment.
+
+volumeMounts
VolumeMount array
+VolumeMounts specifies the volumes listed in “.spec.volumes” to mount into the vineyard deployment.
+
+
+
+
+
+
+VolumeConfig
+VolumeConfig holds all configuration about persistent volume
+Appears in:
+
+
+
+
+Field
+Description
+
+
+
+pvcName
string
+the name of pvc
+
+mountPath
string
+the mount path of pv
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/notes/references/python-api.html b/notes/references/python-api.html
new file mode 100644
index 0000000000..34f188d3e5
--- /dev/null
+++ b/notes/references/python-api.html
@@ -0,0 +1,5997 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Python API Reference - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Python API Reference
+
+Objects
+
+
+class vineyard. ObjectID
+Opaque type for vineyard’s object id. The object ID is generated by vineyard server,
+the underlying type of ObjectID
is a 64-bit unsigned integer. Wrapper
+utilities are provided to interact with the external python world.
+>>> id = ObjectID ( "000043c5c6d5e646" )
+>>> id
+000043c5c6d5e646
+>>> repr ( id )
+'000043c5c6d5e646'
+>>> print ( id )
+ObjectID <"000043c5c6d5e646">
+>>> int ( id )
+74516723525190
+
+
+
+
+__eq__ ( )
+Return self==value.
+
+
+
+
+__hash__ ( )
+Return hash(self).
+
+
+
+
+__init__ ( )
+
+
+
+
+__repr__ ( )
+Return repr(self).
+
+
+
+
+__str__ ( )
+Return str(self).
+
+
+
+
+
+
+class vineyard. Object
+Base class for vineyard objects.
+
+
+static from_ ( )
+
+
+from_ ( meta : ObjectMeta ) → Object
+
+
+Construct a new object from the meta.
+:param meta: ObjectMeta
+
+The meta of the object.
+
+
+Returns:
+Object
+
+
+
+
+
+
+property id
+The object id of this object.
+
+
+
+
+property isglobal
+Whether the object is a global object.
+
+
+
+
+property islocal
+Whether the object is a local object.
+
+
+
+
+property ispersist
+Whether the object is a persistent object. The word “persistent” means the object could
+be seen by clients that connect to other vineyard server instances.
+
+
+
+
+member ( )
+
+
+member ( self , name : str ) → Object
+
+
+Get the member object of this object.
+
+Parameters:
+name – str
+The name of the member object.
+
+Returns:
+The member object.
+
+Return type:
+Object
+
+
+
+
See also
+
ObjectMeta.get, ObjectMeta.__getitem__
+
+
+
+
+
+property meta
+The metadata of this object.
+
+
+
+
+property nbytes
+The nbytes of this object.
+
+
+
+
+property signature
+The object signature of this object.
+
+
+
+
+property typename
+The typename of this object. typename
is the string value of the C++ type,
+e.g., vineyard::Array<int>
, vineyard::Table
.
+
+
+
+
+
+
+class vineyard. ObjectBuilder
+
+
+
+
+
+Vineyard client
+
+
+vineyard. connect ( * args , ** kwargs ) [source]
+Connect to vineyard by specified UNIX-domain socket or TCP endpoint.
+If no arguments are provided and failed to resolve both the environment
+variables VINEYARD_IPC_SOCKET
, VINEYARD_RPC_ENDPOINT
,
+VINEYARD_CONFIG
, and the default configuration file
+/var/run/vineyard-config.yaml
and
+/var/run/vineyard/vineyard-config.yaml
, it will launch a standalone
+vineyardd server in the background and then connect to it.
+The connect() method has various overloading:
+
+
+connect(socket: str,
+
+username: str = None,
+
+password: str = None) -> IPCClient
+Connect to vineyard via UNIX domain socket for IPC service:
+client = vineyard . connect ( '/var/run/vineyard.sock' )
+
+
+
+Parameters:
+socket: str UNIX domain socket path to setup an IPC connection.
+
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Returns: IPCClient: The connected IPC client.
+
+
+
+
+
+
+connect(host: str,
+
+port: int or str,
+
+username: str = None,
+
+password: str = None) -> RPCClient
+Connect to vineyard via TCP socket.
+
+Parameters:
+host: str Hostname to connect to.
+
+port: int or str The TCP that listened by vineyard TCP service.
+
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Returns: RPCClient: The connected RPC client.
+
+
+
+
+
+
+connect(endpoint: (str, int or str),
+
+username: str = None,
+
+password: str = None) -> RPCClient
+Connect to vineyard via TCP socket.
+
+Parameters:
+endpoint: tuple(str, int or str) Endpoint to connect to. The parameter is a tuple, in which the first
+element is the host, and the second parameter is the port (can be int
+a str).
+
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Returns: RPCClient: The connected RPC client.
+
+
+
+
+
+
+connect(username: str = None,
+
+password: str = None) -> IPCClient or RPCClient
+Connect to vineyard via UNIX domain socket or TCP endpoint. This method normally
+usually no arguments, and will first tries to resolve IPC socket from the
+environment variable VINEYARD_IPC_SOCKET and connect to it. If it fails to
+establish a connection with vineyard server, the method will tries to resolve
+RPC endpoint from the environment variable VINEYARD_RPC_ENDPOINT . If both
+tries are failed, this method will try to resolve the configuration file that
+contains IPC socket and RPC endpoint from the environment variable
+VINEYARD_CONFIG , and then connect to the vineyard server with the
+resolved configuration.
+If above all are failed, this method will raise a ConnectionFailed
+exception.
+In rare cases, user may be not sure about if the IPC socket or RPC endpoint
+is available, i.e., the variable might be None
. In such cases this
+method can accept a None as arguments, and do resolution as described above.
+
+Parameters:
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Raises: ConnectionFailed
+
+
+
+
+
+
+
+
+class vineyard. Client ( socket : str | None = None , port : int | str | None = None , host : str | None = None , endpoint : Tuple [ str , str | int ] | None = None , session : int | None = None , username : str | None = None , password : str | None = None , config : str | None = None ) [source]
+Client is responsible for managing IPC and RPC clients for Vineyard
+and provides a high-level interface to fetch objects from the Vineyard cluster.
+
+
+allocated_size ( object_id : Object | ObjectID ) → int [source]
+
+
+allocated_size ( target : Object or ObjectID ) → int [source]
+
+
+Get the allocated size of the given object.
+
+Parameters:
+target – Object or ObjectID
+The given Object.
+
+Returns:
+int
+
+
+
+
+
+
+clear ( ) → None [source]
+
+
+clear ( ) → None [source]
+
+
+Drop all objects that visible to the current instance in the vineyard cluster.
+
+
+
+
+close ( ) → None [source]
+Close the client.
+
+
+
+
+property compression : bool
+Whether the compression is enabled for underlying RPC client.
+
+
+
+
+property connected
+Whether the client instance has been connected to the vineyard server.
+
+
+
+
+create_blob ( size : int | List [ int ] ) → BlobBuilder | List [ BlobBuilder ] [source]
+
+
+create_blob ( size : int ) → BlobBuilder [source]
+Allocate a blob in vineyard server.
+
+Parameters:
+size: int The size of blob that will be allocated on vineyardd.
+
+
+
+Returns: BlobBuilder
+
+
+
+
+
+
+create_blob ( sizes : List [ int ] ) → List [ BlobBuilder ] [source]
+Allocate blobs in vineyard server.
+
+Parameters:
+size: List[int] The size of blobs that will be allocated on vineyardd.
+
+
+
+Returns: List[BlobBuilder]
+
+
+
+
+
+
+create_blob ( size : int ) → BlobBuilder [source]
+Allocate a blob in vineyard server.
+
+Parameters:
+size: int The size of blob that will be allocated on vineyardd.
+
+
+
+Returns: BlobBuilder
+
+
+
+
+
+
+create_blob ( sizes : List [ int ] ) → List [ BlobBuilder ] [source]
+Allocate blobs in vineyard server.
+
+Parameters:
+size: List[int] The size of blobs that will be allocated on vineyardd.
+
+
+
+Returns: List[BlobBuilder]
+
+
+
+
+
+
+
+
+create_empty_blob ( ) → BlobBuilder [source]
+
+
+create_empty_blob ( ) → Blob [source]
+
+
+Create an empty blob in vineyard server.
+
+Returns:
+Blob
+
+
+
+
+
+
+create_metadata ( metadata : ObjectMeta | List [ ObjectMeta ] , instance_id : int | None = None ) → ObjectMeta | List [ ObjectMeta ] [source]
+
+
+create_metadata ( metadata : ObjectMeta | List [ ObjectMeta ] ) [source]
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd.
+
+Parameters:
+metadata – ObjectMeta
+The metadata that will be created on vineyardd.
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata(metadata: Union[ObjectMeta, List[ObjectMeta]],
+
+instance_id: InstanceID)
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd with a specified instance id.
+
+Parameters:
+
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata ( metadata : ObjectMeta | List [ ObjectMeta ] ) [source]
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd.
+
+Parameters:
+metadata – ObjectMeta
+The metadata that will be created on vineyardd.
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata(metadata: Union[ObjectMeta, List[ObjectMeta]],
+
+instance_id: InstanceID)
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd with a specified instance id.
+
+Parameters:
+
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+
+
+create_remote_blob ( blob_builder : RemoteBlobBuilder | List [ RemoteBlobBuilder ] ) → ObjectMeta | List [ ObjectMeta ] [source]
+
+
+create_remote_blob ( blob_builder : RemoteBlobBuilder ) → ObjectMeta [source]
+Put the remote blob to connected remote vineyard instance. The blob_builder
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+vineyard_rpc_client = vineyard . connect ( * vineyard_endpoint . split ( ':' ))
+
+buffer_writer = RemoteBlobBuilder ( len ( payload ))
+buffer_writer . copy ( 0 , payload )
+blob_meta = vineyard_rpc_client . create_remote_blob ( buffer_writer )
+
+
+
+Parameters:
+blob_builder: RemoteBlobBuilder The remote blob to create.
+
+
+
+Returns: ObjectMeta
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+create_remote_blob ( blob_builders : List [ RemoteBlobBuilder ] ) → List [ ObjectMeta ] [source]
+Put the remote blobs to connected remote vineyard instance. The blob_builders
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+
+Returns: List[ObjectMeta]
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+create_remote_blob ( blob_builder : RemoteBlobBuilder ) → ObjectMeta [source]
+Put the remote blob to connected remote vineyard instance. The blob_builder
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+vineyard_rpc_client = vineyard . connect ( * vineyard_endpoint . split ( ':' ))
+
+buffer_writer = RemoteBlobBuilder ( len ( payload ))
+buffer_writer . copy ( 0 , payload )
+blob_meta = vineyard_rpc_client . create_remote_blob ( buffer_writer )
+
+
+
+Parameters:
+blob_builder: RemoteBlobBuilder The remote blob to create.
+
+
+
+Returns: ObjectMeta
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+create_remote_blob ( blob_builders : List [ RemoteBlobBuilder ] ) → List [ ObjectMeta ] [source]
+Put the remote blobs to connected remote vineyard instance. The blob_builders
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+
+Returns: List[ObjectMeta]
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+
+
+delete ( object : ObjectID | Object | ObjectMeta | List [ ObjectID ] , force : bool = False , deep : bool = True , memory_trim : bool = False ) → None [source]
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+
+
+drop_name ( name : str ) → None [source]
+
+
+drop_name ( name : str or ObjectName ) → None [source]
+
+
+Remove the association of the given name.
+
+Parameters:
+name – str
+The name that will be removed.
+
+
+
+
+
+
+exists ( object : ObjectID ) → bool [source]
+
+
+exists ( object_id : ObjectID ) → bool [source]
+
+
+Whether the given object exists.
+
+Parameters:
+object_id – ObjectID
+The object id to check if exists.
+
+Returns:
+True
when the specified object exists.
+
+Return type:
+bool
+
+
+
+
+
+
+find_shared_memory ( pointer : int ) → ObjectID [source]
+
+
+find_shared_memory ( target : ptr ) → bool [source]
+
+
+Find the corresponding blob (if exists) of the given pointer.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+ObjectID
+
+
+
+
+find_shared_memory ( target : ptr ) → bool [source]
+
+
+Find the corresponding blob (if exists) of the given pointer.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+ObjectID
+
+
+
+
+
+
+get ( object_id : ObjectID | None = None , name : str | None = None , resolver : ResolverContext | None = None , fetch : bool = False , ** kwargs ) [source]
+Get vineyard object as python value.
+>>> arr_id = vineyard . ObjectID ( '00002ec13bc81226' )
+>>> arr = client . get ( arr_id )
+>>> arr
+array([0, 1, 2, 3, 4, 5, 6, 7])
+
+
+
+Parameters:
+
+client – IPCClient or RPCClient
+The vineyard client to use.
+object_id – ObjectID
+The object id that will be obtained from vineyard.
+name – ObjectID
+The object name that will be obtained from vineyard, ignored if
+object_id
is not None.
+resolver – When retrieving vineyard object, an optional resolver can be specified.
+If no resolver given, the default resolver context will be used.
+fetch – Whether to trigger a migration when the target object is located on
+remote instances.
+kw – User-specific argument that will be passed to the builder.
+
+
+Returns:
+A python object that return by the resolver, by resolving an vineyard object.
+
+
+
+
+
+
+get_blob ( object_id : ObjectID , unsafe : bool = False ) → Blob [source]
+
+
+get_blob ( object_id : ObjectID , unsafe : bool = false ) → Blob [source]
+
+
+Getting a blob from vineyard using the given object ID.
+
+Parameters:
+
+
+Returns:
+Blob
+
+
+
+
See also
+
IPCClient.get_blob
+RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+get_blobs ( object_ids : List [ ObjectID ] , unsafe : bool = False ) → List [ Blob ] [source]
+
+
+get_blobs ( object_ids : List [ ObjectID ] , unsafe : bool = false ) → List [ Blob ] [source]
+
+
+Getting blobs from vineyard using the given object IDs.
+
+Parameters:
+
+
+Returns:
+List[Blob]
+
+
+
+
See also
+
IPCClient.get_blobs
+RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+get_meta ( object_id : ObjectID , sync_remote : bool = True ) → ObjectMeta [source]
+
+
+get_meta ( object_id : ObjectID , sync_remote : bool = False ) → ObjectMeta [source]
+
+
+Get object metadata from vineyard.
+
+Parameters:
+
+object_id – ObjectID
+The object id to get.
+sync_remote – bool
+If the target object is a remote object, code_remote=True
will force
+a meta synchronization on the vineyard server. Default is False
.
+
+
+Returns:
+ObjectMeta
+
+
+
+
+
+
+get_metas ( object_ids : List [ ObjectID ] , sync_remote : bool = True ) → List [ ObjectMeta ] [source]
+
+
+get_metas ( object_ids : List [ ObjectID ] , sync_remote : bool = False ) [source]
+
+-> List[ObjectMeta]
+
+
+Get metadatas of multiple objects from vineyard.
+
+Parameters:
+
+object_ids – List[ObjectID]
+The object ids to get.
+sync_remote – bool
+If the target object is a remote object, code_remote=True
will force
+a meta synchronization on the vineyard server. Default is False
.
+
+
+Returns:
+List[ObjectMeta]
+
+
+
+
+
+
+get_name ( name : str , wait : bool = False ) → ObjectID [source]
+
+
+get_name ( name : str or ObjectName , wait : bool = False ) → ObjectID [source]
+
+
+Get the associated object id of the given name.
+
+Parameters:
+
+name – str
+The name that will be queried.
+wait – bool
+Whether to wait util the name appears, if wait, the request will be blocked
+until the name been registered.
+
+
+Returns:
+The associated object id with the name.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+get_object ( object_id : ObjectID , sync_remote : bool = True , fetch : bool = False ) → Object [source]
+
+
+get_object ( object_id : ObjectID , fetch : bool , sync_remote : bool = True ) → Object [source]
+
+
+Get object from vineyard.
+
+Parameters:
+
+object_id – ObjectID
+The object id to get.
+fetch – bool
+whether to trigger the migration of the object from the remote vineyardd
+to the connected one.
+sync_remote – bool
+whether to synchronize the metadata from the metadata service.
+
+
+Returns:
+Object
+
+
+
+
+
+
+get_objects ( object_ids : List [ ObjectID ] , sync_remote : bool = True ) → List [ Object ] [source]
+
+
+get_objects ( object_ids : List [ ObjectID ] , sync_remote : bool = True ) → List [ Object ] [source]
+
+
+Get multiple objects from vineyard.
+
+Parameters:
+
+
+Returns:
+List[Object]
+
+
+
+
+
+
+get_remote_blob ( object_id : ObjectID , unsafe : bool = False ) → RemoteBlob [source]
+
+
+get_remote_blob ( object_id : ObjectID , unsafe : bool = false ) → RemoteBlob [source]
+
+
+Getting a remote blob from vineyard using the given object ID.
+Note that getting remote blobs requires network transfer and may yields significate
+overhead.
+
+Parameters:
+
+
+Returns:
+RemoteBlob
+
+
+
+
See also
+
IPCClient.get_blob
+IPCClient.get_blobs
+RPCClient.get_remote_blobs
+
+
+
+
+
+get_remote_blobs ( object_ids : List [ ObjectID ] , unsafe : bool = False ) → List [ RemoteBlob ] [source]
+
+
+get_remote_blobs ( object_ids : List [ ObjectID ] , unsafe : bool = false ) [source]
+
+-> List[RemoteBlob]
+
+
+Getting remote blobs from vineyard using the given object IDs.
+Note that getting remote blobs requires network transfer and may yields significate
+overhead.
+
+Parameters:
+
+
+Returns:
+List[RemoteBlob]
+
+
+
+
See also
+
IPCClient.get_blob
+IPCClient.get_blobs
+RPCClient.get_remote_blob
+
+
+
+
+
+property instance_id
+The instance id of the connected vineyard server.
+
+
+
+
+property ipc_socket
+The UNIX domain socket location of connected vineyard server.
+
+
+
+
+property is_ipc
+Whether the client is connected to vineyard server via UNIX domain socket.
+
+
+
+
+property is_rpc
+Whether the client is connected to vineyard server via RPC endpoint.
+
+
+
+
+is_shared_memory ( pointer : int ) → bool [source]
+
+
+is_shared_memory ( target : ptr ) → bool [source]
+
+
+Check if the address is on the shared memory region.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+bool
+
+
+
+
+is_shared_memory ( target : ptr ) → bool [source]
+
+
+Check if the address is on the shared memory region.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+bool
+
+
+
+
+
+
+list_metadatas ( pattern : str , regex : bool = False , limit : int = 5 , nobuffer : bool = False ) → List [ ObjectMeta ] [source]
+
+
+list_metadatas(pattern: str, regex: bool = False, limit: int = 5,
+
+nobuffer: bool = False) -> List[Object]
+
+
+List all objects in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the object’s typename.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be
+used as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+nobuffer – bool
+Whether to fill the buffers in returned object metadatas. Default value
+is False.
+
+
+Returns:
+List[ObjectMeta]
+
+
+
+
+
+
+list_names ( pattern : str , regex : bool = False , limit : int = 5 ) → List [ str ] [source]
+
+
+list_names ( pattern : str , regex : bool = False , limit : int = 5 ) [source]
+
+-> Dict[str, ObjectID]
+
+
+List all names in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the name.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be used
+as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+
+
+Returns:
+Dict[str, ObjectID]
+
+
+
+
+
+
+list_objects ( pattern : str , regex : bool = False , limit : int = 5 ) → List [ ObjectID ] [source]
+
+
+list_objects ( pattern : str , regex : bool = False , limit : int = 5 ) [source]
+
+-> List[Object]
+
+
+List all objects in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the object’s typename.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be used
+as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+
+
+Returns:
+List[Object]
+
+
+
+
+
+
+memory_trim ( ) → bool [source]
+
+
+memory_trim ( ) → bool [source]
+
+
+Trim the memory pool inside the shared memory allocator to return the unused
+physical memory back to the OS kernel, like the malloc_trim API from glibc.
+Returns True if it actually released any memory.
+
+
+
+
+property meta
+The metadata information of the vineyard server. The value is a nested dict, the
+first-level key is the instance id, and the second-level key is the cluster metadata
+fields.
+>>> client . meta
+{
+ 14: {
+ 'hostid': '54058007061210',
+ 'hostname': '127.0.0.1',
+ 'timestamp': '6882550126788354072'
+ },
+ 15: {
+ 'hostid': '48843417291806',
+ 'hostname': '127.0.0.1',
+ 'timestamp': '6882568290204737414'
+ }
+}
+
+
+
+
+
+
+persist ( object : ObjectID | Object | ObjectMeta ) → None [source]
+
+
+persist ( object_id : ObjectID ) → None [source]
+
+
+Persist the object of the given object id. After persisting, the object will be visible
+by clients that connect to other vineyard server instances.
+
+Parameters:
+object_id – ObjectID
+The object that will be persist.
+
+
+
+
+persist ( object_meta : ObjectMeta ) → None [source]
+
+
+Persist the given object.
+
+Parameters:
+object_meta – ObjectMeta
+The object that will be persist.
+
+
+
+
+persist ( object : Object ) → None [source]
+
+
+Persist the given object.
+
+Parameters:
+object – Object
+The object that will be persist.
+
+
+
+
+
+
+put ( value : Any , builder : BuilderContext | None = None , persist : bool = False , name : str | None = None , ** kwargs ) [source]
+Put python value to vineyard.
+>>> arr = np . arange ( 8 )
+>>> arr_id = client . put ( arr )
+>>> arr_id
+00002ec13bc81226
+
+
+
+Parameters:
+
+client – IPCClient or RPCClient
+The vineyard client to use.
+value – The python value that will be put to vineyard. Supported python value
+types are decided by modules that registered to vineyard. By default,
+python value can be put to vineyard after serialized as a bytes buffer
+using pickle.
+builder – optional
+When putting python value to vineyard, an optional builder can be
+specified to tell vineyard how to construct the corresponding vineyard
+Object
. If not specified, the default builder context will be
+used to select a proper builder.
+persist – bool, optional
+If true, persist the object after creation.
+name – str, optional
+If given, the name will be automatically associated with the resulted
+object. Note that only take effect when the object is persisted.
+kw – User-specific argument that will be passed to the builder.
+
+
+Returns:
+The result object id will be returned.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+put_name ( object : Object | ObjectMeta | ObjectID , name : str ) → None [source]
+
+
+put_name(object: ObjectID or ObjectMeta or Object,
+
+name: str or ObjectName) -> None
+
+
+Associate the given object id with a name. An ObjectID
can be associated with
+more than one names.
+
+Parameters:
+
+object_id – ObjectID
+name – str
+
+
+
+
+
+
+
+property remote_instance_id : int
+The instance id of the connected remote vineyard server.
+
+
+
+
+reset ( ) → None [source]
+
+
+reset ( ) → None [source]
+
+
+Alias of ClientBase.clear()
.
+
+
+
+
+property rpc_endpoint
+The RPC endpoint of the connected vineyard server.
+
+
+
+
+shallow_copy ( object_id : ObjectID , extra_metadata : dict | None = None ) → ObjectID [source]
+
+
+shallow_copy ( object_id : ObjectID ) → ObjectID [source]
+
+
+Create a shallow copy of the given vineyard object.
+
+Parameters:
+object_id – ObjectID
+The vineyard object that is requested to be shallow-copied.
+
+Returns:
+The object id of newly shallow-copied vineyard object.
+
+Return type:
+ObjectID
+
+
+
+
+shallow_copy ( object_id : ObjectID , extra_metadata : dict ) → ObjectID [source]
+
+
+Create a shallow copy of the given vineyard object, with extra metadata.
+
+Parameters:
+
+object_id – ObjectID
+The vineyard object that is requested to be shallow-copied.
+extra_metadata – dict
+Extra metadata to apply to the newly created object. The fields of extra
+metadata must be primitive types, e.g., string, number, and cannot be
+array or dict.
+
+
+Returns:
+The object id of newly shallow-copied vineyard object.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+property spread : bool
+Whether the spread is enabled for underlying RPC client.
+
+
+
+
+property status
+The status the of connected vineyard server, returns a InstanceStatus
.
+
+
See also
+
InstanceStatus
+
+
+
+
+
+sync_meta ( ) → None [source]
+
+
+sync_meta ( ) → None [source]
+
+
+Synchronize remote metadata to local immediately.
+
+
+
+
+property version
+The version number string of connected vineyard server, in the format of semver:
+MAJOR.MINOR.PATCH
.
+
+
+
+
+with_compression ( enabled : bool = True ) [source]
+Disable compression for the following put operations.
+
+
+
+
+with_spread ( enabled : bool = True ) [source]
+Enable spread for the following put operations.
+
+
+
+
+
+
+class vineyard. IPCClient
+IPC client that connects to vineyard instance’s UNIX domain socket.
+
+
+allocated_size ( )
+
+
+allocated_size ( target : Object or ObjectID ) → int
+
+
+Get the allocated size of the given object.
+
+Parameters:
+target – Object or ObjectID
+The given Object.
+
+Returns:
+int
+
+
+
+
+
+
+clear ( )
+
+
+clear ( ) → None
+
+
+Drop all objects that visible to the current instance in the vineyard cluster.
+
+
+
+
+close ( )
+Close the client.
+
+
+
+
+property connected
+Whether the client instance has been connected to the vineyard server.
+
+
+
+
+create_blob ( )
+
+
+create_blob ( size : int ) → BlobBuilder
+Allocate a blob in vineyard server.
+
+Parameters:
+size: int The size of blob that will be allocated on vineyardd.
+
+
+
+Returns: BlobBuilder
+
+
+
+
+
+
+create_blob ( sizes : List [ int ] ) → List [ BlobBuilder ]
+Allocate blobs in vineyard server.
+
+Parameters:
+size: List[int] The size of blobs that will be allocated on vineyardd.
+
+
+
+Returns: List[BlobBuilder]
+
+
+
+
+
+
+create_blob ( size : int ) → BlobBuilder
+Allocate a blob in vineyard server.
+
+Parameters:
+size: int The size of blob that will be allocated on vineyardd.
+
+
+
+Returns: BlobBuilder
+
+
+
+
+
+
+create_blob ( sizes : List [ int ] ) → List [ BlobBuilder ]
+Allocate blobs in vineyard server.
+
+Parameters:
+size: List[int] The size of blobs that will be allocated on vineyardd.
+
+
+
+Returns: List[BlobBuilder]
+
+
+
+
+
+
+
+
+create_empty_blob ( )
+
+
+create_empty_blob ( ) → Blob
+
+
+Create an empty blob in vineyard server.
+
+Returns:
+Blob
+
+
+
+
+
+
+create_metadata ( )
+
+
+create_metadata ( metadata : ObjectMeta | List [ ObjectMeta ] )
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd.
+
+Parameters:
+metadata – ObjectMeta
+The metadata that will be created on vineyardd.
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata(metadata: Union[ObjectMeta, List[ObjectMeta]],
+
+instance_id: InstanceID)
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd with a specified instance id.
+
+Parameters:
+
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata ( metadata : ObjectMeta | List [ ObjectMeta ] )
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd.
+
+Parameters:
+metadata – ObjectMeta
+The metadata that will be created on vineyardd.
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata(metadata: Union[ObjectMeta, List[ObjectMeta]],
+
+instance_id: InstanceID)
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd with a specified instance id.
+
+Parameters:
+
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+
+
+delete ( )
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+
+
+drop_name ( )
+
+
+drop_name ( name : str or ObjectName ) → None
+
+
+Remove the association of the given name.
+
+Parameters:
+name – str
+The name that will be removed.
+
+
+
+
+
+
+exists ( )
+
+
+exists ( object_id : ObjectID ) → bool
+
+
+Whether the given object exists.
+
+Parameters:
+object_id – ObjectID
+The object id to check if exists.
+
+Returns:
+True
when the specified object exists.
+
+Return type:
+bool
+
+
+
+
+
+
+find_shared_memory ( )
+
+
+find_shared_memory ( target : ptr ) → bool
+
+
+Find the corresponding blob (if exists) of the given pointer.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+ObjectID
+
+
+
+
+find_shared_memory ( target : ptr ) → bool
+
+
+Find the corresponding blob (if exists) of the given pointer.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+ObjectID
+
+
+
+
+
+
+get ( object_id : ObjectID | None = None , name : str | None = None , resolver : ResolverContext | None = None , fetch : bool = False , ** kwargs )
+Get vineyard object as python value.
+>>> arr_id = vineyard . ObjectID ( '00002ec13bc81226' )
+>>> arr = client . get ( arr_id )
+>>> arr
+array([0, 1, 2, 3, 4, 5, 6, 7])
+
+
+
+Parameters:
+
+client – IPCClient or RPCClient
+The vineyard client to use.
+object_id – ObjectID
+The object id that will be obtained from vineyard.
+name – ObjectID
+The object name that will be obtained from vineyard, ignored if
+object_id
is not None.
+resolver – When retrieving vineyard object, an optional resolver can be specified.
+If no resolver given, the default resolver context will be used.
+fetch – Whether to trigger a migration when the target object is located on
+remote instances.
+kw – User-specific argument that will be passed to the builder.
+
+
+Returns:
+A python object that return by the resolver, by resolving an vineyard object.
+
+
+
+
+
+
+get_blob ( )
+
+
+get_blob ( object_id : ObjectID , unsafe : bool = false ) → Blob
+
+
+Getting a blob from vineyard using the given object ID.
+
+Parameters:
+
+
+Returns:
+Blob
+
+
+
+
See also
+
IPCClient.get_blob
+RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+get_blobs ( )
+
+
+get_blobs ( object_ids : List [ ObjectID ] , unsafe : bool = false ) → List [ Blob ]
+
+
+Getting blobs from vineyard using the given object IDs.
+
+Parameters:
+
+
+Returns:
+List[Blob]
+
+
+
+
See also
+
IPCClient.get_blobs
+RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+get_meta ( )
+
+
+get_meta ( object_id : ObjectID , sync_remote : bool = False ) → ObjectMeta
+
+
+Get object metadata from vineyard.
+
+Parameters:
+
+object_id – ObjectID
+The object id to get.
+sync_remote – bool
+If the target object is a remote object, code_remote=True
will force
+a meta synchronization on the vineyard server. Default is False
.
+
+
+Returns:
+ObjectMeta
+
+
+
+
+
+
+get_metas ( )
+
+
+get_metas ( object_ids : List [ ObjectID ] , sync_remote : bool = False )
+
+-> List[ObjectMeta]
+
+
+Get metadatas of multiple objects from vineyard.
+
+Parameters:
+
+object_ids – List[ObjectID]
+The object ids to get.
+sync_remote – bool
+If the target object is a remote object, code_remote=True
will force
+a meta synchronization on the vineyard server. Default is False
.
+
+
+Returns:
+List[ObjectMeta]
+
+
+
+
+
+
+get_name ( )
+
+
+get_name ( name : str or ObjectName , wait : bool = False ) → ObjectID
+
+
+Get the associated object id of the given name.
+
+Parameters:
+
+name – str
+The name that will be queried.
+wait – bool
+Whether to wait util the name appears, if wait, the request will be blocked
+until the name been registered.
+
+
+Returns:
+The associated object id with the name.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+get_object ( )
+
+
+get_object ( object_id : ObjectID , fetch : bool , sync_remote : bool = True ) → Object
+
+
+Get object from vineyard.
+
+Parameters:
+
+object_id – ObjectID
+The object id to get.
+fetch – bool
+whether to trigger the migration of the object from the remote vineyardd
+to the connected one.
+sync_remote – bool
+whether to synchronize the metadata from the metadata service.
+
+
+Returns:
+Object
+
+
+
+
+
+
+get_objects ( )
+
+
+get_objects ( object_ids : List [ ObjectID ] , sync_remote : bool = True ) → List [ Object ]
+
+
+Get multiple objects from vineyard.
+
+Parameters:
+
+
+Returns:
+List[Object]
+
+
+
+
+
+
+property instance_id
+The instance id of the connected vineyard server.
+
+
+
+
+property ipc_socket
+The UNIX domain socket location of connected vineyard server.
+
+
+
+
+property is_ipc
+Whether the client is connected to vineyard server via UNIX domain socket.
+
+
+
+
+property is_rpc
+Whether the client is connected to vineyard server via RPC endpoint.
+
+
+
+
+is_shared_memory ( )
+
+
+is_shared_memory ( target : ptr ) → bool
+
+
+Check if the address is on the shared memory region.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+bool
+
+
+
+
+is_shared_memory ( target : ptr ) → bool
+
+
+Check if the address is on the shared memory region.
+
+Parameters:
+target – address, in int format
+The given address.
+
+Returns:
+bool
+
+
+
+
+
+
+list_metadatas ( )
+
+
+list_metadatas(pattern: str, regex: bool = False, limit: int = 5,
+
+nobuffer: bool = False) -> List[Object]
+
+
+List all objects in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the object’s typename.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be
+used as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+nobuffer – bool
+Whether to fill the buffers in returned object metadatas. Default value
+is False.
+
+
+Returns:
+List[ObjectMeta]
+
+
+
+
+
+
+list_names ( )
+
+
+list_names ( pattern : str , regex : bool = False , limit : int = 5 )
+
+-> Dict[str, ObjectID]
+
+
+List all names in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the name.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be used
+as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+
+
+Returns:
+Dict[str, ObjectID]
+
+
+
+
+
+
+list_objects ( )
+
+
+list_objects ( pattern : str , regex : bool = False , limit : int = 5 )
+
+-> List[Object]
+
+
+List all objects in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the object’s typename.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be used
+as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+
+
+Returns:
+List[Object]
+
+
+
+
+
+
+memory_trim ( )
+
+
+memory_trim ( ) → bool
+
+
+Trim the memory pool inside the shared memory allocator to return the unused
+physical memory back to the OS kernel, like the malloc_trim API from glibc.
+Returns True if it actually released any memory.
+
+
+
+
+property meta
+The metadata information of the vineyard server. The value is a nested dict, the
+first-level key is the instance id, and the second-level key is the cluster metadata
+fields.
+>>> client . meta
+{
+ 14: {
+ 'hostid': '54058007061210',
+ 'hostname': '127.0.0.1',
+ 'timestamp': '6882550126788354072'
+ },
+ 15: {
+ 'hostid': '48843417291806',
+ 'hostname': '127.0.0.1',
+ 'timestamp': '6882568290204737414'
+ }
+}
+
+
+
+
+
+
+persist ( )
+
+
+persist ( object_id : ObjectID ) → None
+
+
+Persist the object of the given object id. After persisting, the object will be visible
+by clients that connect to other vineyard server instances.
+
+Parameters:
+object_id – ObjectID
+The object that will be persist.
+
+
+
+
+persist ( object_meta : ObjectMeta ) → None
+
+
+Persist the given object.
+
+Parameters:
+object_meta – ObjectMeta
+The object that will be persist.
+
+
+
+
+persist ( object : Object ) → None
+
+
+Persist the given object.
+
+Parameters:
+object – Object
+The object that will be persist.
+
+
+
+
+
+
+put ( value : Any , builder : BuilderContext | None = None , persist : bool = False , name : str | None = None , ** kwargs )
+Put python value to vineyard.
+>>> arr = np . arange ( 8 )
+>>> arr_id = client . put ( arr )
+>>> arr_id
+00002ec13bc81226
+
+
+
+Parameters:
+
+client – IPCClient or RPCClient
+The vineyard client to use.
+value – The python value that will be put to vineyard. Supported python value
+types are decided by modules that registered to vineyard. By default,
+python value can be put to vineyard after serialized as a bytes buffer
+using pickle.
+builder – optional
+When putting python value to vineyard, an optional builder can be
+specified to tell vineyard how to construct the corresponding vineyard
+Object
. If not specified, the default builder context will be
+used to select a proper builder.
+persist – bool, optional
+If true, persist the object after creation.
+name – str, optional
+If given, the name will be automatically associated with the resulted
+object. Note that only take effect when the object is persisted.
+kw – User-specific argument that will be passed to the builder.
+
+
+Returns:
+The result object id will be returned.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+put_name ( )
+
+
+put_name(object: ObjectID or ObjectMeta or Object,
+
+name: str or ObjectName) -> None
+
+
+Associate the given object id with a name. An ObjectID
can be associated with
+more than one names.
+
+Parameters:
+
+object_id – ObjectID
+name – str
+
+
+
+
+
+
+
+reset ( )
+
+
+reset ( ) → None
+
+
+Alias of ClientBase.clear()
.
+
+
+
+
+property rpc_endpoint
+The RPC endpoint of the connected vineyard server.
+
+
+
+
+shallow_copy ( )
+
+
+shallow_copy ( object_id : ObjectID ) → ObjectID
+
+
+Create a shallow copy of the given vineyard object.
+
+Parameters:
+object_id – ObjectID
+The vineyard object that is requested to be shallow-copied.
+
+Returns:
+The object id of newly shallow-copied vineyard object.
+
+Return type:
+ObjectID
+
+
+
+
+shallow_copy ( object_id : ObjectID , extra_metadata : dict ) → ObjectID
+
+
+Create a shallow copy of the given vineyard object, with extra metadata.
+
+Parameters:
+
+object_id – ObjectID
+The vineyard object that is requested to be shallow-copied.
+extra_metadata – dict
+Extra metadata to apply to the newly created object. The fields of extra
+metadata must be primitive types, e.g., string, number, and cannot be
+array or dict.
+
+
+Returns:
+The object id of newly shallow-copied vineyard object.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+property status
+The status the of connected vineyard server, returns a InstanceStatus
.
+
+
See also
+
InstanceStatus
+
+
+
+
+
+sync_meta ( )
+
+
+sync_meta ( ) → None
+
+
+Synchronize remote metadata to local immediately.
+
+
+
+
+property version
+The version number string of connected vineyard server, in the format of semver:
+MAJOR.MINOR.PATCH
.
+
+
+
+
+
+
+class vineyard. RPCClient
+RPC client that connects to vineyard instance’s RPC endpoints.
+
+
+clear ( )
+
+
+clear ( ) → None
+
+
+Drop all objects that visible to the current instance in the vineyard cluster.
+
+
+
+
+close ( )
+Close the client.
+
+
+
+
+property connected
+Whether the client instance has been connected to the vineyard server.
+
+
+
+
+create_metadata ( )
+
+
+create_metadata ( metadata : ObjectMeta | List [ ObjectMeta ] )
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd.
+
+Parameters:
+metadata – ObjectMeta
+The metadata that will be created on vineyardd.
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata(metadata: Union[ObjectMeta, List[ObjectMeta]],
+
+instance_id: InstanceID)
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd with a specified instance id.
+
+Parameters:
+
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata ( metadata : ObjectMeta | List [ ObjectMeta ] )
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd.
+
+Parameters:
+metadata – ObjectMeta
+The metadata that will be created on vineyardd.
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+create_metadata(metadata: Union[ObjectMeta, List[ObjectMeta]],
+
+instance_id: InstanceID)
+
+-> Union[ObjectMeta, List[ObjectMeta]]
+
+
+Create metadata in vineyardd with a specified instance id.
+
+Parameters:
+
+
+Returns:
+The result created metadata.
+
+Return type:
+Union[ObjectMeta , List[ObjectMeta ]]
+
+
+
+
+
+
+create_remote_blob ( )
+
+
+create_remote_blob ( blob_builder : RemoteBlobBuilder ) → ObjectMeta
+Put the remote blob to connected remote vineyard instance. The blob_builder
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+vineyard_rpc_client = vineyard . connect ( * vineyard_endpoint . split ( ':' ))
+
+buffer_writer = RemoteBlobBuilder ( len ( payload ))
+buffer_writer . copy ( 0 , payload )
+blob_meta = vineyard_rpc_client . create_remote_blob ( buffer_writer )
+
+
+
+Parameters:
+blob_builder: RemoteBlobBuilder The remote blob to create.
+
+
+
+Returns: ObjectMeta
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+create_remote_blob ( blob_builders : List [ RemoteBlobBuilder ] ) → List [ ObjectMeta ]
+Put the remote blobs to connected remote vineyard instance. The blob_builders
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+
+Returns: List[ObjectMeta]
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+create_remote_blob ( blob_builder : RemoteBlobBuilder ) → ObjectMeta
+Put the remote blob to connected remote vineyard instance. The blob_builder
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+vineyard_rpc_client = vineyard . connect ( * vineyard_endpoint . split ( ':' ))
+
+buffer_writer = RemoteBlobBuilder ( len ( payload ))
+buffer_writer . copy ( 0 , payload )
+blob_meta = vineyard_rpc_client . create_remote_blob ( buffer_writer )
+
+
+
+Parameters:
+blob_builder: RemoteBlobBuilder The remote blob to create.
+
+
+
+Returns: ObjectMeta
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+create_remote_blob ( blob_builders : List [ RemoteBlobBuilder ] ) → List [ ObjectMeta ]
+Put the remote blobs to connected remote vineyard instance. The blob_builders
+is assumed to be ready and modification on the blob_builder
after creation
+won’t take effect.
+Note that creating remote blobs requires network transfer and may yields significate
+overhead.
+
+Returns: List[ObjectMeta]
+
+See Also: RPCClient.get_remote_blob
+RPCClient.get_remote_blobs
+
+
+
+
+
+
+
+
+delete ( )
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+delete(object_id: ObjectID or List[ObjectID], force: bool = false,
+
+deep: bool = true, memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+
+object_id – ObjectID or list of ObjectID
+Objects that will be deleted. The object_id
can be a single
+ObjectID
, or a list of ObjectID
.
+force – bool
+Forcedly delete an object means the member will be recursively deleted
+even if the member object is also referred by others. The default value
+is True
.
+deep –
bool
+Deeply delete an object means we will deleting the members recursively.
+The default value is True
.
+Note that when deleting objects which have direct blob members, the
+processing on those blobs yields a “deep” behavior.
+
+memory_trim –
bool
+Whether to trim the memory pool inside the shared memory allocator to
+return the unused physical memory back to the OS kernel, like the
+malloc_trim API from glibc. Default value is False.
+Note that the memory trimming operation is a best-effort operation and
+may not release any memory at all.
+
+
+
+
+
+
+delete(object_meta: ObjectMeta, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object_meta – The corresponding object meta to delete.
+
+
+
+
+delete(object: Object, force: bool = false, deep: bool = true,
+
+memory_trim: bool = False) -> None
+
+
+Delete the specific vineyard object.
+
+Parameters:
+object – The corresponding object meta to delete.
+
+
+
+
+
+
+drop_name ( )
+
+
+drop_name ( name : str or ObjectName ) → None
+
+
+Remove the association of the given name.
+
+Parameters:
+name – str
+The name that will be removed.
+
+
+
+
+
+
+exists ( )
+
+
+exists ( object_id : ObjectID ) → bool
+
+
+Whether the given object exists.
+
+Parameters:
+object_id – ObjectID
+The object id to check if exists.
+
+Returns:
+True
when the specified object exists.
+
+Return type:
+bool
+
+
+
+
+
+
+get ( object_id : ObjectID | None = None , name : str | None = None , resolver : ResolverContext | None = None , fetch : bool = False , ** kwargs )
+Get vineyard object as python value.
+>>> arr_id = vineyard . ObjectID ( '00002ec13bc81226' )
+>>> arr = client . get ( arr_id )
+>>> arr
+array([0, 1, 2, 3, 4, 5, 6, 7])
+
+
+
+Parameters:
+
+client – IPCClient or RPCClient
+The vineyard client to use.
+object_id – ObjectID
+The object id that will be obtained from vineyard.
+name – ObjectID
+The object name that will be obtained from vineyard, ignored if
+object_id
is not None.
+resolver – When retrieving vineyard object, an optional resolver can be specified.
+If no resolver given, the default resolver context will be used.
+fetch – Whether to trigger a migration when the target object is located on
+remote instances.
+kw – User-specific argument that will be passed to the builder.
+
+
+Returns:
+A python object that return by the resolver, by resolving an vineyard object.
+
+
+
+
+
+
+get_meta ( )
+
+
+get_meta ( object_id : ObjectID ) → ObjectMeta
+
+
+Get object metadata from vineyard.
+
+Parameters:
+object_id – ObjectID
+The object id to get.
+
+Returns:
+ObjectMeta
+
+
+
+
+
+
+get_metas ( )
+
+
+get_metas(object_ids: List[ObjectID] -> List[ObjectMeta]
+
+
+Get metadatas of multiple objects from vineyard.
+
+Parameters:
+object_ids – List[ObjectID]
+
+Returns:
+List[ObjectMeta]
+
+
+
+
+
+
+get_name ( )
+
+
+get_name ( name : str or ObjectName , wait : bool = False ) → ObjectID
+
+
+Get the associated object id of the given name.
+
+Parameters:
+
+name – str
+The name that will be queried.
+wait – bool
+Whether to wait util the name appears, if wait, the request will be blocked
+until the name been registered.
+
+
+Returns:
+The associated object id with the name.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+get_object ( )
+
+
+get_object ( object_id : ObjectID , sync_remote : bool = True ) → Object
+
+
+Get object from vineyard.
+
+Parameters:
+
+
+Returns:
+Object
+
+
+
+
+
+
+get_objects ( )
+
+
+get_objects ( object_ids : List [ ObjectID ] , sync_remote : bool = True ) → List [ Object ]
+
+
+Get multiple objects from vineyard.
+
+Parameters:
+
+
+Returns:
+List[Object]
+
+
+
+
+
+
+get_remote_blob ( )
+
+
+get_remote_blob ( object_id : ObjectID , unsafe : bool = false ) → RemoteBlob
+
+
+Getting a remote blob from vineyard using the given object ID.
+Note that getting remote blobs requires network transfer and may yields significate
+overhead.
+
+Parameters:
+
+
+Returns:
+RemoteBlob
+
+
+
+
See also
+
IPCClient.get_blob
+IPCClient.get_blobs
+RPCClient.get_remote_blobs
+
+
+
+
+
+get_remote_blobs ( )
+
+
+get_remote_blobs ( object_ids : List [ ObjectID ] , unsafe : bool = false )
+
+-> List[RemoteBlob]
+
+
+Getting remote blobs from vineyard using the given object IDs.
+Note that getting remote blobs requires network transfer and may yields significate
+overhead.
+
+Parameters:
+
+
+Returns:
+List[RemoteBlob]
+
+
+
+
See also
+
IPCClient.get_blob
+IPCClient.get_blobs
+RPCClient.get_remote_blob
+
+
+
+
+
+property instance_id
+The instance id of the connected vineyard server.
+
+
+
+
+property ipc_socket
+The UNIX domain socket location of connected vineyard server.
+
+
+
+
+is_fetchable ( )
+Whether the rpc client is able to fetch objects from the connected vineyard server.
+When the instance connected by the rpc client is not the same as the instance
+of metadata, the rpc client is not able to fetch the object.
+
+
+
+
+property is_ipc
+Whether the client is connected to vineyard server via UNIX domain socket.
+
+
+
+
+property is_rpc
+Whether the client is connected to vineyard server via RPC endpoint.
+
+
+
+
+list_metadatas ( )
+
+
+list_metadatas(pattern: str, regex: bool = False, limit: int = 5,
+
+nobuffer: bool = False) -> List[Object]
+
+
+List all objects in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the object’s typename.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be
+used as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+nobuffer – bool
+Whether to fill the buffers in returned object metadatas. Default value
+is False.
+
+
+Returns:
+List[ObjectMeta]
+
+
+
+
+
+
+list_names ( )
+
+
+list_names ( pattern : str , regex : bool = False , limit : int = 5 )
+
+-> Dict[str, ObjectID]
+
+
+List all names in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the name.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be used
+as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+
+
+Returns:
+Dict[str, ObjectID]
+
+
+
+
+
+
+list_objects ( )
+
+
+list_objects ( pattern : str , regex : bool = False , limit : int = 5 )
+
+-> List[Object]
+
+
+List all objects in current vineyard server.
+
+Parameters:
+
+pattern – str
+The pattern string that will be matched against the object’s typename.
+regex – bool
+Whether the pattern is a regex expression, otherwise the pattern will be
+used as wildcard pattern. Default value is False.
+limit – int
+The limit to list. Default value is 5.
+
+
+Returns:
+List[Object]
+
+
+
+
+
+
+memory_trim ( )
+
+
+memory_trim ( ) → bool
+
+
+Trim the memory pool inside the shared memory allocator to return the unused
+physical memory back to the OS kernel, like the malloc_trim API from glibc.
+Returns True if it actually released any memory.
+
+
+
+
+property meta
+The metadata information of the vineyard server. The value is a nested dict, the
+first-level key is the instance id, and the second-level key is the cluster metadata
+fields.
+>>> client . meta
+{
+ 14: {
+ 'hostid': '54058007061210',
+ 'hostname': '127.0.0.1',
+ 'timestamp': '6882550126788354072'
+ },
+ 15: {
+ 'hostid': '48843417291806',
+ 'hostname': '127.0.0.1',
+ 'timestamp': '6882568290204737414'
+ }
+}
+
+
+
+
+
+
+persist ( )
+
+
+persist ( object_id : ObjectID ) → None
+
+
+Persist the object of the given object id. After persisting, the object will be visible
+by clients that connect to other vineyard server instances.
+
+Parameters:
+object_id – ObjectID
+The object that will be persist.
+
+
+
+
+persist ( object_meta : ObjectMeta ) → None
+
+
+Persist the given object.
+
+Parameters:
+object_meta – ObjectMeta
+The object that will be persist.
+
+
+
+
+persist ( object : Object ) → None
+
+
+Persist the given object.
+
+Parameters:
+object – Object
+The object that will be persist.
+
+
+
+
+
+
+put ( value : Any , builder : BuilderContext | None = None , persist : bool = False , name : str | None = None , ** kwargs )
+Put python value to vineyard.
+>>> arr = np . arange ( 8 )
+>>> arr_id = client . put ( arr )
+>>> arr_id
+00002ec13bc81226
+
+
+
+Parameters:
+
+client – IPCClient or RPCClient
+The vineyard client to use.
+value – The python value that will be put to vineyard. Supported python value
+types are decided by modules that registered to vineyard. By default,
+python value can be put to vineyard after serialized as a bytes buffer
+using pickle.
+builder – optional
+When putting python value to vineyard, an optional builder can be
+specified to tell vineyard how to construct the corresponding vineyard
+Object
. If not specified, the default builder context will be
+used to select a proper builder.
+persist – bool, optional
+If true, persist the object after creation.
+name – str, optional
+If given, the name will be automatically associated with the resulted
+object. Note that only take effect when the object is persisted.
+kw – User-specific argument that will be passed to the builder.
+
+
+Returns:
+The result object id will be returned.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+put_name ( )
+
+
+put_name(object: ObjectID or ObjectMeta or Object,
+
+name: str or ObjectName) -> None
+
+
+Associate the given object id with a name. An ObjectID
can be associated with
+more than one names.
+
+Parameters:
+
+object_id – ObjectID
+name – str
+
+
+
+
+
+
+
+property remote_instance_id
+The instance id of the connected remote vineyard server.
+
+
+
+
+reset ( )
+
+
+reset ( ) → None
+
+
+Alias of ClientBase.clear()
.
+
+
+
+
+property rpc_endpoint
+The RPC endpoint of the connected vineyard server.
+
+
+
+
+shallow_copy ( )
+
+
+shallow_copy ( object_id : ObjectID ) → ObjectID
+
+
+Create a shallow copy of the given vineyard object.
+
+Parameters:
+object_id – ObjectID
+The vineyard object that is requested to be shallow-copied.
+
+Returns:
+The object id of newly shallow-copied vineyard object.
+
+Return type:
+ObjectID
+
+
+
+
+shallow_copy ( object_id : ObjectID , extra_metadata : dict ) → ObjectID
+
+
+Create a shallow copy of the given vineyard object, with extra metadata.
+
+Parameters:
+
+object_id – ObjectID
+The vineyard object that is requested to be shallow-copied.
+extra_metadata – dict
+Extra metadata to apply to the newly created object. The fields of extra
+metadata must be primitive types, e.g., string, number, and cannot be
+array or dict.
+
+
+Returns:
+The object id of newly shallow-copied vineyard object.
+
+Return type:
+ObjectID
+
+
+
+
+
+
+property status
+The status the of connected vineyard server, returns a InstanceStatus
.
+
+
See also
+
InstanceStatus
+
+
+
+
+
+sync_meta ( )
+
+
+sync_meta ( ) → None
+
+
+Synchronize remote metadata to local immediately.
+
+
+
+
+property version
+The version number string of connected vineyard server, in the format of semver:
+MAJOR.MINOR.PATCH
.
+
+
+
+
+
+
+Vineyard cluster
+
+
+class vineyard. InstanceStatus
+InstanceStatus
represents the status of connected vineyard instance, including
+the instance identity, memory statistics and workloads on this instance.
+>>> status = client . status
+>>> print ( status )
+InstanceStatus:
+ instance_id: 5
+ deployment: local
+ memory_usage: 360
+ memory_limit: 268435456
+ deferred_requests: 0
+ ipc_connections: 1
+ rpc_connections: 0
+>>> status . instance_id
+5
+>>> status . deployment
+'local'
+>>> status . memory_usage
+360
+>>> status . memory_limit
+268435456
+>>> status . deferred_requests
+0
+>>> status . ipc_connections
+1
+>>> status . rpc_connections
+0
+
+
+
+
+__init__ ( * args , ** kwargs )
+
+
+
+
+__repr__ ( )
+Return repr(self).
+
+
+
+
+__str__ ( )
+Return str(self).
+
+
+
+
+property deferred_requests
+Report number of waiting requests of current vineyardd instance.
+
+
+
+
+property deployment
+The deployment mode of the connected vineyardd cluster, can be "local"
and
+"distributed"
.
+
+
+
+
+property instance_id
+Return the instance id of vineyardd that the client is connected to.
+
+
+
+
+property ipc_connections
+Report number of alive IPC connections on the current vineyardd instance.
+
+
+
+
+property memory_limit
+Report memory limit (in bytes) of current vineyardd instance.
+
+
+
+
+property memory_usage
+Report memory usage (in bytes) of current vineyardd instance.
+
+
+
+
+property rpc_connections
+Report number of alive RPC connections on the current vineyardd instance.
+
+
+
+
+
+
+Blob
+
+
+class vineyard. Blob
+Blob
in vineyard is a consecutive readonly shared memory.
+
+
+property address
+The memory address value of this blob.
+
+
+
+
+static empty ( )
+Create an empty blob (with size as 0
).
+
+
+
+
+property is_empty
+Whether the blob is an empty blob, i.e., the size of this blob is 0.
+
+
+
+
+property size
+Size of the blob.
+
+
+
+
+
+
+class vineyard. BlobBuilder
+BlobBuilder
is the builder for creating a finally immutable blob in
+vineyard server.
+A BlobBuilder
can only be explicitly created using the
+IPCClient.create_blob()
.
+
+
See also
+
IPCClient.create_blob
+IPCClient.create_empty_blob
+
+
+
+abort ( )
+Abort the blob builder if it is not sealed yet.
+
+
+
+
+property address
+The memory address value of this blob builder.
+
+
+
+
+copy ( )
+
+
+copy ( self , offset : int , ptr : int , size : int , concurrency : int = 6 )
+
+
+Copy the given address to the given offset.
+
+
+copy ( self , offset : int , ptr : int , size : int , concurrency : int = 6 )
+
+
+Copy the given address to the given offset.
+
+
+copy ( self , offset : int , ptr : int , size : int , concurrency : int = 6 )
+
+
+Copy the given address to the given offset.
+
+
+
+
+property id
+ObjectID of this blob builder.
+
+
+
+
+shrink ( )
+Shrink the blob builder to the given size if it is not sealed yet.
+
+
+
+
+property size
+Size of this blob builder.
+
+
+
+
+
+
+class vineyard. RemoteBlob
+RemoteBlob
is a holder for Blob
in cases like the Blob
+doesn’t exist in the local vineyardd instance but the client still want th access
+the data with a tolerable network-transfer overhead.
+
+
+property address
+The memory address value of this blob.
+
+
+
+
+property id
+Object ID of the remote blob.
+
+
+
+
+property instance_id
+The instance ID where the blob is actually placed at.
+
+
+
+
+property is_empty
+Whether the blob is an empty blob, i.e., the size of this blob is 0.
+
+
+
+
+property size
+The size of this blob.
+
+
+
+
+
+
+class vineyard. RemoteBlobBuilder
+RemoteBlobBuilder
is the builder for creating a finally immutable blob in
+vineyard server over a RPC client.
+A RemoteBlobBuilder
can only be explicitly initialized using
+RemoteBlobBuilder()
, then be filled the content and finally be sent to remote
+vineyard instance over the network.
+
+
See also
+
IPCClient.create_blob
+IPCClient.create_empty_blob
+
+
+
+abort ( )
+Abort the blob builder if it is not sealed yet.
+
+
+
+
+property address
+The memory address value of this blob builder.
+
+
+
+
+copy ( )
+
+
+copy ( self , offset : int , ptr : int , size : int , concurrency : int = 6 )
+
+
+Copy the given address to the given offset.
+
+
+copy ( self , offset : int , ptr : int , size : int , concurrency : int = 6 )
+
+
+Copy the given address to the given offset.
+
+
+copy ( self , offset : int , ptr : int , size : int , concurrency : int = 6 )
+
+
+Copy the given address to the given offset.
+
+
+
+
+property size
+Size of this blob builder.
+
+
+
+
+
+
+Resolvers and builders
+
+
+class vineyard.core.resolver. ResolverContext ( parent_context : ResolverContext | None = None ) [source]
+
+
+
+
+vineyard.core.resolver. get_current_resolvers ( ) → ResolverContext [source]
+Obtain current resolver context.
+
+
+
+
+vineyard.core.resolver. resolver_context ( resolvers : Dict [ str , Callable ] | None = None , base : ResolverContext | None = None ) → Generator [ ResolverContext , Any , Any ] [source]
+Open a new context for register resolvers, without populating outside
+the global environment.
+The resolver_context
can be useful when users have more than
+more resolver for a certain type, e.g., the vineyard::Tensor
+object can be resolved as numpy.ndarray
or xgboost::DMatrix
.
+We could have
+def numpy_resolver ( obj ):
+ ...
+
+default_resolver_context . register ( 'vineyard::Tensor' , numpy_resolver )
+
+
+and
+def xgboost_resolver ( obj ):
+ ...
+
+default_resolver_context . register ( 'vineyard::Tensor' , xgboost_resolver )
+
+
+Obviously there’s a conflict, and the stackable resolver_context
could
+help there,
+with resolver_context ({ 'vineyard::Tensor' , xgboost_resolver }):
+ ...
+
+
+Assuming the default context resolves vineyard::Tensor
to
+numpy.ndarray
, inside the with resolver_context
the
+vineyard::Tensor
will be resolved to xgboost::DMatrix
,
+and after exiting the context the global environment will be restored
+back as default.
+The with resolver_context
is nestable as well.
+
+
See also
+
builder_context
+driver_context
+
+
+
+
+
+class vineyard.core.builder. BuilderContext ( parent_context : BuilderContext | None = None ) [source]
+
+
+register ( type_id : type , builder : Callable ) [source]
+Register a Python type to the builder context.
+
+Parameters:
+
+type_id (Python type ) – Like int , or numpy.ndarray
+builder (callable , e.g. , a method , callable object ) – A builder translates a python object to vineyard, it accepts a Python
+value as parameter, and returns an vineyard object as result.
+
+
+
+
+
+
+
+run ( client , value , ** kw ) [source]
+Follows the MRO to find the proper builder for given python value.
+Here “Follows the MRO” implies:
+
+If the type of python value has been found in the context, the registered
+builder will be used.
+If not, it follows the MRO chain from down to top to find a registered
+Python type and used the associated builder.
+When the traversal reaches the object
type, since there’s a default
+builder that serialization the python value, the parameter will be serialized
+and be put into a blob.
+
+
+
+
+
+
+
+vineyard.core.builder. get_current_builders ( ) → BuilderContext [source]
+Obtain the current builder context.
+
+
+
+
+vineyard.core.builder. builder_context ( builders : Dict [ type , Callable ] | None = None , base : BuilderContext | None = None ) → Generator [ BuilderContext , Any , Any ] [source]
+Open a new context for register builders, without populating outside global
+environment.
+
+
See also
+
resolver_context
+driver_context
+
+
+
+
+
+class vineyard.core.driver. DriverContext [source]
+
+
+
+
+vineyard.core.driver. get_current_drivers ( ) [source]
+Obtain current driver context.
+
+
+
+
+vineyard.core.driver. driver_context ( drivers = None , base = None ) [source]
+Open a new context for register drivers, without populting outside global
+environment.
+
+
See also
+
builder_context
+resolver_context
+
+
+
+
+
+Shared memory
+
+
+class vineyard.shared_memory. SharedMemory ( vineyard_client , name = None , create = False , size = 0 ) [source]
+
+
+property buf
+A memoryview of contents of the shared memory block.
+
+
+
+
+freeze ( ) [source]
+Seal the shared memory to make it visible for other processes.
+
+
+
+
+property name
+Unique name that identifies the shared memory block.
+
+
+
+
+property size
+Size in bytes.
+
+
+
+
+unlink ( ) [source]
+Requests that the underlying shared memory block be destroyed.
+
+
+
+
+
+
+class vineyard.shared_memory. ShareableList ( vineyard_client , sequence = None , * , name = None ) [source]
+Pattern for a mutable list-like object shareable via a shared
+memory block. It differs from the built-in list type in that these
+lists can not change their overall length (i.e. no append, insert,
+etc.)
+Because values are packed into a memoryview as bytes, the struct
+packing format for any storable value must require no more than 8
+characters to describe its format.
+The ShareableList in vineyard differs slightly with its equivalent
+in the multiprocessing.shared_memory.ShareableList, as it becomes
+immutable after obtaining from the vineyard backend.
+
+
See also
+
multiprocessing.shared_memory.ShareableList
+
+
+
+freeze ( ) [source]
+Make the shareable list immutable and visible for other vineyard clients.
+
+
+
+
+
+
+Deployment
+
+
+vineyard. connect ( * args , ** kwargs ) [source]
+Connect to vineyard by specified UNIX-domain socket or TCP endpoint.
+If no arguments are provided and failed to resolve both the environment
+variables VINEYARD_IPC_SOCKET
, VINEYARD_RPC_ENDPOINT
,
+VINEYARD_CONFIG
, and the default configuration file
+/var/run/vineyard-config.yaml
and
+/var/run/vineyard/vineyard-config.yaml
, it will launch a standalone
+vineyardd server in the background and then connect to it.
+The connect() method has various overloading:
+
+
+connect(socket: str,
+
+username: str = None,
+
+password: str = None) -> IPCClient
+Connect to vineyard via UNIX domain socket for IPC service:
+client = vineyard . connect ( '/var/run/vineyard.sock' )
+
+
+
+Parameters:
+socket: str UNIX domain socket path to setup an IPC connection.
+
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Returns: IPCClient: The connected IPC client.
+
+
+
+
+
+
+connect(host: str,
+
+port: int or str,
+
+username: str = None,
+
+password: str = None) -> RPCClient
+Connect to vineyard via TCP socket.
+
+Parameters:
+host: str Hostname to connect to.
+
+port: int or str The TCP that listened by vineyard TCP service.
+
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Returns: RPCClient: The connected RPC client.
+
+
+
+
+
+
+connect(endpoint: (str, int or str),
+
+username: str = None,
+
+password: str = None) -> RPCClient
+Connect to vineyard via TCP socket.
+
+Parameters:
+endpoint: tuple(str, int or str) Endpoint to connect to. The parameter is a tuple, in which the first
+element is the host, and the second parameter is the port (can be int
+a str).
+
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Returns: RPCClient: The connected RPC client.
+
+
+
+
+
+
+connect(username: str = None,
+
+password: str = None) -> IPCClient or RPCClient
+Connect to vineyard via UNIX domain socket or TCP endpoint. This method normally
+usually no arguments, and will first tries to resolve IPC socket from the
+environment variable VINEYARD_IPC_SOCKET and connect to it. If it fails to
+establish a connection with vineyard server, the method will tries to resolve
+RPC endpoint from the environment variable VINEYARD_RPC_ENDPOINT . If both
+tries are failed, this method will try to resolve the configuration file that
+contains IPC socket and RPC endpoint from the environment variable
+VINEYARD_CONFIG , and then connect to the vineyard server with the
+resolved configuration.
+If above all are failed, this method will raise a ConnectionFailed
+exception.
+In rare cases, user may be not sure about if the IPC socket or RPC endpoint
+is available, i.e., the variable might be None
. In such cases this
+method can accept a None as arguments, and do resolution as described above.
+
+Parameters:
+username: str Username to login, default to None.
+
+password: str Password to login, default to None.
+
+
+
+Raises: ConnectionFailed
+
+
+
+
+
+
+
+
+vineyard. get_current_socket ( ) → str [source]
+Get current vineyard UNIX-domain socket established by vineyard.try_init()
.
+
+Raises:
+ValueError if vineyard is not initialized. –
+
+
+
+
+
+
+vineyard.deploy.local. start_vineyardd ( meta : str | None = 'etcd' , etcd_endpoints : str | None = None , etcd_prefix : str | None = None , vineyardd_path : str | None = None , size : str | None = '' , socket : str | None = None , rpc : str | None = True , rpc_socket_port : str | None = 9600 , debug = False ) → Generator [ Tuple [ Popen , str , str ] , None , None ] [source]
+Launch a local vineyard cluster.
+
+Parameters:
+
+meta – str, optional.
+Metadata backend, can be “etcd”, “redis” and “local”. Defaults to
+“etcd”.
+etcd_endpoint – str
+Launching vineyard using specified etcd endpoints. If not specified,
+vineyard will launch its own etcd instance.
+etcd_prefix – str
+Specify a common prefix to establish a local vineyard cluster.
+vineyardd_path – str
+Location of vineyard server program. If not specified, vineyard will
+use its own bundled vineyardd binary.
+size –
int
+The memory size limit for vineyard’s shared memory. The memory size
+can be a plain integer or as a fixed-point number using one of these
+suffixes:
+
+You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki.
+Defaults to “”, means not limited.
+For example, the following represent roughly the same value:
+128974848 , 129 k , 129 M , 123 Mi , 1 G , 10 Gi , ...
+
+
+
+socket –
str
+The UNIX domain socket socket path that vineyard server will listen on.
+Default is None.
+When the socket parameter is None, a random path under temporary directory
+will be generated and used.
+
+rpc_socket_port – int
+The port that vineyard will use to provided RPC service.
+debug – bool
+Whether print debug logs.
+
+
+Returns:
+Yields a tuple with the subprocess as the first element and the UNIX-domain
+IPC socket as the second element.
+
+Return type:
+(proc, socket)
+
+
+
+
+
+
+vineyard.deploy.distributed. start_vineyardd ( hosts = None , etcd_endpoints = None , vineyardd_path = None , size = '' , socket = '/var/run/vineyard.sock' , rpc_socket_port = 9600 , debug = False ) [source]
+Launch a local vineyard cluster in a distributed fashion.
+
+Parameters:
+
+hosts – list of str
+A list of machines to launch vineyard server.
+etcd_endpoint – str
+Launching vineyard using specified etcd endpoints. If not specified,
+vineyard will launch its own etcd instance.
+vineyardd_path – str
+Location of vineyard server program. If not specified, vineyard will
+use its own bundled vineyardd binary.
+size –
int
+The memory size limit for vineyard’s shared memory. The memory size
+can be a plain integer or as a fixed-point number using one of these
+suffixes:
+
+You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki.
+Defaults to “”, means not limited.
+For example, the following represent roughly the same value:
+128974848 , 129 k , 129 M , 123 Mi , 1 G , 10 Gi , ...
+
+
+
+socket – str
+The UNIX domain socket socket path that vineyard server will listen on.
+rpc_socket_port – int
+The port that vineyard will use to privode RPC service.
+debug – bool
+Whether print debug logs.
+
+
+
+
+
+
+
+vineyard.deploy.kubernetes. start_vineyardd ( namespace = 'vineyard' , size = '512Mi' , socket = '/var/run/vineyard.sock' , rpc_socket_port = 9600 , vineyard_image = 'vineyardcloudnative/vineyardd:latest' , vineyard_image_pull_policy = 'IfNotPresent' , vineyard_image_pull_secrets = None , k8s_client = None ) [source]
+Launch a vineyard cluster on kubernetes.
+
+Parameters:
+
+namespace – str
+namespace in kubernetes
+size –
int
+The memory size limit for vineyard’s shared memory. The memory size
+can be a plain integer or as a fixed-point number using one of these
+suffixes:
+
+You can also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki.
+For example, the following represent roughly the same value:
+128974848 , 129 k , 129 M , 123 Mi , 1 G , 10 Gi , ...
+
+
+
+socket – str
+The UNIX domain socket socket path that vineyard server will listen on.
+rpc_socket_port – int
+The port that vineyard will use to provide RPC service.
+k8s_client – kubernetes.client.api.ApiClient
+A kubernetes client. If not specified, vineyard will try to resolve the
+kubernetes configuration from current context.
+vineyard_image – str
+The docker image of vineyardd to launch the daemonset.
+vineyard_image_pull_policy – str
+The docker image pull policy of vineyardd.
+vineyard_image_pull_secrets – str
+The docker image pull secrets of vineyardd.
+
+
+Returns:
+A list of created kubernetes resources during the deploying process. The
+resources can be later release using delete_kubernetes_objects()
.
+
+
+
+
See also
+
vineyard.deploy.kubernetes.delete_kubernetes_objects
+
+
+
+
+
+vineyard.deploy.kubernetes. delete_kubernetes_objects ( targets , k8s_client = None , verbose = False , wait = False , timeout_seconds = 60 , ** kwargs ) [source]
+Delete the given kubernetes resources.
+
+Parameters:
+
+target – List
+List of Kubernetes objects
+k8s_client – The kubernetes client. If not specified, vineyard will try to resolve
+the kubernetes configuration from current context.
+verbose – bool
+Whether to print the deletion logs.
+wait – bool
+Whether to wait for the deletion to complete.
+timeout_seconds – int
+The timeout in seconds for waiting for the deletion to complete.
+
+
+
+
+
See also
+
vineyard.deploy.kubernetes.start_vineyardd
+vineyard.deploy.kubernetes.delete_kubernetes_object
+
+
+
+
+
+I/O Drivers
+
+
+vineyard.io. open ( path , * args , mode = 'r' , handlers = None , chunk_hook : Callable | None = None , ** kwargs ) [source]
+Open a path as a reader or writer, depends on the parameter mode
.
+If mode
is r
, it will open a stream for read, and open a
+stream for write when mode
is w
.
+
+Parameters:
+
+path (str ) – Path to open.
+mode (char ) – Mode about how to open the path, r
is for read and w
for write.
+handlers – A dict that will be filled with a handler
that contains the process
+handler of the underlying read/write process that can be joined using
+join
to capture the possible errors during the I/O proceeding.
+chunk_hook (callable , optional ) –
If the read/write target is a global dataframe (e.g., csv,
+orc, parquet, etc.), the hook will be called for each chunk
+to be read or write (usually a pyarrow.RecordBatch
).
+The hook should return a pyarrow.RecordBatch
object
+and should be stateless as the invoke order is not guaranteed.
+E.g.,
+def exchange_column ( batch ):
+ import pyarrow as pa
+
+ columns = batch . columns
+ first = columns [ 0 ]
+ second = columns [ 1 ]
+ columns = [ second , first ] + columns [ 2 :]
+ return pa . RecordBatch . from_arrays ( columns , schema = batch . schema )
+
+
+
+vineyard_ipc_socket (str ) – Vineyard’s IPC socket location.
+vineyard_endpoint (str ) – Vineyard’s RPC socket address.
+
+
+
+
+
+
+
+
+vineyard.io. read ( path , * args , handlers = None , accumulate = False , chunk_hook : Callable | None = None , ** kwargs ) [source]
+Open a path and read it as a single stream.
+
+Parameters:
+
+path (str ) – Path to read, the last reader registered for the scheme of
+the path will be used.
+handlers (list , optional ) – If handlers is not None, launched worker processes will be
+emplaced into the list for further customized job lifecycle
+management. Default is None.
+accumulate (bool , optional ) – If accumulate
is True, it will return a data frame,
+rather than dataframe stream. Default is False.
+chunk_hook (callable , optional ) –
If the read/write target is a global dataframe (e.g., csv,
+orc, parquet, etc.), the hook will be called for each chunk
+to be read or write (usually a pyarrow.RecordBatch
).
+The hook should return a pyarrow.RecordBatch
object
+and should be stateless as the invoke order is not guaranteed.
+E.g.,
+def exchange_column ( batch ):
+ import pyarrow as pa
+
+ columns = batch . columns
+ first = columns [ 0 ]
+ second = columns [ 1 ]
+ columns = [ second , first ] + columns [ 2 :]
+ return pa . RecordBatch . from_arrays ( columns , schema = batch . schema )
+
+
+
+vineyard_ipc_socket (str ) – The local or remote vineyard’s IPC socket location that the
+remote readers will use to establish connections with the
+vineyard server.
+vineyard_endpoint (str , optional ) – An optional address of vineyard’s RPC socket, which will be
+used for retrieving server’s information on the client side.
+If not provided, the vineyard_ipc_socket will be used, or
+it will tries to discovery vineyard’s IPC or RPC endpoints
+from environment variables.
+
+
+
+
+
+
+
+vineyard.io. write ( path , stream , * args , handlers = None , chunk_hook : Callable | None = None , ** kwargs ) [source]
+Write the stream to a given path.
+
+Parameters:
+
+path (str ) – Path to write, the last writer registered for the scheme of the path
+will be used.
+stream (vineyard stream ) – Stream that produces the data to write.
+handlers (list , optional ) – If handlers is not None, launched worker processes will be
+emplaced into the list for further customized job lifecycle
+management. Default is None.
+chunk_hook (callable , optional ) –
If the read/write target is a global dataframe (e.g., csv,
+orc, parquet, etc.), the hook will be called for each chunk
+to be read or write (usually a pyarrow.RecordBatch
).
+The hook should return a pyarrow.RecordBatch
object
+and should be stateless as the invoke order is not guaranteed.
+E.g.,
+def exchange_column ( batch ):
+ import pyarrow as pa
+
+ columns = batch . columns
+ first = columns [ 0 ]
+ second = columns [ 1 ]
+ columns = [ second , first ] + columns [ 2 :]
+ return pa . RecordBatch . from_arrays ( columns , schema = batch . schema )
+
+
+
+vineyard_ipc_socket (str ) – The local or remote vineyard’s IPC socket location that the remote
+readers will use to establish connections with the vineyard server.
+vineyard_endpoint (str , optional ) – An optional address of vineyard’s RPC socket, which will be used for
+retrieving server’s information on the client side. If not provided,
+the vineyard_ipc_socket will be used, or it will tries to discovery
+vineyard’s IPC or RPC endpoints from environment variables.
+
+
+
+
+
+
+
+Streams
+
+
+class vineyard.io.byte. ByteStream ( meta : ObjectMeta , params : Dict | None = None ) [source]
+
+
+
+
+class vineyard.io.dataframe. DataframeStream ( meta : ObjectMeta , params : Dict | None = None ) [source]
+
+
+
+
+class vineyard.io.recordbatch. RecordBatchStream ( meta : ObjectMeta , params : Dict [ str , Any ] | None = None ) [source]
+
+
+
+
+Interacting with the CSI Driver
+
+
+vineyard.csi. read ( path : str ) [source]
+Read vineyard object from path, and return python value.
+Notice, the API is only used for CSI driver.
+
+Parameters:
+path – str
+The path that represents a vineyard object.
+
+
+>>> arr = vineyard . read ( '/a/b/c/d/f' )
+>>> arr
+array([0, 1, 2, 3, 4, 5, 6, 7])
+
+
+
+Returns:
+A python object that return by the resolver, by resolving an vineyard object.
+
+
+
+
+
+
+vineyard.csi. write ( value : Any , path : str ) [source]
+Write python value to vineyard.
+Notice, the API is only used for CSI driver.
+
+Parameters:
+path – str
+The path that represents a vineyard object.
+
+
+>>> arr = np . arange ( 8 )
+>>> vineyard . write ( arr )
+
+
+
+
+
+
+
+Vineyard LLM KV Cache
+Before using the KV Cache, you need to install the vineyard-llm
package.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/objects.inv b/objects.inv
new file mode 100644
index 0000000000..034a97010d
Binary files /dev/null and b/objects.inv differ
diff --git a/search.html b/search.html
new file mode 100644
index 0000000000..89ed5a3f5a
--- /dev/null
+++ b/search.html
@@ -0,0 +1,450 @@
+
+
+
+
+
+
+
+
+
+Search - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+
+
+
Error
+
+ Please activate JavaScript to enable the search functionality.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/searchindex.js b/searchindex.js
new file mode 100644
index 0000000000..44afba01cb
--- /dev/null
+++ b/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({"docnames": ["cncf/2022-vineyard-annual", "cncf/2023-vineyard-annual", "docs", "notes/architecture", "notes/cloud-native/deploy-kubernetes", "notes/cloud-native/vineyard-operator", "notes/cloud-native/vineyardctl", "notes/developers", "notes/developers/build-from-source", "notes/developers/contributing", "notes/developers/faq", "notes/developers/roadmap", "notes/developers/troubleshooting", "notes/getting-started", "notes/integration-bigdata", "notes/integration-orchestration", "notes/integration/airflow", "notes/integration/dask", "notes/integration/kedro", "notes/integration/ml", "notes/integration/ray", "notes/key-concepts", "notes/key-concepts/data-accessing", "notes/key-concepts/io-drivers", "notes/key-concepts/objects", "notes/key-concepts/streams", "notes/key-concepts/vcdl", "notes/references", "notes/references/cpp-api", "notes/references/crds", "notes/references/python-api", "tutorials/data-processing", "tutorials/data-processing/accelerate-data-sharing-in-kedro", "tutorials/data-processing/distributed-learning", "tutorials/data-processing/gpu-memory-sharing", "tutorials/data-processing/python-sharedmemory", "tutorials/data-processing/using-objects-python", "tutorials/extending", "tutorials/extending/define-datatypes-cpp", "tutorials/extending/define-datatypes-python", "tutorials/kubernetes", "tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes", "tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver", "tutorials/kubernetes/ml-pipeline-mars-pytorch", "tutorials/kubernetes/using-vineyard-operator", "tutorials/kubernetes/vineyard-on-fluid", "tutorials/tutorials"], "filenames": ["cncf/2022-vineyard-annual.md", "cncf/2023-vineyard-annual.md", "docs.rst", "notes/architecture.rst", "notes/cloud-native/deploy-kubernetes.rst", "notes/cloud-native/vineyard-operator.rst", "notes/cloud-native/vineyardctl.md", "notes/developers.rst", "notes/developers/build-from-source.rst", "notes/developers/contributing.rst", "notes/developers/faq.rst", "notes/developers/roadmap.rst", "notes/developers/troubleshooting.rst", "notes/getting-started.rst", "notes/integration-bigdata.rst", "notes/integration-orchestration.rst", "notes/integration/airflow.rst", "notes/integration/dask.rst", "notes/integration/kedro.md", "notes/integration/ml.rst", "notes/integration/ray.rst", "notes/key-concepts.rst", "notes/key-concepts/data-accessing.rst", "notes/key-concepts/io-drivers.rst", "notes/key-concepts/objects.rst", "notes/key-concepts/streams.rst", "notes/key-concepts/vcdl.rst", "notes/references.rst", "notes/references/cpp-api.rst", "notes/references/crds.md", "notes/references/python-api.rst", "tutorials/data-processing.rst", "tutorials/data-processing/accelerate-data-sharing-in-kedro.rst", "tutorials/data-processing/distributed-learning.ipynb", "tutorials/data-processing/gpu-memory-sharing.rst", "tutorials/data-processing/python-sharedmemory.rst", "tutorials/data-processing/using-objects-python.rst", "tutorials/extending.rst", "tutorials/extending/define-datatypes-cpp.rst", "tutorials/extending/define-datatypes-python.rst", "tutorials/kubernetes.rst", "tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes.rst", "tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.rst", "tutorials/kubernetes/ml-pipeline-mars-pytorch.rst", "tutorials/kubernetes/using-vineyard-operator.rst", "tutorials/kubernetes/vineyard-on-fluid.rst", "tutorials/tutorials.rst"], "titles": ["Vineyard 2022 Annual Review", "Vineyard 2023 Annual Review", "Why bother?", "Architecture", "Deploy on Kubernetes", "Vineyard Operator", "vineyardctl
", "Getting Involved", "Building from source", "Contributing to vineyard", "Frequently Asked Questions", "Roadmap", "Troubleshooting", "Getting Started", "Big-data on Vineyard", "Workflow orchestration", "Airflow on Vineyard", "Dask on Vineyard", "Kedro Vineyard Plugin", "Machine Learning with Vineyard", "Ray on Vineyard", "Key Concepts", "Data Accessing", "I/O Drivers", "Objects", "Streams in Vineyard", "Code Generation for Boilerplate", "API Reference", "C++ API Reference", "API Reference", "Python API Reference", "Data processing", "Accelerate Data Sharing in Kedro", "Distributed Learning with Vineyard", "Sharing GPU Memory", "multiprocessing.shared_memory
in Python", "Sharing Python Objects with Vineyard", "Extending vineyard", "Defining Custom Data Types in C++", "Define Data Types in Python", "Vineyard on Kubernetes", "Data sharing with Vineyard on Kubernetes", "Efficient data sharing in Kubeflow with Vineyard CSI Driver", "Machine learning with Vineyard on Kubernetes", "Use vineyard operator", "Vineyard + Fluid in Action: Train a Linear Regression Model on ACK", "Data processing"], "terms": {"i": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 21, 22, 26, 28, 29, 31, 32, 33, 34, 35, 36, 38, 39, 41, 42, 43, 44, 45, 46], "an": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 16, 17, 18, 19, 21, 22, 25, 26, 28, 29, 30, 31, 34, 38, 40, 43, 44, 45, 46], "memori": [0, 1, 2, 5, 6, 10, 11, 12, 13, 16, 17, 18, 19, 22, 24, 28, 29, 31, 32, 33, 35, 36, 38, 39, 42, 45, 46], "immut": [0, 1, 2, 3, 10, 11, 13, 21, 25, 28, 30, 34], "data": [0, 1, 4, 5, 6, 8, 10, 11, 13, 15, 16, 17, 18, 21, 23, 25, 26, 29, 30, 34, 36, 37, 40, 43, 44], "manag": [0, 1, 2, 3, 4, 5, 10, 11, 13, 16, 17, 22, 24, 29, 30, 40, 42, 43, 44, 46], "provid": [0, 1, 2, 3, 5, 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 28, 30, 33, 34, 37, 38, 42, 44, 46], "out": [0, 1, 8, 9, 18, 33, 44], "box": [0, 1], "high": [0, 1, 2, 5, 6, 10, 11, 13, 15, 24, 29, 30], "level": [0, 1, 2, 10, 13, 22, 24, 30], "abstract": [0, 1, 5, 10, 13, 21, 24, 25, 34], "zero": [0, 1, 2, 10, 13, 16, 22, 28, 31, 36, 38, 39, 44, 46], "copi": [0, 1, 2, 3, 10, 11, 13, 16, 22, 25, 28, 30, 31, 32, 34, 36, 38, 39, 42, 45, 46], "share": [0, 1, 4, 5, 8, 10, 11, 12, 14, 15, 16, 18, 19, 21, 22, 24, 25, 26, 28, 29, 31, 33, 35, 38, 39, 40, 45, 46], "distribut": [0, 1, 2, 5, 6, 8, 9, 10, 11, 13, 14, 17, 29, 30, 31, 36, 39, 43, 46], "big": [0, 1, 2, 13, 16, 33, 40, 46], "task": [0, 1, 2, 4, 5, 6, 16, 17, 18, 22, 24, 31, 32, 33, 37, 42, 46], "graph": [0, 1, 2, 3, 8, 10, 16, 24, 28, 37, 38, 46], "analyt": [0, 1, 2, 10, 13, 16], "numer": [0, 1, 2, 3, 19, 24, 33, 38, 43], "comput": [0, 1, 2, 3, 5, 11, 13, 14, 16, 17, 21, 22, 23, 24, 25, 28, 29, 31, 33, 34, 37, 39, 41, 46], "machin": [0, 1, 2, 3, 10, 14, 17, 24, 30, 31, 32, 33, 36, 39, 40, 42, 45, 46], "learn": [0, 1, 2, 3, 10, 11, 13, 14, 31, 32, 40, 42, 44, 45, 46], "effici": [0, 1, 3, 4, 5, 13, 15, 16, 18, 22, 24, 25, 31, 33, 37, 38, 40, 46], "across": [0, 1, 2, 3, 5, 10, 15, 16, 17, 22, 24, 36, 38, 39, 43], "differ": [0, 1, 2, 3, 5, 10, 11, 12, 16, 17, 22, 23, 24, 30, 32, 33, 34, 35, 38, 39, 42, 43], "system": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 13, 16, 18, 21, 24, 32, 33, 42, 43, 44, 45], "object": [0, 1, 2, 4, 9, 10, 11, 12, 15, 16, 18, 19, 21, 26, 29, 31, 33, 34, 40, 41, 42, 44, 45, 46], "e": [0, 1, 2, 3, 5, 6, 10, 11, 12, 13, 15, 18, 19, 23, 24, 25, 28, 30, 33, 34, 38], "g": [0, 1, 2, 3, 5, 6, 10, 11, 12, 13, 15, 18, 23, 24, 25, 28, 30, 33, 34, 38], "tensor": [0, 1, 2, 3, 5, 6, 9, 10, 16, 17, 22, 28, 30, 33, 36, 37, 38, 39, 44, 46], "tabl": [0, 1, 2, 6, 30, 37, 38, 43, 46], "polyglot": [0, 1], "support": [0, 1, 3, 5, 6, 8, 9, 10, 11, 12, 16, 19, 22, 23, 28, 29, 30, 31, 34, 42, 44, 46], "current": [0, 1, 3, 4, 5, 6, 16, 28, 30, 44, 45], "includ": [0, 1, 2, 3, 5, 6, 9, 11, 14, 16, 24, 27, 28, 29, 30, 33, 38, 44, 45], "c": [0, 1, 3, 4, 5, 6, 8, 9, 11, 13, 19, 24, 25, 26, 27, 30, 34, 37, 41, 42, 43, 44, 46], "python": [0, 1, 2, 6, 9, 11, 15, 16, 24, 27, 31, 32, 33, 37, 38, 41, 44, 46], "java": [0, 1, 38, 44], "built": [0, 1, 5, 6, 8, 9, 18, 19, 22, 25, 28, 30, 37, 38, 42, 46], "stream": [0, 5, 6, 10, 13, 21, 23, 29], "access": [0, 3, 6, 10, 11, 13, 16, 21, 24, 28, 30, 32, 34, 36, 38, 39, 42, 44, 45], "pipelin": [0, 1, 2, 3, 10, 15, 16, 18, 19, 25, 28, 31, 40, 46], "extens": [0, 3, 24, 38], "driver": [0, 1, 2, 3, 6, 13, 21, 24, 29], "framework": [0, 5, 10, 11, 14, 19, 33, 39], "set": [0, 5, 6, 7, 8, 9, 10, 12, 13, 17, 22, 24, 28, 29, 32, 33, 38, 43, 44, 45], "elimin": [0, 2, 15, 17, 38], "boilerpl": [0, 2, 4, 13, 28, 38], "part": [0, 2, 3, 5, 11, 24, 33, 36, 38, 45], "engin": [0, 1, 3, 5, 9, 10, 11, 13, 14, 15, 21, 22, 24, 25, 26, 29, 31, 33, 34, 37, 46], "o": [0, 3, 5, 6, 8, 10, 11, 13, 15, 17, 18, 21, 28, 32, 33, 41], "serial": [0, 2, 5, 10, 15, 16, 18, 24, 25, 30, 32, 45], "checkpoint": [0, 33], "align": [0, 1, 2, 10], "build": [0, 1, 3, 4, 6, 7, 13, 18, 19, 24, 28, 30, 32, 36, 38, 39, 42, 43], "kubernet": [0, 1, 5, 6, 10, 11, 13, 15, 29, 30, 31, 42, 45], "deploi": [0, 1, 2, 5, 8, 10, 11, 13, 22, 29, 30, 31, 40, 41, 43, 46], "scale": [0, 1, 2, 3, 9, 15, 16, 18, 32, 42], "ar": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 17, 18, 21, 22, 23, 24, 26, 28, 29, 30, 32, 33, 34, 38, 41, 42, 43, 44, 45], "observ": [0, 1, 2, 5, 12, 32, 38], "crd": [0, 1, 4, 5, 6, 11, 29, 42, 43, 44], "make": [0, 1, 4, 5, 8, 9, 10, 11, 16, 24, 28, 29, 30, 32, 33, 35, 36, 39, 42, 43, 44], "possibl": [0, 1, 5, 10, 28, 30, 33], "intens": [0, 1, 2, 31, 37, 46], "workflow": [0, 1, 2, 4, 5, 13, 14, 16, 18, 31, 40, 44, 45, 46], "cloud": [0, 1, 2, 6, 10, 13, 16, 45], "nativ": [0, 1, 2, 6, 10, 13, 16, 24, 45], "infrastructur": [0, 1, 2, 3, 13, 16, 21], "awar": [0, 1, 2, 11, 13, 22, 24, 35, 40, 46], "schedul": [0, 1, 2, 3, 4, 10, 11, 13, 16, 17, 18, 22, 24, 33, 40, 41, 43, 44, 46], "plugin": [0, 1, 6, 10, 11, 32, 43, 45], "design": [0, 1, 2, 3, 5, 9, 10, 11, 13, 16, 21, 22, 23, 24, 28, 33, 38, 42, 44, 45], "which": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 22, 23, 24, 28, 29, 30, 33, 34, 36, 39, 42, 44, 45], "environ": [0, 1, 2, 5, 6, 7, 8, 9, 16, 18, 21, 28, 29, 30, 33, 39, 45], "wa": [0, 1, 7, 22, 36, 39], "accept": [0, 1, 7, 30], "sandbox": [0, 1, 2, 7, 11], "apr": 0, "28th": 0, "2021": [0, 7, 11], "link": [0, 1, 6, 8, 24], "your": [0, 1, 5, 6, 7, 10, 12, 13, 16, 18, 32, 42, 43, 44, 45], "": [0, 1, 2, 3, 4, 5, 6, 9, 10, 13, 16, 21, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 35, 37, 38, 39, 41, 42, 43, 44, 45, 46], "page": [0, 1, 6, 10, 12, 21, 27], "we": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 35, 36, 38, 39, 41, 42, 43, 44, 45, 46], "look": [0, 1, 6, 18, 30, 42], "sign": [0, 1], "consist": [0, 1, 2, 3, 5, 9, 17, 24, 25, 33, 36, 38, 43, 44], "increas": [0, 1, 2, 12, 24, 28], "contribut": [0, 1], "activ": [0, 1, 5, 6, 16, 17, 33], "pleas": [0, 1, 5, 6, 8, 9, 10, 11, 12, 17, 18, 22, 25, 27, 34, 35, 38, 41, 43, 44, 45], "feel": [0, 1, 9, 10], "free": [0, 1, 9, 10, 34], "add": [0, 1, 4, 5, 6, 9, 24, 28, 30, 32, 42, 44, 45], "commentari": [0, 1], "colour": [0, 1], "number": [0, 1, 5, 6, 9, 28, 29, 30, 33, 45], "see": [0, 1, 5, 6, 8, 13, 16, 18, 22, 24, 26, 28, 30, 32, 33, 35, 41], "stargaz": [0, 1], "fork": [0, 1, 9, 25, 28], "http": [0, 1, 4, 5, 6, 8, 9, 10, 16, 18, 28, 32, 42, 43, 44, 45], "io": [0, 1, 2, 4, 5, 6, 8, 9, 17, 18, 23, 25, 30, 32, 41, 42, 43, 44, 45], "d": [0, 1, 13, 17, 30, 33, 41], "3": [0, 1, 4, 5, 6, 8, 12, 13, 17, 18, 19, 30, 32, 33, 38, 41, 42, 43], "star": [0, 1], "repositori": [0, 1, 5, 9, 33, 43, 44, 45], "orgid": [0, 1], "1": [0, 1, 5, 6, 9, 10, 13, 16, 17, 18, 19, 22, 23, 24, 25, 30, 32, 33, 34, 36, 38, 39, 41, 42, 43], "from": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 16, 17, 18, 22, 24, 25, 27, 28, 30, 32, 34, 35, 36, 38, 39, 41, 42, 44, 45], "now": [0, 1, 5, 33, 38, 43, 44], "2y": [0, 1], "commit": [0, 1, 7], "per": [0, 1], "week": [0, 1, 11], "group": [0, 1, 29, 39], "var": [0, 1, 5, 6, 12, 13, 30, 36, 39, 44, 45], "period": [0, 1], "w": [0, 1, 30], "repogroup": [0, 1], "all": [0, 1, 4, 5, 6, 8, 9, 10, 24, 27, 28, 29, 30, 32, 33, 41, 42, 43, 44, 45], "6m": [0, 1], "contributor": [0, 1], "compani": [0, 1], "7": [0, 1, 5, 13, 19, 30, 32, 33, 42, 44, 45], "d7": [0, 1], "repogroup_nam": [0, 1], "1y": [0, 1], "The": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 15, 18, 19, 21, 22, 23, 24, 26, 28, 29, 30, 32, 33, 34, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46], "commun": [0, 1, 2, 3, 7, 9, 16, 22, 25, 28, 44], "ha": [0, 1, 5, 6, 7, 8, 9, 10, 24, 25, 28, 29, 30, 32, 38, 44], "grown": [0, 1], "sinc": [0, 1, 10, 28, 30, 33, 38, 42], "enter": [0, 1, 32, 43, 44], "11": [0, 5, 18, 32, 41, 42, 45], "26": [0, 1, 5], "github": [0, 1, 4, 5, 6, 7, 8, 9, 18, 32, 42, 45], "300": 0, "600": [0, 1, 6, 45], "20": [0, 8, 17, 32, 42, 45], "80": [0, 1, 5, 6, 22, 42], "organ": [0, 8, 16, 24], "12": [0, 5, 6, 18, 33, 34, 41], "how": [0, 1, 5, 10, 13, 17, 18, 21, 24, 28, 29, 30, 31, 32, 33, 38, 40, 41, 42, 44, 45, 46], "mani": [0, 1, 2, 5, 12, 22, 28, 29, 33], "do": [0, 1, 5, 6, 8, 9, 10, 11, 28, 30, 32, 41, 42, 43], "you": [0, 1, 4, 5, 6, 7, 8, 9, 10, 12, 13, 17, 18, 21, 22, 25, 29, 30, 32, 38, 40, 41, 42, 43, 44, 45, 46], "have": [0, 1, 3, 4, 5, 6, 7, 12, 13, 17, 18, 19, 22, 23, 28, 30, 32, 33, 35, 38, 39, 41, 42, 43, 44], "organis": [0, 1], "thei": [0, 1, 6, 11, 17, 23, 28, 32, 33], "exist": [0, 1, 2, 3, 5, 6, 9, 21, 28, 30, 31, 33, 38, 41, 46], "file": [0, 1, 3, 5, 6, 9, 11, 18, 23, 28, 29, 30, 32, 33, 41, 42, 44, 45], "appropri": [0, 1, 2, 5, 43], "2": [0, 1, 5, 6, 9, 13, 16, 17, 18, 19, 22, 24, 25, 30, 32, 33, 38, 41, 42, 43], "committ": [0, 1], "list": [0, 1, 5, 6, 11, 13, 17, 18, 19, 22, 24, 25, 28, 29, 30, 33, 41, 43], "initi": [0, 1, 6, 10, 13, 17, 28, 30, 33, 34, 38, 42, 45], "name": [0, 1, 4, 5, 6, 13, 17, 18, 19, 24, 28, 29, 30, 32, 33, 35, 38, 41, 42, 43, 44, 45], "id": [0, 1, 5, 6, 8, 16, 19, 22, 24, 25, 28, 29, 30, 32, 38, 41, 43, 44, 45], "affili": [0, 1], "email": [0, 1], "tao": [0, 1, 2], "he": [0, 1, 2], "sighingnow": [0, 1], "alibaba": [0, 1, 45], "linzhu": [0, 1], "ht": [0, 1], "inc": [0, 1], "com": [0, 1, 4, 5, 6, 8, 9, 18, 32, 42, 43, 44, 45], "xiaojian": [0, 1], "luo": [0, 1], "luoxiaojian": [0, 1], "lxj193371": [0, 1], "wenyuan": [0, 1, 2], "yu": [0, 1, 2], "wenyuanyu": [0, 1], "ywy": [0, 1], "weibin": [0, 1], "zeng": [0, 1], "acezen": [0, 1], "qiaozi": [0, 1], "zwb": [0, 1], "siyuan": [0, 1], "zhang": [0, 1], "siyuan0322": [0, 1], "siyuanzhang": [0, 1], "zsy": [0, 1], "diwen": [0, 1, 2], "zhu": [0, 1, 2], "andydiwenzhu": [0, 1], "zdw": [0, 1], "new": [0, 2, 3, 5, 6, 9, 18, 21, 25, 28, 30, 38, 42, 43], "thi": [0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 14, 16, 17, 18, 19, 22, 24, 25, 26, 28, 30, 32, 33, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46], "year": [0, 1, 11], "ke": [0, 1, 2], "meng": [0, 1, 2], "septicmk": [0, 1], "mengk": [0, 1], "mk": [0, 1], "lihong": [0, 1], "lin": [0, 1], "linlih": [0, 1], "pku": [0, 1], "linlh": [0, 1], "stu": [0, 1], "edu": [0, 1, 45], "cn": [0, 1, 45], "pei": [0, 1], "li": [0, 1, 2, 28], "peilii": [0, 1], "cmu": [0, 1], "peili": [0, 1], "dev": [0, 1, 5, 8, 9, 32, 42], "gmail": [0, 1], "what": [0, 1, 5, 10, 11, 16, 24], "know": [0, 1, 29, 44], "about": [0, 1, 5, 10, 11, 13, 16, 18, 25, 29, 30, 32, 33, 34, 42, 44, 45], "chang": [0, 1, 3, 11, 13, 30, 32, 34, 42], "last": [0, 1, 28, 30, 33, 44], "join": [0, 1, 7, 13, 25, 30, 43], "If": [0, 1, 4, 5, 6, 7, 8, 9, 10, 12, 13, 19, 21, 28, 29, 30, 32, 41, 42, 43, 44, 45], "can": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46], "end": [0, 1, 3, 10, 11, 16, 28, 32, 33, 45], "user": [0, 1, 2, 3, 5, 6, 10, 11, 12, 13, 15, 16, 21, 22, 23, 24, 28, 30, 31, 33, 36, 37, 38, 39, 43, 46], "so": [0, 1, 5, 6, 10, 23, 28, 29, 33, 42, 43, 44], "sever": [0, 5, 6, 11, 23, 24, 29, 43, 44], "case": [0, 9, 10, 12, 19, 22, 24, 25, 30, 31, 35, 39, 46], "where": [0, 1, 2, 3, 5, 10, 12, 13, 16, 17, 18, 22, 28, 30, 33, 36, 38, 39, 40, 41, 46], "been": [0, 1, 5, 7, 8, 9, 10, 22, 28, 30, 44], "both": [0, 1, 3, 5, 10, 11, 17, 22, 28, 30, 31, 34, 44, 46], "test": [0, 1, 5, 6, 8, 10, 11, 18, 25, 32, 33, 41, 42, 43, 44, 45], "product": [0, 1, 2, 9, 43], "graphscop": [0, 1, 2, 22, 24, 43], "stage": [0, 1, 16, 45], "open": [0, 7, 8, 10, 11, 17, 23, 28, 30, 42, 44, 45], "sourc": [0, 1, 7, 11, 13, 14, 23, 28, 30, 38, 42, 45], "process": [0, 1, 2, 3, 5, 9, 10, 11, 13, 14, 16, 17, 22, 23, 24, 26, 28, 29, 30, 33, 34, 36, 38, 39, 43, 45], "platform": [0, 1, 9, 11, 14, 16, 45], "us": [0, 1, 3, 4, 5, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21, 23, 24, 27, 28, 29, 30, 31, 32, 33, 34, 36, 38, 39, 41, 42, 43, 46], "storag": [0, 2, 3, 5, 6, 11, 16, 18, 21, 25, 29, 33, 40, 44, 46], "weilaisudu": 0, "transit": [0, 1], "behind": [0, 24], "mar": [0, 2, 22, 24, 43], "scientif": 0, "numpi": [0, 11, 13, 16, 22, 25, 30, 36, 39, 41, 44, 45], "panda": [0, 2, 11, 13, 15, 16, 18, 19, 22, 25, 33, 41, 45], "like": [0, 1, 3, 5, 6, 8, 10, 11, 13, 15, 16, 18, 24, 28, 30, 34, 38, 42], "api": [0, 3, 5, 11, 13, 16, 22, 24, 25, 33, 34, 42], "actor": 0, "chunk": [0, 5, 10, 13, 17, 22, 24, 25, 28, 30], "esrf": 0, "joint": 0, "research": [0, 9], "facil": 0, "situat": [0, 10, 28, 38], "franc": 0, "one": [0, 1, 6, 11, 19, 22, 25, 28, 30, 33, 41, 42, 43, 44], "biggest": 0, "x": [0, 17, 32, 33, 44, 45], "rai": [0, 22], "scienc": [0, 1], "europ": 0, "bliss": 0, "softwar": [0, 8, 9], "serv": [0, 1, 10, 11, 13, 14, 16, 25, 31, 38, 40, 46], "between": [0, 1, 2, 3, 4, 5, 6, 10, 11, 16, 18, 22, 24, 26, 29, 31, 32, 33, 34, 39, 46], "sensor": 0, "job": [0, 2, 3, 10, 11, 22, 29, 30, 40, 43, 44, 46], "pingan": [0, 1], "larg": [0, 1, 2, 3, 10, 11, 12, 15, 16, 18, 22, 24, 32], "fin": [0, 1], "tech": [0, 1], "china": [0, 1], "dataset": [0, 1, 13, 15, 17, 18, 19, 24, 31, 32, 33, 43, 46], "among": [0, 1, 9, 10, 16, 17, 18, 42], "also": [0, 1, 4, 5, 6, 7, 8, 13, 16, 17, 18, 22, 24, 26, 28, 30, 33, 42, 43, 44], "integr": [0, 1, 2, 5, 9, 11, 13, 14, 15, 16, 17, 19, 21, 22, 24, 26, 29, 31, 37, 38, 39, 40, 42, 46], "apach": [0, 1, 8, 9, 11, 15, 16], "airflow": [0, 1, 11, 15], "orchestr": [0, 1, 4, 5, 16, 32, 40, 46], "wide": 0, "publish": [0, 1], "astronom": 0, "registri": [0, 3, 6, 18, 24, 32, 37, 42, 43, 46], "receiv": [0, 3, 6, 19, 25], "much": [0, 4], "feedback": [0, 1], "haven": [0, 1], "t": [0, 1, 3, 4, 5, 6, 9, 10, 13, 26, 28, 30, 38, 42, 44], "track": [0, 1], "actual": [0, 1, 23, 24, 30], "yet": [0, 1, 6, 28, 30], "perform": [0, 1, 3, 5, 11, 12, 15, 16, 18, 22, 24, 25, 28, 31, 45, 46], "against": [0, 1, 6, 28, 30], "its": [0, 1, 2, 4, 5, 9, 10, 16, 17, 21, 22, 24, 28, 30, 38, 39, 40, 42, 46], "won": [0, 1, 28, 30], "penal": [0, 1], "good": [0, 1, 41], "reason": [0, 1, 42], "successfulli": [0, 1, 5, 7, 8, 10, 18, 32, 38, 41, 42, 44], "archiv": [0, 1, 34], "bring": [0, 1, 2, 11], "valu": [0, 1, 2, 3, 5, 6, 10, 12, 13, 16, 17, 19, 22, 24, 28, 30, 33, 35, 36, 39], "shown": [0, 5, 9, 22, 23, 42, 44], "gain": [0, 1, 18], "intern": [0, 6, 10, 21, 28, 30, 38], "involv": [0, 2, 3, 5, 16, 18, 22, 25, 26, 31, 38, 46], "etl": [0, 16], "our": [0, 1, 7, 8, 9, 10, 11, 16, 18, 24, 32, 33, 38, 39], "hasn": 0, "becom": [0, 1, 2, 3, 4, 5, 18, 24, 28, 30, 32, 33, 35, 38], "still": [0, 1, 3, 10, 18, 28, 30, 32, 34, 42], "aim": [0, 11, 33], "more": [0, 1, 3, 5, 6, 10, 11, 12, 13, 16, 18, 22, 24, 25, 28, 30, 32, 35, 41, 42, 43, 44], "specif": [0, 1, 2, 3, 5, 6, 10, 11, 18, 23, 24, 28, 29, 30, 36, 38, 39, 42], "ll": [0, 18], "keep": [0, 1, 5], "move": [0, 1, 3, 16, 22, 28, 38], "toward": [0, 1], "follow": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17, 18, 23, 24, 26, 27, 28, 30, 32, 33, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46], "next": [0, 1, 4, 5, 6, 9, 10, 18, 25, 29, 32, 33, 38, 42, 45], "cross": [0, 2, 3, 10, 26, 33], "improv": [0, 1, 7, 9, 10, 11, 24, 31, 46], "paradigm": [0, 24], "applic": [0, 1, 2, 3, 5, 10, 11, 16, 18, 24, 33, 41, 42], "work": [0, 1, 4, 6, 10, 11, 12, 15, 16, 18, 32, 38], "togeth": 0, "By": [0, 3, 12, 13, 24, 30, 31, 37, 46], "help": [0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 13, 28, 30, 33, 38, 39, 45], "workload": [0, 1, 2, 3, 4, 5, 10, 11, 16, 29, 30, 33, 41], "better": [0, 11, 32], "need": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 15, 17, 18, 24, 28, 29, 30, 32, 34, 38, 42, 43, 44, 45], "engag": [0, 1, 7], "show": [0, 5, 6, 9, 32, 41, 42, 45], "ad": [0, 1, 2, 3, 11, 19, 22, 28, 35, 38, 44], "achiev": [0, 1, 10, 13, 16, 22, 28, 45], "upcom": [0, 1], "incredibli": [0, 1], "benefit": [0, 1, 10, 11, 18, 42], "believ": [0, 1, 16], "critic": [0, 1], "success": [0, 1, 2, 5, 9, 13, 28], "submit": [0, 18, 32, 42, 45], "propos": 0, "kubecon": [0, 1], "confer": [0, 1, 2], "past": 0, "got": [0, 44], "reject": 0, "hope": [0, 1], "could": [0, 1, 2, 4, 5, 6, 8, 9, 10, 11, 25, 28, 30, 38, 39, 44], "opportun": [0, 1, 11, 16], "introduc": [0, 1, 6, 11, 45], "border": [0, 1], "think": [0, 1], "meet": [0, 1], "criteria": [0, 1], "further": [0, 1, 5, 11, 24, 30, 38, 43], "explor": [0, 1, 2, 5, 13, 25, 27, 44, 45], "get": [0, 1, 4, 5, 8, 11, 17, 18, 19, 21, 22, 23, 25, 28, 30, 32, 33, 36, 39, 41, 42, 43, 44, 45], "forward": [0, 1, 6, 32, 33, 42], "futur": [0, 1, 7, 34, 44], "address": [1, 3, 6, 9, 10, 11, 12, 24, 28, 30, 33], "ineffici": [1, 18], "go": [1, 3, 8, 11, 18, 43], "rust": [1, 3, 11, 44], "seamless": [1, 5, 9, 13, 15, 25, 37, 39, 40, 46], "cluster": [1, 3, 10, 11, 18, 22, 24, 28, 29, 33, 36, 39, 41, 43], "deploy": [1, 3, 4, 5, 9, 10, 11, 12, 28, 29, 32, 33, 41, 42, 43, 44], "flyte": 1, "kubeflow": 1, "unifi": [1, 2], "intrus": [1, 15, 18, 31, 32, 46], "experi": [1, 15, 31, 33, 46], "leverag": [1, 2, 3, 18, 22, 34, 37, 46], "effort": [1, 2, 5, 6, 7, 30], "migrat": [1, 2, 3, 5, 9, 10, 13, 16, 18, 22, 28, 30, 45], "batch": [1, 10, 17, 19, 28, 29, 30, 33, 43], "40": [1, 33, 42], "750": 1, "110": 1, "8": [1, 5, 6, 13, 17, 18, 19, 30, 32, 36, 39, 42, 44, 45], "releas": [1, 5, 18, 28, 30, 32, 42, 44], "5": [1, 6, 13, 18, 19, 28, 30, 32, 33, 42, 44, 45], "month": [1, 11], "major": [1, 11, 23, 28, 30], "languag": [1, 2, 3, 13, 24, 26, 44], "sdk": [1, 3, 11, 27, 38], "collabor": 1, "extern": [1, 2, 3, 4, 5, 13, 16, 18, 29, 30, 33, 44], "enabl": [1, 2, 3, 5, 6, 9, 10, 11, 13, 15, 16, 17, 19, 22, 24, 25, 28, 29, 30, 31, 39, 46], "seamlessli": [1, 5, 13, 14, 15, 16, 17, 24, 31, 40, 46], "interoper": [1, 13], "kedro": [1, 15, 31, 46], "attent": 1, "hive": 1, "let": [1, 2, 33, 38, 43, 44], "easili": [1, 2, 3, 8, 9, 15, 22, 24, 33, 37, 46], "connect": [1, 3, 6, 10, 12, 17, 18, 22, 24, 25, 28, 30, 33, 36, 38, 39, 41, 45], "tradit": [1, 10], "hadoop": 1, "ecosystem": [1, 11, 13, 37, 46], "emerg": 1, "ai": [1, 2, 16, 45], "pydata": 1, "A": [1, 2, 5, 8, 9, 10, 11, 13, 18, 19, 24, 25, 28, 30, 33, 36, 39, 41, 42, 44], "version": [1, 6, 9, 10, 11, 27, 28, 30, 41, 42, 44, 45], "csi": [1, 11, 29], "optim": [1, 2, 4, 16, 17, 24, 33, 42], "step": [1, 4, 5, 8, 16, 17, 18, 26, 33, 38, 41, 42, 43], "onli": [1, 3, 5, 6, 9, 10, 16, 19, 22, 24, 28, 29, 30, 33, 42, 45], "minor": [1, 11, 28, 30], "code": [1, 2, 7, 8, 11, 12, 13, 15, 18, 23, 28, 31, 33, 34, 38, 39, 41, 42, 43, 45, 46], "conduct": 1, "seri": [1, 18], "around": 1, "paper": 1, "sigmod": [1, 2], "top": [1, 9, 14, 30, 37, 46], "tier": 1, "lei": [1, 2], "wang": [1, 2], "ye": [1, 2, 10], "cao": [1, 2], "sanhong": [1, 2], "jingren": [1, 2], "zhou": [1, 2], "acm": [1, 2], "sig": [1, 2, 6, 44], "industri": [1, 2], "dl": [1, 32], "org": [1, 5, 8, 16, 28], "doi": 1, "10": [1, 4, 5, 6, 17, 22, 25, 32, 33, 41, 42, 44], "1145": 1, "3589780": 1, "dashanji": 1, "caoy": [1, 43], "shumin": 1, "yuan": 1, "vegetableysm": 1, "yuanshumin": 1, "ysm": 1, "denghao": 1, "lidh15": 1, "lidhrandom": 1, "two": [1, 4, 5, 6, 10, 11, 13, 17, 19, 22, 25, 26, 28, 30, 33, 36, 38, 39, 41, 42, 44, 45], "startdt": 1, "qidianyun": 1, "startup": [1, 12], "centric": 1, "datafram": [1, 2, 3, 5, 6, 10, 13, 15, 16, 17, 18, 22, 25, 28, 30, 33, 38, 41, 43, 45], "artifact": [1, 11, 32, 43], "compos": [1, 3, 10, 28, 34], "pass": [1, 5, 13, 19, 24, 28, 30, 34], "eager": 1, "evalu": [1, 18, 33, 45], "statu": [1, 4, 5, 6, 18, 28, 30, 32, 38, 41, 42, 43, 44], "besid": [1, 5, 6], "notic": [1, 5, 6, 23, 30, 38, 42, 43], "some": [1, 5, 6, 11, 18, 22, 24, 25, 28, 29, 39, 41, 42], "other": [1, 3, 5, 8, 9, 11, 13, 16, 22, 24, 25, 28, 30, 32, 33, 35, 36, 39, 41, 43, 45], "question": [1, 2, 44], "infer": 1, "scenario": [1, 5, 10, 16, 17, 22, 29, 36, 39], "eas": [1, 11, 21, 31, 38, 46], "start": [1, 5, 6, 10, 11, 21, 22, 23, 25, 33, 43, 44], "three": [1, 3, 5, 16, 22, 24, 33, 41, 43, 44], "aspect": [1, 33], "especi": [1, 6, 11], "spark": [1, 22], "most": [1, 9, 23, 28], "popular": 1, "non": [1, 2, 18, 24, 28], "interfac": [1, 18, 30, 34, 35], "final": [1, 6, 9, 18, 25, 28, 30, 32, 33, 39, 43, 45], "inter": [1, 3, 10, 25, 33], "oper": [1, 3, 9, 10, 11, 12, 13, 15, 16, 18, 22, 24, 25, 26, 28, 30, 32, 38, 40, 42, 43, 46], "invest": 1, "lot": [1, 42, 43], "along": [1, 3, 17, 24, 32, 38, 43], "declar": [1, 5, 38], "wai": [1, 2, 3, 10, 42, 45], "function": [1, 3, 5, 6, 11, 13, 16, 19, 23, 24, 28, 33, 38, 40, 45, 46], "attract": 1, "own": [1, 3, 23, 28, 30, 38], "posit": 1, "For": [1, 3, 5, 6, 9, 10, 11, 12, 16, 17, 22, 24, 25, 27, 28, 30, 32, 33, 34, 35, 38, 39, 41, 43, 44], "exampl": [1, 4, 5, 9, 12, 13, 16, 17, 18, 22, 23, 26, 28, 30, 36, 38, 39, 41, 44, 45], "Or": [1, 12, 13, 42], "concentr": 1, "document": [1, 10, 12, 16, 17, 18, 27, 29, 45], "mainli": [1, 28], "focus": 1, "domain": [1, 3, 10, 12, 13, 16, 28, 29, 30, 38], "find": [1, 5, 7, 8, 9, 10, 23, 28, 30, 42, 43, 45], "gather": 1, "seek": 1, "llm": 1, "preprocess": [1, 6, 42, 45], "train": [1, 6, 10, 31, 42, 43, 46], "cost": [1, 2, 5, 10, 11, 13, 15, 16, 17, 18, 22, 24, 32, 42], "usual": [1, 2, 3, 6, 18, 28, 30], "wg": 1, "With": [1, 3, 4, 10, 18, 33, 36, 39], "servic": [1, 4, 5, 6, 10, 18, 24, 28, 29, 30, 41, 43, 44, 45], "desk": 1, "websit": 1, "friendli": [1, 11], "compon": [1, 2, 3, 4, 5, 6, 11, 18, 24, 39, 40, 42, 44, 46], "easier": [1, 16, 18], "host": [1, 5, 6, 9, 10, 22, 28, 29, 30, 33, 34, 43], "kiosk": 1, "furthermor": 1, "distributed-system": 2, "shared-memori": 2, "graph-analyt": 2, "in-memory-storag": 2, "big-data-analyt": 2, "distributed-comp": 2, "intermedi": [2, 5, 13, 15, 16, 18, 24, 32, 40, 45, 46], "modern": [2, 16, 22], "challeng": [2, 3, 10], "often": [2, 3, 5, 16, 45], "caus": 2, "signific": [2, 16, 17, 22, 31, 38, 42, 46], "bottleneck": 2, "consid": [2, 10, 16, 19, 24, 26, 45], "fraud": [2, 43], "detect": 2, "real": [2, 5, 16, 33, 36, 39, 45], "life": 2, "prefer": [2, 4, 45], "program": [2, 3, 10, 13, 17, 24, 30], "dedic": [2, 9, 16, 33, 44], "same": [2, 5, 6, 10, 17, 19, 22, 24, 28, 29, 30, 33, 36, 39, 42, 45], "sql": 2, "demand": 2, "technic": 2, "term": [2, 27], "failov": 2, "etc": [2, 6, 30, 34, 42], "polymorph": 2, "relat": [2, 6, 10, 11, 16, 28, 43, 44, 45], "network": [2, 3, 16, 22, 28, 30, 33, 42, 45], "increasingli": 2, "preval": [2, 22], "mai": [2, 7, 8, 9, 10, 11, 12, 24, 28, 29, 30, 34, 38, 39, 41, 42], "best": [2, 5, 6, 30, 45], "store": [2, 3, 5, 6, 10, 11, 16, 17, 19, 21, 24, 28, 29, 33, 36, 38, 39, 42, 43, 44], "exchang": 2, "them": [2, 5, 6, 13, 17, 24, 25, 33, 38, 41, 43], "transform": [2, 4, 5, 16, 35], "back": [2, 5, 6, 13, 28, 29, 30, 34], "forth": [2, 28], "result": [2, 3, 16, 17, 24, 28, 30, 34, 38, 45], "overhead": [2, 18, 22, 24, 25, 30, 33, 45], "save": [2, 16, 18, 24, 33, 36, 39, 41, 42, 45], "load": [2, 4, 5, 15, 16, 17, 18, 24, 28, 32, 33, 42, 45], "requir": [2, 3, 4, 5, 6, 8, 9, 10, 12, 16, 22, 23, 24, 25, 28, 29, 30, 37, 38, 39, 42, 43, 45, 46], "incur": [2, 10, 16, 17, 22, 45], "v6d": [2, 4, 5, 6, 8, 9, 42, 43, 44], "offer": [2, 3, 4, 5, 9, 10, 13, 21, 22, 24, 26, 27, 35, 37, 46], "without": [2, 6, 10, 15, 16, 18, 24, 28, 30, 31, 32, 33, 42, 46], "extra": [2, 13, 28, 30], "deseri": [2, 5, 16, 24, 25], "when": [2, 3, 4, 5, 9, 10, 11, 12, 15, 16, 18, 22, 23, 24, 26, 28, 29, 30, 31, 32, 33, 34, 38, 45, 46], "defin": [2, 3, 5, 6, 16, 24, 25, 26, 29, 33, 37, 45, 46], "metadata": [2, 3, 4, 5, 10, 11, 26, 29, 36, 38, 39, 41, 42, 44], "payload": [2, 3, 10, 22, 28, 30, 34, 36, 38, 39], "separ": [2, 5, 33], "model": [2, 10, 13, 17, 43], "captur": [2, 30], "common": [2, 3, 8, 12, 28, 30, 42], "method": [2, 4, 5, 13, 17, 19, 22, 23, 24, 26, 28, 30, 35, 38, 43, 44], "sharabl": [2, 13, 26], "gener": [2, 3, 5, 6, 8, 9, 10, 11, 13, 17, 18, 24, 25, 28, 30, 32, 33, 38, 41, 42, 45], "descript": [2, 5, 9, 24, 29], "annot": [2, 3, 5, 26], "member": [2, 7, 24, 26, 28, 29, 30, 38, 39], "automat": [2, 6, 9, 10, 26, 28, 30, 33, 34, 38, 39], "minim": [2, 10, 13, 15, 24, 25], "In": [2, 3, 4, 5, 6, 10, 11, 12, 13, 16, 17, 19, 22, 24, 28, 30, 31, 33, 34, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46], "substanti": 2, "portion": [2, 10, 16], "unrel": 2, "core": [2, 12, 13, 17, 21, 24, 28, 30, 33], "These": [2, 10, 22, 37, 38, 45, 46], "variou": [2, 5, 11, 13, 16, 19, 21, 22, 24, 30, 31, 38, 39, 44, 45, 46], "adapt": [2, 16, 29, 34, 38], "partit": [2, 3, 5, 10, 17, 22, 24, 28], "strategi": [2, 5, 6, 17], "due": [2, 3, 16, 22, 45], "structur": [2, 3, 8, 11, 13, 19, 24, 26, 28, 33, 37, 38, 46], "reusabl": 2, "lead": [2, 24, 42], "complex": [2, 3, 10, 13, 15, 16, 19, 24, 31, 46], "redund": 2, "manipul": [2, 3, 28], "extend": [2, 11, 33], "capabl": [2, 10, 11, 17, 22, 24, 31, 46], "regist": [2, 3, 10, 16, 17, 23, 24, 28, 30, 33, 37, 39, 46], "reus": [2, 3], "divers": 2, "embrac": 2, "abil": [2, 32], "put": [2, 3, 13, 17, 19, 22, 24, 25, 28, 30, 33, 36, 39, 41, 44, 45], "arbitrari": [2, 13], "coordin": 2, "flow": [2, 16, 45], "base": [2, 3, 5, 6, 8, 9, 10, 11, 16, 22, 24, 28, 30, 32, 38, 39, 42, 43], "guid": [2, 4, 9, 10, 13, 21, 22, 38, 42, 44], "acceler": [2, 5, 13, 31, 46], "tutori": [2, 16, 32, 38, 40, 41, 44, 45, 46], "faq": [2, 10], "frequent": 2, "ask": [2, 9], "discuss": [2, 7, 10, 36, 39], "dure": [2, 5, 6, 7, 24, 28, 30], "adopt": [2, 3], "2023": [2, 41, 44], "cncf": [2, 7, 11], "project": [2, 7, 9, 11, 18, 32], "made": [2, 28], "figur": [3, 5, 17, 22, 41], "illustr": [3, 17, 22], "vineyard": [3, 7, 10, 11, 15, 21, 22, 23, 24, 26, 27, 29, 31, 34, 35, 39], "On": [3, 36, 39], "daemon": [3, 4, 5, 10, 13, 17, 33, 38], "aforement": [3, 10, 33], "instanc": [3, 5, 6, 10, 13, 19, 22, 24, 28, 30, 33, 34, 36, 38, 39, 42, 44, 45], "primari": [3, 10], "space": [3, 21, 28], "via": [3, 6, 10, 13, 22, 28, 30, 34, 41, 42, 44], "unix": [3, 6, 8, 10, 12, 13, 16, 28, 29, 30], "socket": [3, 5, 6, 10, 12, 13, 16, 18, 28, 29, 30, 36, 39], "through": [3, 10, 22, 33, 35, 36, 38, 39, 40, 45, 46], "map": [3, 5, 6, 10, 19, 22, 24, 28, 30, 33, 36, 38, 39, 42], "As": [3, 5, 9, 16, 17, 22, 23, 24, 29, 36, 38, 39, 41, 42, 45], "previous": [3, 17, 24, 42, 45], "mention": [3, 19, 24, 33], "resid": [3, 10, 28, 36, 39, 40, 46], "correspond": [3, 5, 10, 13, 19, 22, 23, 24, 28, 30, 33, 36, 38, 39, 42, 45], "respons": [3, 7, 22, 28, 30, 38, 45], "maintain": [3, 7, 24, 38], "layout": [3, 24, 38], "properti": [3, 24, 30], "each": [3, 5, 10, 16, 17, 22, 30, 32, 33, 36, 39, 42, 43, 45], "backend": [3, 5, 6, 15, 16, 24, 30, 31, 42, 46], "kei": [3, 6, 11, 13, 24, 28, 30, 32, 33, 38], "etcd": [3, 4, 5, 6, 9, 10, 12, 24, 28, 29, 30, 41, 42, 44], "ensur": [3, 4, 5, 6, 9, 10, 11, 16, 24, 28, 33, 35, 43, 44, 45], "ipc": [3, 6, 10, 12, 13, 16, 22, 24, 28, 29, 30, 36, 44], "rpc": [3, 4, 5, 6, 10, 11, 22, 28, 29, 30, 41, 44], "retriev": [3, 5, 10, 17, 22, 24, 25, 28, 30, 36, 38, 39], "howev": [3, 10, 16, 22, 24, 33, 36, 38, 39], "type": [3, 4, 5, 6, 9, 15, 16, 18, 19, 22, 23, 24, 25, 26, 30, 33, 37, 44, 46], "avail": [3, 4, 5, 9, 11, 16, 18, 22, 28, 29, 30, 32, 35, 42, 44], "priorit": [3, 10], "greater": 3, "low": [3, 5, 6, 10, 22, 29, 33], "precis": [3, 16, 24], "manner": [3, 5, 10, 22, 24, 28, 31, 43, 46], "routin": [3, 13], "local": [3, 5, 6, 9, 10, 11, 16, 18, 23, 24, 28, 29, 30, 32, 33, 36, 39, 42, 43, 44, 45], "establish": [3, 4, 5, 26, 30, 42, 45], "mmap": [3, 13, 28], "transfer": [3, 16, 18, 22, 30, 33, 34], "descriptor": 3, "remot": [3, 6, 9, 10, 11, 16, 28, 30, 41], "tcp": [3, 4, 5, 6, 22, 28, 30, 33, 44], "port": [3, 4, 5, 6, 28, 29, 30, 32, 42, 44], "bound": [3, 28, 29], "unlik": [3, 28], "doesn": [3, 28, 30, 42], "allow": [3, 5, 10, 16, 18, 22, 23, 24, 34, 36, 39], "less": [3, 29, 32, 33], "regard": [3, 9, 42], "rdma": 3, "builder": [3, 13, 17, 22, 26, 28, 33, 37, 46], "resolv": [3, 9, 12, 13, 16, 17, 19, 26, 28, 33, 37, 38, 46], "consum": [3, 5, 6, 10, 13, 22, 23, 41], "produc": [3, 5, 6, 10, 13, 30, 38, 41], "newli": [3, 30], "well": [3, 8, 9, 11, 18, 19, 22, 30, 33, 34, 38, 44, 45], "hoc": 3, "wrap": [3, 19], "offici": [3, 18, 42, 43], "under": [3, 6, 8, 9, 13, 30, 34, 42, 43], "heavi": 3, "develop": [3, 5, 7, 10, 16, 24, 28, 32, 33, 34, 38, 45], "pluggabl": [3, 5, 6, 13, 29], "assign": 3, "certain": [3, 5, 30, 33], "particular": [3, 33], "synchron": [3, 6, 22, 24, 28, 29, 30, 34], "databas": [3, 16], "read": [3, 5, 17, 28, 30, 33, 41, 43], "write": [3, 28, 30, 41, 43, 44, 45], "while": [3, 5, 6, 9, 10, 15, 16, 18, 19, 22, 24, 25, 33, 44], "re": [3, 17, 39], "reorgan": 3, "balanc": 3, "typic": [3, 10, 12, 22, 25, 33, 38, 39], "emploi": [3, 5, 17, 22, 24, 28, 43], "mechan": [3, 6, 13, 24, 26, 34], "implement": [3, 9, 11, 13, 15, 17, 21, 24, 28, 34, 37, 38, 46], "cannot": [3, 5, 10, 13, 16, 18, 28, 29, 30, 35, 36, 39, 45], "co": [3, 10, 11, 22], "locat": [3, 6, 10, 12, 13, 16, 18, 22, 28, 30, 38], "pair": [3, 24, 28, 30, 36, 39], "sender": 3, "don": [3, 4, 5, 6, 13, 42, 44], "decoupl": [3, 24], "technologi": 3, "creat": [3, 10, 11, 13, 18, 22, 24, 25, 28, 30, 32, 33, 34, 36, 38, 41, 42, 43, 44], "alloc": [3, 12, 13, 22, 24, 28, 30, 34, 38], "blob": [3, 5, 11, 24, 26, 36, 38, 39, 44], "hand": [3, 36, 39, 42], "techniqu": [3, 17, 22, 24], "examin": [3, 10, 22], "practic": 3, "analysi": [3, 24, 38], "identifi": [3, 5, 9, 13, 16, 26, 28, 30, 43], "four": [3, 44], "fragment": [3, 10, 24], "fit": [3, 6, 10, 11, 13, 16, 17, 24, 33, 45], "never": [3, 24, 28], "modifi": [3, 5, 7, 9, 15, 28, 33, 35, 42, 45], "after": [3, 5, 6, 8, 9, 10, 11, 16, 18, 19, 28, 30, 32, 34, 35, 44, 45], "creation": [3, 5, 30, 45], "csr": [3, 24], "format": [3, 5, 6, 11, 24, 28, 30, 42], "flexibl": [3, 10, 24, 34, 39], "choic": [3, 24], "fulli": [3, 8, 11, 24], "determin": [3, 10, 24], "difficulti": 3, "handl": [3, 15, 16, 18, 23, 28, 32, 33, 34, 39, 42], "index": [3, 9, 18, 24, 25, 27, 28, 33, 38, 45], "vertic": [3, 24], "edg": [3, 16, 24], "iter": [3, 28, 30], "mean": [3, 6, 13, 22, 24, 28, 30, 42], "themselv": 3, "moreov": [3, 15, 24], "codegen": 3, "tool": [3, 4, 6, 10, 18, 41, 44], "transplant": 3, "few": [3, 33], "throughout": 3, "hold": [3, 22, 24, 28, 29, 36], "variabl": [3, 6, 8, 16, 18, 28, 30, 33, 45], "long": [3, 10], "modul": [3, 8, 30, 35, 43], "down": [3, 30, 42], "entir": [3, 10, 22, 24, 28, 36, 39, 42, 45], "run": [3, 4, 5, 6, 8, 10, 12, 13, 17, 18, 19, 30, 32, 33, 36, 39, 41, 43, 44, 45], "script": [3, 9, 45], "trillion": 3, "background": [3, 30], "distributedli": [3, 17, 33], "onc": [3, 4, 6, 8, 11, 13, 28, 35], "seal": [3, 6, 9, 22, 28, 30, 38], "NOT": [3, 9], "anymor": [3, 18], "thu": [3, 28, 33, 42], "suitabl": [3, 18], "cach": [3, 33, 42], "rapidli": 3, "want": [4, 5, 6, 8, 29, 30, 41, 42, 45], "quickli": [4, 6, 10], "command": [4, 5, 6, 9, 10, 12, 13, 16, 18, 22, 30, 32, 41, 42, 44, 45], "vineyardctl": [4, 41, 42], "pip3": [4, 8, 9, 13, 16, 18, 44], "python3": [4, 5, 8, 10, 12, 13, 18, 32, 36, 39, 41, 42], "m": [4, 5, 6, 9, 10, 12, 13, 16, 18, 30, 32, 36, 39, 41, 42], "ctl": [4, 32, 41, 42], "namespac": [4, 5, 6, 18, 29, 30, 32, 41, 42, 43, 44, 45], "There": [4, 5, 8, 10, 24, 42], "directli": [4, 17, 24, 28, 34, 44], "prior": 4, "kubectl": [4, 5, 6, 18, 32, 41, 42, 43, 44, 45], "kind": [4, 5, 6, 11, 18, 19, 21, 28, 29, 32, 34, 41, 42, 43, 44], "repo": [4, 5, 32, 43, 44, 45], "oss": [4, 32, 44], "ap": [4, 32, 44], "southeast": [4, 32, 44], "aliyunc": [4, 32, 44], "updat": [4, 5, 8, 9, 28, 32, 38, 42, 44, 45], "until": [4, 5, 25, 28, 30], "clone": [4, 8], "git": [4, 8, 45], "docker": [4, 18, 30, 42, 43, 44], "imag": [4, 5, 6, 9, 17, 18, 29, 30, 41, 42, 43, 44], "cd": [4, 8, 9, 18, 32, 42, 43], "k8": [4, 5, 6, 18, 32, 42, 43, 44], "first": [4, 5, 9, 11, 17, 22, 24, 25, 28, 30, 32, 33, 36, 38, 39, 42, 43, 44, 45], "import": [4, 5, 6, 11, 13, 16, 17, 19, 22, 25, 30, 33, 35, 36, 39, 41, 42, 44, 45], "vineyardcloudn": [4, 5, 6, 9, 30], "latest": [4, 5, 6, 8, 9, 18, 30, 32, 41, 42, 43, 44, 45], "check": [4, 5, 6, 9, 10, 12, 18, 28, 30, 34, 41, 42, 43, 44], "n": [4, 5, 6, 18, 32, 34, 41, 42, 43, 44, 45], "restart": [4, 5, 32, 41, 42, 43, 44, 45], "ag": [4, 5, 18, 32, 41, 42, 43, 44], "pod": [4, 5, 6, 10, 12, 29, 32, 42, 43, 44, 45], "control": [4, 5, 6, 11, 28, 32, 42, 43, 44], "5c6f4bc454": [4, 5], "8xm8q": [4, 5], "0": [4, 5, 6, 8, 9, 10, 13, 17, 18, 19, 22, 24, 25, 28, 30, 32, 33, 38, 39, 41, 42, 43, 45], "62m": 4, "ip": [4, 5, 28, 41, 44], "metric": [4, 5, 6, 17, 29, 33, 43, 44, 45], "clusterip": [4, 5, 6, 44], "96": [4, 5, 44], "240": [4, 5], "173": [4, 5, 32], "none": [4, 5, 16, 17, 18, 23, 30, 33, 36, 39, 41, 44], "8443": [4, 5, 44], "webhook": [4, 5, 6, 43, 44, 45], "41": [4, 5, 42, 44], "132": [4, 5], "443": [4, 5, 44], "up": [4, 5, 6, 7, 9, 11, 12, 29, 30, 44, 45], "TO": [4, 5, 42, 44], "date": [4, 5, 9, 16, 42, 44], "app": [4, 5, 6, 41, 42, 43, 44], "desir": [4, 5, 29, 44], "replicaset": [4, 5, 44], "vineyardd": [4, 5, 9, 10, 11, 12, 13, 18, 28, 30, 32, 33, 34, 41, 42, 43, 44], "replica": [4, 5, 6, 29, 32, 41, 44, 45], "cat": [4, 5, 6, 32, 41, 44], "eof": [4, 5, 32, 41, 44], "appli": [4, 5, 6, 18, 26, 30, 32, 33, 41, 42, 43, 44], "f": [4, 5, 6, 16, 17, 18, 22, 30, 32, 33, 41, 42, 43, 44, 45], "apivers": [4, 5, 6, 29, 32, 41, 44], "v1alpha1": [4, 5, 6, 44], "sampl": [4, 5, 6, 18, 23, 41, 42, 43, 44], "default": [4, 5, 6, 10, 12, 13, 19, 22, 24, 28, 29, 30, 32, 34, 39, 41, 43, 44, 45], "spec": [4, 5, 6, 11, 29, 41, 44], "9600": [4, 5, 6, 22, 30, 44], "imagepullpolici": [4, 5, 6, 29, 44], "ifnotpres": [4, 5, 6, 30, 44], "necessari": [4, 5, 9, 24, 33, 38], "depend": [4, 5, 6, 11, 16, 18, 28, 30, 42], "server": [4, 5, 6, 8, 10, 11, 12, 16, 18, 22, 24, 30, 32, 38, 42, 45], "configur": [4, 6, 9, 12, 16, 17, 29, 30, 32, 42, 43, 44, 45], "setup": [4, 8, 17, 18, 21, 30, 32, 36, 39], "complet": [4, 5, 9, 11, 16, 18, 24, 30, 34, 43, 44, 45], "conveni": [4, 22], "inspect": [4, 24, 30], "etcd0": [4, 5, 43], "48": [4, 5, 42], "etcd1": [4, 5, 43], "etcd2": [4, 5, 43], "72": [4, 5], "5cc797668f": [4, 5], "9ggr9": [4, 5], "nhw7p": [4, 5], "r56h7": [4, 5], "174": [4, 5], "2379": [4, 5, 6, 10], "128": [4, 5, 12, 17], "87": [4, 5], "2380": [4, 5, 6], "116": [4, 5], "99": [4, 5], "182": [4, 5], "102": [4, 5], "183": [4, 5], "addit": [4, 8, 10, 16, 21, 24, 33, 39, 43, 45], "plai": 4, "crucial": 4, "role": [4, 6, 32, 43, 44], "trigger": [4, 10, 16, 28, 29, 30], "movement": [4, 16], "detail": [4, 5, 9, 10, 11, 13, 17, 18, 21, 22, 25, 27, 28, 35, 41, 43, 44], "found": [4, 5, 9, 13, 28, 30, 38], "To": [4, 5, 7, 9, 10, 12, 13, 17, 24, 26, 28, 32, 33, 38, 39, 42, 43, 44], "simplifi": [4, 16, 17, 29, 38], "interact": [4, 6, 18, 24], "line": [4, 6, 9, 10, 12, 13, 18, 28, 33, 41, 45], "autom": 4, "demonstr": [5, 11, 13, 16, 17, 18, 22, 23, 24, 31, 33, 35, 38, 39, 43, 44, 45, 46], "refer": [5, 6, 8, 10, 11, 12, 16, 17, 18, 22, 24, 25, 34, 38, 41, 42, 43, 44, 45], "effortlessli": [5, 13, 15, 22, 31, 46], "must": [5, 6, 24, 28, 30, 32, 33, 34], "account": [5, 16, 22, 43], "ultim": 5, "upon": [5, 9, 13, 21, 22, 39], "readi": [5, 6, 30, 32, 41, 42, 43, 44], "custom": [5, 6, 11, 19, 23, 24, 26, 30, 37, 42, 44, 46], "path": [5, 6, 13, 17, 18, 23, 28, 29, 30, 42, 43, 44, 45], "mount": [5, 6, 10, 29, 42, 45], "someth": 5, "contain": [5, 6, 9, 10, 17, 18, 19, 24, 28, 29, 30, 33, 38, 39, 42, 43, 44, 45], "yaml": [5, 6, 18, 30, 32, 41, 42, 44], "should": [5, 6, 10, 12, 13, 19, 24, 28, 29, 30, 41], "securitycontext": [5, 6, 29, 42], "privileg": [5, 42], "true": [5, 6, 13, 16, 17, 22, 24, 25, 28, 30, 33, 34, 35, 41, 44, 45], "volum": [5, 6, 10, 29, 42, 43, 44], "hostpath": [5, 6, 29, 44], "volumemount": [5, 6, 29, 44], "mountpath": [5, 6, 29, 44], "entri": [5, 24, 28, 30], "within": [5, 9, 10, 12, 16, 17, 21, 22, 24, 33, 36, 39, 42, 44], "resourc": [5, 6, 10, 11, 12, 24, 30, 41, 42, 43, 44, 45], "definit": [5, 11, 24, 28, 29, 38], "similar": [5, 10, 22, 25], "label": [5, 6, 10, 17, 19, 28, 33, 41, 43, 44], "field": [5, 6, 26, 28, 29, 30, 38], "cr": [5, 6, 44], "demo": [5, 18, 44], "accord": [5, 23, 24, 42, 45], "previou": [5, 17, 41, 42, 44], "inject": [5, 16, 41, 45], "bin": [5, 6, 8, 9, 32, 43, 44], "sh": [5, 42, 43], "bash": [5, 6, 12, 41, 44], "sock": [5, 6, 12, 13, 16, 18, 22, 25, 29, 30, 44], "sleep": [5, 6, 25, 41, 42, 44], "done": [5, 6, 32, 42, 43], "befor": [5, 6, 9, 11, 16, 28, 29, 30, 32, 42, 44], "v1": [5, 6, 32, 41, 43, 44], "selector": [5, 6, 29, 41, 44], "matchlabel": [5, 6, 41, 44], "templat": [5, 6, 18, 26, 28, 38, 41, 44, 45], "ghcr": [5, 6, 42], "py": [5, 6, 8, 9, 18, 41, 42, 45], "env": [5, 6, 29, 32, 42], "job_nam": 5, "fals": [5, 6, 17, 22, 24, 28, 30, 33, 34, 35, 44], "grok": [5, 6], "export": [5, 6, 8, 16, 18, 42], "size": [5, 6, 10, 24, 25, 26, 28, 29, 30, 32, 33, 36, 38, 39, 43, 45], "spill": [5, 6, 11, 28, 29], "persistentvolumeclaimspec": [5, 29], "persistentvolumespec": [5, 29], "spilllowerr": [5, 6, 29], "spillupperr": [5, 6, 29], "streamthreshold": [5, 6, 29], "synccrd": [5, 6, 29], "here": [5, 6, 13, 17, 18, 19, 28, 30, 34, 44, 45], "l": [5, 18, 43, 44], "55664458f8": 5, "h4jzk": 5, "usr": [5, 6, 32, 43], "sync_crd": [5, 6], "stream_threshold": [5, 6], "etcd_cmd": [5, 6], "etcd_prefix": [5, 6, 30], "etcd_endpoint": [5, 6, 10, 30], "vineyardd_uid": [5, 6], "7b0c2ec8": 5, "49f3": 5, "4f8f": 5, "9e5f": 5, "8576a4dc4321": 5, "vineyardd_nam": [5, 6], "vineyardd_namespac": [5, 6], "containerport": [5, 6], "protocol": [5, 6, 26], "emptydir": [5, 6], "sure": [5, 28, 29, 30, 43], "1024mi": 5, "e2": [5, 43], "inspir": [5, 6], "expos": [5, 10, 32], "panel": 5, "global": [5, 6, 10, 17, 22, 24, 28, 29, 30, 33, 36, 39, 44], "repres": [5, 10, 11, 13, 24, 26, 28, 29, 30, 33, 36, 39], "signatur": [5, 22, 24, 28, 29, 30, 44], "typenam": [5, 6, 19, 22, 24, 26, 28, 29, 30, 36, 38, 39, 44], "o001bcbcea406acd0": 5, "s001bcbcea4069f60": 5, "globaldatafram": [5, 17, 28], "o001bcc19dbfc9c34": 5, "s001bcc19dbfc8d7a": 5, "just": [5, 32, 33, 42, 44], "hostnam": [5, 6, 29, 30], "o001bcbce202ab390": 5, "s001bcbce202aa6f6": 5, "worker2": [5, 41, 44], "o001bcbce21d273e4": 5, "s001bcbce21d269c2": 5, "worker": [5, 10, 16, 17, 18, 22, 29, 30, 32, 33, 41, 42, 43, 44], "o001bcbce24606f6a": 5, "s001bcbce246067fc": 5, "worker3": [5, 41, 44], "place": [5, 8, 10, 24, 29, 30, 38], "close": [5, 28, 30, 41], "input": [5, 6, 10, 16, 18, 33, 38, 40, 45, 46], "therebi": [5, 42, 45], "reduc": [5, 10, 24, 32, 42, 45], "overal": [5, 24, 30, 38, 42], "summar": 5, "node": [5, 6, 10, 15, 16, 18, 22, 24, 28, 29, 32, 41, 42, 43, 44, 45], "present": [5, 10, 16, 30], "doe": [5, 6, 10, 12, 13, 28, 42], "ani": [5, 6, 7, 9, 10, 11, 16, 18, 22, 24, 30, 32, 33, 42, 43], "round": [5, 33], "robin": 5, "approach": [5, 21, 22, 31, 36, 39, 46], "second": [5, 6, 17, 28, 30, 32, 34, 36, 39, 42, 44], "polici": [5, 6, 28, 29, 30, 40, 46], "assum": [5, 6, 22, 30, 39, 41], "lifecycl": [5, 30], "attempt": 5, "imagin": 5, "node1": 5, "node2": 5, "9": [5, 19, 32, 33, 41, 42, 44], "node3": 5, "replica1": 5, "replica2": 5, "4": [5, 13, 18, 19, 30, 32, 33, 35, 36, 39, 41, 42], "replica3": 5, "alongsid": 5, "reli": [5, 16, 26], "inform": [5, 9, 10, 12, 13, 16, 21, 22, 24, 28, 30, 43], "below": [5, 7, 13, 16, 35, 43, 44, 45], "clear": [5, 28, 30, 33, 38, 42], "comprehens": [5, 9, 27, 31, 46], "than": [5, 6, 12, 28, 29, 30, 32, 33, 42], "concaten": [5, 17, 33], "string": [5, 6, 24, 28, 29, 30, 33, 38], "job1": [5, 6, 44], "job2": [5, 6], "job3": 5, "schedulernam": [5, 44], "section": [5, 9, 10, 12, 17, 21, 22, 25, 32, 38, 41, 42, 44, 45], "begin": [5, 22, 28], "outlin": [5, 7], "earlier": 5, "Then": [5, 6, 8, 9, 22, 24, 33, 41, 42], "proce": [5, 28, 44], "6f479d695b": 5, "698xb": 5, "3m16": 5, "7zrw6": 5, "o001c87014cf03c70": 5, "s001c87014cf03262": 5, "sequenc": [5, 10, 25, 28, 30, 45], "o001c8729e49e06b8": 5, "s001c8729e49dfbb4": 5, "o001c87014ca81924": 5, "s001c87014ca80acc": 5, "int64": [5, 17], "o001c8729e4590626": 5, "s001c8729e458f47a": 5, "configmap": [5, 6, 43, 45], "record": [5, 28, 32, 42, 43], "nodenam": 5, "valuefrom": [5, 6], "fieldref": 5, "fieldpath": 5, "configmapref": 5, "envfrom": 5, "8m12": 5, "b5b58cbdc": 5, "4s7b2": 5, "6m24": 5, "cd5v2": 5, "n6zvm": 5, "abov": [5, 9, 10, 13, 16, 17, 22, 24, 30, 32, 33, 38, 41, 42, 43, 44], "dig": 5, "happen": [5, 11, 35], "elegantli": 5, "primarili": [5, 43], "state": [5, 6, 11, 28, 29, 33, 39], "bbf596bf4": 5, "985vc": 5, "brief": 5, "introduct": [5, 21], "temporari": [5, 30, 39], "persist": [5, 6, 12, 13, 17, 28, 29, 30, 36, 39, 41, 44, 45], "purpos": [5, 17], "note": [5, 6, 22, 28, 30, 44], "therefor": [5, 43], "passiv": 5, "exce": [5, 33], "capac": [5, 6], "watermark": [5, 6, 29], "surpass": 5, "excess": [5, 32], "reach": [5, 11, 28, 30], "persistentvolum": [5, 6, 10, 29], "storageclassnam": [5, 6, 29], "manual": [5, 6, 9, 42], "1gi": [5, 6], "accessmod": [5, 6], "readwriteonc": [5, 6], "request": [5, 6, 12, 28, 30, 44, 45], "512mi": [5, 6, 30], "understand": [5, 13, 21, 22, 24, 38], "addition": [5, 10, 22, 25], "valuabl": 5, "insight": [5, 42], "effect": [5, 16, 17, 30, 39, 40, 42, 44, 46], "world": [5, 6, 13, 16, 30, 33, 34, 36, 39], "convert": [5, 17, 28, 30, 33], "convers": [5, 39], "subsequ": [5, 10, 17, 22], "assist": [5, 9, 10], "workload1": 5, "execut": [5, 6, 9, 14, 16, 17, 18, 19, 22, 32, 45], "o001d1b280049b146": 5, "s001d1b280049a4d4": 5, "recordbatchstream": [5, 25, 30], "evid": [5, 24], "workload2": 5, "rememb": 5, "required_job_nam": 5, "remain": [5, 16], "pend": 5, "indic": [5, 9, 12, 28, 33, 34, 43], "consequ": 5, "86c99c995f": 5, "nzns8": 5, "2m": 5, "646b78f494": 5, "cvz2w": 5, "53": [5, 32, 33, 44], "durat": [5, 18], "assembl": [5, 10, 22, 29], "119": 5, "fzws7": 5, "5m55": 5, "4m": 5, "5m": 5, "podnam": 5, "o001d1b56f0ec01f8": 5, "s001d1b56f0ebf578": 5, "o001d1b5707c74e62": 5, "s001d1b5707c742e0": 5, "o001d1b571f47cfe2": 5, "s001d1b571f47c3c0": 5, "o001d1b5736a6fd6c": 5, "s001d1b5736a6f1cc": 5, "o001d1b574d9b94a": 5, "s001d1b574d9b8a9e": 5, "o001d1b5765629cbc": 5, "s001d1b57656290a8": 5, "o001d1b57809911c": 5, "s001d1b57809904e0": 5, "o001d1b5797a9f958": 5, "s001d1b5797a9ee82": 5, "o001d1b57add9581c": 5, "s001d1b57add94e62": 5, "o001d1b57c53875a": 5, "s001d1b57c5386a22": 5, "o001d1b57dc2c74e": 5, "s001d1b57dc2c6a4a": 5, "obtain": [5, 8, 13, 16, 17, 22, 28, 30, 43, 45], "reschedul": 5, "9m55": 5, "8m": 5, "9m": 5, "adjust": 5, "It": [5, 6, 7, 11, 16, 17, 18, 19, 21, 24, 28, 30, 38], "particularli": [5, 12], "accommod": [5, 37, 38, 39, 46], "redistribut": 5, "At": [5, 10, 28, 38], "helm": [5, 10, 11, 32, 44, 45], "main": [5, 6, 9, 18, 38, 42, 43, 45], "dockerfil": [5, 9], "tag": [5, 16, 19, 32, 45], "2022": [5, 11, 45], "jupyt": 5, "vineyard_ipc_socket": [5, 6, 16, 18, 28, 30], "vineyard_rpc_socket": [5, 6], "my": [5, 6, 9], "8786": [5, 33], "dask_schedul": [5, 17, 33], "o001d2a6ae6c6e2e8": 5, "s001d2a6ae6c6d4f4": 5, "o001d2a6a6483ac44": 5, "s001d2a6a6483a3c": 5, "o001d2a6a64a29cf4": 5, "s001d2a6a64a28f2": 5, "o001d2a6a66709f20": 5, "s001d2a6a667092a2": 5, "o001d2a6ace0f6e30": 5, "s001d2a6ace0f65b8": 5, "wait": [5, 6, 10, 28, 30, 41, 42, 43, 44, 45], "finish": [5, 6, 25, 28, 33, 41], "5dbfc54997": 5, "7kghk": 5, "92": [5, 43], "cvrt2": 5, "49": 5, "5m43": 5, "4m30": 5, "79wcm": 5, "3m30": 5, "o001d2ab523e3fbd0": 5, "s001d2ab523e3f0e6": 5, "o001d2dc18d72a47": 5, "s001d2dc18d729ab6": 5, "whole": [5, 24, 42, 45], "directori": [5, 6, 8, 9, 18, 29, 30, 42, 43, 45], "backup": [5, 43], "recov": [5, 43], "restor": [5, 30, 33], "vineyarddnam": [5, 29], "vineyarddnamespac": [5, 29], "backuppath": [5, 29], "dump": [5, 6, 15, 28, 30, 45], "crash": [5, 9], "point": [5, 30, 38], "backupnam": [5, 29], "backupnamespac": [5, 29], "relationship": 5, "recoveri": 5, "o000ef92379fd8850": 5, "o000ef9ea5189718d": 5, "o000ef9237a3a5432": 5, "o000ef9eb5d26ad5": 5, "o000ef97a8289973f": 5, "o000ef9ed586ef1d3": 5, "succe": [5, 6, 28], "relev": [6, 9, 42, 44], "sidecar": [6, 41, 43], "basic": [6, 11, 22, 24, 41], "j": [6, 8, 9], "usag": [6, 9, 21, 28, 30], "json": [6, 16, 28, 30], "gen": [6, 43], "doc": [6, 8, 9, 16, 28, 44], "cmd": [6, 18], "readm": 6, "md": 6, "h": [6, 9, 28], "kubeconfig": [6, 18, 43, 45], "home": [6, 32, 43], "kube": [6, 43, 44], "config": [6, 29, 30, 32, 43, 44], "verbos": [6, 29, 30, 33, 42], "print": [6, 13, 16, 25, 30, 33, 36, 39, 41, 42, 43, 44], "log": [6, 29, 30, 32, 38, 41, 42, 43], "v": [6, 8, 13, 17, 25, 28], "insert": [6, 25, 29, 30, 38], "assembli": [6, 29], "target": [6, 9, 13, 19, 24, 25, 28, 29, 30, 33, 45], "timeoutsecond": [6, 29], "specifi": [6, 9, 12, 16, 17, 28, 29, 30, 33, 38, 42], "pv": [6, 29], "flag": [6, 10, 11, 29, 42], "pvc": [6, 29], "limit": [6, 11, 12, 22, 28, 30, 33], "1000": [6, 32, 45], "instead": [6, 13, 28, 33, 44], "objectid": [6, 13, 17, 22, 28, 30, 33, 34, 44], "persistentvolumeclaim": 6, "repartit": [6, 10, 13, 29], "dask": [6, 14, 22, 29, 33], "int": [6, 25, 28, 30, 33, 38, 39], "timeout": [6, 29, 30, 42, 43], "endpoint": [6, 22, 28, 30, 43], "nodeid": 6, "csinode1": 6, "deployvineyarddeploy": 6, "o000018d29207fd01": 6, "o000018d80d264010": 6, "alreadi": [6, 8, 9, 10, 28, 32, 42], "scope": [6, 17, 42], "sperat": 6, "comma": 6, "attacherimag": [6, 29], "attach": [6, 29], "v4": 6, "enabletoler": [6, 29], "toler": [6, 11, 29, 30], "pull": [6, 28, 29, 30, 42], "livenessprobeimag": [6, 29], "livenessprob": 6, "v2": 6, "noderegistrarimag": [6, 29], "noderegistrar": 6, "registrar": [6, 29], "6": [6, 19, 30, 32, 33, 41, 42, 44, 45], "provisionerimag": [6, 29], "provision": [6, 29, 44], "v3": [6, 18, 32, 42], "enabletopologi": [6, 29], "topologi": [6, 29], "alwai": [6, 10, 28], "class": [6, 16, 19, 26, 28, 29, 30, 33, 35, 38], "volumebindingmod": [6, 29], "bind": [6, 12, 29, 43, 45], "mode": [6, 28, 29, 30], "waitforfirstconsum": 6, "old": 6, "ones": [6, 24, 36, 39], "left": 6, "column": [6, 13, 17, 18, 19, 25, 28, 30, 33, 41, 45], "right": 6, "stdin": 6, "v0": [6, 32, 44], "owner": [6, 16], "pluginimag": [6, 29], "backupimag": [6, 29], "daskrepartitionimag": [6, 29], "distributedassemblyimag": [6, 29], "localassemblyimag": [6, 29], "recoverimag": [6, 29], "secur": [6, 29], "context": [6, 29, 30, 39, 43, 44], "cpu": [6, 12, 29, 34, 42], "metic": 6, "reserve_memori": 6, "reserv": [6, 28, 29], "enough": [6, 28], "physic": [6, 28, 30], "power": [6, 14, 30], "equival": [6, 30], "ei": [6, 30], "pi": [6, 30], "ti": [6, 30], "gi": [6, 30], "mi": [6, 30, 42], "ki": [6, 30], "replac": [6, 33], "claim": [6, 28], "threshold": [6, 29], "percentag": [6, 29], "total": [6, 16, 28, 29, 30, 33], "pvcname": [6, 29], "client": [6, 10, 11, 12, 13, 16, 22, 24, 32, 33, 34, 35, 36, 38, 39, 41, 44, 45], "output": [6, 10, 13, 19, 33, 45], "everi": [6, 11, 24, 28, 29], "time": [6, 10, 11, 22, 24, 25, 32, 39], "given": [6, 13, 18, 28, 30], "object_id": [6, 13, 28, 30, 33, 34], "xxxxxxxx": 6, "unsaf": [6, 11, 28, 30], "syncremot": 6, "code_remot": [6, 30], "forc": [6, 9, 28, 30], "meta": [6, 22, 24, 28, 30, 38, 39, 44], "even": [6, 11, 24, 28, 30, 31, 32, 36, 39, 46], "instanceid": [6, 28, 30], "127": [6, 10, 30], "manifest": [6, 42], "statefulset": 6, "100000": [6, 16, 45], "etcd_nod": 6, "null": 6, "ownerrefer": 6, "advertis": 6, "peer": 6, "url": 6, "listen": [6, 13, 30, 36, 39], "restartpolici": 6, "targetport": 6, "creationtimestamp": 6, "simpl": [6, 18, 19, 45], "nginx": 6, "14": [6, 8, 18, 30, 33, 42, 44], "except": [6, 25, 28, 30, 33], "itself": [6, 22, 26], "remov": [6, 10, 30, 44], "unnecessari": 6, "pkg": 6, "html": [6, 8, 9, 16, 28], "instal": [6, 10, 16, 18, 30, 32, 41, 42, 43, 44], "rpc_servic": 6, "etcd_servic": 6, "etcd_internal_servic": 6, "etcd_pod": 6, "rather": [6, 28, 30], "whether": [6, 9, 10, 28, 30, 34, 42, 43], "injecti": 6, "dag": [6, 16], "suffix": [6, 30], "_with_vineyard": 6, "workflow_with_vineyard": 6, "suppos": [6, 41, 42], "argoproj": [6, 18, 32, 42], "generatenam": 6, "mlop": [6, 32], "entrypoint": [6, 28], "arg": [6, 13, 23, 25, 28, 30, 45], "claimnam": 6, "paramet": [6, 10, 12, 18, 28, 30, 38], "argument": [6, 9, 12, 22, 28, 30, 34], "action": [6, 16, 28], "setownerrefer": 6, "readwritemani": 6, "1mi": 6, "jsonpath": [6, 41], "singl": [6, 10, 12, 22, 24, 28, 30, 33, 42], "benchmark": [6, 18, 32], "falseth": 6, "origin": [6, 28, 32, 38, 42], "pattern": [6, 22, 28, 30], "regex": [6, 28, 30], "prc": 6, "match": [6, 11, 28, 30, 39], "maximum": [6, 28], "return": [6, 13, 16, 17, 18, 19, 22, 23, 25, 26, 28, 30, 33, 38, 39], "sort": 6, "instance_id": [6, 22, 24, 28, 29, 30, 44], "p": [6, 17, 18, 30, 32, 42, 43], "r": [6, 8, 18, 22, 23, 30, 39], "k": [6, 25, 28, 30, 42], "health": 6, "probe": [6, 29], "8081": 6, "leader": [6, 43], "elect": [6, 43], "8080": 6, "cert": 6, "dir": 6, "certif": [6, 8], "12345": 6, "hello": [6, 34, 36, 39], "podaffin": 6, "globalobject": [6, 11, 43], "localobject": [6, 11, 43], "affin": [6, 45], "requiredduringschedulingignoredduringexecut": 6, "labelselector": 6, "matchexpress": 6, "topologykei": 6, "web": 6, "podantiaffin": 6, "16": [6, 32, 41, 44, 45], "alpin": 6, "april": [7, 11], "u": [7, 8, 9, 13, 44], "welcom": [7, 9], "slack": 7, "channel": 7, "instruct": [7, 9, 21], "encount": [7, 9, 12, 13, 16, 25], "issu": [7, 9, 10, 11, 22, 24, 28, 33], "journei": 7, "solut": [7, 16, 33, 40, 46], "troubleshoot": 7, "public": [7, 26, 28, 38], "roadmap": 7, "goal": 7, "highlight": 7, "ongo": 7, "packag": [8, 9, 11, 13, 16, 18, 19, 25, 30, 42, 44], "pip": [8, 9, 13, 41, 45], "submodul": 8, "init": [8, 33, 42], "compil": [8, 10, 11, 17, 33, 42], "arrow": [8, 9, 28, 38], "gflag": [8, 9], "glog": [8, 9], "boost": [8, 9], "mpi": 8, "librari": [8, 33, 39, 45], "protobuf": [8, 9], "grpc": [8, 9, 42], "And": [8, 33], "libclang": [8, 9], "04": [8, 42], "apt": 8, "y": [8, 17, 45], "ca": 8, "cmake": [8, 9], "doxygen": [8, 9], "libboost": 8, "libcurl4": 8, "openssl": 8, "libgflag": 8, "libgoogl": 8, "libgrpc": 8, "libmpich": 8, "libprotobuf": 8, "libssl": 8, "libunwind": [8, 11], "libz": 8, "wget": [8, 32], "jfrog": 8, "artifactori": 8, "lsb_releas": 8, "short": [8, 24], "tr": 8, "z": 8, "codenam": 8, "deb": 8, "tmp": [8, 12, 13, 16, 18, 22, 25, 43], "libarrow": 8, "brew": [8, 9], "llvm": 8, "mpich": 8, "zlib": 8, "autoconf": 8, "recommend": [8, 9, 10, 12, 21, 32, 44], "accomplish": [8, 10], "cc": 8, "cxx": 8, "prefix": [8, 9, 30, 42], "clang": [8, 9], "mkdir": [8, 9, 43], "nproc": [8, 9], "sudo": [8, 12, 13, 32], "option": [8, 9, 13, 17, 28, 30], "binari": [8, 29, 30, 33], "static": [8, 28, 30, 38], "lib": [8, 39], "folder": 8, "bdist_wheel": 8, "sphinx": [8, 9], "txt": [8, 45], "skip": [8, 32, 33, 42], "continu": [8, 9, 25, 32], "ci": [8, 9], "cento": [8, 9, 11], "arch": [8, 9], "linux": [8, 9, 32], "team": 9, "warmli": 9, "enhanc": [9, 11, 15, 22, 24, 31, 38, 40, 46], "refin": [9, 11], "licens": [9, 42], "17": [9, 32, 41], "parsec": 9, "streamlin": [9, 38], "ubuntu": 9, "maco": 9, "incorpor": [9, 15, 31, 46], "vineyard_test": 9, "properli": 9, "etcd_distro": 9, "runner": [9, 18], "cpp": 9, "contrib": [9, 16, 17, 18, 19, 32, 33], "messag": [9, 10, 18], "exit": [9, 28, 30, 39], "adaptor": 9, "ro": 9, "unittest": 9, "array_test": 9, "dataframe_test": 9, "navig": 9, "_build": 9, "visit": 9, "delv": 9, "adher": [9, 16], "syntax": 9, "convent": [9, 28], "markup": 9, "area": 9, "wish": 9, "appreci": 9, "enthusiasm": 9, "util": [9, 10, 16, 17, 19, 24, 25, 28, 30, 31, 35, 43, 44, 46], "tracker": 9, "unexpect": 9, "behavior": [9, 28, 30], "search": [9, 27, 45], "kindli": 9, "essenti": [9, 10, 17, 29, 38], "problem": [9, 16], "greatli": [9, 11, 42], "diagnos": 9, "fix": [9, 30], "featur": [9, 11, 15, 17, 19, 21, 33, 43, 44, 45], "guidelin": 9, "prevent": [9, 23, 28], "accident": 9, "inclus": 9, "secret": [9, 30, 32], "hook": [9, 16, 30], "dco": 9, "googl": 9, "style": 9, "patch": [9, 11, 28, 30, 43], "makefil": 9, "vineyard_clformat": 9, "compli": 9, "cpplint": 9, "cmakefil": 9, "vineyard_cpplint": 9, "titl": 9, "bugfix": [9, 11], "bracket": 9, "1234": [9, 35], "vector": [9, 24, 28, 38, 43], "2345": [9, 41], "pytorch": [9, 28, 33, 43], "rebas": 9, "unless": 9, "merg": 9, "conflict": [9, 10, 30, 42], "branch": 9, "recent": 9, "upstream": 9, "fetch": [9, 16, 22, 30, 41, 45], "mark": [9, 28, 30], "push": [9, 18, 28, 32, 42, 43], "manylinux2014": 9, "reliabl": 9, "pypa": 9, "manylinux1": 9, "concis": 10, "answer": 10, "concern": 10, "post": 10, "multipl": [10, 16, 17, 22, 24, 28, 30, 31, 36, 39, 42, 43, 45, 46], "vast": 10, "parallel": [10, 16, 17, 33], "individu": [10, 16], "reader": [10, 23, 25, 28, 30, 34, 43], "simultan": 10, "absolut": 10, "entiti": [10, 24], "safe": [10, 28], "concurr": [10, 11, 30], "launch": [10, 12, 16, 17, 18, 22, 30, 33, 36, 39], "simpli": [10, 13, 19, 44], "necess": 10, "No": 10, "medium": [10, 18], "kafka": [10, 23], "small": [10, 24], "mini": 10, "consecut": [10, 30, 45], "distinct": [10, 22], "normal": [10, 28, 30, 34], "contrast": [10, 22], "would": [10, 11, 24, 28, 36, 39], "de": [10, 15, 18, 32, 33], "regardless": [10, 42], "axi": [10, 17, 18, 19, 24, 28, 33, 45], "decis": 10, "plan": [10, 11], "b": [10, 13, 16, 19, 22, 25, 30, 35, 36, 39, 41], "h1": 10, "h2": 10, "h3": 10, "h4": 10, "o1": 10, "o2": 10, "respect": [10, 24, 28, 42, 43, 45], "b1": 10, "b2": 10, "initcontain": 10, "although": 10, "whenev": 10, "24": [10, 43, 44], "highli": [10, 44], "why": 10, "try": [10, 16, 18, 25, 28, 30, 32, 44], "again": 10, "cut": 11, "deliv": [11, 32], "hopefulli": 11, "later": [11, 16, 30, 36, 39], "aug": 11, "filesystem": 11, "view": [11, 24, 28, 43], "fashion": [11, 16, 28, 30, 33], "Such": 11, "realloc": [11, 28], "lineag": 11, "mutat": [11, 43], "carefulli": 11, "transpar": [11, 16], "disk": [11, 17, 28], "too": [11, 12, 24, 28], "gpu": [11, 28, 31, 46], "devic": [11, 34], "boarder": 11, "deep": [11, 17, 28, 30], "gnn": 11, "juli": 11, "experiment": [11, 16, 17, 33, 44], "unseal": [11, 28], "onlin": 11, "tne": 11, "june": 11, "compat": [11, 28, 35, 42], "archlinux": 11, "ld_library_path": 11, "backward": [11, 28], "third": 11, "parti": 11, "homebrew": 11, "preliminari": 11, "expect": [11, 28, 33], "investig": 11, "runtim": [11, 45], "mayb": 11, "anoth": [11, 22, 25, 34, 36, 39, 44, 45], "robust": 11, "hub": 11, "chart": [11, 32, 44, 45], "stabl": [11, 16, 28, 42], "full": [11, 22], "far": 11, "take": [11, 18, 22, 30, 33, 38], "half": 11, "sink": [11, 13, 14], "daemonset": [11, 30], "prototyp": [11, 33], "brought": [11, 18], "criterion": 11, "pypi": [11, 45], "dockerhub": 11, "guidanc": [12, 43], "aris": 12, "improp": 12, "error": [12, 13, 28, 30], "send": [12, 22, 28], "etcdserv": 12, "txn": [12, 43], "correctli": 12, "transact": [12, 43], "max": [12, 28], "op": 12, "102400": 12, "permiss": [12, 13, 43, 44], "deni": [12, 13], "root": [12, 13, 18, 24, 28], "either": [12, 13, 28, 39], "degrad": 12, "cgroup": 12, "tune": [12, 38], "hardwar": 12, "incom": 13, "stop": [13, 28], "press": 13, "ctrl": 13, "termin": [13, 33, 42, 44], "writabl": 13, "call": [13, 19, 23, 28, 30, 34], "former": [13, 25], "latter": [13, 25], "ndarrai": [13, 30, 39], "arr": [13, 17, 19, 30], "uniqu": [13, 24, 28, 30], "np": [13, 16, 17, 18, 19, 22, 25, 30, 36, 39, 41, 44, 45], "random": [13, 16, 19, 22, 25, 30, 33, 41, 45], "rand": [13, 16, 19, 22], "o0015c78883eddf1c": 13, "shared_arrai": 13, "39736989": 13, "38047846": 13, "01948815": 13, "38332264": 13, "61671189": 13, "48903213": 13, "03875045": 13, "5873005": 13, "nest": [13, 30, 39], "df": [13, 17, 19, 22, 45], "pd": [13, 16, 17, 18, 19, 22, 25, 33, 41, 42, 45], "weight": [13, 33, 45], "shared_datafram": 13, "hood": 13, "multiprocess": [13, 30, 31, 46], "mp": 13, "def": [13, 16, 17, 18, 23, 25, 30, 33, 39, 45], "randn": [13, 41], "100": [13, 24, 25, 32, 33, 41, 45], "abcd": [13, 41], "sum": [13, 16, 18, 32, 41], "__name__": [13, 25], "__main__": [13, 25], "529080": 13, "969152": 13, "067356": 13, "003676": 13, "dtype": [13, 17, 24, 25, 33, 38, 39, 41], "float64": [13, 17, 22, 41, 44], "beyond": 13, "over": [13, 22, 25, 28, 30], "idl": 13, "glue": 13, "architectur": [13, 21, 22], "overview": [13, 45], "concept": [13, 22, 24, 28], "vcdl": [13, 21, 26], "discov": [13, 31, 46], "natur": [13, 16, 24], "varieti": 14, "empow": 15, "cumbersom": 15, "pickl": [15, 16, 18, 30, 32], "xcom": [15, 16], "compar": [15, 28, 32, 42], "altern": [15, 18, 31, 46], "aw": [15, 18, 32], "s3": [15, 16, 18], "minio": [15, 18, 32, 42], "allevi": [16, 26], "programmat": 16, "author": [16, 43], "monitor": 16, "direct": [16, 19, 28, 30, 38], "acycl": 16, "schedule_interv": 16, "start_dat": 16, "days_ago": 16, "tutorial_taskflow_api_etl": 16, "extract": [16, 33, 38], "data_str": 16, "1001": [16, 45], "301": [16, 45], "27": 16, "1002": 16, "433": 16, "21": 16, "1003": 16, "502": 16, "22": [16, 32], "order_data_dict": 16, "multiple_output": 16, "dict": [16, 18, 19, 25, 28, 30], "total_order_valu": 16, "float": [16, 17, 24, 25, 28, 30], "order": [16, 24, 28, 30], "2f": 16, "order_data": 16, "order_summari": 16, "tutorial_etl_dag": 16, "form": [16, 19, 24, 36, 39, 44, 45], "sequenti": [16, 17, 45], "describ": [16, 24, 29, 30, 44], "excel": 16, "sqlite": 16, "mysql": [16, 42], "postgresql": 16, "hdf": 16, "vineyardxcom": 16, "basexcom": 16, "staticmethod": 16, "serialize_valu": 16, "deserialize_valu": 16, "underli": [16, 22, 28, 30], "celeryexecutor": 16, "might": [16, 18, 30], "necessit": 16, "readili": [16, 44], "scientist": 16, "focu": 16, "logic": [16, 23, 24, 45], "airflow__core__xcom_backend": 16, "airflow__vineyard__ipc_socket": 16, "decor": 16, "default_arg": 16, "taskflow_etl_panda": 16, "taskflow_etl_pandas_dag": 16, "deal": [16, 43], "taskflow": 16, "potenti": 16, "flexibli": [16, 24], "tutorial_taskflow_api": 16, "arrai": [17, 19, 26, 28, 29, 30, 36, 38, 39], "showcas": [17, 43], "blog": 17, "tf_config": 17, "mnist": 17, "duplic": [17, 28], "simul": [17, 42, 45], "builder_context": [17, 30, 33], "dask_context": 17, "dask_preprocess": 17, "get_mnist": 17, "x_train": [17, 18, 45], "y_train": [17, 18, 45], "_": [17, 33], "tf": [17, 19, 33], "kera": 17, "load_data": 17, "uint8": 17, "255": 17, "rang": [17, 25, 33], "astyp": [17, 19, 25], "delai": 17, "dd": [17, 33], "from_delai": 17, "gdf": 17, "concat": [17, 33], "gdf_id": [17, 33], "ml": [17, 19, 33, 40, 42, 46], "register_tf_typ": [17, 33], "resolver_context": [17, 30, 33, 39], "mnist_dataset": 17, "batch_siz": [17, 19, 33], "train_dataset": [17, 33], "repeat": 17, "experimental_distribut": 17, "auto_shard_polici": 17, "autoshardpolici": 17, "off": 17, "train_datasets_no_auto_shard": 17, "with_opt": 17, "build_and_compile_cnn_model": 17, "layer": [17, 33], "inputlay": 17, "input_shap": 17, "28": [17, 32, 36, 39], "reshap": 17, "target_shap": 17, "conv2d": 17, "32": [17, 33], "relu": [17, 33], "flatten": 17, "dens": [17, 33], "loss": [17, 33], "sparsecategoricalcrossentropi": [17, 33], "from_logit": 17, "sgd": 17, "learning_r": [17, 33], "001": [17, 33], "accuraci": [17, 33], "per_worker_batch_s": 17, "64": [17, 28, 30, 32, 44], "multiworkermirroredstrategi": 17, "multi_worker_model": 17, "epoch": [17, 33], "steps_per_epoch": 17, "70": [17, 42], "were": 17, "pre": 17, "downstream": 17, "advantag": [17, 24, 37, 46], "recomput": 17, "repeatedli": 17, "tf_flower": 17, "resnet50": 17, "400": [17, 24], "slot": 17, "get_imag": 17, "idx": [17, 25, 28, 33], "num": 17, "flower_photo": 17, "rglob": 17, "jpg": 17, "rb": 17, "img": 17, "bytesio": 17, "resiz": 17, "224": 17, "preprocess_input": 17, "img_to_arrai": 17, "append": [17, 25, 30, 33], "block_id": 17, "include_top": 17, "pred": 17, "predict": [17, 33, 45], "stack": 17, "100352": 17, "da": 17, "shape": [17, 19, 24, 28, 33], "244": [17, 41], "map_block": 17, "drop_axi": 17, "global_tensor_id": 17, "18": 18, "tell": [18, 30], "prepar": [18, 28, 43, 44, 45], "iri": 18, "starter": 18, "split_data": 18, "str": [18, 30, 45], "tupl": [18, 28, 30], "data_train": 18, "frac": 18, "train_fract": 18, "random_st": 18, "data_test": 18, "drop": [18, 19, 28, 30, 45], "target_column": 18, "x_test": [18, 45], "y_test": [18, 45], "make_predict": 18, "x_train_numpi": 18, "to_numpi": [18, 33], "x_test_numpi": 18, "squared_dist": 18, "nearest_neighbour": 18, "argmin": 18, "y_pred": [18, 45], "iloc": 18, "05": 18, "25": [18, 32, 41, 42], "23": [18, 32], "38": [18, 44], "56": [18, 35, 42], "info": [18, 38, 41, 43, 44], "session": [18, 28, 30], "355": 18, "57": 18, "example_iris_data": 18, "csvdataset": 18, "data_catalog": 18, "343": 18, "memorydataset": 18, "split": [18, 24, 30, 45], "329": 18, "382": 18, "sequential_runn": 18, "85": 18, "argo": 18, "those": [18, 22, 24, 28, 30, 32, 35], "csv": [18, 30, 43], "filepath": 18, "02_intermedi": 18, "credenti": [18, 32], "larger": [18, 24], "sequentialrunn": 18, "45": [18, 44], "34": 18, "vineyarddataset": 18, "modif": [18, 30, 31, 33, 38, 42, 46], "longer": 18, "suffer": 18, "catalog": 18, "rewrit": 18, "unspecifi": 18, "__default__": 18, "ds_name": 18, "download": [18, 32, 42, 43], "walk": [18, 33], "minikub": [18, 32], "grep": [18, 32, 42, 43], "3c92da8241c6": 18, "minut": 18, "ago": [18, 32, 42], "690mb": 18, "yml": [18, 32], "rw": 18, "3685": 18, "jun": 18, "55": 18, "prioriti": [18, 45], "sg6qf": 18, "succeed": [18, 28], "18m": 18, "30": [18, 41, 42, 45], "report": [18, 30], "from_tensor_slic": 19, "data_id": 19, "vineyard_cli": [19, 25, 30], "vin_data": 19, "pop": 19, "bridg": 19, "dictionari": [19, 33], "pa": [19, 30, 39], "from_arrai": [19, 30], "f0": 19, "f1": 19, "row": [19, 24, 28, 45], "from_batch": 19, "inherit": [19, 38], "torch": 19, "customdataset": 19, "tensordataset": 19, "from_numpi": 19, "float32": [19, 33], "col": 19, "f2": 19, "gluon": 19, "mx": 19, "arraydataset": 19, "dmatrix": [19, 30, 39], "vin_tensor_id": 19, "vin_df_id": 19, "feature_nam": [19, 33], "sometim": 19, "kwarg": [19, 23, 30], "vin_rb_id": 19, "vin_tab_id": 19, "pipeline_def": 19, "pipe": [19, 25], "device_id": 19, "num_thread": 19, "pipe_out": 19, "vin_pip": 19, "tensorlist": 19, "depth": 21, "cover": [21, 33, 45], "soon": 21, "smoother": 21, "builtin": 21, "depict": 22, "explain": [22, 24], "consider": 22, "globaltensor": [22, 28], "perspect": 22, "pictur": 22, "aggreg": [22, 25], "suit": [22, 27, 44, 45], "commonli": [22, 24], "presto": 22, "vineyard_ipc_cli": 22, "o00053008257020f8": 22, "_c": [22, 44], "534487": 22, "261941": 22, "901056": 22, "441583": 22, "687568": 22, "671564": 22, "raw": [22, 43], "get_meta": [22, 30, 44], "objectmeta": [22, 28, 29, 30, 38, 39], "nbyte": [22, 24, 28, 30, 39, 44], "1460186430481176": 22, "transient": [22, 30, 44], "__values_": [22, 24], "o0005300822f54d1c": 22, "order_": [22, 44], "shape_": [22, 24, 44], "1460186388165810": 22, "doubl": [22, 24, 44], "value_type_": [22, 24, 44], "value_type_meta_": [22, 44], "f8": [22, 44], "buffer_": [22, 24, 26, 39, 44], "o8005300822d858df": 22, "create_blob": [22, 30], "empti": [22, 28, 30], "blobbuild": [22, 30], "fill": [22, 28, 30], "get_blob": [22, 30], "mock": 22, "abcdefgh1234567890uvwxyz": 22, "buffer_build": [22, 38, 39], "len": [22, 28, 30, 33, 39], "o800532e4ab1f2087": 22, "byte": [22, 28, 30], "memoryview": [22, 30], "vineyard_rpc_cli": [22, 30], "localhost": [22, 32, 33, 43], "o000a45730a85f8f": 22, "884227": 22, "576031": 22, "863040": 22, "069815": 22, "297906": 22, "911874": 22, "facilit": [22, 24, 25], "associ": [22, 25, 28, 30, 38, 45], "absenc": 22, "feasibl": 22, "explicitli": [22, 24, 28, 30, 42], "create_remote_blob": [22, 30], "remoteblobbuild": [22, 30], "get_remote_blob": [22, 30], "remoteblob": [22, 28, 30], "impli": [22, 24, 30], "remote_buffer_build": 22, "remote_blob_meta": 22, "remote_blob": [22, 28], "0x142204870": 22, "subtl": 22, "buffer": [22, 28, 30, 34, 36, 38, 39], "fly": 22, "head": [23, 44], "scheme": [23, 30], "topic": 23, "invok": [23, 28, 30], "dispatch": 23, "registr": 23, "register": 23, "urlpars": 23, "_factori": 23, "rais": [23, 28, 30], "runtimeerror": [23, 30], "unabl": 23, "proper": [23, 30], "local_driv": 23, "importantli": 23, "revis": [23, 44], "fulfil": 23, "compris": [24, 39], "collect": [24, 28, 37, 46], "hierarch": [24, 28, 36, 39], "tree": [24, 28], "idea": [24, 41], "pointer": [24, 28, 30, 34, 42], "length": [24, 30, 38, 39, 44], "column_s": 24, "conform": 24, "simpler": 24, "semant": [24, 28, 35], "o800527ecdf05cff9": 24, "39": [24, 44], "o000527ecdffd95c4": 24, "partition_index_": [24, 44], "1451273207424436": 24, "o800527ecdeaf1015": 24, "o000527ece12e4f0a": 24, "800": 24, "1451273227452968": 24, "columns_": 24, "o000527ece15d374c": 24, "1200": [24, 43], "partition_index_column_": 24, "partition_index_row_": 24, "row_batch_index_": 24, "1451273231074538": 24, "sub": [24, 26], "mere": 24, "piec": 24, "meaning": 24, "interpret": 24, "significantli": [24, 32], "self": [24, 28, 30], "exploit": 24, "amount": [24, 38], "composit": 24, "recurs": [24, 30], "travers": [24, 30], "construct": [24, 28, 30, 34, 38, 39], "shard": 24, "replic": 24, "billion": 24, "subset": 24, "todo": 24, "subsect": 24, "costli": 24, "burden": [24, 26], "categor": [24, 33], "known": [24, 26], "live": [24, 29], "immedi": [24, 28, 30], "progress": 24, "visibl": [24, 28, 30, 35, 36, 39, 44], "notabl": 24, "permit": 24, "plug": 24, "scan": 25, "filter": [25, 45], "thread": 25, "recordbatch": [25, 28, 30], "generate_random_datafram": 25, "item": [25, 29, 41, 43], "total_chunk": 25, "writer": [25, 28, 30, 42], "randint": [25, 45], "chunk_id": 25, "loop": 25, "stopiter": 25, "assert_frame_equ": 25, "break": 25, "test_recordbatch_stream": 25, "bool": [25, 28, 30], "client1": [25, 36, 39], "client2": [25, 36, 39], "stream1": 25, "stream2": 25, "thread1": 25, "thread2": 25, "fundament": 26, "auto": [26, 38], "const": [26, 28, 34, 38], "size_t": [26, 28, 38], "loc": [26, 28, 33], "size_": 26, "reinterpret_cast": [26, 34, 38], "privat": [26, 38], "std": [26, 28, 34, 38], "shared_ptr": [26, 28, 34, 38], "synthes": 26, "treat": [26, 28, 30], "deem": 26, "ffi": 26, "wrapper": [26, 30], "site": 27, "uint64_t": 28, "opaqu": [28, 30], "bit": [28, 30], "unsign": [28, 30], "integ": [28, 29, 30, 33], "objectbas": 28, "enable_shared_from_thi": 28, "scalar": 28, "subclass": 28, "arrowfragmentgroup": 28, "basebinaryarrai": 28, "arraytyp": 28, "baselistarrai": 28, "booleanarrai": 28, "fixedsizebinaryarrai": 28, "fixedsizelistarrai": 28, "hashmap": [28, 38], "prime_number_hash_wi": 28, "equal_to": 28, "hdatafram": 28, "kvcach": 28, "kvcacheblock": 28, "nullarrai": 28, "numericarrai": [28, 39], "parallelstream": 28, "perfecthashmap": 28, "refcntmapobject": 28, "schemaproxi": 28, "arrowfragmentbas": 28, "itensor": 28, "kvtensor": 28, "virtual": [28, 38], "void": [28, 38], "come": 28, "getmetadata": 28, "inlin": 28, "postconstruct": 28, "noth": 28, "though": [28, 36, 39], "_seal": [28, 38], "clientbas": [28, 30], "isloc": [28, 30], "verb": [28, 43], "otherwis": [28, 30], "iff": 28, "ispersist": [28, 30], "isglob": [28, 30], "protect": 28, "attribut": [28, 30, 45], "id_": [28, 38], "mutabl": [28, 30], "meta_": [28, 38], "friend": [28, 38], "plasmacli": 28, "rpcclient": [28, 30], "objectfactori": 28, "objectbuild": [28, 30], "collectionbuild": 28, "arrowfragmentgroupbuild": 28, "blobwrit": [28, 38], "booleanarraybasebuild": 28, "dataframebasebuild": 28, "fixedsizebinaryarraybasebuild": 28, "fixedsizelistarraybasebuild": 28, "kvcacheblockbuild": 28, "kvcachebuild": 28, "kvtensorbuild": 28, "nullarraybasebuild": 28, "parallelstreambasebuild": 28, "recordbatchbasebuild": 28, "refcntmapobjectbuild": 28, "schemaproxybasebuild": 28, "sequencebasebuild": 28, "tensorbasebuild": 28, "overrid": [28, 38], "set_seal": 28, "abl": [28, 30, 34], "readonli": [28, 30], "const_iter": 28, "nlohmann": 28, "iteration_proxy_valu": 28, "setclient": 28, "getclient": 28, "setid": 28, "getid": 28, "getsignatur": 28, "resetsignatur": 28, "reset": [28, 30], "setglob": 28, "settypenam": [28, 38], "type_nam": [28, 38], "gettypenam": 28, "setnbyt": [28, 38], "getnbyt": 28, "reflect": 28, "monopolist": 28, "bulk": [28, 36, 39], "getinstanceid": 28, "forceloc": 28, "haskei": 28, "resetkei": 28, "addkeyvalu": [28, 38], "unordered_map": 28, "unorderedmap": 28, "getkeyvalu": [28, 38], "deduct": 28, "addremoteblob": 28, "addmemb": [28, 38], "member_id": 28, "getmemb": [28, 38], "getmembermeta": 28, "getbuff": 28, "blob_id": [28, 36, 39], "indirect": 28, "setbuff": 28, "memoryusag": 28, "pretti": 28, "timestamp": [28, 30], "millisecond": 28, "insid": [28, 30], "unknown": 28, "tostr": 28, "printmeta": 28, "incomplet": 28, "mutmetadata": 28, "setmetadata": 28, "bufferset": 28, "getbufferset": 28, "unique_ptr": [28, 38], "nobject": 28, "uintptr_t": 28, "stuff": 28, "leav": [28, 43], "copyabl": 28, "basicipccli": 28, "delet": [28, 30, 42, 43, 44, 45], "getdata": 28, "sync_remot": [28, 30], "block": [28, 30], "createdata": 28, "createmetadata": [28, 38], "meta_data": 28, "placehold": 28, "sync": [28, 42], "syncmetadata": 28, "deldata": [28, 34], "yield": [28, 30], "memory_trim": [28, 30], "trim": [28, 30], "pool": [28, 30], "unus": [28, 30], "listdata": 28, "meta_tre": 28, "regular": 28, "express": [28, 30], "glob": 28, "listnam": 28, "createstream": 28, "openstream": 28, "streamopenmod": 28, "fail": [28, 30, 43], "pushnextstreamchunk": 28, "kstreamdrain": 28, "kstreamfinish": 28, "poll": 28, "pullnextstreamchunk": 28, "stopstream": 28, "abort": [28, 30], "dropstream": 28, "ifpersist": 28, "shallowcopi": 28, "target_id": 28, "shallow": [28, 30], "extra_metadata": [28, 30], "feed": [28, 33], "putnam": 28, "assoici": 28, "getnam": 28, "queri": [28, 30], "dropnam": 28, "deregist": 28, "kept": 28, "migrateobject": 28, "result_id": 28, "memorytrim": 28, "kernel": [28, 30, 34], "malloc_trim": [28, 30], "glibc": [28, 30], "evict": 28, "pin": 28, "being": [28, 35], "reload": 28, "possibli": 28, "unpin": 28, "aliv": [28, 30], "disconnect": 28, "ipc_socket": [28, 30, 38, 39], "anonym": 28, "closesess": 28, "ipcsocket": 28, "rpcendpoint": 28, "isipc": 28, "isrpc": 28, "remote_instance_id": [28, 30], "sessionid": 28, "session_id": 28, "clusterinfo": 28, "instancestatu": [28, 30], "struct": [28, 30], "semver": [28, 30], "tryacquirelock": 28, "actural_kei": 28, "acquir": 28, "lock": 28, "tryreleaselock": 28, "unlock": 28, "debug": [28, 30, 42], "sent": [28, 30], "handler": [28, 30], "compression_en": 28, "set_compression_en": 28, "dowrit": 28, "message_out": 28, "doread": 28, "message_in": 28, "connected_": 28, "ipc_socket_": 28, "rpc_endpoint_": 28, "vineyard_conn_": 28, "session_id_": 28, "instance_id_": 28, "server_version_": 28, "support_rpc_compression_": 28, "recursive_mutex": 28, "client_mutex_": 28, "compression_enabled_": 28, "usagetrack": 28, "talk": 28, "usernam": [28, 30], "password": [28, 30], "fetchandgetmetadata": 28, "createblob": [28, 38], "getblob": 28, "bypass": 28, "creatediskblob": 28, "filenam": 28, "smaller": 28, "enlarg": 28, "ftruncat": 28, "getnextstreamchunk": 28, "mutablebuff": [28, 34], "satisfi": 28, "accumul": [28, 30], "getobject": [28, 38], "constructor": [28, 38], "cast": 28, "concret": 28, "runtime_error": 28, "fetchandgetobject": 28, "occur": 28, "throw": 28, "dynamic_cast": 28, "deduc": 28, "int_arrai": 28, "listobjectmeta": 28, "nobuff": [28, 30], "listobject": 28, "issharedmemori": 28, "belong": [28, 30], "region": [28, 30, 32], "side": [28, 30, 39], "isinus": 28, "is_in_us": 28, "cold": 28, "isspil": 28, "is_spil": 28, "allocateds": 28, "createarena": 28, "fd": 28, "available_s": 28, "releasearena": 28, "offset": [28, 30, 39], "source_cli": 28, "select": [28, 30], "plasmaid": 28, "plasma_id": 28, "decreas": 28, "count": 28, "onreleas": 28, "creategpubuff": [28, 34], "createbuff": 28, "getgpubuff": [28, 34], "actual_kei": 28, "releaserequest": 28, "ondelet": 28, "postseal": 28, "getdepend": 28, "bid": 28, "special": 28, "getbuffers": 28, "dropbuff": 28, "deleteobject": 28, "shrinkbuff": 28, "shrink": [28, 30], "shouldn": 28, "madvis": 28, "vineyard_rpc_endpoint": [28, 30], "rpc_endpoint": [28, 30], "tpc": 28, "uint32_t": 28, "unaccess": 28, "isfetch": 28, "createremoteblob": 28, "remoteblobwrit": 28, "getremoteblob": 28, "expens": 28, "explicit": 28, "memory_usag": [28, 30], "memory_limit": [28, 30], "upper": 28, "deferred_request": [28, 30], "defer": 28, "queue": 28, "ipc_connect": [28, 30], "rpc_connect": [28, 30], "unit": [28, 33, 36, 39, 41], "allocated_s": [28, 30], "char": [28, 30, 34, 38], "arrowbuff": 28, "bufferorempti": 28, "valid": [28, 43], "arrowbufferorempti": 28, "makeempti": 28, "fromalloc": 28, "estim": 28, "frompoint": 28, "content": [28, 30, 34], "bytestream": [28, 30], "bareregist": 28, "setbuffersizelimit": 28, "writebyt": 28, "ptr": [28, 30], "writelin": 28, "flushbuff": 28, "readlin": 28, "element": [28, 30, 36, 38, 39], "arraybuild": 28, "arraybasebuild": 28, "vec": [28, 38], "give": [28, 45], "noexcept": 28, "hash": [28, 30], "keyhash": 28, "keyequ": 28, "ska": 28, "detailv3": 28, "sherwood_v3_entri": 28, "hasher": 28, "keyorvaluehash": 28, "equal": 28, "keyorvalueequ": 28, "value_typ": [28, 39], "size_typ": 28, "difference_typ": 28, "ptrdiff_t": 28, "key_equ": 28, "const_refer": 28, "const_point": 28, "flat_hash_table_typ": 28, "sherwood_v3_t": 28, "allocator_trait": 28, "rebind_alloc": 28, "bucket_count": 28, "cell": 28, "load_factor": 28, "factor": [28, 42], "lh": 28, "rh": 28, "hashmapbuild": 28, "hashmapbasebuild": 28, "flat_hash_map": 28, "emplac": [28, 30], "cbegin": 28, "cend": 28, "associatedatabuff": 28, "data_buff": 28, "value_t": 28, "value_pointer_t": 28, "value_const_pointer_t": 28, "arrowtensort": 28, "arrowtensortyp": 28, "int64_t": 28, "stride": 28, "tensor_attribut": 28, "ith": 28, "partition_index": 28, "anytyp": 28, "auxiliary_buff": 28, "arrowtensor": 28, "tensorbuild": 28, "itensorbuild": 28, "set_shap": 28, "set_partition_index": 28, "conncet": 28, "asbatch": 28, "dataframebuild": 28, "partition_index_row": 28, "partition_index_column": 28, "set_row_batch_index": 28, "row_batch_index": 28, "set_index": 28, "addcolumn": 28, "dropcolumn": 28, "bidirectional_iterator_tag": 28, "sequencebuild": 28, "setsiz": 28, "setvalu": 28, "scalarbuild": 28, "scalarbasebuild": 28, "holder": [28, 30], "partition_shap": 28, "localpartit": 28, "globaltensorbuild": 28, "set_partition_shap": 28, "addpartit": 28, "partition_id": 28, "partition_shape_row": 28, "partition_shape_column": 28, "globaldataframebuild": 28, "number_of_partitions_on_row": 28, "number_of_partitions_on_column": 28, "schema": [29, 30], "appear": [29, 30, 38], "listmeta": 29, "objecid": 29, "nolint": 29, "lll": 29, "boolean": 29, "enableverboselog": 29, "whose": 29, "etcdreplica": 29, "reservememori": 29, "envvar": 29, "000043c5c6d5e646": 30, "repr": 30, "74516723525190": 30, "__eq__": 30, "__hash__": 30, "__init__": 30, "__repr__": 30, "__str__": 30, "from_": 30, "param": 30, "word": 30, "seen": 30, "__getitem__": 30, "hashmap_id": 30, "0000347aebe92dd0": 30, "num_elements_": 30, "num_slots_minus_one_": 30, "max_lookups_": 30, "entries_": 30, "__contains__": 30, "global_": 30, "__setitem__": 30, "add_memb": [30, 39], "add_remote_blob": 30, "get_memb": 30, "plain": 30, "set_glob": 30, "vineyard_config": 30, "standalon": [30, 42], "overload": 30, "ipcclient": 30, "login": [30, 42], "tri": 30, "connectionfail": 30, "rare": 30, "resolut": [30, 39], "compress": [30, 32], "create_empty_blob": 30, "create_metadata": [30, 39], "union": 30, "blob_build": 30, "signif": 30, "vineyard_endpoint": 30, "buffer_writ": 30, "blob_meta": 30, "forcedli": 30, "deepli": 30, "object_meta": 30, "drop_nam": 30, "objectnam": 30, "find_shared_memori": 30, "resolvercontext": 30, "arr_id": 30, "00002ec13bc81226": 30, "ignor": [30, 33], "kw": 30, "get_nam": [30, 41], "get_object": [30, 36, 39], "is_ipc": 30, "is_rpc": 30, "is_shared_memori": 30, "list_metadata": 30, "wildcard": 30, "list_nam": 30, "list_object": 30, "hostid": 30, "54058007061210": 30, "6882550126788354072": 30, "15": [30, 33, 42], "48843417291806": 30, "6882568290204737414": 30, "buildercontext": 30, "arang": 30, "decid": 30, "put_nam": 30, "alia": [30, 32], "shallow_copi": 30, "primit": 30, "spread": 30, "sync_meta": 30, "with_compress": 30, "disabl": 30, "with_spread": 30, "is_fetch": 30, "ident": 30, "statist": 30, "360": 30, "268435456": 30, "is_empti": 30, "th": 30, "parent_context": 30, "get_current_resolv": 30, "callabl": 30, "popul": [30, 38], "outsid": 30, "xgboost": [30, 39], "numpy_resolv": [30, 39], "obj": [30, 39], "default_resolver_context": [30, 39], "xgboost_resolv": [30, 39], "obvious": 30, "stackabl": [30, 39], "nestabl": 30, "driver_context": 30, "type_id": 30, "translat": 30, "mro": 30, "chain": 30, "get_current_build": 30, "drivercontext": 30, "get_current_driv": 30, "popult": 30, "shared_memori": [30, 31, 46], "sharedmemori": [30, 31, 35, 46], "buf": 30, "freez": [30, 35], "unlink": 30, "destroi": [30, 44], "shareablelist": [30, 35], "shareabl": 30, "becaus": [30, 36], "pack": 30, "storabl": 30, "charact": 30, "slightli": [30, 35, 42], "get_current_socket": 30, "try_init": 30, "valueerror": 30, "start_vineyardd": 30, "vineyardd_path": 30, "rpc_socket_port": 30, "popen": [30, 33], "redi": 30, "bundl": 30, "roughli": 30, "128974848": 30, "129k": 30, "129m": 30, "123mi": 30, "1g": 30, "10gi": 30, "subprocess": [30, 33], "proc": [30, 42], "privod": 30, "vineyard_imag": 30, "vineyard_image_pull_polici": 30, "vineyard_image_pull_secret": 30, "k8s_client": 30, "apicli": 30, "delete_kubernetes_object": 30, "timeout_second": 30, "60": [30, 42], "chunk_hook": 30, "proceed": 30, "orc": 30, "parquet": 30, "pyarrow": [30, 39, 45], "stateless": 30, "guarante": [30, 45], "exchange_column": 30, "frame": [30, 37, 46], "discoveri": 30, "dataframestream": 30, "studi": [31, 46], "intuit": [31, 46], "eleg": [31, 46], "multi": [32, 33], "v1alpha4": [32, 44], "plane": [32, 43, 44], "kindest": [32, 43, 44], "7698c96655": [32, 42], "jg2d": 32, "b888f4458": [32, 42], "x4qf2": 32, "8g": 32, "8gi": 32, "jump": 32, "minioadmin": 32, "bucket": [32, 45], "s3api": 32, "9000": 32, "min": 32, "mc": 32, "amd64": 32, "chmod": 32, "mv": 32, "mb": 32, "conf": 32, "benchmark_aws_s3": 32, "client_kwarg": 32, "aws_access_key_id": 32, "aws_secret_access_kei": 32, "region_nam": 32, "fceaeb5a6688": 32, "07gb": 32, "multipli": 32, "500": [32, 45], "watch": [32, 42, 43], "similarli": [32, 33, 42], "liter": 32, "access_key_id": 32, "secret_access_kei": 32, "2000": 32, "cloudpickl": 32, "calcul": 32, "13": [32, 33, 42, 45], "74": 32, "84": 32, "267": 32, "109": 32, "164": 32, "322": 32, "510": 32, "231": 32, "335": 32, "632": 32, "1069": 32, "comparison": 32, "impress": 32, "domin": 32, "outperform": 32, "margin": 32, "thank": [32, 43, 44], "avoid": 32, "zstd": 32, "upload": [32, 42], "growth": 33, "mimic": 33, "facto": 33, "standard": 33, "horovod": 33, "easi": 33, "tensorflow": 33, "mxnet": 33, "huge": 33, "principl": [33, 38], "covertyp": 33, "uci": 33, "forest": 33, "cartograph": 33, "506": 33, "011": 33, "accordingli": 33, "notebook": 33, "sp": 33, "dask_work": 33, "read_csv": 33, "raw_data": 33, "covtyp": 33, "header": 33, "encod": 33, "represent": 33, "warn": 33, "filterwarn": 33, "soil_type_valu": 33, "soil_type_": 33, "wilderness_area_valu": 33, "area_type_": 33, "soil_typ": 33, "lambda": 33, "nonzero": 33, "wilderness_area": 33, "csv_header": 33, "elev": 33, "slope": 33, "horizontal_distance_to_hydrologi": 33, "vertical_distance_to_hydrologi": 33, "horizontal_distance_to_roadwai": 33, "hillshade_9am": 33, "hillshade_noon": 33, "hillshade_3pm": 33, "horizontal_distance_to_fire_point": 33, "cover_typ": 33, "54": [33, 42], "ignore_index": 33, "register_dask_typ": 33, "get_dataset_from_csv": 33, "csv_file_path": 33, "shuffl": 33, "make_csv_dataset": 33, "column_nam": 33, "column_default": 33, "label_nam": 33, "target_feature_nam": 33, "num_epoch": 33, "procedur": 33, "test_dataset": 33, "run_experi": 33, "adam": 33, "sparsecategoricalaccuraci": 33, "train_data_fil": 33, "test_data_fil": 33, "histori": 33, "get_dataset_from_vineyard": 33, "len_test": 33, "hvd": 33, "distributedoptim": 33, "callback": 33, "broadcast": 33, "rank": 33, "broadcastglobalvariablescallback": 33, "target_feature_label": 33, "numeric_feature_nam": 33, "categorical_features_with_vocabulari": 33, "categorical_feature_nam": 33, "num_class": 33, "dropout_r": 33, "265": [33, 42], "hidden_unit": 33, "create_model_input": 33, "els": 33, "spars": 33, "hot": 33, "categoryencod": 33, "memor": 33, "dimension": 33, "embed": 33, "unseen": 33, "combin": [33, 43], "stringlookup": 33, "encode_input": 33, "use_embed": 33, "encoded_featur": 33, "vocabulari": 33, "lookup": 33, "mask": 33, "token": 33, "nor": 33, "oov": 33, "mask_token": 33, "num_oov_indic": 33, "output_mod": 33, "embedding_dim": 33, "math": 33, "sqrt": 33, "dimens": 33, "input_dim": 33, "output_dim": 33, "expand_dim": 33, "all_featur": 33, "baselin": 33, "create_baseline_model": 33, "batchnorm": 33, "dropout": 33, "softmax": 33, "baseline_model": 33, "shutdown": 33, "horovodrun": 33, "worri": 33, "cudaipcopenmemhandl": 34, "ppu": 34, "raii": 34, "nullptr": [34, 38], "return_on_error": [34, 38], "data_s": 34, "is_cpu": 34, "is_mut": 34, "mutable_data": 34, "printkernel": 34, "cudabuffermirror": 34, "mirror": 34, "memcpi": [34, 38], "cudahostalloc": 34, "destruct": 34, "printf": 34, "gpumalloc_test": 34, "cu": 34, "bb": 35, "78": 35, "o8000000119aa10c0": 35, "frozen": 35, "aka": 35, "value1": 35, "shm": 35, "segment": [36, 39], "o800000011cfa7040": [36, 39], "sake": [36, 39], "simplic": [36, 39], "sock1": [36, 39], "sock2": [36, 39], "id1": [36, 39], "id2": [36, 39], "obj1": [36, 39], "obj2": [36, 39], "id_pair": [36, 39], "obj_pair": [36, 39], "value_pair": [36, 39], "tailor": [37, 46], "instantli": [37, 46], "craft": [37, 46], "snippet": 38, "grasp": 38, "assert": 38, "__attribute__": 38, "static_pointer_cast": 38, "helper": 38, "stub": 38, "factori": 38, "human": 38, "readabl": 38, "int32": 38, "int32_t": 38, "dynamic_pointer_cast": 38, "vectorbuild": 38, "static_cast": 38, "malloc": 38, "sizeof": 38, "ok": 38, "make_shar": 38, "buffer_object": 38, "argc": 38, "argv": 38, "vineyard_check_ok": 38, "ipcserv": 38, "cout": 38, "endl": 38, "dsl": 38, "stai": 38, "sneak": 38, "peek": 38, "mod": [38, 43], "numeric_array_build": 39, "length_": 39, "null_count_": 39, "null_count": 39, "offset_": 39, "null_bitmap": 39, "null_bitmap_": 39, "numeric_array_resolv": 39, "normalize_dtyp": 39, "from_numpy_dtyp": 39, "as_arrow_buff": 39, "from_buff": 39, "builder_ctx": 39, "resolver_ctx": 39, "revert": 39, "rout": [40, 46], "central": [40, 46], "test_datafram": 41, "xxxxabcd": 41, "test_basic_data_unit": 41, "infin": [41, 44], "168469": 41, "19": [41, 44], "269489": 41, "332533": 41, "714950": 41, "2345000505447388": 41, "07": 41, "21t15": 41, "42": 41, "981": 41, "0800": 41, "lapp": 41, "owid": 41, "nomin": 41, "gate": 41, "5fd45fdd66": 41, "fq55z": 41, "3m37": 41, "qjr5c": 41, "35": 41, "ssqb7": 41, "29": 41, "3m53": 41, "dataframe_obj": 41, "unit_obj": 41, "587912": 41, "059792": 41, "863514": 41, "682567": 41, "quiet": 41, "slow": 42, "speed": 42, "cli": 42, "648fc9b7bf": 42, "zwnhd": 42, "4d3h": 42, "79c8ffb879": 42, "6k8mk": 42, "f9kkr": 42, "lzgwz": 42, "csidriv": 42, "fb7cb5b5d": 42, "nlrx": 42, "4m23": 42, "69j77": 42, "k85hb": 42, "zhfz4": 42, "read_pickl": [42, 45], "write_pickl": 42, "volumeop": 42, "storageclass_nam": 42, "kubflow": 42, "choos": 42, "5628953ffe08": 42, "47gb": 42, "94c8c75b960a": 42, "5aab1b120261": 42, "5246d09e6f5": 42, "nf": 42, "mnt": 42, "rbac": [42, 43], "kubeflow_registri": 42, "gcr": 42, "awk": [42, 43, 44], "exec": [42, 43, 44], "crictl": 42, "argoexec": 42, "complianc": 42, "sha256": [42, 43], "0ce9bf20ac9cbb21e84ff0762d5ae508d21e9c85fde2b14b51363bd1b8cd7528": 42, "quai": 42, "ft6sj": 42, "4d1h": 42, "sfrjd": 42, "data_multipli": 42, "4000": 42, "5000": [42, 45], "6000": [42, 45], "3000": 42, "ir": 42, "recogn": 42, "pipeline_vers": 42, "kustom": [42, 43], "ref": 42, "condit": [42, 43], "5c95fc7fdd": 42, "d65cf": 42, "49m": 42, "6c84679764": 42, "k8q6j": 42, "86bf69dc54": 42, "2brxq": 42, "envoi": 42, "6448d544f5": 42, "z4sc8": 42, "784b8b5fb4": 42, "8mtm7": 42, "79c5499dd8": 42, "6jjmm": 42, "65dff76b66": 42, "tdtx5": 42, "6546dcc959": 42, "k8t84": 42, "48m": 42, "persistenceag": 42, "79479cdb74": 42, "q6lq9": 42, "scheduledworkflow": 42, "5cbdc7d885": 42, "lx9r7": 42, "ui": 42, "7c94d6f4b7": 42, "z2tv": 42, "viewer": 42, "685f449686": 42, "bz55g": 42, "visualizationserv": 42, "7c8f97864d": 42, "sp8p6": 42, "c999c6c8": 42, "nwp9d": 42, "proxi": [42, 43, 44], "agent": 42, "77d7b57c99": 42, "plrpb": 42, "crashloopbackoff": 42, "2m17": 42, "6c85bc4f95": 42, "dw889": 42, "portforward": 42, "svc": 42, "8088": 42, "echo": 42, "sy": 42, "vm": 42, "drop_cach": 42, "14000": 42, "18000": 42, "21000": 42, "317": 42, "270": 42, "403": 42, "331": 42, "504": 42, "389": 42, "affect": 42, "But": 42, "215": 42, "140": 42, "298": 42, "198": 42, "398": 42, "257": 42, "33": 42, "75": 42, "faster": 42, "02": 42, "76": 42, "93": [42, 44], "nearli": 42, "constant": [42, 45], "pars": 42, "That": 42, "276": 42, "229": 42, "365": 42, "291": 42, "440": 42, "352": 42, "createvolum": 42, "deletevolum": 42, "213": 42, "133": 42, "302": 42, "208": 42, "377": 42, "8500": 42, "12000": 42, "73": 42, "15000": 42, "88": 42, "almost": 42, "summari": 42, "turn": 42, "reduct": 42, "fraudul": 43, "classifi": 43, "purchas": 43, "reproduc": 43, "a16c878c5091c1e5c9eff0a1fca065665f47edb4c8c75408b3d33e22f0ec0d05": 43, "cni": [43, 44], "storageclass": [43, 44], "5001": [43, 45], "c3a672704524": 43, "b14a7037d2e7": 43, "8d7366c22fd8": 43, "digest": 43, "ea06c833351f19c5db28163406c55e2108676c27fdafea7652500c55ce333b9d": 43, "946": 43, "opt": 43, "gsbot": 43, "rolenam": 43, "maxdesclen": 43, "edit": [43, 45], "customresourcedefinit": 43, "apiextens": 43, "serviceaccount": 43, "clusterrol": [43, 44], "rolebind": 43, "clusterrolebind": 43, "mutatingwebhookconfigur": 43, "admissionregistr": 43, "validatingwebhookconfigur": 43, "met": 43, "verifi": 43, "68": 43, "7f569b57c5": 43, "46tgq": 43, "6ffcb96cbc": 43, "gs2v9": 43, "67": 43, "n59gg": 43, "xwpzd": 43, "curl": 43, "ol": 43, "githubusercont": 43, "gstest": 43, "master": [43, 44], "apigroup": 43, "bug": 44, "coredn": 44, "6d4b75cb6d": 44, "k2sk2": 44, "xm4dt": 44, "52": 44, "kindnet": 44, "fp24b": 44, "h6swp": 44, "mtkd4": 44, "zxxpd": 44, "apiserv": 44, "6zgq2": 44, "8vghn": 44, "c7vz5": 44, "kd4zz": 44, "9cd9bd544": 44, "2vrtq": 44, "2m30": 44, "114": 44, "newest": 44, "hang": 44, "tight": 44, "grab": 44, "happi": 44, "wed": 44, "jan": 44, "uninstal": 44, "fun": 44, "5bcbb75fb6": 44, "cfdpk": 44, "153": 44, "134": 44, "101": [44, 45], "879798cb6": 44, "qpvtw": 44, "2m59": 44, "x4m2x": 44, "matur": 44, "golang": 44, "6fd84bc897": 44, "27glp": 44, "tlb22": 44, "onam": 44, "shell": [44, 45], "objid": 44, "o001027d7c86a49f0": 44, "o801027d7c85c472": 44, "4547407361228035": 44, "tail": 44, "deprec": 44, "rpc_client": 44, "vineyardruntim": 45, "22gb": 45, "ossutil": 45, "divid": 45, "insuffici": 45, "num_row": 45, "estat": 45, "market": 45, "pkl": 45, "22g": 45, "10000": 45, "mssubclass": 45, "201": 45, "lotfrontag": 45, "50": 45, "151": 45, "lotarea": 45, "20001": 45, "overallqu": 45, "overallcond": 45, "yearbuilt": 45, "1900": 45, "yearremodadd": 45, "masvnrarea": 45, "bsmtfinsf1": 45, "2001": 45, "bsmtfinsf2": 45, "bsmtunfsf": 45, "totalbsmtsf": 45, "3001": 45, "1stflrsf": 45, "4001": 45, "2ndflrsf": 45, "lowqualfinsf": 45, "grlivarea": 45, "bsmtfullbath": 45, "bsmthalfbath": 45, "fullbath": 45, "halfbath": 45, "bedroomabvgr": 45, "kitchenabvgr": 45, "totrmsabvgrd": 45, "fireplac": 45, "garageyrblt": 45, "garagecar": 45, "garagearea": 45, "wooddecksf": 45, "501": 45, "openporchsf": 45, "enclosedporch": 45, "3ssnporch": 45, "screenporch": 45, "poolarea": 45, "miscval": 45, "totalroom": 45, "garageag": 45, "31": 45, "remodag": 45, "houseag": 45, "totalbath": 45, "totalporchsf": 45, "totalsf": 45, "6001": 45, "totalarea": 45, "mosold": 45, "yrsold": 45, "2006": 45, "salepric": 45, "50000": 45, "800001": 45, "to_pickl": 45, "cp": 45, "aliyun": 45, "zh": 45, "spm": 45, "a2c4g": 45, "11186623": 45, "i3": 45, "cloudn": 45, "devel": 45, "subtask": 45, "constraint": 45, "fuse": 45, "pluginsprofil": 45, "pluginconfig": 45, "lcontrol": 45, "appendix": 45, "client_config": 45, "clientconfig": 45, "fluid_client": 45, "fluidclient": 45, "create_dataset": 45, "dataset_nam": 45, "get_dataset": 45, "30gi": 45, "bind_runtim": 45, "runtime_typ": 45, "vineyard_runtime_kind": 45, "cache_capacity_gib": 45, "cache_medium": 45, "mem": 45, "sklearn": 45, "model_select": 45, "train_test_split": 45, "4800": 45, "del": 45, "test_siz": 45, "linear_model": 45, "linearregress": 45, "joblib": 45, "x_train_data": 45, "y_train_data": 45, "mean_squared_error": 45, "x_test_data": 45, "y_test_data": 45, "err": 45, "packages_to_instal": 45, "scikit": 45, "pip_index_url": 45, "tuna": 45, "tsinghua": 45, "preprocess_processor": 45, "create_processor": 45, "train_processor": 45, "test_processor": 45, "processor": 45, "dataset_mountpath": 45, "run_id": 45, "suggest": 45, "encapsul": 45, "coher": 45, "orderli": 45, "cleanup": 45, "clean": 45}, "objects": {"": [[28, 0, 1, "_CPPv4I0EN8vineyard5ArrayE", "vineyard::Array"], [28, 1, 1, "_CPPv4N8vineyard5Array9ConstructERK10ObjectMeta", "vineyard::Array::Construct"], [28, 2, 1, "_CPPv4N8vineyard5Array9ConstructERK10ObjectMeta", "vineyard::Array::Construct::meta"], [28, 1, 1, "_CPPv4N8vineyard5Array6CreateEv", "vineyard::Array::Create"], [28, 3, 1, "_CPPv4I0EN8vineyard5ArrayE", "vineyard::Array::T"], [28, 1, 1, "_CPPv4NK8vineyard5Array4dataEv", "vineyard::Array::data"], [28, 1, 1, "_CPPv4NK8vineyard5ArrayixE6size_t", "vineyard::Array::operator[]"], [28, 2, 1, "_CPPv4NK8vineyard5ArrayixE6size_t", "vineyard::Array::operator[]::loc"], [28, 1, 1, "_CPPv4NK8vineyard5Array4sizeEv", "vineyard::Array::size"], [28, 0, 1, "_CPPv4I0EN8vineyard12ArrayBuilderE", "vineyard::ArrayBuilder"], [28, 1, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6Client6size_t", "vineyard::ArrayBuilder::ArrayBuilder"], [28, 1, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientPK1T6size_t", "vineyard::ArrayBuilder::ArrayBuilder"], [28, 1, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientRKNSt6vectorI1TEE", "vineyard::ArrayBuilder::ArrayBuilder"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6Client6size_t", "vineyard::ArrayBuilder::ArrayBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientPK1T6size_t", "vineyard::ArrayBuilder::ArrayBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientRKNSt6vectorI1TEE", "vineyard::ArrayBuilder::ArrayBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientPK1T6size_t", "vineyard::ArrayBuilder::ArrayBuilder::data"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6Client6size_t", "vineyard::ArrayBuilder::ArrayBuilder::size"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientPK1T6size_t", "vineyard::ArrayBuilder::ArrayBuilder::size"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientRKNSt6vectorI1TEE", "vineyard::ArrayBuilder::ArrayBuilder::vec"], [28, 1, 1, "_CPPv4N8vineyard12ArrayBuilder5BuildER6Client", "vineyard::ArrayBuilder::Build"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilder5BuildER6Client", "vineyard::ArrayBuilder::Build::client"], [28, 3, 1, "_CPPv4I0EN8vineyard12ArrayBuilderE", "vineyard::ArrayBuilder::T"], [28, 1, 1, "_CPPv4N8vineyard12ArrayBuilder4dataEv", "vineyard::ArrayBuilder::data"], [28, 1, 1, "_CPPv4NK8vineyard12ArrayBuilder4dataEv", "vineyard::ArrayBuilder::data"], [28, 1, 1, "_CPPv4N8vineyard12ArrayBuilderixE6size_t", "vineyard::ArrayBuilder::operator[]"], [28, 2, 1, "_CPPv4N8vineyard12ArrayBuilderixE6size_t", "vineyard::ArrayBuilder::operator[]::idx"], [28, 1, 1, "_CPPv4NK8vineyard12ArrayBuilder4sizeEv", "vineyard::ArrayBuilder::size"], [28, 1, 1, "_CPPv4N8vineyard12ArrayBuilderD0Ev", "vineyard::ArrayBuilder::~ArrayBuilder"], [28, 0, 1, "_CPPv4N8vineyard4BlobE", "vineyard::Blob"], [28, 1, 1, "_CPPv4NK8vineyard4Blob11ArrowBufferEv", "vineyard::Blob::ArrowBuffer"], [28, 1, 1, "_CPPv4NK8vineyard4Blob18ArrowBufferOrEmptyEv", "vineyard::Blob::ArrowBufferOrEmpty"], [28, 1, 1, "_CPPv4NK8vineyard4Blob6BufferEv", "vineyard::Blob::Buffer"], [28, 1, 1, "_CPPv4NK8vineyard4Blob13BufferOrEmptyEv", "vineyard::Blob::BufferOrEmpty"], [28, 1, 1, "_CPPv4N8vineyard4Blob9ConstructERK10ObjectMeta", "vineyard::Blob::Construct"], [28, 2, 1, "_CPPv4N8vineyard4Blob9ConstructERK10ObjectMeta", "vineyard::Blob::Construct::meta"], [28, 1, 1, "_CPPv4N8vineyard4Blob6CreateEv", "vineyard::Blob::Create"], [28, 1, 1, "_CPPv4NK8vineyard4Blob4DumpEv", "vineyard::Blob::Dump"], [28, 1, 1, "_CPPv4N8vineyard4Blob13FromAllocatorER6ClientK8ObjectIDK9uintptr_tK6size_t", "vineyard::Blob::FromAllocator"], [28, 2, 1, "_CPPv4N8vineyard4Blob13FromAllocatorER6ClientK8ObjectIDK9uintptr_tK6size_t", "vineyard::Blob::FromAllocator::client"], [28, 2, 1, "_CPPv4N8vineyard4Blob13FromAllocatorER6ClientK8ObjectIDK9uintptr_tK6size_t", "vineyard::Blob::FromAllocator::object_id"], [28, 2, 1, "_CPPv4N8vineyard4Blob13FromAllocatorER6ClientK8ObjectIDK9uintptr_tK6size_t", "vineyard::Blob::FromAllocator::pointer"], [28, 2, 1, "_CPPv4N8vineyard4Blob13FromAllocatorER6ClientK8ObjectIDK9uintptr_tK6size_t", "vineyard::Blob::FromAllocator::size"], [28, 1, 1, "_CPPv4N8vineyard4Blob11FromPointerER6ClientK9uintptr_tK6size_t", "vineyard::Blob::FromPointer"], [28, 2, 1, "_CPPv4N8vineyard4Blob11FromPointerER6ClientK9uintptr_tK6size_t", "vineyard::Blob::FromPointer::client"], [28, 2, 1, "_CPPv4N8vineyard4Blob11FromPointerER6ClientK9uintptr_tK6size_t", "vineyard::Blob::FromPointer::pointer"], [28, 2, 1, "_CPPv4N8vineyard4Blob11FromPointerER6ClientK9uintptr_tK6size_t", "vineyard::Blob::FromPointer::size"], [28, 1, 1, "_CPPv4N8vineyard4Blob9MakeEmptyER6Client", "vineyard::Blob::MakeEmpty"], [28, 2, 1, "_CPPv4N8vineyard4Blob9MakeEmptyER6Client", "vineyard::Blob::MakeEmpty::client"], [28, 1, 1, "_CPPv4NK8vineyard4Blob14allocated_sizeEv", "vineyard::Blob::allocated_size"], [28, 1, 1, "_CPPv4NK8vineyard4Blob4dataEv", "vineyard::Blob::data"], [28, 1, 1, "_CPPv4NK8vineyard4Blob4sizeEv", "vineyard::Blob::size"], [28, 0, 1, "_CPPv4N8vineyard10BlobWriterE", "vineyard::BlobWriter"], [28, 1, 1, "_CPPv4N8vineyard10BlobWriter5AbortER6Client", "vineyard::BlobWriter::Abort"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter5AbortER6Client", "vineyard::BlobWriter::Abort::client"], [28, 1, 1, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERKNSt6stringE", "vineyard::BlobWriter::AddKeyValue"], [28, 1, 1, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERRNSt6stringE", "vineyard::BlobWriter::AddKeyValue"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERKNSt6stringE", "vineyard::BlobWriter::AddKeyValue::key"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERRNSt6stringE", "vineyard::BlobWriter::AddKeyValue::key"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERKNSt6stringE", "vineyard::BlobWriter::AddKeyValue::value"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERRNSt6stringE", "vineyard::BlobWriter::AddKeyValue::value"], [28, 1, 1, "_CPPv4NK8vineyard10BlobWriter6BufferEv", "vineyard::BlobWriter::Buffer"], [28, 1, 1, "_CPPv4N8vineyard10BlobWriter5BuildER6Client", "vineyard::BlobWriter::Build"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter5BuildER6Client", "vineyard::BlobWriter::Build::client"], [28, 1, 1, "_CPPv4NK8vineyard10BlobWriter4DumpEv", "vineyard::BlobWriter::Dump"], [28, 1, 1, "_CPPv4N8vineyard10BlobWriter6ShrinkER6ClientK6size_t", "vineyard::BlobWriter::Shrink"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter6ShrinkER6ClientK6size_t", "vineyard::BlobWriter::Shrink::client"], [28, 2, 1, "_CPPv4N8vineyard10BlobWriter6ShrinkER6ClientK6size_t", "vineyard::BlobWriter::Shrink::size"], [28, 1, 1, "_CPPv4N8vineyard10BlobWriter4dataEv", "vineyard::BlobWriter::data"], [28, 1, 1, "_CPPv4NK8vineyard10BlobWriter4dataEv", "vineyard::BlobWriter::data"], [28, 1, 1, "_CPPv4NK8vineyard10BlobWriter2idEv", "vineyard::BlobWriter::id"], [28, 1, 1, "_CPPv4NK8vineyard10BlobWriter4sizeEv", "vineyard::BlobWriter::size"], [28, 0, 1, "_CPPv4N8vineyard10ByteStreamE", "vineyard::ByteStream"], [28, 1, 1, "_CPPv4N8vineyard10ByteStream6CreateEv", "vineyard::ByteStream::Create"], [28, 1, 1, "_CPPv4N8vineyard10ByteStream11FlushBufferEv", "vineyard::ByteStream::FlushBuffer"], [28, 1, 1, "_CPPv4N8vineyard10ByteStream8ReadLineERNSt6stringE", "vineyard::ByteStream::ReadLine"], [28, 2, 1, "_CPPv4N8vineyard10ByteStream8ReadLineERNSt6stringE", "vineyard::ByteStream::ReadLine::line"], [28, 1, 1, "_CPPv4N8vineyard10ByteStream18SetBufferSizeLimitE6size_t", "vineyard::ByteStream::SetBufferSizeLimit"], [28, 2, 1, "_CPPv4N8vineyard10ByteStream18SetBufferSizeLimitE6size_t", "vineyard::ByteStream::SetBufferSizeLimit::limit"], [28, 1, 1, "_CPPv4N8vineyard10ByteStream10WriteBytesEPKc6size_t", "vineyard::ByteStream::WriteBytes"], [28, 2, 1, "_CPPv4N8vineyard10ByteStream10WriteBytesEPKc6size_t", "vineyard::ByteStream::WriteBytes::len"], [28, 2, 1, "_CPPv4N8vineyard10ByteStream10WriteBytesEPKc6size_t", "vineyard::ByteStream::WriteBytes::ptr"], [28, 1, 1, "_CPPv4N8vineyard10ByteStream9WriteLineERKNSt6stringE", "vineyard::ByteStream::WriteLine"], [28, 2, 1, "_CPPv4N8vineyard10ByteStream9WriteLineERKNSt6stringE", "vineyard::ByteStream::WriteLine::line"], [28, 0, 1, "_CPPv4N8vineyard6ClientE", "vineyard::Client"], [28, 1, 1, "_CPPv4N8vineyard6Client13AllocatedSizeEK8ObjectIDR6size_t", "vineyard::Client::AllocatedSize"], [28, 2, 1, "_CPPv4N8vineyard6Client13AllocatedSizeEK8ObjectIDR6size_t", "vineyard::Client::AllocatedSize::id"], [28, 2, 1, "_CPPv4N8vineyard6Client13AllocatedSizeEK8ObjectIDR6size_t", "vineyard::Client::AllocatedSize::size"], [28, 1, 1, "_CPPv4N8vineyard6Client6ClientEv", "vineyard::Client::Client"], [28, 1, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringE", "vineyard::Client::Connect"], [28, 1, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringE", "vineyard::Client::Connect"], [28, 1, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Connect"], [28, 1, 1, "_CPPv4N8vineyard6Client7ConnectEv", "vineyard::Client::Connect"], [28, 2, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringE", "vineyard::Client::Connect::ipc_socket"], [28, 2, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Connect::ipc_socket"], [28, 2, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringE", "vineyard::Client::Connect::password"], [28, 2, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Connect::password"], [28, 2, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringE", "vineyard::Client::Connect::username"], [28, 2, 1, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Connect::username"], [28, 1, 1, "_CPPv4N8vineyard6Client11CreateArenaEK6size_tRiR6size_tR9uintptr_tR9uintptr_t", "vineyard::Client::CreateArena"], [28, 2, 1, "_CPPv4N8vineyard6Client11CreateArenaEK6size_tRiR6size_tR9uintptr_tR9uintptr_t", "vineyard::Client::CreateArena::available_size"], [28, 2, 1, "_CPPv4N8vineyard6Client11CreateArenaEK6size_tRiR6size_tR9uintptr_tR9uintptr_t", "vineyard::Client::CreateArena::base"], [28, 2, 1, "_CPPv4N8vineyard6Client11CreateArenaEK6size_tRiR6size_tR9uintptr_tR9uintptr_t", "vineyard::Client::CreateArena::fd"], [28, 2, 1, "_CPPv4N8vineyard6Client11CreateArenaEK6size_tRiR6size_tR9uintptr_tR9uintptr_t", "vineyard::Client::CreateArena::size"], [28, 2, 1, "_CPPv4N8vineyard6Client11CreateArenaEK6size_tRiR6size_tR9uintptr_tR9uintptr_t", "vineyard::Client::CreateArena::space"], [28, 1, 1, "_CPPv4N8vineyard6Client10CreateBlobE6size_tRNSt10unique_ptrI10BlobWriterEE", "vineyard::Client::CreateBlob"], [28, 2, 1, "_CPPv4N8vineyard6Client10CreateBlobE6size_tRNSt10unique_ptrI10BlobWriterEE", "vineyard::Client::CreateBlob::blob"], [28, 2, 1, "_CPPv4N8vineyard6Client10CreateBlobE6size_tRNSt10unique_ptrI10BlobWriterEE", "vineyard::Client::CreateBlob::size"], [28, 1, 1, "_CPPv4N8vineyard6Client11CreateBlobsERKNSt6vectorI6size_tEERNSt6vectorINSt10unique_ptrI10BlobWriterEEEE", "vineyard::Client::CreateBlobs"], [28, 2, 1, "_CPPv4N8vineyard6Client11CreateBlobsERKNSt6vectorI6size_tEERNSt6vectorINSt10unique_ptrI10BlobWriterEEEE", "vineyard::Client::CreateBlobs::blobs"], [28, 2, 1, "_CPPv4N8vineyard6Client11CreateBlobsERKNSt6vectorI6size_tEERNSt6vectorINSt10unique_ptrI10BlobWriterEEEE", "vineyard::Client::CreateBlobs::sizes"], [28, 1, 1, "_CPPv4N8vineyard6Client12CreateBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateBuffer"], [28, 2, 1, "_CPPv4N8vineyard6Client12CreateBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateBuffer::buffer"], [28, 2, 1, "_CPPv4N8vineyard6Client12CreateBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateBuffer::id"], [28, 2, 1, "_CPPv4N8vineyard6Client12CreateBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateBuffer::payload"], [28, 2, 1, "_CPPv4N8vineyard6Client12CreateBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateBuffer::size"], [28, 1, 1, "_CPPv4N8vineyard6Client13CreateBuffersERKNSt6vectorI6size_tEERNSt6vectorI8ObjectIDEERNSt6vectorI7PayloadEERNSt6vectorINSt10shared_ptrI13MutableBufferEEEE", "vineyard::Client::CreateBuffers"], [28, 2, 1, "_CPPv4N8vineyard6Client13CreateBuffersERKNSt6vectorI6size_tEERNSt6vectorI8ObjectIDEERNSt6vectorI7PayloadEERNSt6vectorINSt10shared_ptrI13MutableBufferEEEE", "vineyard::Client::CreateBuffers::buffers"], [28, 2, 1, "_CPPv4N8vineyard6Client13CreateBuffersERKNSt6vectorI6size_tEERNSt6vectorI8ObjectIDEERNSt6vectorI7PayloadEERNSt6vectorINSt10shared_ptrI13MutableBufferEEEE", "vineyard::Client::CreateBuffers::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client13CreateBuffersERKNSt6vectorI6size_tEERNSt6vectorI8ObjectIDEERNSt6vectorI7PayloadEERNSt6vectorINSt10shared_ptrI13MutableBufferEEEE", "vineyard::Client::CreateBuffers::payloads"], [28, 2, 1, "_CPPv4N8vineyard6Client13CreateBuffersERKNSt6vectorI6size_tEERNSt6vectorI8ObjectIDEERNSt6vectorI7PayloadEERNSt6vectorINSt10shared_ptrI13MutableBufferEEEE", "vineyard::Client::CreateBuffers::sizes"], [28, 1, 1, "_CPPv4N8vineyard6Client14CreateDiskBlobE6size_tRKNSt6stringERNSt10unique_ptrI10BlobWriterEE", "vineyard::Client::CreateDiskBlob"], [28, 2, 1, "_CPPv4N8vineyard6Client14CreateDiskBlobE6size_tRKNSt6stringERNSt10unique_ptrI10BlobWriterEE", "vineyard::Client::CreateDiskBlob::blob"], [28, 2, 1, "_CPPv4N8vineyard6Client14CreateDiskBlobE6size_tRKNSt6stringERNSt10unique_ptrI10BlobWriterEE", "vineyard::Client::CreateDiskBlob::path"], [28, 2, 1, "_CPPv4N8vineyard6Client14CreateDiskBlobE6size_tRKNSt6stringERNSt10unique_ptrI10BlobWriterEE", "vineyard::Client::CreateDiskBlob::size"], [28, 1, 1, "_CPPv4N8vineyard6Client15CreateGPUBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateGPUBuffer"], [28, 2, 1, "_CPPv4N8vineyard6Client15CreateGPUBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateGPUBuffer::buffer"], [28, 2, 1, "_CPPv4N8vineyard6Client15CreateGPUBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateGPUBuffer::id"], [28, 2, 1, "_CPPv4N8vineyard6Client15CreateGPUBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateGPUBuffer::payload"], [28, 2, 1, "_CPPv4N8vineyard6Client15CreateGPUBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE", "vineyard::Client::CreateGPUBuffer::size"], [28, 1, 1, "_CPPv4N8vineyard6Client7DefaultEv", "vineyard::Client::Default"], [28, 1, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKb", "vineyard::Client::DelData"], [28, 1, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKbKb", "vineyard::Client::DelData"], [28, 1, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::Client::DelData"], [28, 1, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::Client::DelData"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKb", "vineyard::Client::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKbKb", "vineyard::Client::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::Client::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::Client::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKb", "vineyard::Client::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKbKb", "vineyard::Client::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::Client::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::Client::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKb", "vineyard::Client::DelData::id"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKbKb", "vineyard::Client::DelData::id"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::Client::DelData::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::Client::DelData::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKbKb", "vineyard::Client::DelData::memory_trim"], [28, 2, 1, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::Client::DelData::memory_trim"], [28, 1, 1, "_CPPv4N8vineyard6Client10DisconnectEv", "vineyard::Client::Disconnect"], [28, 1, 1, "_CPPv4N8vineyard6Client10DropBufferEK8ObjectIDKi", "vineyard::Client::DropBuffer"], [28, 2, 1, "_CPPv4N8vineyard6Client10DropBufferEK8ObjectIDKi", "vineyard::Client::DropBuffer::fd"], [28, 2, 1, "_CPPv4N8vineyard6Client10DropBufferEK8ObjectIDKi", "vineyard::Client::DropBuffer::id"], [28, 1, 1, "_CPPv4N8vineyard6Client19FetchAndGetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::FetchAndGetMetaData"], [28, 2, 1, "_CPPv4N8vineyard6Client19FetchAndGetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::FetchAndGetMetaData::id"], [28, 2, 1, "_CPPv4N8vineyard6Client19FetchAndGetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::FetchAndGetMetaData::meta_data"], [28, 2, 1, "_CPPv4N8vineyard6Client19FetchAndGetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::FetchAndGetMetaData::sync_remote"], [28, 1, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::FetchAndGetObject"], [28, 1, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::FetchAndGetObject"], [28, 1, 1, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDKb", "vineyard::Client::FetchAndGetObject"], [28, 1, 1, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::FetchAndGetObject"], [28, 3, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::FetchAndGetObject::T"], [28, 3, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::FetchAndGetObject::T"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::FetchAndGetObject::id"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::FetchAndGetObject::id"], [28, 2, 1, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDKb", "vineyard::Client::FetchAndGetObject::id"], [28, 2, 1, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::FetchAndGetObject::id"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::FetchAndGetObject::object"], [28, 2, 1, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::FetchAndGetObject::object"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::FetchAndGetObject::sync_remote"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::FetchAndGetObject::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDKb", "vineyard::Client::FetchAndGetObject::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::FetchAndGetObject::sync_remote"], [28, 1, 1, "_CPPv4N8vineyard6Client4ForkER6Client", "vineyard::Client::Fork"], [28, 2, 1, "_CPPv4N8vineyard6Client4ForkER6Client", "vineyard::Client::Fork::client"], [28, 1, 1, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDRNSt10shared_ptrI4BlobEE", "vineyard::Client::GetBlob"], [28, 1, 1, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDbRNSt10shared_ptrI4BlobEE", "vineyard::Client::GetBlob"], [28, 2, 1, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDRNSt10shared_ptrI4BlobEE", "vineyard::Client::GetBlob::blob"], [28, 2, 1, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDbRNSt10shared_ptrI4BlobEE", "vineyard::Client::GetBlob::blob"], [28, 2, 1, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDRNSt10shared_ptrI4BlobEE", "vineyard::Client::GetBlob::id"], [28, 2, 1, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDbRNSt10shared_ptrI4BlobEE", "vineyard::Client::GetBlob::id"], [28, 2, 1, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDbRNSt10shared_ptrI4BlobEE", "vineyard::Client::GetBlob::unsafe"], [28, 1, 1, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI4BlobEEEE", "vineyard::Client::GetBlobs"], [28, 1, 1, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI4BlobEEEE", "vineyard::Client::GetBlobs"], [28, 2, 1, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI4BlobEEEE", "vineyard::Client::GetBlobs::blobs"], [28, 2, 1, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI4BlobEEEE", "vineyard::Client::GetBlobs::blobs"], [28, 2, 1, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI4BlobEEEE", "vineyard::Client::GetBlobs::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI4BlobEEEE", "vineyard::Client::GetBlobs::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI4BlobEEEE", "vineyard::Client::GetBlobs::unsafe"], [28, 1, 1, "_CPPv4N8vineyard6Client9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE", "vineyard::Client::GetBuffer"], [28, 2, 1, "_CPPv4N8vineyard6Client9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE", "vineyard::Client::GetBuffer::buffer"], [28, 2, 1, "_CPPv4N8vineyard6Client9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE", "vineyard::Client::GetBuffer::id"], [28, 1, 1, "_CPPv4N8vineyard6Client14GetBufferSizesERKNSt3setI8ObjectIDEERNSt3mapI8ObjectID6size_tEE", "vineyard::Client::GetBufferSizes"], [28, 2, 1, "_CPPv4N8vineyard6Client14GetBufferSizesERKNSt3setI8ObjectIDEERNSt3mapI8ObjectID6size_tEE", "vineyard::Client::GetBufferSizes::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client14GetBufferSizesERKNSt3setI8ObjectIDEERNSt3mapI8ObjectID6size_tEE", "vineyard::Client::GetBufferSizes::sizes"], [28, 1, 1, "_CPPv4N8vineyard6Client10GetBuffersERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE", "vineyard::Client::GetBuffers"], [28, 2, 1, "_CPPv4N8vineyard6Client10GetBuffersERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE", "vineyard::Client::GetBuffers::buffers"], [28, 2, 1, "_CPPv4N8vineyard6Client10GetBuffersERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE", "vineyard::Client::GetBuffers::ids"], [28, 1, 1, "_CPPv4N8vineyard6Client13GetDependencyERK8ObjectIDRNSt3setI8ObjectIDEE", "vineyard::Client::GetDependency"], [28, 2, 1, "_CPPv4N8vineyard6Client13GetDependencyERK8ObjectIDRNSt3setI8ObjectIDEE", "vineyard::Client::GetDependency::bids"], [28, 2, 1, "_CPPv4N8vineyard6Client13GetDependencyERK8ObjectIDRNSt3setI8ObjectIDEE", "vineyard::Client::GetDependency::id"], [28, 1, 1, "_CPPv4N8vineyard6Client12GetGPUBufferEK8ObjectIDKbRNSt10shared_ptrI6BufferEE", "vineyard::Client::GetGPUBuffer"], [28, 2, 1, "_CPPv4N8vineyard6Client12GetGPUBufferEK8ObjectIDKbRNSt10shared_ptrI6BufferEE", "vineyard::Client::GetGPUBuffer::buffer"], [28, 2, 1, "_CPPv4N8vineyard6Client12GetGPUBufferEK8ObjectIDKbRNSt10shared_ptrI6BufferEE", "vineyard::Client::GetGPUBuffer::id"], [28, 2, 1, "_CPPv4N8vineyard6Client12GetGPUBufferEK8ObjectIDKbRNSt10shared_ptrI6BufferEE", "vineyard::Client::GetGPUBuffer::unsafe"], [28, 1, 1, "_CPPv4N8vineyard6Client13GetGPUBuffersERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE", "vineyard::Client::GetGPUBuffers"], [28, 2, 1, "_CPPv4N8vineyard6Client13GetGPUBuffersERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE", "vineyard::Client::GetGPUBuffers::buffers"], [28, 2, 1, "_CPPv4N8vineyard6Client13GetGPUBuffersERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE", "vineyard::Client::GetGPUBuffers::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client13GetGPUBuffersERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE", "vineyard::Client::GetGPUBuffers::unsafe"], [28, 1, 1, "_CPPv4N8vineyard6Client11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::GetMetaData"], [28, 1, 1, "_CPPv4N8vineyard6Client11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb", "vineyard::Client::GetMetaData"], [28, 2, 1, "_CPPv4N8vineyard6Client11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::GetMetaData::id"], [28, 2, 1, "_CPPv4N8vineyard6Client11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb", "vineyard::Client::GetMetaData::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::GetMetaData::meta_data"], [28, 2, 1, "_CPPv4N8vineyard6Client11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::Client::GetMetaData::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard6Client11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb", "vineyard::Client::GetMetaData::sync_remote"], [28, 1, 1, "_CPPv4N8vineyard6Client18GetNextStreamChunkEK8ObjectIDK6size_tRNSt10unique_ptrI13MutableBufferEE", "vineyard::Client::GetNextStreamChunk"], [28, 2, 1, "_CPPv4N8vineyard6Client18GetNextStreamChunkEK8ObjectIDK6size_tRNSt10unique_ptrI13MutableBufferEE", "vineyard::Client::GetNextStreamChunk::blob"], [28, 2, 1, "_CPPv4N8vineyard6Client18GetNextStreamChunkEK8ObjectIDK6size_tRNSt10unique_ptrI13MutableBufferEE", "vineyard::Client::GetNextStreamChunk::id"], [28, 2, 1, "_CPPv4N8vineyard6Client18GetNextStreamChunkEK8ObjectIDK6size_tRNSt10unique_ptrI13MutableBufferEE", "vineyard::Client::GetNextStreamChunk::size"], [28, 1, 1, "_CPPv4I0EN8vineyard6Client9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::GetObject"], [28, 1, 1, "_CPPv4I0EN8vineyard6Client9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::GetObject"], [28, 1, 1, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDKb", "vineyard::Client::GetObject"], [28, 1, 1, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::GetObject"], [28, 3, 1, "_CPPv4I0EN8vineyard6Client9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::GetObject::T"], [28, 3, 1, "_CPPv4I0EN8vineyard6Client9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::GetObject::T"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::GetObject::id"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::GetObject::id"], [28, 2, 1, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDKb", "vineyard::Client::GetObject::id"], [28, 2, 1, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::GetObject::id"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::GetObject::object"], [28, 2, 1, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::GetObject::object"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::Client::GetObject::sync_remote"], [28, 2, 1, "_CPPv4I0EN8vineyard6Client9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::Client::GetObject::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDKb", "vineyard::Client::GetObject::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::Client::GetObject::sync_remote"], [28, 1, 1, "_CPPv4N8vineyard6Client10GetObjectsERKNSt6vectorI8ObjectIDEEKb", "vineyard::Client::GetObjects"], [28, 2, 1, "_CPPv4N8vineyard6Client10GetObjectsERKNSt6vectorI8ObjectIDEEKb", "vineyard::Client::GetObjects::ids"], [28, 2, 1, "_CPPv4N8vineyard6Client10GetObjectsERKNSt6vectorI8ObjectIDEEKb", "vineyard::Client::GetObjects::sync_remote"], [28, 1, 1, "_CPPv4NK8vineyard6Client5IsIPCEv", "vineyard::Client::IsIPC"], [28, 1, 1, "_CPPv4N8vineyard6Client7IsInUseERK8ObjectIDRb", "vineyard::Client::IsInUse"], [28, 2, 1, "_CPPv4N8vineyard6Client7IsInUseERK8ObjectIDRb", "vineyard::Client::IsInUse::id"], [28, 2, 1, "_CPPv4N8vineyard6Client7IsInUseERK8ObjectIDRb", "vineyard::Client::IsInUse::is_in_use"], [28, 1, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEK9uintptr_t", "vineyard::Client::IsSharedMemory"], [28, 1, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEK9uintptr_tR8ObjectID", "vineyard::Client::IsSharedMemory"], [28, 1, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEPKv", "vineyard::Client::IsSharedMemory"], [28, 1, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEPKvR8ObjectID", "vineyard::Client::IsSharedMemory"], [28, 2, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEK9uintptr_tR8ObjectID", "vineyard::Client::IsSharedMemory::object_id"], [28, 2, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEPKvR8ObjectID", "vineyard::Client::IsSharedMemory::object_id"], [28, 2, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEK9uintptr_t", "vineyard::Client::IsSharedMemory::target"], [28, 2, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEK9uintptr_tR8ObjectID", "vineyard::Client::IsSharedMemory::target"], [28, 2, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEPKv", "vineyard::Client::IsSharedMemory::target"], [28, 2, 1, "_CPPv4NK8vineyard6Client14IsSharedMemoryEPKvR8ObjectID", "vineyard::Client::IsSharedMemory::target"], [28, 1, 1, "_CPPv4N8vineyard6Client9IsSpilledERK8ObjectIDRb", "vineyard::Client::IsSpilled"], [28, 2, 1, "_CPPv4N8vineyard6Client9IsSpilledERK8ObjectIDRb", "vineyard::Client::IsSpilled::id"], [28, 2, 1, "_CPPv4N8vineyard6Client9IsSpilledERK8ObjectIDRb", "vineyard::Client::IsSpilled::is_spilled"], [28, 1, 1, "_CPPv4N8vineyard6Client14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::Client::ListObjectMeta"], [28, 2, 1, "_CPPv4N8vineyard6Client14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::Client::ListObjectMeta::limit"], [28, 2, 1, "_CPPv4N8vineyard6Client14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::Client::ListObjectMeta::nobuffer"], [28, 2, 1, "_CPPv4N8vineyard6Client14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::Client::ListObjectMeta::pattern"], [28, 2, 1, "_CPPv4N8vineyard6Client14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::Client::ListObjectMeta::regex"], [28, 1, 1, "_CPPv4N8vineyard6Client11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::Client::ListObjects"], [28, 2, 1, "_CPPv4N8vineyard6Client11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::Client::ListObjects::limit"], [28, 2, 1, "_CPPv4N8vineyard6Client11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::Client::ListObjects::pattern"], [28, 2, 1, "_CPPv4N8vineyard6Client11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::Client::ListObjects::regex"], [28, 1, 1, "_CPPv4N8vineyard6Client8OnDeleteERK8ObjectID", "vineyard::Client::OnDelete"], [28, 2, 1, "_CPPv4N8vineyard6Client8OnDeleteERK8ObjectID", "vineyard::Client::OnDelete::id"], [28, 1, 1, "_CPPv4N8vineyard6Client9OnReleaseERK8ObjectID", "vineyard::Client::OnRelease"], [28, 2, 1, "_CPPv4N8vineyard6Client9OnReleaseERK8ObjectID", "vineyard::Client::OnRelease::id"], [28, 1, 1, "_CPPv4N8vineyard6Client4OpenERKNSt6stringE", "vineyard::Client::Open"], [28, 1, 1, "_CPPv4N8vineyard6Client4OpenERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Open"], [28, 2, 1, "_CPPv4N8vineyard6Client4OpenERKNSt6stringE", "vineyard::Client::Open::ipc_socket"], [28, 2, 1, "_CPPv4N8vineyard6Client4OpenERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Open::ipc_socket"], [28, 2, 1, "_CPPv4N8vineyard6Client4OpenERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Open::password"], [28, 2, 1, "_CPPv4N8vineyard6Client4OpenERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::Client::Open::username"], [28, 1, 1, "_CPPv4N8vineyard6Client8PostSealERK10ObjectMeta", "vineyard::Client::PostSeal"], [28, 2, 1, "_CPPv4N8vineyard6Client8PostSealERK10ObjectMeta", "vineyard::Client::PostSeal::meta_data"], [28, 1, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR10ObjectMeta", "vineyard::Client::PullNextStreamChunk"], [28, 1, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR8ObjectID", "vineyard::Client::PullNextStreamChunk"], [28, 1, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE", "vineyard::Client::PullNextStreamChunk"], [28, 1, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10unique_ptrI6BufferEE", "vineyard::Client::PullNextStreamChunk"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR10ObjectMeta", "vineyard::Client::PullNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR8ObjectID", "vineyard::Client::PullNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE", "vineyard::Client::PullNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10unique_ptrI6BufferEE", "vineyard::Client::PullNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR10ObjectMeta", "vineyard::Client::PullNextStreamChunk::id"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR8ObjectID", "vineyard::Client::PullNextStreamChunk::id"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE", "vineyard::Client::PullNextStreamChunk::id"], [28, 2, 1, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10unique_ptrI6BufferEE", "vineyard::Client::PullNextStreamChunk::id"], [28, 1, 1, "_CPPv4N8vineyard6Client7ReleaseERK8ObjectID", "vineyard::Client::Release"], [28, 1, 1, "_CPPv4N8vineyard6Client7ReleaseERKNSt6vectorI8ObjectIDEE", "vineyard::Client::Release"], [28, 2, 1, "_CPPv4N8vineyard6Client7ReleaseERK8ObjectID", "vineyard::Client::Release::id"], [28, 2, 1, "_CPPv4N8vineyard6Client7ReleaseERKNSt6vectorI8ObjectIDEE", "vineyard::Client::Release::ids"], [28, 1, 1, "_CPPv4N8vineyard6Client12ReleaseArenaEKiRKNSt6vectorI6size_tEERKNSt6vectorI6size_tEE", "vineyard::Client::ReleaseArena"], [28, 2, 1, "_CPPv4N8vineyard6Client12ReleaseArenaEKiRKNSt6vectorI6size_tEERKNSt6vectorI6size_tEE", "vineyard::Client::ReleaseArena::fd"], [28, 2, 1, "_CPPv4N8vineyard6Client12ReleaseArenaEKiRKNSt6vectorI6size_tEERKNSt6vectorI6size_tEE", "vineyard::Client::ReleaseArena::offsets"], [28, 2, 1, "_CPPv4N8vineyard6Client12ReleaseArenaEKiRKNSt6vectorI6size_tEERKNSt6vectorI6size_tEE", "vineyard::Client::ReleaseArena::sizes"], [28, 1, 1, "_CPPv4N8vineyard6Client4SealERK8ObjectID", "vineyard::Client::Seal"], [28, 2, 1, "_CPPv4N8vineyard6Client4SealERK8ObjectID", "vineyard::Client::Seal::object_id"], [28, 1, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8ObjectIDR8ObjectIDR6Client", "vineyard::Client::ShallowCopy"], [28, 1, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8PlasmaIDR8ObjectIDR12PlasmaClient", "vineyard::Client::ShallowCopy"], [28, 2, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8ObjectIDR8ObjectIDR6Client", "vineyard::Client::ShallowCopy::id"], [28, 2, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8PlasmaIDR8ObjectIDR12PlasmaClient", "vineyard::Client::ShallowCopy::plasma_id"], [28, 2, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8ObjectIDR8ObjectIDR6Client", "vineyard::Client::ShallowCopy::source_client"], [28, 2, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8PlasmaIDR8ObjectIDR12PlasmaClient", "vineyard::Client::ShallowCopy::source_client"], [28, 2, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8ObjectIDR8ObjectIDR6Client", "vineyard::Client::ShallowCopy::target_id"], [28, 2, 1, "_CPPv4N8vineyard6Client11ShallowCopyEK8PlasmaIDR8ObjectIDR12PlasmaClient", "vineyard::Client::ShallowCopy::target_id"], [28, 1, 1, "_CPPv4N8vineyard6Client12ShrinkBufferEK8ObjectIDK6size_t", "vineyard::Client::ShrinkBuffer"], [28, 2, 1, "_CPPv4N8vineyard6Client12ShrinkBufferEK8ObjectIDK6size_t", "vineyard::Client::ShrinkBuffer::id"], [28, 2, 1, "_CPPv4N8vineyard6Client12ShrinkBufferEK8ObjectIDK6size_t", "vineyard::Client::ShrinkBuffer::size"], [28, 1, 1, "_CPPv4N8vineyard6Client14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::Client::TryAcquireLock"], [28, 2, 1, "_CPPv4N8vineyard6Client14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::Client::TryAcquireLock::actual_key"], [28, 2, 1, "_CPPv4N8vineyard6Client14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::Client::TryAcquireLock::key"], [28, 2, 1, "_CPPv4N8vineyard6Client14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::Client::TryAcquireLock::result"], [28, 1, 1, "_CPPv4N8vineyard6Client14TryReleaseLockENSt6stringERb", "vineyard::Client::TryReleaseLock"], [28, 2, 1, "_CPPv4N8vineyard6Client14TryReleaseLockENSt6stringERb", "vineyard::Client::TryReleaseLock::key"], [28, 2, 1, "_CPPv4N8vineyard6Client14TryReleaseLockENSt6stringERb", "vineyard::Client::TryReleaseLock::result"], [28, 1, 1, "_CPPv4N8vineyard6ClientD0Ev", "vineyard::Client::~Client"], [28, 0, 1, "_CPPv4N8vineyard10ClientBaseE", "vineyard::ClientBase"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase5ClearEv", "vineyard::ClientBase::Clear"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10ClientBaseERK10ClientBase", "vineyard::ClientBase::ClientBase"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10ClientBaseERR10ClientBase", "vineyard::ClientBase::ClientBase"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10ClientBaseEv", "vineyard::ClientBase::ClientBase"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase12CloseSessionEv", "vineyard::ClientBase::CloseSession"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase11ClusterInfoERNSt3mapI10InstanceID4jsonEE", "vineyard::ClientBase::ClusterInfo"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11ClusterInfoERNSt3mapI10InstanceID4jsonEE", "vineyard::ClientBase::ClusterInfo::meta"], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase9ConnectedEv", "vineyard::ClientBase::Connected"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERK4jsonR8ObjectIDR9SignatureR10InstanceID", "vineyard::ClientBase::CreateData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERKNSt6vectorI4jsonEERNSt6vectorI8ObjectIDEERNSt6vectorI9SignatureEERNSt6vectorI10InstanceIDEE", "vineyard::ClientBase::CreateData"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERK4jsonR8ObjectIDR9SignatureR10InstanceID", "vineyard::ClientBase::CreateData::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERKNSt6vectorI4jsonEERNSt6vectorI8ObjectIDEERNSt6vectorI9SignatureEERNSt6vectorI10InstanceIDEE", "vineyard::ClientBase::CreateData::ids"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERK4jsonR8ObjectIDR9SignatureR10InstanceID", "vineyard::ClientBase::CreateData::instance_id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERKNSt6vectorI4jsonEERNSt6vectorI8ObjectIDEERNSt6vectorI9SignatureEERNSt6vectorI10InstanceIDEE", "vineyard::ClientBase::CreateData::instance_ids"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERK4jsonR8ObjectIDR9SignatureR10InstanceID", "vineyard::ClientBase::CreateData::signature"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERKNSt6vectorI4jsonEERNSt6vectorI8ObjectIDEERNSt6vectorI9SignatureEERNSt6vectorI10InstanceIDEE", "vineyard::ClientBase::CreateData::signatures"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERK4jsonR8ObjectIDR9SignatureR10InstanceID", "vineyard::ClientBase::CreateData::tree"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10CreateDataERKNSt6vectorI4jsonEERNSt6vectorI8ObjectIDEERNSt6vectorI9SignatureEERNSt6vectorI10InstanceIDEE", "vineyard::ClientBase::CreateData::trees"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaR8ObjectID", "vineyard::ClientBase::CreateMetaData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaRK10InstanceIDR8ObjectID", "vineyard::ClientBase::CreateMetaData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERK10InstanceIDRNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::CreateMetaData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::CreateMetaData"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaR8ObjectID", "vineyard::ClientBase::CreateMetaData::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaRK10InstanceIDR8ObjectID", "vineyard::ClientBase::CreateMetaData::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERK10InstanceIDRNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::CreateMetaData::ids"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::CreateMetaData::ids"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaRK10InstanceIDR8ObjectID", "vineyard::ClientBase::CreateMetaData::instance_id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERK10InstanceIDRNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::CreateMetaData::instance_id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaR8ObjectID", "vineyard::ClientBase::CreateMetaData::meta_data"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaRK10InstanceIDR8ObjectID", "vineyard::ClientBase::CreateMetaData::meta_data"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERK10InstanceIDRNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::CreateMetaData::meta_datas"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::CreateMetaData::meta_datas"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase12CreateStreamERK8ObjectID", "vineyard::ClientBase::CreateStream"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase12CreateStreamERK8ObjectID", "vineyard::ClientBase::CreateStream::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase5DebugERK4jsonR4json", "vineyard::ClientBase::Debug"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5DebugERK4jsonR4json", "vineyard::ClientBase::Debug::debug"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5DebugERK4jsonR4json", "vineyard::ClientBase::Debug::tree"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKb", "vineyard::ClientBase::DelData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKbKb", "vineyard::ClientBase::DelData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::ClientBase::DelData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::ClientBase::DelData"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKb", "vineyard::ClientBase::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKbKb", "vineyard::ClientBase::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::ClientBase::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::ClientBase::DelData::deep"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKb", "vineyard::ClientBase::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKbKb", "vineyard::ClientBase::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::ClientBase::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::ClientBase::DelData::force"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKb", "vineyard::ClientBase::DelData::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKbKb", "vineyard::ClientBase::DelData::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKb", "vineyard::ClientBase::DelData::ids"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::ClientBase::DelData::ids"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKbKb", "vineyard::ClientBase::DelData::memory_trim"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb", "vineyard::ClientBase::DelData::memory_trim"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10DisconnectEv", "vineyard::ClientBase::Disconnect"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase8DropNameERKNSt6stringE", "vineyard::ClientBase::DropName"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase8DropNameERKNSt6stringE", "vineyard::ClientBase::DropName::name"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10DropStreamEK8ObjectID", "vineyard::ClientBase::DropStream"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10DropStreamEK8ObjectID", "vineyard::ClientBase::DropStream::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase5EvictERKNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::Evict"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5EvictERKNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::Evict::objects"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase6ExistsEK8ObjectIDRb", "vineyard::ClientBase::Exists"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase6ExistsEK8ObjectIDRb", "vineyard::ClientBase::Exists::exists"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase6ExistsEK8ObjectIDRb", "vineyard::ClientBase::Exists::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7GetDataEK8ObjectIDR4jsonKbKb", "vineyard::ClientBase::GetData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7GetDataERKNSt6vectorI8ObjectIDEERNSt6vectorI4jsonEEKbKb", "vineyard::ClientBase::GetData"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataEK8ObjectIDR4jsonKbKb", "vineyard::ClientBase::GetData::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataERKNSt6vectorI8ObjectIDEERNSt6vectorI4jsonEEKbKb", "vineyard::ClientBase::GetData::ids"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataEK8ObjectIDR4jsonKbKb", "vineyard::ClientBase::GetData::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataERKNSt6vectorI8ObjectIDEERNSt6vectorI4jsonEEKbKb", "vineyard::ClientBase::GetData::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataEK8ObjectIDR4jsonKbKb", "vineyard::ClientBase::GetData::tree"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataERKNSt6vectorI8ObjectIDEERNSt6vectorI4jsonEEKbKb", "vineyard::ClientBase::GetData::trees"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataEK8ObjectIDR4jsonKbKb", "vineyard::ClientBase::GetData::wait"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetDataERKNSt6vectorI8ObjectIDEERNSt6vectorI4jsonEEKbKb", "vineyard::ClientBase::GetData::wait"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::ClientBase::GetMetaData"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::ClientBase::GetMetaData::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::ClientBase::GetMetaData::meta_data"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::ClientBase::GetMetaData::sync_remote"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7GetNameERKNSt6stringER8ObjectIDKb", "vineyard::ClientBase::GetName"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetNameERKNSt6stringER8ObjectIDKb", "vineyard::ClientBase::GetName::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetNameERKNSt6stringER8ObjectIDKb", "vineyard::ClientBase::GetName::name"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7GetNameERKNSt6stringER8ObjectIDKb", "vineyard::ClientBase::GetName::wait"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase9IPCSocketEv", "vineyard::ClientBase::IPCSocket"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase9IfPersistEK8ObjectIDRb", "vineyard::ClientBase::IfPersist"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase9IfPersistEK8ObjectIDRb", "vineyard::ClientBase::IfPersist::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase9IfPersistEK8ObjectIDRb", "vineyard::ClientBase::IfPersist::persist"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase14InstanceStatusERNSt10shared_ptrI14InstanceStatusEE", "vineyard::ClientBase::InstanceStatus"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14InstanceStatusERNSt10shared_ptrI14InstanceStatusEE", "vineyard::ClientBase::InstanceStatus::status"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase9InstancesERNSt6vectorI10InstanceIDEE", "vineyard::ClientBase::Instances"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase9InstancesERNSt6vectorI10InstanceIDEE", "vineyard::ClientBase::Instances::instances"], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase5IsIPCEv", "vineyard::ClientBase::IsIPC"], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase5IsRPCEv", "vineyard::ClientBase::IsRPC"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt3mapINSt6stringENSt6stringEEE", "vineyard::ClientBase::Label"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt6stringERKNSt6stringE", "vineyard::ClientBase::Label"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt6stringERKNSt6stringE", "vineyard::ClientBase::Label::key"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt3mapINSt6stringENSt6stringEEE", "vineyard::ClientBase::Label::labels"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt3mapINSt6stringENSt6stringEEE", "vineyard::ClientBase::Label::object"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt6stringERKNSt6stringE", "vineyard::ClientBase::Label::object"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt6stringERKNSt6stringE", "vineyard::ClientBase::Label::value"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase8ListDataERKNSt6stringEKbK6size_tRNSt13unordered_mapI8ObjectID4jsonEE", "vineyard::ClientBase::ListData"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase8ListDataERKNSt6stringEKbK6size_tRNSt13unordered_mapI8ObjectID4jsonEE", "vineyard::ClientBase::ListData::limit"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase8ListDataERKNSt6stringEKbK6size_tRNSt13unordered_mapI8ObjectID4jsonEE", "vineyard::ClientBase::ListData::meta_trees"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase8ListDataERKNSt6stringEKbK6size_tRNSt13unordered_mapI8ObjectID4jsonEE", "vineyard::ClientBase::ListData::pattern"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase8ListDataERKNSt6stringEKbK6size_tRNSt13unordered_mapI8ObjectID4jsonEE", "vineyard::ClientBase::ListData::regex"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase9ListNamesERKNSt6stringEKbK6size_tRNSt3mapINSt6stringE8ObjectIDEE", "vineyard::ClientBase::ListNames"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase9ListNamesERKNSt6stringEKbK6size_tRNSt3mapINSt6stringE8ObjectIDEE", "vineyard::ClientBase::ListNames::limit"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase9ListNamesERKNSt6stringEKbK6size_tRNSt3mapINSt6stringE8ObjectIDEE", "vineyard::ClientBase::ListNames::names"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase9ListNamesERKNSt6stringEKbK6size_tRNSt3mapINSt6stringE8ObjectIDEE", "vineyard::ClientBase::ListNames::pattern"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase9ListNamesERKNSt6stringEKbK6size_tRNSt3mapINSt6stringE8ObjectIDEE", "vineyard::ClientBase::ListNames::regex"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase4LoadERKNSt6vectorI8ObjectIDEEKb", "vineyard::ClientBase::Load"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase4LoadERKNSt6vectorI8ObjectIDEEKb", "vineyard::ClientBase::Load::objects"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase4LoadERKNSt6vectorI8ObjectIDEEKb", "vineyard::ClientBase::Load::pin"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10MemoryTrimERb", "vineyard::ClientBase::MemoryTrim"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10MemoryTrimERb", "vineyard::ClientBase::MemoryTrim::trimmed"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase13MigrateObjectEK8ObjectIDR8ObjectID", "vineyard::ClientBase::MigrateObject"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase13MigrateObjectEK8ObjectIDR8ObjectID", "vineyard::ClientBase::MigrateObject::object_id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase13MigrateObjectEK8ObjectIDR8ObjectID", "vineyard::ClientBase::MigrateObject::result_id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase4OpenERKNSt6stringE", "vineyard::ClientBase::Open"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase4OpenERKNSt6stringE", "vineyard::ClientBase::Open::ipc_socket"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10OpenStreamERK8ObjectID14StreamOpenMode", "vineyard::ClientBase::OpenStream"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10OpenStreamERK8ObjectID14StreamOpenMode", "vineyard::ClientBase::OpenStream::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10OpenStreamERK8ObjectID14StreamOpenMode", "vineyard::ClientBase::OpenStream::mode"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7PersistEK8ObjectID", "vineyard::ClientBase::Persist"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7PersistEK8ObjectID", "vineyard::ClientBase::Persist::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR10ObjectMeta", "vineyard::ClientBase::PullNextStreamChunk"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR8ObjectID", "vineyard::ClientBase::PullNextStreamChunk"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE", "vineyard::ClientBase::PullNextStreamChunk"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR10ObjectMeta", "vineyard::ClientBase::PullNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR8ObjectID", "vineyard::ClientBase::PullNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE", "vineyard::ClientBase::PullNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR10ObjectMeta", "vineyard::ClientBase::PullNextStreamChunk::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR8ObjectID", "vineyard::ClientBase::PullNextStreamChunk::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE", "vineyard::ClientBase::PullNextStreamChunk::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase19PushNextStreamChunkEK8ObjectIDK8ObjectID", "vineyard::ClientBase::PushNextStreamChunk"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PushNextStreamChunkEK8ObjectIDK8ObjectID", "vineyard::ClientBase::PushNextStreamChunk::chunk"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase19PushNextStreamChunkEK8ObjectIDK8ObjectID", "vineyard::ClientBase::PushNextStreamChunk::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7PutNameEK8ObjectIDRKNSt6stringE", "vineyard::ClientBase::PutName"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7PutNameEK8ObjectIDRKNSt6stringE", "vineyard::ClientBase::PutName::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7PutNameEK8ObjectIDRKNSt6stringE", "vineyard::ClientBase::PutName::name"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase11RPCEndpointEv", "vineyard::ClientBase::RPCEndpoint"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7ReleaseERK8ObjectID", "vineyard::ClientBase::Release"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7ReleaseERK8ObjectID", "vineyard::ClientBase::Release::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDR8ObjectID", "vineyard::ClientBase::ShallowCopy"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDRK4jsonR8ObjectID", "vineyard::ClientBase::ShallowCopy"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDRK4jsonR8ObjectID", "vineyard::ClientBase::ShallowCopy::extra_metadata"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDR8ObjectID", "vineyard::ClientBase::ShallowCopy::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDRK4jsonR8ObjectID", "vineyard::ClientBase::ShallowCopy::id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDR8ObjectID", "vineyard::ClientBase::ShallowCopy::target_id"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDRK4jsonR8ObjectID", "vineyard::ClientBase::ShallowCopy::target_id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase10StopStreamEK8ObjectIDb", "vineyard::ClientBase::StopStream"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10StopStreamEK8ObjectIDb", "vineyard::ClientBase::StopStream::failed"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase10StopStreamEK8ObjectIDb", "vineyard::ClientBase::StopStream::id"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase12SyncMetaDataEv", "vineyard::ClientBase::SyncMetaData"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::ClientBase::TryAcquireLock"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::ClientBase::TryAcquireLock::actural_key"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::ClientBase::TryAcquireLock::key"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::ClientBase::TryAcquireLock::result"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase14TryReleaseLockENSt6stringERb", "vineyard::ClientBase::TryReleaseLock"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14TryReleaseLockENSt6stringERb", "vineyard::ClientBase::TryReleaseLock::key"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase14TryReleaseLockENSt6stringERb", "vineyard::ClientBase::TryReleaseLock::result"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase5UnpinERKNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::Unpin"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase5UnpinERKNSt6vectorI8ObjectIDEE", "vineyard::ClientBase::Unpin::objects"], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase7VersionEv", "vineyard::ClientBase::Version"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase13client_mutex_E", "vineyard::ClientBase::client_mutex_"], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase19compression_enabledEv", "vineyard::ClientBase::compression_enabled"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase20compression_enabled_E", "vineyard::ClientBase::compression_enabled_"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase10connected_E", "vineyard::ClientBase::connected_"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase6doReadER4json", "vineyard::ClientBase::doRead"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase6doReadERNSt6stringE", "vineyard::ClientBase::doRead"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase6doReadERNSt6stringE", "vineyard::ClientBase::doRead::message_in"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase6doReadER4json", "vineyard::ClientBase::doRead::root"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase7doWriteERKNSt6stringE", "vineyard::ClientBase::doWrite"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase7doWriteERKNSt6stringE", "vineyard::ClientBase::doWrite::message_out"], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase11instance_idEv", "vineyard::ClientBase::instance_id"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase12instance_id_E", "vineyard::ClientBase::instance_id_"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase11ipc_socket_E", "vineyard::ClientBase::ipc_socket_"], [28, 1, 1, "_CPPv4N8vineyard10ClientBaseaSERK10ClientBase", "vineyard::ClientBase::operator="], [28, 1, 1, "_CPPv4N8vineyard10ClientBaseaSERR10ClientBase", "vineyard::ClientBase::operator="], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase18remote_instance_idEv", "vineyard::ClientBase::remote_instance_id"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase13rpc_endpoint_E", "vineyard::ClientBase::rpc_endpoint_"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase15server_version_E", "vineyard::ClientBase::server_version_"], [28, 1, 1, "_CPPv4NK8vineyard10ClientBase10session_idEv", "vineyard::ClientBase::session_id"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase11session_id_E", "vineyard::ClientBase::session_id_"], [28, 1, 1, "_CPPv4N8vineyard10ClientBase23set_compression_enabledEb", "vineyard::ClientBase::set_compression_enabled"], [28, 2, 1, "_CPPv4N8vineyard10ClientBase23set_compression_enabledEb", "vineyard::ClientBase::set_compression_enabled::enabled"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase24support_rpc_compression_E", "vineyard::ClientBase::support_rpc_compression_"], [28, 4, 1, "_CPPv4N8vineyard10ClientBase14vineyard_conn_E", "vineyard::ClientBase::vineyard_conn_"], [28, 1, 1, "_CPPv4N8vineyard10ClientBaseD0Ev", "vineyard::ClientBase::~ClientBase"], [28, 0, 1, "_CPPv4N8vineyard9DataFrameE", "vineyard::DataFrame"], [28, 1, 1, "_CPPv4NK8vineyard9DataFrame7AsBatchEb", "vineyard::DataFrame::AsBatch"], [28, 2, 1, "_CPPv4NK8vineyard9DataFrame7AsBatchEb", "vineyard::DataFrame::AsBatch::copy"], [28, 1, 1, "_CPPv4NK8vineyard9DataFrame6ColumnERK4json", "vineyard::DataFrame::Column"], [28, 2, 1, "_CPPv4NK8vineyard9DataFrame6ColumnERK4json", "vineyard::DataFrame::Column::column"], [28, 1, 1, "_CPPv4NK8vineyard9DataFrame7ColumnsEv", "vineyard::DataFrame::Columns"], [28, 1, 1, "_CPPv4N8vineyard9DataFrame9ConstructERK10ObjectMeta", "vineyard::DataFrame::Construct"], [28, 2, 1, "_CPPv4N8vineyard9DataFrame9ConstructERK10ObjectMeta", "vineyard::DataFrame::Construct::meta"], [28, 1, 1, "_CPPv4N8vineyard9DataFrame6CreateEv", "vineyard::DataFrame::Create"], [28, 1, 1, "_CPPv4NK8vineyard9DataFrame5IndexEv", "vineyard::DataFrame::Index"], [28, 1, 1, "_CPPv4NK8vineyard9DataFrame15partition_indexEv", "vineyard::DataFrame::partition_index"], [28, 1, 1, "_CPPv4NK8vineyard9DataFrame5shapeEv", "vineyard::DataFrame::shape"], [28, 0, 1, "_CPPv4N8vineyard16DataFrameBuilderE", "vineyard::DataFrameBuilder"], [28, 1, 1, "_CPPv4N8vineyard16DataFrameBuilder9AddColumnERK4jsonNSt10shared_ptrI14ITensorBuilderEE", "vineyard::DataFrameBuilder::AddColumn"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder9AddColumnERK4jsonNSt10shared_ptrI14ITensorBuilderEE", "vineyard::DataFrameBuilder::AddColumn::builder"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder9AddColumnERK4jsonNSt10shared_ptrI14ITensorBuilderEE", "vineyard::DataFrameBuilder::AddColumn::column"], [28, 1, 1, "_CPPv4N8vineyard16DataFrameBuilder5BuildER6Client", "vineyard::DataFrameBuilder::Build"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder5BuildER6Client", "vineyard::DataFrameBuilder::Build::client"], [28, 1, 1, "_CPPv4NK8vineyard16DataFrameBuilder6ColumnERK4json", "vineyard::DataFrameBuilder::Column"], [28, 2, 1, "_CPPv4NK8vineyard16DataFrameBuilder6ColumnERK4json", "vineyard::DataFrameBuilder::Column::column"], [28, 1, 1, "_CPPv4N8vineyard16DataFrameBuilder16DataFrameBuilderER6Client", "vineyard::DataFrameBuilder::DataFrameBuilder"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder16DataFrameBuilderER6Client", "vineyard::DataFrameBuilder::DataFrameBuilder::client"], [28, 1, 1, "_CPPv4N8vineyard16DataFrameBuilder10DropColumnERK4json", "vineyard::DataFrameBuilder::DropColumn"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder10DropColumnERK4json", "vineyard::DataFrameBuilder::DropColumn::column"], [28, 1, 1, "_CPPv4NK8vineyard16DataFrameBuilder15partition_indexEv", "vineyard::DataFrameBuilder::partition_index"], [28, 1, 1, "_CPPv4N8vineyard16DataFrameBuilder9set_indexENSt10shared_ptrI14ITensorBuilderEE", "vineyard::DataFrameBuilder::set_index"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder9set_indexENSt10shared_ptrI14ITensorBuilderEE", "vineyard::DataFrameBuilder::set_index::builder"], [28, 1, 1, "_CPPv4N8vineyard16DataFrameBuilder19set_partition_indexE6size_t6size_t", "vineyard::DataFrameBuilder::set_partition_index"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder19set_partition_indexE6size_t6size_t", "vineyard::DataFrameBuilder::set_partition_index::partition_index_column"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder19set_partition_indexE6size_t6size_t", "vineyard::DataFrameBuilder::set_partition_index::partition_index_row"], [28, 1, 1, "_CPPv4N8vineyard16DataFrameBuilder19set_row_batch_indexE6size_t", "vineyard::DataFrameBuilder::set_row_batch_index"], [28, 2, 1, "_CPPv4N8vineyard16DataFrameBuilder19set_row_batch_indexE6size_t", "vineyard::DataFrameBuilder::set_row_batch_index::row_batch_index"], [28, 0, 1, "_CPPv4N8vineyard15GlobalDataFrameE", "vineyard::GlobalDataFrame"], [28, 1, 1, "_CPPv4N8vineyard15GlobalDataFrame6CreateEv", "vineyard::GlobalDataFrame::Create"], [28, 1, 1, "_CPPv4NK8vineyard15GlobalDataFrame15LocalPartitionsER6Client", "vineyard::GlobalDataFrame::LocalPartitions"], [28, 2, 1, "_CPPv4NK8vineyard15GlobalDataFrame15LocalPartitionsER6Client", "vineyard::GlobalDataFrame::LocalPartitions::client"], [28, 1, 1, "_CPPv4N8vineyard15GlobalDataFrame13PostConstructERK10ObjectMeta", "vineyard::GlobalDataFrame::PostConstruct"], [28, 2, 1, "_CPPv4N8vineyard15GlobalDataFrame13PostConstructERK10ObjectMeta", "vineyard::GlobalDataFrame::PostConstruct::meta"], [28, 1, 1, "_CPPv4NK8vineyard15GlobalDataFrame15partition_shapeEv", "vineyard::GlobalDataFrame::partition_shape"], [28, 0, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilderE", "vineyard::GlobalDataFrameBuilder"], [28, 1, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder12AddPartitionEK8ObjectID", "vineyard::GlobalDataFrameBuilder::AddPartition"], [28, 2, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder12AddPartitionEK8ObjectID", "vineyard::GlobalDataFrameBuilder::AddPartition::partition_id"], [28, 1, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder13AddPartitionsERKNSt6vectorI8ObjectIDEE", "vineyard::GlobalDataFrameBuilder::AddPartitions"], [28, 2, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder13AddPartitionsERKNSt6vectorI8ObjectIDEE", "vineyard::GlobalDataFrameBuilder::AddPartitions::partition_ids"], [28, 1, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder22GlobalDataFrameBuilderER6Client", "vineyard::GlobalDataFrameBuilder::GlobalDataFrameBuilder"], [28, 2, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder22GlobalDataFrameBuilderER6Client", "vineyard::GlobalDataFrameBuilder::GlobalDataFrameBuilder::client"], [28, 1, 1, "_CPPv4NK8vineyard22GlobalDataFrameBuilder15partition_shapeEv", "vineyard::GlobalDataFrameBuilder::partition_shape"], [28, 1, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder19set_partition_shapeEK6size_tK6size_t", "vineyard::GlobalDataFrameBuilder::set_partition_shape"], [28, 2, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder19set_partition_shapeEK6size_tK6size_t", "vineyard::GlobalDataFrameBuilder::set_partition_shape::partition_shape_column"], [28, 2, 1, "_CPPv4N8vineyard22GlobalDataFrameBuilder19set_partition_shapeEK6size_tK6size_t", "vineyard::GlobalDataFrameBuilder::set_partition_shape::partition_shape_row"], [28, 0, 1, "_CPPv4N8vineyard12GlobalTensorE", "vineyard::GlobalTensor"], [28, 1, 1, "_CPPv4N8vineyard12GlobalTensor6CreateEv", "vineyard::GlobalTensor::Create"], [28, 1, 1, "_CPPv4NK8vineyard12GlobalTensor15LocalPartitionsER6Client", "vineyard::GlobalTensor::LocalPartitions"], [28, 2, 1, "_CPPv4NK8vineyard12GlobalTensor15LocalPartitionsER6Client", "vineyard::GlobalTensor::LocalPartitions::client"], [28, 1, 1, "_CPPv4N8vineyard12GlobalTensor13PostConstructERK10ObjectMeta", "vineyard::GlobalTensor::PostConstruct"], [28, 2, 1, "_CPPv4N8vineyard12GlobalTensor13PostConstructERK10ObjectMeta", "vineyard::GlobalTensor::PostConstruct::meta"], [28, 1, 1, "_CPPv4NK8vineyard12GlobalTensor15partition_shapeEv", "vineyard::GlobalTensor::partition_shape"], [28, 1, 1, "_CPPv4NK8vineyard12GlobalTensor5shapeEv", "vineyard::GlobalTensor::shape"], [28, 0, 1, "_CPPv4N8vineyard19GlobalTensorBuilderE", "vineyard::GlobalTensorBuilder"], [28, 1, 1, "_CPPv4N8vineyard19GlobalTensorBuilder12AddPartitionEK8ObjectID", "vineyard::GlobalTensorBuilder::AddPartition"], [28, 2, 1, "_CPPv4N8vineyard19GlobalTensorBuilder12AddPartitionEK8ObjectID", "vineyard::GlobalTensorBuilder::AddPartition::partition_id"], [28, 1, 1, "_CPPv4N8vineyard19GlobalTensorBuilder13AddPartitionsERKNSt6vectorI8ObjectIDEE", "vineyard::GlobalTensorBuilder::AddPartitions"], [28, 2, 1, "_CPPv4N8vineyard19GlobalTensorBuilder13AddPartitionsERKNSt6vectorI8ObjectIDEE", "vineyard::GlobalTensorBuilder::AddPartitions::partition_ids"], [28, 1, 1, "_CPPv4N8vineyard19GlobalTensorBuilder19GlobalTensorBuilderER6Client", "vineyard::GlobalTensorBuilder::GlobalTensorBuilder"], [28, 2, 1, "_CPPv4N8vineyard19GlobalTensorBuilder19GlobalTensorBuilderER6Client", "vineyard::GlobalTensorBuilder::GlobalTensorBuilder::client"], [28, 1, 1, "_CPPv4NK8vineyard19GlobalTensorBuilder15partition_shapeEv", "vineyard::GlobalTensorBuilder::partition_shape"], [28, 1, 1, "_CPPv4N8vineyard19GlobalTensorBuilder19set_partition_shapeERKNSt6vectorI7int64_tEE", "vineyard::GlobalTensorBuilder::set_partition_shape"], [28, 2, 1, "_CPPv4N8vineyard19GlobalTensorBuilder19set_partition_shapeERKNSt6vectorI7int64_tEE", "vineyard::GlobalTensorBuilder::set_partition_shape::partition_shape"], [28, 1, 1, "_CPPv4N8vineyard19GlobalTensorBuilder9set_shapeERKNSt6vectorI7int64_tEE", "vineyard::GlobalTensorBuilder::set_shape"], [28, 2, 1, "_CPPv4N8vineyard19GlobalTensorBuilder9set_shapeERKNSt6vectorI7int64_tEE", "vineyard::GlobalTensorBuilder::set_shape::shape"], [28, 1, 1, "_CPPv4NK8vineyard19GlobalTensorBuilder5shapeEv", "vineyard::GlobalTensorBuilder::shape"], [28, 0, 1, "_CPPv4I0000EN8vineyard7HashmapE", "vineyard::Hashmap"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap9ConstructERK10ObjectMeta", "vineyard::Hashmap::Construct"], [28, 2, 1, "_CPPv4N8vineyard7Hashmap9ConstructERK10ObjectMeta", "vineyard::Hashmap::Construct::meta"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap6CreateEv", "vineyard::Hashmap::Create"], [28, 3, 1, "_CPPv4I0000EN8vineyard7HashmapE", "vineyard::Hashmap::E"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap5EntryE", "vineyard::Hashmap::Entry"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap12EntryPointerE", "vineyard::Hashmap::EntryPointer"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap5EqualE", "vineyard::Hashmap::Equal"], [28, 3, 1, "_CPPv4I0000EN8vineyard7HashmapE", "vineyard::Hashmap::H"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap6HasherE", "vineyard::Hashmap::Hasher"], [28, 3, 1, "_CPPv4I0000EN8vineyard7HashmapE", "vineyard::Hashmap::K"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap8KeyEqualE", "vineyard::Hashmap::KeyEqual"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap7KeyHashE", "vineyard::Hashmap::KeyHash"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap13PostConstructERK10ObjectMeta", "vineyard::Hashmap::PostConstruct"], [28, 2, 1, "_CPPv4N8vineyard7Hashmap13PostConstructERK10ObjectMeta", "vineyard::Hashmap::PostConstruct::meta"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap1TE", "vineyard::Hashmap::T"], [28, 3, 1, "_CPPv4I0000EN8vineyard7HashmapE", "vineyard::Hashmap::V"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap2atERK1K", "vineyard::Hashmap::at"], [28, 2, 1, "_CPPv4NK8vineyard7Hashmap2atERK1K", "vineyard::Hashmap::at::key"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap5beginEv", "vineyard::Hashmap::begin"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap12bucket_countEv", "vineyard::Hashmap::bucket_count"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap13const_pointerE", "vineyard::Hashmap::const_pointer"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap15const_referenceE", "vineyard::Hashmap::const_reference"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap5countERK1K", "vineyard::Hashmap::count"], [28, 2, 1, "_CPPv4NK8vineyard7Hashmap5countERK1K", "vineyard::Hashmap::count::key"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap15difference_typeE", "vineyard::Hashmap::difference_type"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap5emptyEv", "vineyard::Hashmap::empty"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap3endEv", "vineyard::Hashmap::end"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap4findERK1K", "vineyard::Hashmap::find"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap4findERK1K", "vineyard::Hashmap::find"], [28, 2, 1, "_CPPv4N8vineyard7Hashmap4findERK1K", "vineyard::Hashmap::find::key"], [28, 2, 1, "_CPPv4NK8vineyard7Hashmap4findERK1K", "vineyard::Hashmap::find::key"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap20flat_hash_table_typeE", "vineyard::Hashmap::flat_hash_table_type"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap6hasherE", "vineyard::Hashmap::hasher"], [28, 0, 1, "_CPPv4N8vineyard7Hashmap8iteratorE", "vineyard::Hashmap::iterator"], [28, 4, 1, "_CPPv4N8vineyard7Hashmap8iterator7currentE", "vineyard::Hashmap::iterator::current"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap8iterator8iteratorE12EntryPointer", "vineyard::Hashmap::iterator::iterator"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap8iterator8iteratorEv", "vineyard::Hashmap::iterator::iterator"], [28, 2, 1, "_CPPv4N8vineyard7Hashmap8iterator8iteratorE12EntryPointer", "vineyard::Hashmap::iterator::iterator::current"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap8iteratorneERK8iteratorRK8iterator", "vineyard::Hashmap::iterator::operator!="], [28, 2, 1, "_CPPv4N8vineyard7Hashmap8iteratorneERK8iteratorRK8iterator", "vineyard::Hashmap::iterator::operator!=::lhs"], [28, 2, 1, "_CPPv4N8vineyard7Hashmap8iteratorneERK8iteratorRK8iterator", "vineyard::Hashmap::iterator::operator!=::rhs"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap8iteratormlEv", "vineyard::Hashmap::iterator::operator*"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap8iteratorppEi", "vineyard::Hashmap::iterator::operator++"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap8iteratorppEv", "vineyard::Hashmap::iterator::operator++"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap8iteratorptEv", "vineyard::Hashmap::iterator::operator->"], [28, 1, 1, "_CPPv4N8vineyard7Hashmap8iteratoreqERK8iteratorRK8iterator", "vineyard::Hashmap::iterator::operator=="], [28, 2, 1, "_CPPv4N8vineyard7Hashmap8iteratoreqERK8iteratorRK8iterator", "vineyard::Hashmap::iterator::operator==::lhs"], [28, 2, 1, "_CPPv4N8vineyard7Hashmap8iteratoreqERK8iteratorRK8iterator", "vineyard::Hashmap::iterator::operator==::rhs"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap9key_equalE", "vineyard::Hashmap::key_equal"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap11load_factorEv", "vineyard::Hashmap::load_factor"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap7pointerE", "vineyard::Hashmap::pointer"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap9referenceE", "vineyard::Hashmap::reference"], [28, 1, 1, "_CPPv4NK8vineyard7Hashmap4sizeEv", "vineyard::Hashmap::size"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap9size_typeE", "vineyard::Hashmap::size_type"], [28, 5, 1, "_CPPv4N8vineyard7Hashmap10value_typeE", "vineyard::Hashmap::value_type"], [28, 0, 1, "_CPPv4I0000EN8vineyard14HashmapBuilderE", "vineyard::HashmapBuilder"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder19AssociateDataBufferENSt10shared_ptrI4BlobEE", "vineyard::HashmapBuilder::AssociateDataBuffer"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder19AssociateDataBufferENSt10shared_ptrI4BlobEE", "vineyard::HashmapBuilder::AssociateDataBuffer::data_buffer"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder5BuildER6Client", "vineyard::HashmapBuilder::Build"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder5BuildER6Client", "vineyard::HashmapBuilder::Build::client"], [28, 3, 1, "_CPPv4I0000EN8vineyard14HashmapBuilderE", "vineyard::HashmapBuilder::E"], [28, 3, 1, "_CPPv4I0000EN8vineyard14HashmapBuilderE", "vineyard::HashmapBuilder::H"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder14HashmapBuilderER6Client", "vineyard::HashmapBuilder::HashmapBuilder"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder14HashmapBuilderER6ClientRRN3ska13flat_hash_mapI1K1V1H1EEE", "vineyard::HashmapBuilder::HashmapBuilder"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder14HashmapBuilderER6Client", "vineyard::HashmapBuilder::HashmapBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder14HashmapBuilderER6ClientRRN3ska13flat_hash_mapI1K1V1H1EEE", "vineyard::HashmapBuilder::HashmapBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder14HashmapBuilderER6ClientRRN3ska13flat_hash_mapI1K1V1H1EEE", "vineyard::HashmapBuilder::HashmapBuilder::hashmap"], [28, 3, 1, "_CPPv4I0000EN8vineyard14HashmapBuilderE", "vineyard::HashmapBuilder::K"], [28, 3, 1, "_CPPv4I0000EN8vineyard14HashmapBuilderE", "vineyard::HashmapBuilder::V"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder2atERK1K", "vineyard::HashmapBuilder::at"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder2atERK1K", "vineyard::HashmapBuilder::at"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder2atERK1K", "vineyard::HashmapBuilder::at::key"], [28, 2, 1, "_CPPv4NK8vineyard14HashmapBuilder2atERK1K", "vineyard::HashmapBuilder::at::key"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder5beginEv", "vineyard::HashmapBuilder::begin"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder5beginEv", "vineyard::HashmapBuilder::begin"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder12bucket_countEv", "vineyard::HashmapBuilder::bucket_count"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder6cbeginEv", "vineyard::HashmapBuilder::cbegin"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder4cendEv", "vineyard::HashmapBuilder::cend"], [28, 1, 1, "_CPPv4IDpEN8vineyard14HashmapBuilder7emplaceEbDpRR4Args", "vineyard::HashmapBuilder::emplace"], [28, 3, 1, "_CPPv4IDpEN8vineyard14HashmapBuilder7emplaceEbDpRR4Args", "vineyard::HashmapBuilder::emplace::Args"], [28, 2, 1, "_CPPv4IDpEN8vineyard14HashmapBuilder7emplaceEbDpRR4Args", "vineyard::HashmapBuilder::emplace::args"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder5emptyEv", "vineyard::HashmapBuilder::empty"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder3endEv", "vineyard::HashmapBuilder::end"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder3endEv", "vineyard::HashmapBuilder::end"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder4findERK1K", "vineyard::HashmapBuilder::find"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder4findERK1K", "vineyard::HashmapBuilder::find::key"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder11load_factorEv", "vineyard::HashmapBuilder::load_factor"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilderixERK1K", "vineyard::HashmapBuilder::operator[]"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilderixERR1K", "vineyard::HashmapBuilder::operator[]"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilderixERK1K", "vineyard::HashmapBuilder::operator[]::key"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilderixERR1K", "vineyard::HashmapBuilder::operator[]::key"], [28, 1, 1, "_CPPv4N8vineyard14HashmapBuilder7reserveE6size_t", "vineyard::HashmapBuilder::reserve"], [28, 2, 1, "_CPPv4N8vineyard14HashmapBuilder7reserveE6size_t", "vineyard::HashmapBuilder::reserve::size"], [28, 1, 1, "_CPPv4NK8vineyard14HashmapBuilder4sizeEv", "vineyard::HashmapBuilder::size"], [28, 0, 1, "_CPPv4N8vineyard14InstanceStatusE", "vineyard::InstanceStatus"], [28, 1, 1, "_CPPv4N8vineyard14InstanceStatus14InstanceStatusERK4json", "vineyard::InstanceStatus::InstanceStatus"], [28, 2, 1, "_CPPv4N8vineyard14InstanceStatus14InstanceStatusERK4json", "vineyard::InstanceStatus::InstanceStatus::tree"], [28, 4, 1, "_CPPv4N8vineyard14InstanceStatus17deferred_requestsE", "vineyard::InstanceStatus::deferred_requests"], [28, 4, 1, "_CPPv4N8vineyard14InstanceStatus10deploymentE", "vineyard::InstanceStatus::deployment"], [28, 4, 1, "_CPPv4N8vineyard14InstanceStatus11instance_idE", "vineyard::InstanceStatus::instance_id"], [28, 4, 1, "_CPPv4N8vineyard14InstanceStatus15ipc_connectionsE", "vineyard::InstanceStatus::ipc_connections"], [28, 4, 1, "_CPPv4N8vineyard14InstanceStatus12memory_limitE", "vineyard::InstanceStatus::memory_limit"], [28, 4, 1, "_CPPv4N8vineyard14InstanceStatus12memory_usageE", "vineyard::InstanceStatus::memory_usage"], [28, 4, 1, "_CPPv4N8vineyard14InstanceStatus15rpc_connectionsE", "vineyard::InstanceStatus::rpc_connections"], [28, 0, 1, "_CPPv4N8vineyard6ObjectE", "vineyard::Object"], [28, 1, 1, "_CPPv4N8vineyard6Object5BuildER6Client", "vineyard::Object::Build"], [28, 2, 1, "_CPPv4N8vineyard6Object5BuildER6Client", "vineyard::Object::Build::client"], [28, 1, 1, "_CPPv4N8vineyard6Object9ConstructERK10ObjectMeta", "vineyard::Object::Construct"], [28, 2, 1, "_CPPv4N8vineyard6Object9ConstructERK10ObjectMeta", "vineyard::Object::Construct::meta"], [28, 1, 1, "_CPPv4NK8vineyard6Object8IsGlobalEv", "vineyard::Object::IsGlobal"], [28, 1, 1, "_CPPv4NK8vineyard6Object7IsLocalEv", "vineyard::Object::IsLocal"], [28, 1, 1, "_CPPv4NK8vineyard6Object9IsPersistEv", "vineyard::Object::IsPersist"], [28, 1, 1, "_CPPv4N8vineyard6Object6ObjectEv", "vineyard::Object::Object"], [28, 1, 1, "_CPPv4NK8vineyard6Object7PersistER10ClientBase", "vineyard::Object::Persist"], [28, 2, 1, "_CPPv4NK8vineyard6Object7PersistER10ClientBase", "vineyard::Object::Persist::client"], [28, 1, 1, "_CPPv4N8vineyard6Object13PostConstructERK10ObjectMeta", "vineyard::Object::PostConstruct"], [28, 2, 1, "_CPPv4N8vineyard6Object13PostConstructERK10ObjectMeta", "vineyard::Object::PostConstruct::meta"], [28, 1, 1, "_CPPv4N8vineyard6Object5_SealER6Client", "vineyard::Object::_Seal"], [28, 2, 1, "_CPPv4N8vineyard6Object5_SealER6Client", "vineyard::Object::_Seal::client"], [28, 1, 1, "_CPPv4NK8vineyard6Object2idEv", "vineyard::Object::id"], [28, 4, 1, "_CPPv4N8vineyard6Object3id_E", "vineyard::Object::id_"], [28, 1, 1, "_CPPv4NK8vineyard6Object4metaEv", "vineyard::Object::meta"], [28, 4, 1, "_CPPv4N8vineyard6Object5meta_E", "vineyard::Object::meta_"], [28, 1, 1, "_CPPv4NK8vineyard6Object6nbytesEv", "vineyard::Object::nbytes"], [28, 1, 1, "_CPPv4N8vineyard6ObjectD0Ev", "vineyard::Object::~Object"], [28, 0, 1, "_CPPv4N8vineyard10ObjectBaseE", "vineyard::ObjectBase"], [28, 1, 1, "_CPPv4N8vineyard10ObjectBase5BuildER6Client", "vineyard::ObjectBase::Build"], [28, 2, 1, "_CPPv4N8vineyard10ObjectBase5BuildER6Client", "vineyard::ObjectBase::Build::client"], [28, 1, 1, "_CPPv4N8vineyard10ObjectBase5_SealER6Client", "vineyard::ObjectBase::_Seal"], [28, 2, 1, "_CPPv4N8vineyard10ObjectBase5_SealER6Client", "vineyard::ObjectBase::_Seal::client"], [28, 0, 1, "_CPPv4N8vineyard13ObjectBuilderE", "vineyard::ObjectBuilder"], [28, 1, 1, "_CPPv4N8vineyard13ObjectBuilder5BuildER6Client", "vineyard::ObjectBuilder::Build"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder5BuildER6Client", "vineyard::ObjectBuilder::Build::client"], [28, 1, 1, "_CPPv4N8vineyard13ObjectBuilder4SealER6Client", "vineyard::ObjectBuilder::Seal"], [28, 1, 1, "_CPPv4N8vineyard13ObjectBuilder4SealER6ClientRNSt10shared_ptrI6ObjectEE", "vineyard::ObjectBuilder::Seal"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder4SealER6Client", "vineyard::ObjectBuilder::Seal::client"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder4SealER6ClientRNSt10shared_ptrI6ObjectEE", "vineyard::ObjectBuilder::Seal::client"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder4SealER6ClientRNSt10shared_ptrI6ObjectEE", "vineyard::ObjectBuilder::Seal::object"], [28, 1, 1, "_CPPv4N8vineyard13ObjectBuilder5_SealER6Client", "vineyard::ObjectBuilder::_Seal"], [28, 1, 1, "_CPPv4N8vineyard13ObjectBuilder5_SealER6ClientRNSt10shared_ptrI6ObjectEE", "vineyard::ObjectBuilder::_Seal"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder5_SealER6Client", "vineyard::ObjectBuilder::_Seal::client"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder5_SealER6ClientRNSt10shared_ptrI6ObjectEE", "vineyard::ObjectBuilder::_Seal::client"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder5_SealER6ClientRNSt10shared_ptrI6ObjectEE", "vineyard::ObjectBuilder::_Seal::object"], [28, 1, 1, "_CPPv4NK8vineyard13ObjectBuilder6sealedEv", "vineyard::ObjectBuilder::sealed"], [28, 1, 1, "_CPPv4N8vineyard13ObjectBuilder10set_sealedEKb", "vineyard::ObjectBuilder::set_sealed"], [28, 2, 1, "_CPPv4N8vineyard13ObjectBuilder10set_sealedEKb", "vineyard::ObjectBuilder::set_sealed::sealed"], [28, 1, 1, "_CPPv4N8vineyard13ObjectBuilderD0Ev", "vineyard::ObjectBuilder::~ObjectBuilder"], [28, 5, 1, "_CPPv4N8vineyard8ObjectIDE", "vineyard::ObjectID"], [28, 0, 1, "_CPPv4N8vineyard10ObjectMetaE", "vineyard::ObjectMeta"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK1T", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK5TupleI1TE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3setI1TEE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt6vectorI1TEE", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERK4json", "vineyard::ObjectMeta::AddKeyValue"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERKNSt6stringE", "vineyard::ObjectMeta::AddKeyValue"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK1T", "vineyard::ObjectMeta::AddKeyValue::T"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK5TupleI1TE", "vineyard::ObjectMeta::AddKeyValue::T"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3setI1TEE", "vineyard::ObjectMeta::AddKeyValue::T"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt6vectorI1TEE", "vineyard::ObjectMeta::AddKeyValue::T"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 3, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue::Value"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK1T", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK5TupleI1TE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3setI1TEE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt6vectorI1TEE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERK4json", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERKNSt6stringE", "vineyard::ObjectMeta::AddKeyValue::key"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK1T", "vineyard::ObjectMeta::AddKeyValue::value"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERKNSt6stringE", "vineyard::ObjectMeta::AddKeyValue::value"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapI4json5ValueE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK5TupleI1TE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3setI1TEE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt6vectorI1TEE", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERK4json", "vineyard::ObjectMeta::AddKeyValue::values"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEK8ObjectID", "vineyard::ObjectMeta::AddMember"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEPK6Object", "vineyard::ObjectMeta::AddMember"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK10ObjectMeta", "vineyard::ObjectMeta::AddMember"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK6Object", "vineyard::ObjectMeta::AddMember"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERKNSt10shared_ptrI6ObjectEE", "vineyard::ObjectMeta::AddMember"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEPK6Object", "vineyard::ObjectMeta::AddMember::member"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK10ObjectMeta", "vineyard::ObjectMeta::AddMember::member"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK6Object", "vineyard::ObjectMeta::AddMember::member"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERKNSt10shared_ptrI6ObjectEE", "vineyard::ObjectMeta::AddMember::member"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEK8ObjectID", "vineyard::ObjectMeta::AddMember::member_id"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEK8ObjectID", "vineyard::ObjectMeta::AddMember::name"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEPK6Object", "vineyard::ObjectMeta::AddMember::name"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK10ObjectMeta", "vineyard::ObjectMeta::AddMember::name"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK6Object", "vineyard::ObjectMeta::AddMember::name"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERKNSt10shared_ptrI6ObjectEE", "vineyard::ObjectMeta::AddMember::name"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta13AddRemoteBlobERK10RemoteBlob", "vineyard::ObjectMeta::AddRemoteBlob"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta13AddRemoteBlobERK10RemoteBlob", "vineyard::ObjectMeta::AddRemoteBlob::blob"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta10ForceLocalEv", "vineyard::ObjectMeta::ForceLocal"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE", "vineyard::ObjectMeta::GetBuffer"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE", "vineyard::ObjectMeta::GetBuffer::blob_id"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE", "vineyard::ObjectMeta::GetBuffer::buffer"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta12GetBufferSetEv", "vineyard::ObjectMeta::GetBufferSet"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta9GetClientEv", "vineyard::ObjectMeta::GetClient"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta5GetIdEv", "vineyard::ObjectMeta::GetId"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta13GetInstanceIdEv", "vineyard::ObjectMeta::GetInstanceId"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEK1TRKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER1T", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER5TupleI1TE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3setI1TEE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt6vectorI1TEE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4IENK8vineyard10ObjectMeta11GetKeyValueEK4jsonRKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4IENK8vineyard10ObjectMeta11GetKeyValueEK4jsonRKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta11GetKeyValueERKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta11GetKeyValueERKNSt6stringER4json", "vineyard::ObjectMeta::GetKeyValue"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEK1TRKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue::T"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER1T", "vineyard::ObjectMeta::GetKeyValue::T"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER5TupleI1TE", "vineyard::ObjectMeta::GetKeyValue::T"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3setI1TEE", "vineyard::ObjectMeta::GetKeyValue::T"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt6vectorI1TEE", "vineyard::ObjectMeta::GetKeyValue::T"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue::Value"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEK1TRKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER1T", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER5TupleI1TE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3setI1TEE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt6vectorI1TEE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4IENK8vineyard10ObjectMeta11GetKeyValueEK4jsonRKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4IENK8vineyard10ObjectMeta11GetKeyValueEK4jsonRKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta11GetKeyValueERKNSt6stringE", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta11GetKeyValueERKNSt6stringER4json", "vineyard::ObjectMeta::GetKeyValue::key"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER1T", "vineyard::ObjectMeta::GetKeyValue::value"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta11GetKeyValueERKNSt6stringER4json", "vineyard::ObjectMeta::GetKeyValue::value"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapI4json5ValueE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapINSt6stringE5ValueE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER5TupleI1TE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapI4json5ValueEE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapINSt6stringE5ValueEE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3setI1TEE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt6vectorI1TEE", "vineyard::ObjectMeta::GetKeyValue::values"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberE6StatusRKNSt6stringERNSt10shared_ptrI1TEE", "vineyard::ObjectMeta::GetMember"], [28, 1, 1, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberENSt10shared_ptrI1TEERKNSt6stringE", "vineyard::ObjectMeta::GetMember"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta9GetMemberERKNSt6stringE", "vineyard::ObjectMeta::GetMember"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta9GetMemberERKNSt6stringERNSt10shared_ptrI6ObjectEE", "vineyard::ObjectMeta::GetMember"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberE6StatusRKNSt6stringERNSt10shared_ptrI1TEE", "vineyard::ObjectMeta::GetMember::T"], [28, 3, 1, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberENSt10shared_ptrI1TEERKNSt6stringE", "vineyard::ObjectMeta::GetMember::T"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberE6StatusRKNSt6stringERNSt10shared_ptrI1TEE", "vineyard::ObjectMeta::GetMember::name"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberENSt10shared_ptrI1TEERKNSt6stringE", "vineyard::ObjectMeta::GetMember::name"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta9GetMemberERKNSt6stringE", "vineyard::ObjectMeta::GetMember::name"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta9GetMemberERKNSt6stringERNSt10shared_ptrI6ObjectEE", "vineyard::ObjectMeta::GetMember::name"], [28, 2, 1, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberE6StatusRKNSt6stringERNSt10shared_ptrI1TEE", "vineyard::ObjectMeta::GetMember::object"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta9GetMemberERKNSt6stringERNSt10shared_ptrI6ObjectEE", "vineyard::ObjectMeta::GetMember::object"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta13GetMemberMetaERKNSt6stringE", "vineyard::ObjectMeta::GetMemberMeta"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta13GetMemberMetaERKNSt6stringER10ObjectMeta", "vineyard::ObjectMeta::GetMemberMeta"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta13GetMemberMetaERKNSt6stringER10ObjectMeta", "vineyard::ObjectMeta::GetMemberMeta::meta"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta13GetMemberMetaERKNSt6stringE", "vineyard::ObjectMeta::GetMemberMeta::name"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta13GetMemberMetaERKNSt6stringER10ObjectMeta", "vineyard::ObjectMeta::GetMemberMeta::name"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta9GetNBytesEv", "vineyard::ObjectMeta::GetNBytes"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta12GetSignatureEv", "vineyard::ObjectMeta::GetSignature"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta11GetTypeNameEv", "vineyard::ObjectMeta::GetTypeName"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta6HasKeyERKNSt6stringE", "vineyard::ObjectMeta::HasKey"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta6HasKeyERKNSt6stringE", "vineyard::ObjectMeta::HasKey::key"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta6HaskeyERKNSt6stringE", "vineyard::ObjectMeta::Haskey"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta6HaskeyERKNSt6stringE", "vineyard::ObjectMeta::Haskey::key"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta8IsGlobalEv", "vineyard::ObjectMeta::IsGlobal"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta7IsLocalEv", "vineyard::ObjectMeta::IsLocal"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta5LabelERKNSt6stringE", "vineyard::ObjectMeta::Label"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta5LabelERKNSt6stringE", "vineyard::ObjectMeta::Label::key"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta6LabelsEv", "vineyard::ObjectMeta::Labels"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta11MemoryUsageER4jsonKb", "vineyard::ObjectMeta::MemoryUsage"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta11MemoryUsageEv", "vineyard::ObjectMeta::MemoryUsage"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta11MemoryUsageER4jsonKb", "vineyard::ObjectMeta::MemoryUsage::pretty"], [28, 2, 1, "_CPPv4NK8vineyard10ObjectMeta11MemoryUsageER4jsonKb", "vineyard::ObjectMeta::MemoryUsage::usages"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta8MetaDataEv", "vineyard::ObjectMeta::MetaData"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta11MutMetaDataEv", "vineyard::ObjectMeta::MutMetaData"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta10ObjectMetaERK10ObjectMeta", "vineyard::ObjectMeta::ObjectMeta"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta10ObjectMetaEv", "vineyard::ObjectMeta::ObjectMeta"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta9PrintMetaEv", "vineyard::ObjectMeta::PrintMeta"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta5ResetEv", "vineyard::ObjectMeta::Reset"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta8ResetKeyERKNSt6stringE", "vineyard::ObjectMeta::ResetKey"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta8ResetKeyERKNSt6stringE", "vineyard::ObjectMeta::ResetKey::key"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta14ResetSignatureEv", "vineyard::ObjectMeta::ResetSignature"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9SetBufferERK8ObjectIDRKNSt10shared_ptrI6BufferEE", "vineyard::ObjectMeta::SetBuffer"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9SetBufferERK8ObjectIDRKNSt10shared_ptrI6BufferEE", "vineyard::ObjectMeta::SetBuffer::buffer"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9SetBufferERK8ObjectIDRKNSt10shared_ptrI6BufferEE", "vineyard::ObjectMeta::SetBuffer::id"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9SetClientEP10ClientBase", "vineyard::ObjectMeta::SetClient"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9SetClientEP10ClientBase", "vineyard::ObjectMeta::SetClient::client"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9SetGlobalEb", "vineyard::ObjectMeta::SetGlobal"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9SetGlobalEb", "vineyard::ObjectMeta::SetGlobal::global"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta5SetIdERK8ObjectID", "vineyard::ObjectMeta::SetId"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta5SetIdERK8ObjectID", "vineyard::ObjectMeta::SetId::id"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta11SetMetaDataEP10ClientBaseRK4json", "vineyard::ObjectMeta::SetMetaData"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta11SetMetaDataEP10ClientBaseRK4json", "vineyard::ObjectMeta::SetMetaData::client"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta11SetMetaDataEP10ClientBaseRK4json", "vineyard::ObjectMeta::SetMetaData::meta"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta9SetNBytesEK6size_t", "vineyard::ObjectMeta::SetNBytes"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta9SetNBytesEK6size_t", "vineyard::ObjectMeta::SetNBytes::nbytes"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta11SetTypeNameERKNSt6stringE", "vineyard::ObjectMeta::SetTypeName"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta11SetTypeNameERKNSt6stringE", "vineyard::ObjectMeta::SetTypeName::type_name"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta9TimestampEv", "vineyard::ObjectMeta::Timestamp"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta8ToStringEv", "vineyard::ObjectMeta::ToString"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeE4json6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeENSt6stringE6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeE4json6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::meta"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeENSt6stringE6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::meta"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeE4json6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::nobjects"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeENSt6stringE6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::nobjects"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeE4json6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::objects"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeENSt6stringE6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::objects"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeE4json6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::pointers"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeENSt6stringE6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::pointers"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeE4json6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::sizes"], [28, 2, 1, "_CPPv4N8vineyard10ObjectMeta6UnsafeENSt6stringE6size_tP8ObjectIDP9uintptr_tP6size_t", "vineyard::ObjectMeta::Unsafe::sizes"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta5beginEv", "vineyard::ObjectMeta::begin"], [28, 5, 1, "_CPPv4N8vineyard10ObjectMeta14const_iteratorE", "vineyard::ObjectMeta::const_iterator"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta3endEv", "vineyard::ObjectMeta::end"], [28, 1, 1, "_CPPv4NK8vineyard10ObjectMeta10incompleteEv", "vineyard::ObjectMeta::incomplete"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMetaaSERK10ObjectMeta", "vineyard::ObjectMeta::operator="], [28, 2, 1, "_CPPv4N8vineyard10ObjectMetaaSERK10ObjectMeta", "vineyard::ObjectMeta::operator=::other"], [28, 1, 1, "_CPPv4N8vineyard10ObjectMetaD0Ev", "vineyard::ObjectMeta::~ObjectMeta"], [28, 0, 1, "_CPPv4N8vineyard9RPCClientE", "vineyard::RPCClient"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE", "vineyard::RPCClient::Connect"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_t", "vineyard::RPCClient::Connect"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringEK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient7ConnectEv", "vineyard::RPCClient::Connect"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_t", "vineyard::RPCClient::Connect::host"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::host"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::host"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::password"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::password"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringEK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::password"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::password"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::password"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_t", "vineyard::RPCClient::Connect::port"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::port"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::port"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE", "vineyard::RPCClient::Connect::rpc_endpoint"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringEK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::rpc_endpoint"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::rpc_endpoint"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::session_id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringEK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::session_id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::username"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::username"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringEK9SessionIDRKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::username"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::username"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE", "vineyard::RPCClient::Connect::username"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient16CreateRemoteBlobERKNSt10shared_ptrI16RemoteBlobWriterEER10ObjectMeta", "vineyard::RPCClient::CreateRemoteBlob"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient16CreateRemoteBlobERKNSt10shared_ptrI16RemoteBlobWriterEER10ObjectMeta", "vineyard::RPCClient::CreateRemoteBlob::buffer"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient16CreateRemoteBlobERKNSt10shared_ptrI16RemoteBlobWriterEER10ObjectMeta", "vineyard::RPCClient::CreateRemoteBlob::meta"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient17CreateRemoteBlobsERKNSt6vectorINSt10shared_ptrI16RemoteBlobWriterEEEERNSt6vectorI10ObjectMetaEE", "vineyard::RPCClient::CreateRemoteBlobs"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient17CreateRemoteBlobsERKNSt6vectorINSt10shared_ptrI16RemoteBlobWriterEEEERNSt6vectorI10ObjectMetaEE", "vineyard::RPCClient::CreateRemoteBlobs::buffers"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient17CreateRemoteBlobsERKNSt6vectorINSt10shared_ptrI16RemoteBlobWriterEEEERNSt6vectorI10ObjectMetaEE", "vineyard::RPCClient::CreateRemoteBlobs::metas"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient4ForkER9RPCClient", "vineyard::RPCClient::Fork"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient4ForkER9RPCClient", "vineyard::RPCClient::Fork::client"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::RPCClient::GetMetaData"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb", "vineyard::RPCClient::GetMetaData"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::RPCClient::GetMetaData::id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb", "vineyard::RPCClient::GetMetaData::id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::RPCClient::GetMetaData::meta_data"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb", "vineyard::RPCClient::GetMetaData::meta_data"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataEK8ObjectIDR10ObjectMetaKb", "vineyard::RPCClient::GetMetaData::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb", "vineyard::RPCClient::GetMetaData::sync_remote"], [28, 1, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::RPCClient::GetObject"], [28, 1, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::RPCClient::GetObject"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDKb", "vineyard::RPCClient::GetObject"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::RPCClient::GetObject"], [28, 3, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::RPCClient::GetObject::T"], [28, 3, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::RPCClient::GetObject::T"], [28, 2, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::RPCClient::GetObject::id"], [28, 2, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::RPCClient::GetObject::id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDKb", "vineyard::RPCClient::GetObject::id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::RPCClient::GetObject::id"], [28, 2, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::RPCClient::GetObject::object"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::RPCClient::GetObject::object"], [28, 2, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb", "vineyard::RPCClient::GetObject::sync_remote"], [28, 2, 1, "_CPPv4I0EN8vineyard9RPCClient9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb", "vineyard::RPCClient::GetObject::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDKb", "vineyard::RPCClient::GetObject::sync_remote"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb", "vineyard::RPCClient::GetObject::sync_remote"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient10GetObjectsERKNSt6vectorI8ObjectIDEEKb", "vineyard::RPCClient::GetObjects"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient10GetObjectsERKNSt6vectorI8ObjectIDEEKb", "vineyard::RPCClient::GetObjects::ids"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient10GetObjectsERKNSt6vectorI8ObjectIDEEKb", "vineyard::RPCClient::GetObjects::sync_remote"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDKbRNSt10shared_ptrI10RemoteBlobEE", "vineyard::RPCClient::GetRemoteBlob"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDRNSt10shared_ptrI10RemoteBlobEE", "vineyard::RPCClient::GetRemoteBlob"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDKbRNSt10shared_ptrI10RemoteBlobEE", "vineyard::RPCClient::GetRemoteBlob::buffer"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDRNSt10shared_ptrI10RemoteBlobEE", "vineyard::RPCClient::GetRemoteBlob::buffer"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDKbRNSt10shared_ptrI10RemoteBlobEE", "vineyard::RPCClient::GetRemoteBlob::id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDRNSt10shared_ptrI10RemoteBlobEE", "vineyard::RPCClient::GetRemoteBlob::id"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDKbRNSt10shared_ptrI10RemoteBlobEE", "vineyard::RPCClient::GetRemoteBlob::unsafe"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::ids"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::ids"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::ids"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::ids"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::remote_blobs"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::remote_blobs"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::remote_blobs"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::remote_blobs"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::unsafe"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE", "vineyard::RPCClient::GetRemoteBlobs::unsafe"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient11IsFetchableERK10ObjectMeta", "vineyard::RPCClient::IsFetchable"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11IsFetchableERK10ObjectMeta", "vineyard::RPCClient::IsFetchable::meta"], [28, 1, 1, "_CPPv4NK8vineyard9RPCClient5IsRPCEv", "vineyard::RPCClient::IsRPC"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::RPCClient::ListObjectMeta"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::RPCClient::ListObjectMeta::limit"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::RPCClient::ListObjectMeta::nobuffer"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::RPCClient::ListObjectMeta::pattern"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14ListObjectMetaERKNSt6stringEKbK6size_tb", "vineyard::RPCClient::ListObjectMeta::regex"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::RPCClient::ListObjects"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::RPCClient::ListObjects::limit"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::RPCClient::ListObjects::pattern"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient11ListObjectsERKNSt6stringEKbK6size_t", "vineyard::RPCClient::ListObjects::regex"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::RPCClient::TryAcquireLock"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::RPCClient::TryAcquireLock::actual_key"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::RPCClient::TryAcquireLock::key"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14TryAcquireLockENSt6stringERbRNSt6stringE", "vineyard::RPCClient::TryAcquireLock::result"], [28, 1, 1, "_CPPv4N8vineyard9RPCClient14TryReleaseLockENSt6stringERb", "vineyard::RPCClient::TryReleaseLock"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14TryReleaseLockENSt6stringERb", "vineyard::RPCClient::TryReleaseLock::key"], [28, 2, 1, "_CPPv4N8vineyard9RPCClient14TryReleaseLockENSt6stringERb", "vineyard::RPCClient::TryReleaseLock::result"], [28, 1, 1, "_CPPv4NK8vineyard9RPCClient18remote_instance_idEv", "vineyard::RPCClient::remote_instance_id"], [28, 1, 1, "_CPPv4N8vineyard9RPCClientD0Ev", "vineyard::RPCClient::~RPCClient"], [28, 0, 1, "_CPPv4I0EN8vineyard6ScalarE", "vineyard::Scalar"], [28, 1, 1, "_CPPv4N8vineyard6Scalar9ConstructERK10ObjectMeta", "vineyard::Scalar::Construct"], [28, 2, 1, "_CPPv4N8vineyard6Scalar9ConstructERK10ObjectMeta", "vineyard::Scalar::Construct::meta"], [28, 1, 1, "_CPPv4N8vineyard6Scalar6CreateEv", "vineyard::Scalar::Create"], [28, 3, 1, "_CPPv4I0EN8vineyard6ScalarE", "vineyard::Scalar::T"], [28, 1, 1, "_CPPv4NK8vineyard6Scalar4TypeEv", "vineyard::Scalar::Type"], [28, 1, 1, "_CPPv4NK8vineyard6Scalar5ValueEv", "vineyard::Scalar::Value"], [28, 0, 1, "_CPPv4I0EN8vineyard13ScalarBuilderE", "vineyard::ScalarBuilder"], [28, 1, 1, "_CPPv4N8vineyard13ScalarBuilder13ScalarBuilderER6Client", "vineyard::ScalarBuilder::ScalarBuilder"], [28, 1, 1, "_CPPv4N8vineyard13ScalarBuilder13ScalarBuilderER6ClientRK1T", "vineyard::ScalarBuilder::ScalarBuilder"], [28, 2, 1, "_CPPv4N8vineyard13ScalarBuilder13ScalarBuilderER6Client", "vineyard::ScalarBuilder::ScalarBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard13ScalarBuilder13ScalarBuilderER6ClientRK1T", "vineyard::ScalarBuilder::ScalarBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard13ScalarBuilder13ScalarBuilderER6ClientRK1T", "vineyard::ScalarBuilder::ScalarBuilder::value"], [28, 1, 1, "_CPPv4N8vineyard13ScalarBuilder8SetValueERK1T", "vineyard::ScalarBuilder::SetValue"], [28, 2, 1, "_CPPv4N8vineyard13ScalarBuilder8SetValueERK1T", "vineyard::ScalarBuilder::SetValue::value"], [28, 3, 1, "_CPPv4I0EN8vineyard13ScalarBuilderE", "vineyard::ScalarBuilder::T"], [28, 0, 1, "_CPPv4N8vineyard8SequenceE", "vineyard::Sequence"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence2AtE6size_t", "vineyard::Sequence::At"], [28, 2, 1, "_CPPv4NK8vineyard8Sequence2AtE6size_t", "vineyard::Sequence::At::index"], [28, 1, 1, "_CPPv4N8vineyard8Sequence9ConstructERK10ObjectMeta", "vineyard::Sequence::Construct"], [28, 2, 1, "_CPPv4N8vineyard8Sequence9ConstructERK10ObjectMeta", "vineyard::Sequence::Construct::meta"], [28, 1, 1, "_CPPv4N8vineyard8Sequence6CreateEv", "vineyard::Sequence::Create"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence5FirstEv", "vineyard::Sequence::First"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence6SecondEv", "vineyard::Sequence::Second"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence4SizeEv", "vineyard::Sequence::Size"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence5beginEv", "vineyard::Sequence::begin"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence3endEv", "vineyard::Sequence::end"], [28, 0, 1, "_CPPv4N8vineyard8Sequence8iteratorE", "vineyard::Sequence::iterator"], [28, 1, 1, "_CPPv4N8vineyard8Sequence8iterator8iteratorEPK8Sequence6size_t", "vineyard::Sequence::iterator::iterator"], [28, 2, 1, "_CPPv4N8vineyard8Sequence8iterator8iteratorEPK8Sequence6size_t", "vineyard::Sequence::iterator::iterator::index"], [28, 2, 1, "_CPPv4N8vineyard8Sequence8iterator8iteratorEPK8Sequence6size_t", "vineyard::Sequence::iterator::iterator::sequence"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence8iteratorneE8iterator", "vineyard::Sequence::iterator::operator!="], [28, 2, 1, "_CPPv4NK8vineyard8Sequence8iteratorneE8iterator", "vineyard::Sequence::iterator::operator!=::other"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence8iteratormlEv", "vineyard::Sequence::iterator::operator*"], [28, 1, 1, "_CPPv4N8vineyard8Sequence8iteratorppEv", "vineyard::Sequence::iterator::operator++"], [28, 1, 1, "_CPPv4NK8vineyard8Sequence8iteratoreqE8iterator", "vineyard::Sequence::iterator::operator=="], [28, 2, 1, "_CPPv4NK8vineyard8Sequence8iteratoreqE8iterator", "vineyard::Sequence::iterator::operator==::other"], [28, 0, 1, "_CPPv4N8vineyard15SequenceBuilderE", "vineyard::SequenceBuilder"], [28, 1, 1, "_CPPv4N8vineyard15SequenceBuilder2AtE6size_t", "vineyard::SequenceBuilder::At"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder2AtE6size_t", "vineyard::SequenceBuilder::At::index"], [28, 1, 1, "_CPPv4N8vineyard15SequenceBuilder15SequenceBuilderER6Client", "vineyard::SequenceBuilder::SequenceBuilder"], [28, 1, 1, "_CPPv4N8vineyard15SequenceBuilder15SequenceBuilderER6ClientK6size_t", "vineyard::SequenceBuilder::SequenceBuilder"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder15SequenceBuilderER6Client", "vineyard::SequenceBuilder::SequenceBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder15SequenceBuilderER6ClientK6size_t", "vineyard::SequenceBuilder::SequenceBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder15SequenceBuilderER6ClientK6size_t", "vineyard::SequenceBuilder::SequenceBuilder::size"], [28, 1, 1, "_CPPv4N8vineyard15SequenceBuilder7SetSizeE6size_t", "vineyard::SequenceBuilder::SetSize"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder7SetSizeE6size_t", "vineyard::SequenceBuilder::SetSize::size"], [28, 1, 1, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI13ObjectBuilderEE", "vineyard::SequenceBuilder::SetValue"], [28, 1, 1, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI6ObjectEE", "vineyard::SequenceBuilder::SetValue"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI13ObjectBuilderEE", "vineyard::SequenceBuilder::SetValue::idx"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI6ObjectEE", "vineyard::SequenceBuilder::SetValue::idx"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI13ObjectBuilderEE", "vineyard::SequenceBuilder::SetValue::value"], [28, 2, 1, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI6ObjectEE", "vineyard::SequenceBuilder::SetValue::value"], [28, 1, 1, "_CPPv4NK8vineyard15SequenceBuilder4SizeEv", "vineyard::SequenceBuilder::Size"], [28, 0, 1, "_CPPv4I0EN8vineyard6TensorE", "vineyard::Tensor"], [28, 1, 1, "_CPPv4N8vineyard6Tensor11ArrowTensorEv", "vineyard::Tensor::ArrowTensor"], [28, 5, 1, "_CPPv4N8vineyard6Tensor12ArrowTensorTE", "vineyard::Tensor::ArrowTensorT"], [28, 1, 1, "_CPPv4N8vineyard6Tensor9ConstructERK10ObjectMeta", "vineyard::Tensor::Construct"], [28, 2, 1, "_CPPv4N8vineyard6Tensor9ConstructERK10ObjectMeta", "vineyard::Tensor::Construct::meta"], [28, 1, 1, "_CPPv4N8vineyard6Tensor6CreateEv", "vineyard::Tensor::Create"], [28, 3, 1, "_CPPv4I0EN8vineyard6TensorE", "vineyard::Tensor::T"], [28, 1, 1, "_CPPv4NK8vineyard6Tensor16auxiliary_bufferEv", "vineyard::Tensor::auxiliary_buffer"], [28, 1, 1, "_CPPv4NK8vineyard6Tensor6bufferEv", "vineyard::Tensor::buffer"], [28, 1, 1, "_CPPv4NK8vineyard6Tensor4dataEv", "vineyard::Tensor::data"], [28, 1, 1, "_CPPv4NK8vineyard6TensorixE6size_t", "vineyard::Tensor::operator[]"], [28, 2, 1, "_CPPv4NK8vineyard6TensorixE6size_t", "vineyard::Tensor::operator[]::index"], [28, 1, 1, "_CPPv4NK8vineyard6Tensor15partition_indexEv", "vineyard::Tensor::partition_index"], [28, 1, 1, "_CPPv4NK8vineyard6Tensor5shapeEv", "vineyard::Tensor::shape"], [28, 1, 1, "_CPPv4NK8vineyard6Tensor7stridesEv", "vineyard::Tensor::strides"], [28, 5, 1, "_CPPv4N8vineyard6Tensor21value_const_pointer_tE", "vineyard::Tensor::value_const_pointer_t"], [28, 5, 1, "_CPPv4N8vineyard6Tensor15value_pointer_tE", "vineyard::Tensor::value_pointer_t"], [28, 5, 1, "_CPPv4N8vineyard6Tensor7value_tE", "vineyard::Tensor::value_t"], [28, 1, 1, "_CPPv4NK8vineyard6Tensor10value_typeEv", "vineyard::Tensor::value_type"], [28, 0, 1, "_CPPv4I0EN8vineyard13TensorBuilderE", "vineyard::TensorBuilder"], [28, 1, 1, "_CPPv4N8vineyard13TensorBuilder5BuildER6Client", "vineyard::TensorBuilder::Build"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder5BuildER6Client", "vineyard::TensorBuilder::Build::client"], [28, 3, 1, "_CPPv4I0EN8vineyard13TensorBuilderE", "vineyard::TensorBuilder::T"], [28, 1, 1, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::TensorBuilder"], [28, 1, 1, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::TensorBuilder"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::TensorBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::TensorBuilder::client"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::TensorBuilder::partition_index"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::TensorBuilder::shape"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::TensorBuilder::shape"], [28, 1, 1, "_CPPv4NK8vineyard13TensorBuilder4dataEv", "vineyard::TensorBuilder::data"], [28, 1, 1, "_CPPv4NK8vineyard13TensorBuilder15partition_indexEv", "vineyard::TensorBuilder::partition_index"], [28, 1, 1, "_CPPv4N8vineyard13TensorBuilder19set_partition_indexERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::set_partition_index"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder19set_partition_indexERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::set_partition_index::partition_index"], [28, 1, 1, "_CPPv4N8vineyard13TensorBuilder9set_shapeERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::set_shape"], [28, 2, 1, "_CPPv4N8vineyard13TensorBuilder9set_shapeERKNSt6vectorI7int64_tEE", "vineyard::TensorBuilder::set_shape::shape"], [28, 1, 1, "_CPPv4NK8vineyard13TensorBuilder5shapeEv", "vineyard::TensorBuilder::shape"], [28, 1, 1, "_CPPv4NK8vineyard13TensorBuilder7stridesEv", "vineyard::TensorBuilder::strides"], [28, 5, 1, "_CPPv4N8vineyard13TensorBuilder21value_const_pointer_tE", "vineyard::TensorBuilder::value_const_pointer_t"], [28, 5, 1, "_CPPv4N8vineyard13TensorBuilder15value_pointer_tE", "vineyard::TensorBuilder::value_pointer_t"], [28, 5, 1, "_CPPv4N8vineyard13TensorBuilder7value_tE", "vineyard::TensorBuilder::value_t"]], "vineyard": [[30, 6, 1, "", "Blob"], [30, 6, 1, "", "BlobBuilder"], [30, 6, 1, "", "Client"], [30, 6, 1, "", "IPCClient"], [30, 6, 1, "", "InstanceStatus"], [30, 6, 1, "", "Object"], [30, 6, 1, "", "ObjectBuilder"], [30, 6, 1, "", "ObjectID"], [30, 6, 1, "", "ObjectMeta"], [30, 6, 1, "", "RPCClient"], [30, 6, 1, "", "RemoteBlob"], [30, 6, 1, "", "RemoteBlobBuilder"], [30, 9, 1, "id0", "connect"], [30, 9, 1, "", "get_current_socket"]], "vineyard.Blob": [[30, 7, 1, "", "address"], [30, 8, 1, "", "empty"], [30, 7, 1, "", "is_empty"], [30, 7, 1, "", "size"]], "vineyard.BlobBuilder": [[30, 8, 1, "", "abort"], [30, 7, 1, "", "address"], [30, 8, 1, "", "copy"], [30, 7, 1, "", "id"], [30, 8, 1, "", "shrink"], [30, 7, 1, "", "size"]], "vineyard.Client": [[30, 8, 1, "", "allocated_size"], [30, 8, 1, "", "clear"], [30, 8, 1, "", "close"], [30, 7, 1, "", "compression"], [30, 7, 1, "", "connected"], [30, 8, 1, "", "create_blob"], [30, 8, 1, "", "create_empty_blob"], [30, 8, 1, "", "create_metadata"], [30, 8, 1, "", "create_remote_blob"], [30, 8, 1, "", "delete"], [30, 8, 1, "", "drop_name"], [30, 8, 1, "", "exists"], [30, 8, 1, "", "find_shared_memory"], [30, 8, 1, "", "get"], [30, 8, 1, "", "get_blob"], [30, 8, 1, "", "get_blobs"], [30, 8, 1, "", "get_meta"], [30, 8, 1, "", "get_metas"], [30, 8, 1, "", "get_name"], [30, 8, 1, "", "get_object"], [30, 8, 1, "", "get_objects"], [30, 8, 1, "", "get_remote_blob"], [30, 8, 1, "", "get_remote_blobs"], [30, 7, 1, "", "instance_id"], [30, 7, 1, "", "ipc_socket"], [30, 7, 1, "", "is_ipc"], [30, 7, 1, "", "is_rpc"], [30, 8, 1, "", "is_shared_memory"], [30, 8, 1, "", "list_metadatas"], [30, 8, 1, "", "list_names"], [30, 8, 1, "", "list_objects"], [30, 8, 1, "", "memory_trim"], [30, 7, 1, "", "meta"], [30, 8, 1, "", "persist"], [30, 8, 1, "", "put"], [30, 8, 1, "", "put_name"], [30, 7, 1, "", "remote_instance_id"], [30, 8, 1, "", "reset"], [30, 7, 1, "", "rpc_endpoint"], [30, 8, 1, "", "shallow_copy"], [30, 7, 1, "", "spread"], [30, 7, 1, "", "status"], [30, 8, 1, "", "sync_meta"], [30, 7, 1, "", "version"], [30, 8, 1, "", "with_compression"], [30, 8, 1, "", "with_spread"]], "vineyard.IPCClient": [[30, 8, 1, "", "allocated_size"], [30, 8, 1, "", "clear"], [30, 8, 1, "", "close"], [30, 7, 1, "", "connected"], [30, 8, 1, "", "create_blob"], [30, 8, 1, "", "create_empty_blob"], [30, 8, 1, "", "create_metadata"], [30, 8, 1, "", "delete"], [30, 8, 1, "", "drop_name"], [30, 8, 1, "", "exists"], [30, 8, 1, "", "find_shared_memory"], [30, 8, 1, "", "get"], [30, 8, 1, "", "get_blob"], [30, 8, 1, "", "get_blobs"], [30, 8, 1, "", "get_meta"], [30, 8, 1, "", "get_metas"], [30, 8, 1, "", "get_name"], [30, 8, 1, "", "get_object"], [30, 8, 1, "", "get_objects"], [30, 7, 1, "", "instance_id"], [30, 7, 1, "", "ipc_socket"], [30, 7, 1, "", "is_ipc"], [30, 7, 1, "", "is_rpc"], [30, 8, 1, "", "is_shared_memory"], [30, 8, 1, "", "list_metadatas"], [30, 8, 1, "", "list_names"], [30, 8, 1, "", "list_objects"], [30, 8, 1, "", "memory_trim"], [30, 7, 1, "", "meta"], [30, 8, 1, "", "persist"], [30, 8, 1, "", "put"], [30, 8, 1, "", "put_name"], [30, 8, 1, "", "reset"], [30, 7, 1, "", "rpc_endpoint"], [30, 8, 1, "", "shallow_copy"], [30, 7, 1, "", "status"], [30, 8, 1, "", "sync_meta"], [30, 7, 1, "", "version"]], "vineyard.InstanceStatus": [[30, 8, 1, "", "__init__"], [30, 8, 1, "", "__repr__"], [30, 8, 1, "", "__str__"], [30, 7, 1, "", "deferred_requests"], [30, 7, 1, "", "deployment"], [30, 7, 1, "", "instance_id"], [30, 7, 1, "", "ipc_connections"], [30, 7, 1, "", "memory_limit"], [30, 7, 1, "", "memory_usage"], [30, 7, 1, "", "rpc_connections"]], "vineyard.Object": [[30, 8, 1, "", "from_"], [30, 7, 1, "", "id"], [30, 7, 1, "", "isglobal"], [30, 7, 1, "", "islocal"], [30, 7, 1, "", "ispersist"], [30, 8, 1, "", "member"], [30, 7, 1, "", "meta"], [30, 7, 1, "", "nbytes"], [30, 7, 1, "", "signature"], [30, 7, 1, "", "typename"]], "vineyard.ObjectID": [[30, 8, 1, "", "__eq__"], [30, 8, 1, "", "__hash__"], [30, 8, 1, "", "__init__"], [30, 8, 1, "", "__repr__"], [30, 8, 1, "", "__str__"]], "vineyard.ObjectMeta": [[30, 8, 1, "", "__contains__"], [30, 8, 1, "", "__getitem__"], [30, 8, 1, "", "__init__"], [30, 8, 1, "", "__repr__"], [30, 8, 1, "", "__setitem__"], [30, 8, 1, "", "__str__"], [30, 8, 1, "", "add_member"], [30, 8, 1, "", "add_remote_blob"], [30, 8, 1, "", "get"], [30, 8, 1, "", "get_member"], [30, 7, 1, "", "id"], [30, 7, 1, "", "instance_id"], [30, 7, 1, "", "isglobal"], [30, 7, 1, "", "islocal"], [30, 8, 1, "", "member"], [30, 7, 1, "", "memory_usage"], [30, 7, 1, "", "nbytes"], [30, 8, 1, "", "set_global"], [30, 7, 1, "", "signature"], [30, 7, 1, "", "typename"]], "vineyard.RPCClient": [[30, 8, 1, "", "clear"], [30, 8, 1, "", "close"], [30, 7, 1, "", "connected"], [30, 8, 1, "", "create_metadata"], [30, 8, 1, "", "create_remote_blob"], [30, 8, 1, "", "delete"], [30, 8, 1, "", "drop_name"], [30, 8, 1, "", "exists"], [30, 8, 1, "", "get"], [30, 8, 1, "", "get_meta"], [30, 8, 1, "", "get_metas"], [30, 8, 1, "", "get_name"], [30, 8, 1, "", "get_object"], [30, 8, 1, "", "get_objects"], [30, 8, 1, "", "get_remote_blob"], [30, 8, 1, "", "get_remote_blobs"], [30, 7, 1, "", "instance_id"], [30, 7, 1, "", "ipc_socket"], [30, 8, 1, "", "is_fetchable"], [30, 7, 1, "", "is_ipc"], [30, 7, 1, "", "is_rpc"], [30, 8, 1, "", "list_metadatas"], [30, 8, 1, "", "list_names"], [30, 8, 1, "", "list_objects"], [30, 8, 1, "", "memory_trim"], [30, 7, 1, "", "meta"], [30, 8, 1, "", "persist"], [30, 8, 1, "", "put"], [30, 8, 1, "", "put_name"], [30, 7, 1, "", "remote_instance_id"], [30, 8, 1, "", "reset"], [30, 7, 1, "", "rpc_endpoint"], [30, 8, 1, "", "shallow_copy"], [30, 7, 1, "", "status"], [30, 8, 1, "", "sync_meta"], [30, 7, 1, "", "version"]], "vineyard.RemoteBlob": [[30, 7, 1, "", "address"], [30, 7, 1, "", "id"], [30, 7, 1, "", "instance_id"], [30, 7, 1, "", "is_empty"], [30, 7, 1, "", "size"]], "vineyard.RemoteBlobBuilder": [[30, 8, 1, "", "abort"], [30, 7, 1, "", "address"], [30, 8, 1, "", "copy"], [30, 7, 1, "", "size"]], "vineyard.core.builder": [[30, 6, 1, "", "BuilderContext"], [30, 9, 1, "", "builder_context"], [30, 9, 1, "", "get_current_builders"]], "vineyard.core.builder.BuilderContext": [[30, 8, 1, "", "register"], [30, 8, 1, "", "run"]], "vineyard.core.driver": [[30, 6, 1, "", "DriverContext"], [30, 9, 1, "", "driver_context"], [30, 9, 1, "", "get_current_drivers"]], "vineyard.core.resolver": [[30, 6, 1, "", "ResolverContext"], [30, 9, 1, "", "get_current_resolvers"], [30, 9, 1, "", "resolver_context"]], "vineyard.csi": [[30, 9, 1, "", "read"], [30, 9, 1, "", "write"]], "vineyard.deploy.distributed": [[30, 9, 1, "", "start_vineyardd"]], "vineyard.deploy.kubernetes": [[30, 9, 1, "", "delete_kubernetes_objects"], [30, 9, 1, "", "start_vineyardd"]], "vineyard.deploy.local": [[30, 9, 1, "", "start_vineyardd"]], "vineyard.io.byte": [[30, 6, 1, "", "ByteStream"]], "vineyard.io.dataframe": [[30, 6, 1, "", "DataframeStream"]], "vineyard.io": [[30, 9, 1, "", "open"], [30, 9, 1, "", "read"], [30, 9, 1, "", "write"]], "vineyard.io.recordbatch": [[30, 6, 1, "", "RecordBatchStream"]], "vineyard.shared_memory": [[30, 6, 1, "", "ShareableList"], [30, 6, 1, "", "SharedMemory"]], "vineyard.shared_memory.ShareableList": [[30, 8, 1, "", "freeze"]], "vineyard.shared_memory.SharedMemory": [[30, 7, 1, "", "buf"], [30, 8, 1, "", "freeze"], [30, 7, 1, "", "name"], [30, 7, 1, "", "size"], [30, 8, 1, "", "unlink"]]}, "objtypes": {"0": "cpp:class", "1": "cpp:function", "2": "cpp:functionParam", "3": "cpp:templateParam", "4": "cpp:member", "5": "cpp:type", "6": "py:class", "7": "py:property", "8": "py:method", "9": "py:function"}, "objnames": {"0": ["cpp", "class", "C++ class"], "1": ["cpp", "function", "C++ function"], "2": ["cpp", "functionParam", "C++ function parameter"], "3": ["cpp", "templateParam", "C++ template parameter"], "4": ["cpp", "member", "C++ member"], "5": ["cpp", "type", "C++ type"], "6": ["py", "class", "Python class"], "7": ["py", "property", "Python property"], "8": ["py", "method", "Python method"], "9": ["py", "function", "Python function"]}, "titleterms": {"vineyard": [0, 1, 2, 4, 5, 6, 8, 9, 12, 13, 14, 16, 17, 18, 19, 20, 25, 28, 30, 32, 33, 36, 37, 38, 40, 41, 42, 43, 44, 45, 46], "2022": 0, "annual": [0, 1], "review": [0, 1], "background": [0, 1], "devstat": [0, 1], "maintain": [0, 1], "adopt": [0, 1], "project": [0, 1], "goal": [0, 1, 3], "cncf": [0, 1], "membership": [0, 1], "incub": [0, 1], "2023": 1, "develop": [1, 9], "highlight": 1, "new": 1, "featur": [1, 2, 3], "academ": 1, "research": 1, "why": 2, "bother": 2, "what": 2, "i": [2, 23, 24, 30], "effici": [2, 42], "data": [2, 3, 14, 19, 22, 24, 28, 31, 32, 33, 38, 39, 41, 42, 45, 46], "share": [2, 3, 13, 30, 32, 34, 36, 41, 42], "out": [2, 3], "box": [2, 3], "abstract": [2, 3], "pluggabl": 2, "o": [2, 23, 30], "routin": 2, "orchestr": [2, 3, 15], "kubernet": [2, 4, 12, 18, 32, 40, 41, 43, 44, 46], "us": [2, 9, 19, 22, 25, 44, 45], "case": 2, "get": [2, 6, 7, 13], "start": [2, 4, 12, 13], "now": 2, "read": [2, 42], "paper": 2, "architectur": [3, 5], "overview": 3, "server": [3, 13, 28], "side": 3, "client": [3, 28, 30], "core": 3, "zero": 3, "cost": 3, "memori": [3, 30, 34], "distribut": [3, 16, 22, 24, 28, 33], "big": [3, 14], "task": [3, 13, 45], "high": 3, "level": 3, "conveni": 3, "integr": 3, "python": [3, 8, 13, 30, 35, 36, 39, 45], "notebook": 3, "non": 3, "limit": 3, "NO": 3, "mutabl": 3, "object": [3, 5, 6, 13, 22, 24, 28, 30, 36, 38, 39], "deploi": [4, 6, 18, 32, 42, 44, 45], "quick": 4, "instal": [4, 5, 8, 9, 13, 45], "oper": [4, 5, 6, 29, 44, 45], "option": [4, 6, 44, 45], "1": [4, 11, 44, 45], "from": [4, 8, 19, 33], "helm": 4, "chart": 4, "recommend": 4, "2": [4, 11, 44, 45], "form": 4, "sourc": [4, 8, 9], "code": [4, 9, 26], "wait": 4, "readi": 4, "expect": [4, 5, 42, 43, 44], "output": [4, 5, 42, 43, 44], "creat": [4, 5, 6, 9, 39, 45], "cluster": [4, 5, 6, 30, 32, 42, 44, 45], "refer": [4, 27, 28, 29, 30], "sidecar": [5, 29], "configur": [5, 18], "globalobject": [5, 29], "localobject": [5, 29], "schedul": [5, 6, 45], "util": [5, 22, 38], "plugin": [5, 18], "driver": [5, 23, 30, 42], "checkpoint": 5, "trigger": 5, "job": [5, 6], "assembli": 5, "an": [5, 24, 33], "repartit": 5, "initi": [5, 44], "dask": [5, 17], "failov": 5, "mechan": 5, "vineyardctl": 6, "synopsi": 6, "exampl": [6, 24, 33, 34, 42], "backup": [6, 29], "recov": [6, 29], "csi": [6, 30, 42], "delet": 6, "csidriv": [6, 29], "deploy": [6, 16, 17, 30], "vineyardd": [6, 29], "blob": [6, 22, 28, 30], "info": 6, "metadata": [6, 22, 24, 28, 30], "inject": 6, "argo": [6, 32, 42], "workflow": [6, 9, 15, 32, 42], "l": 6, "manag": 6, "put": 6, "workload": 6, "involv": 7, "build": [8, 9, 45], "etcd": 8, "prepar": [8, 32, 42], "depend": [8, 9], "ubuntu": 8, "debian": 8, "maco": 8, "wheel": 8, "document": [8, 9], "variou": 8, "platform": 8, "contribut": 9, "docker": [9, 32], "run": [9, 16, 42], "unit": 9, "test": 9, "report": 9, "bug": 9, "submit": 9, "pull": 9, "request": 9, "pre": 9, "commit": 9, "sign": 9, "off": 9, "your": [9, 38], "format": 9, "open": 9, "git": 9, "newcom": 9, "releas": [9, 11], "frequent": 10, "ask": 10, "question": 10, "roadmap": 11, "v0": 11, "8": 11, "0": [11, 44], "7": 11, "6": 11, "5": 11, "4": [11, 44, 45], "3": [11, 44, 45], "note": 11, "troubleshoot": 12, "fail": 12, "issu": 12, "launch": 13, "connect": [13, 44], "store": 13, "retriev": 13, "between": [13, 25, 41], "next": 13, "step": [13, 44, 45], "airflow": 16, "introduc": 16, "The": [16, 17], "rational": 16, "how": 16, "enhanc": 16, "address": 16, "challeng": 16, "further": 16, "ahead": 16, "preprocess": [17, 33], "train": [17, 33, 45], "tensorflow": [17, 19], "transfer": 17, "learn": [17, 19, 33, 43], "kedro": [18, 32], "requir": 18, "usag": 18, "machin": [19, 43], "numpi": 19, "datafram": [19, 24], "recordbatch": 19, "pyarrow": 19, "tabl": 19, "pytorch": 19, "mxnet": 19, "xgboost": 19, "tensor": [19, 24], "nvidia": 19, "dali": 19, "rai": 20, "kei": 21, "concept": 21, "access": 22, "ipcclient": 22, "v": [22, 24], "rpcclient": 22, "local": 22, "remot": 22, "inspect": 22, "payload": 24, "two": 24, "column": 24, "where": 24, "each": 24, "separ": 24, "model": [24, 33, 45], "compos": 24, "transient": 24, "persist": 24, "builder": [24, 30, 38, 39], "resolv": [24, 30, 39], "stream": [25, 28, 30], "produc": 25, "consum": 25, "process": [25, 31, 46], "gener": 26, "boilerpl": 26, "api": [27, 28, 29, 30], "c": [28, 38], "basic": 28, "type": [28, 29, 38, 39], "packag": 29, "k8": 29, "v6d": 29, "io": 29, "v1alpha1": 29, "resourc": 29, "backuplist": 29, "backupspec": 29, "csidriverlist": 29, "csidriverspec": 29, "csisidecar": 29, "globalobjectlist": 29, "globalobjectspec": 29, "localobjectlist": 29, "localobjectspec": 29, "metricconfig": 29, "operationlist": 29, "operationspec": 29, "pluginimageconfig": 29, "recoverlist": 29, "recoverspec": 29, "serviceconfig": 29, "sidecarlist": 29, "sidecarspec": 29, "spillconfig": 29, "vineyardclust": 29, "vineyardconfig": 29, "vineyarddlist": 29, "vineyarddspec": 29, "volumeconfig": 29, "interact": 30, "cli": 30, "tool": 30, "llm": 30, "kv": 30, "cach": 30, "acceler": 32, "s3": 32, "servic": 32, "imag": 32, "pipelin": [32, 42, 45], "perform": 32, "kera": 33, "setup": 33, "conclus": 33, "gpu": 34, "cuda": 34, "ipc": 34, "unifi": 34, "multiprocess": 35, "shared_memori": 35, "extend": [37, 46], "defin": [38, 39], "custom": 38, "objectbuild": 38, "regist": 38, "cross": 38, "languag": 38, "compat": 38, "prerequisit": [41, 42], "differ": 41, "contain": 41, "pod": 41, "kubeflow": 42, "kfp": 42, "v1": 42, "v2": 42, "result": 42, "analysi": 42, "durat": 42, "actual": 42, "execut": 42, "time": 42, "write": 42, "dashboard": 42, "clean": 42, "up": 42, "cleanup": 44, "fluid": 45, "action": 45, "linear": 45, "regress": 45, "ack": 45, "dataset": 45, "upload": 45, "oss": 45, "control": 45, "plane": 45, "sdk": 45, "enabl": 45, "collabor": 45}, "envversion": {"sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "nbsphinx": 4, "sphinx.ext.viewcode": 1, "sphinx": 58}, "alltitles": {"Vineyard 2022 Annual Review": [[0, "vineyard-2022-annual-review"]], "Background": [[0, "background"], [1, "background"]], "DevStats": [[0, "devstats"], [1, "devstats"]], "Maintainers": [[0, "maintainers"], [1, "maintainers"]], "Adoption": [[0, "adoption"], [1, "adoption"]], "Project Goals": [[0, "project-goals"], [1, "project-goals"]], "CNCF membership": [[0, "cncf-membership"], [1, "cncf-membership"]], "Incubation": [[0, "incubation"], [1, "incubation"]], "Vineyard 2023 Annual Review": [[1, "vineyard-2023-annual-review"]], "Development": [[1, "development"]], "Highlights of new features": [[1, "highlights-of-new-features"]], "Academic Research": [[1, "academic-research"]], "Why bother?": [[2, "why-bother"]], "What is Vineyard?": [[2, "what-is-vineyard"]], "Features": [[2, "features"]], "Efficient data sharing": [[2, "efficient-data-sharing"]], "Out-of-the-box data abstraction": [[2, "out-of-the-box-data-abstraction"]], "Pluggable I/O routines": [[2, "pluggable-i-o-routines"]], "Data orchestration on Kubernetes": [[2, "data-orchestration-on-kubernetes"]], "Use cases": [[2, "use-cases"]], "Get started now!": [[2, "get-started-now"]], "Read the Paper": [[2, "read-the-paper"]], "Architecture": [[3, "architecture"], [5, "architecture"]], "Overview": [[3, "overview"]], "Server side": [[3, "server-side"]], "Client side": [[3, "client-side"]], "Core features": [[3, "core-features"]], "Zero-cost in-memory data sharing": [[3, "zero-cost-in-memory-data-sharing"]], "Distributed data sharing in big data tasks": [[3, "distributed-data-sharing-in-big-data-tasks"]], "Out-of-the-box high-level data abstraction": [[3, "out-of-the-box-high-level-data-abstraction"]], "Convenient data integration": [[3, "convenient-data-integration"]], "Data orchestration in a Python notebook": [[3, "data-orchestration-in-a-python-notebook"]], "Non-goals and limitations": [[3, "non-goals-and-limitations"]], "NO mutable objects": [[3, "no-mutable-objects"]], "Deploy on Kubernetes": [[4, "deploy-on-kubernetes"]], "Quick start": [[4, "quick-start"]], "Install vineyard-operator": [[4, "install-vineyard-operator"]], "Option #1: Install from helm chart (recommended)": [[4, "option-1-install-from-helm-chart-recommended"]], "Option #2: Install form source code": [[4, "option-2-install-form-source-code"]], "Wait vineyard-operator ready": [[4, "wait-vineyard-operator-ready"]], "Expected output": [[4, null], [4, null], [5, null], [5, null], [5, null], [42, null], [43, null], [43, null], [43, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null], [44, null]], "Create vineyard cluster": [[4, "create-vineyard-cluster"]], "References": [[4, "references"]], "Vineyard Operator": [[5, "vineyard-operator"]], "Create a vineyard Cluster": [[5, "create-a-vineyard-cluster"]], "Installing vineyard as sidecar": [[5, "installing-vineyard-as-sidecar"]], "Sidecar Configurations": [[5, "id3"]], "Objects in Vineyard": [[5, "objects-in-vineyard"]], "GlobalObject": [[5, "globalobject"], [29, "globalobject"]], "LocalObject": [[5, "localobject"], [29, "localobject"]], "Vineyard Scheduler": [[5, "vineyard-scheduler"]], "Utilizing the Vineyard Scheduler": [[5, "utilizing-the-vineyard-scheduler"]], "Scheduler Plugin Configurations": [[5, null]], "Operations and drivers": [[5, "operations-and-drivers"]], "Checkpoint": [[5, "checkpoint"]], "Triggering a checkpoint job": [[5, "triggering-a-checkpoint-job"]], "Assembly": [[5, "assembly"]], "Triggering an assembly job": [[5, "triggering-an-assembly-job"]], "Assembly Drivers Configurations": [[5, null]], "Repartitioning": [[5, "repartitioning"]], "Initiating a Repartition Job": [[5, "initiating-a-repartition-job"]], "Dask Repartition Drivers Configurations": [[5, null]], "Failover mechanism of vineyard cluster": [[5, "failover-mechanism-of-vineyard-cluster"]], "vineyardctl": [[6, "vineyardctl"]], "Synopsis": [[6, "synopsis"], [6, "id2"], [6, "id5"], [6, "id8"], [6, "id15"], [6, "id34"], [6, "id37"], [6, "id40"], [6, "id43"], [6, "id48"], [6, "id51"], [6, "id56"], [6, "id59"], [6, "id62"], [6, "id65"], [6, "id68"], [6, "id71"], [6, "id76"], [6, "id79"], [6, "id82"], [6, "id87"], [6, "id92"], [6, "id95"]], "Options": [[6, "options"], [6, "id1"], [6, "id4"], [6, "id7"], [6, "id10"], [6, "id12"], [6, "id14"], [6, "id17"], [6, "id19"], [6, "id21"], [6, "id23"], [6, "id25"], [6, "id27"], [6, "id29"], [6, "id31"], [6, "id33"], [6, "id36"], [6, "id39"], [6, "id42"], [6, "id45"], [6, "id47"], [6, "id50"], [6, "id53"], [6, "id55"], [6, "id58"], [6, "id61"], [6, "id64"], [6, "id67"], [6, "id70"], [6, "id73"], [6, "id75"], [6, "id78"], [6, "id81"], [6, "id84"], [6, "id86"], [6, "id89"], [6, "id91"], [6, "id94"], [6, "id97"]], "vineyardctl create": [[6, "vineyardctl-create"]], "Examples": [[6, "examples"], [6, "id3"], [6, "id6"], [6, "id9"], [6, "id11"], [6, "id13"], [6, "id16"], [6, "id18"], [6, "id20"], [6, "id22"], [6, "id24"], [6, "id26"], [6, "id28"], [6, "id30"], [6, "id32"], [6, "id35"], [6, "id38"], [6, "id41"], [6, "id44"], [6, "id46"], [6, "id49"], [6, "id52"], [6, "id54"], [6, "id57"], [6, "id60"], [6, "id63"], [6, "id66"], [6, "id69"], [6, "id72"], [6, "id74"], [6, "id77"], [6, "id80"], [6, "id83"], [6, "id85"], [6, "id88"], [6, "id90"], [6, "id93"], [6, "id96"]], "vineyardctl create backup": [[6, "vineyardctl-create-backup"]], "vineyardctl create operation": [[6, "vineyardctl-create-operation"]], "vineyardctl create recover": [[6, "vineyardctl-create-recover"]], "vineyardctl csi": [[6, "vineyardctl-csi"]], "vineyardctl delete": [[6, "vineyardctl-delete"]], "vineyardctl delete backup": [[6, "vineyardctl-delete-backup"]], "vineyardctl delete csidriver": [[6, "vineyardctl-delete-csidriver"]], "vineyardctl delete operation": [[6, "vineyardctl-delete-operation"]], "vineyardctl delete operator": [[6, "vineyardctl-delete-operator"]], "vineyardctl delete recover": [[6, "vineyardctl-delete-recover"]], "vineyardctl delete vineyard-cluster": [[6, "vineyardctl-delete-vineyard-cluster"]], "vineyardctl delete vineyard-deployment": [[6, "vineyardctl-delete-vineyard-deployment"]], "vineyardctl delete vineyardd": [[6, "vineyardctl-delete-vineyardd"]], "vineyardctl deploy": [[6, "vineyardctl-deploy"]], "vineyardctl deploy backup-job": [[6, "vineyardctl-deploy-backup-job"]], "vineyardctl deploy csidriver": [[6, "vineyardctl-deploy-csidriver"]], "vineyardctl deploy operator": [[6, "vineyardctl-deploy-operator"]], "vineyardctl deploy recover-job": [[6, "vineyardctl-deploy-recover-job"]], "vineyardctl deploy vineyard-cluster": [[6, "vineyardctl-deploy-vineyard-cluster"]], "vineyardctl deploy vineyard-deployment": [[6, "vineyardctl-deploy-vineyard-deployment"]], "vineyardctl deploy vineyardd": [[6, "vineyardctl-deploy-vineyardd"]], "vineyardctl get": [[6, "vineyardctl-get"]], "vineyardctl get blob": [[6, "vineyardctl-get-blob"]], "vineyardctl get cluster-info": [[6, "vineyardctl-get-cluster-info"]], "vineyardctl get metadata": [[6, "vineyardctl-get-metadata"]], "vineyardctl get object": [[6, "vineyardctl-get-object"]], "vineyardctl inject": [[6, "vineyardctl-inject"]], "vineyardctl inject argo-workflow": [[6, "vineyardctl-inject-argo-workflow"]], "vineyardctl ls": [[6, "vineyardctl-ls"]], "vineyardctl ls blobs": [[6, "vineyardctl-ls-blobs"]], "vineyardctl ls metadatas": [[6, "vineyardctl-ls-metadatas"]], "vineyardctl ls objects": [[6, "vineyardctl-ls-objects"]], "vineyardctl manager": [[6, "vineyardctl-manager"]], "vineyardctl put": [[6, "vineyardctl-put"]], "vineyardctl schedule": [[6, "vineyardctl-schedule"]], "vineyardctl schedule workflow": [[6, "vineyardctl-schedule-workflow"]], "vineyardctl schedule workload": [[6, "vineyardctl-schedule-workload"]], "Getting Involved": [[7, "getting-involved"]], "Building from source": [[8, "building-from-source"]], "Install vineyard": [[8, "install-vineyard"]], "Install etcd": [[8, "install-etcd"]], "Install from source": [[8, "install-from-source"]], "Prepare dependencies": [[8, "prepare-dependencies"]], "Dependencies": [[8, "dependencies"]], "Install on Ubuntu (or Debian)": [[8, "install-on-ubuntu-or-debian"]], "Dependencies on MacOS": [[8, "dependencies-on-macos"]], "Building vineyard": [[8, "building-vineyard"]], "Building python wheels": [[8, "building-python-wheels"]], "Building the documentation": [[8, "building-the-documentation"]], "Building on various platforms": [[8, "building-on-various-platforms"]], "Contributing to vineyard": [[9, "contributing-to-vineyard"]], "Install development dependencies": [[9, "install-development-dependencies"]], "Developing Vineyard Using Docker": [[9, "developing-vineyard-using-docker"]], "Build the source": [[9, "build-the-source"]], "Running Unit Tests": [[9, "running-unit-tests"]], "Documentation": [[9, "documentation"]], "Reporting Bugs": [[9, "reporting-bugs"]], "Submitting Pull Requests": [[9, "submitting-pull-requests"]], "Install Pre-commit": [[9, "install-pre-commit"]], "Sign Off Your Commits": [[9, "sign-off-your-commits"]], "Code Formatting": [[9, "code-formatting"]], "Open a Pull Request": [[9, "open-a-pull-request"]], "Git Workflow for Newcomers": [[9, "git-workflow-for-newcomers"]], "Creating a Release": [[9, "creating-a-release"]], "Frequently Asked Questions": [[10, "frequently-asked-questions"]], "Roadmap": [[11, "roadmap"]], "v0.8.0": [[11, "v0-8-0"]], "v0.7.0": [[11, "v0-7-0"]], "v0.6.0": [[11, "v0-6-0"]], "v0.5.0": [[11, "v0-5-0"]], "v0.4.0": [[11, "v0-4-0"]], "v0.3.0": [[11, "v0-3-0"]], "v0.2.0": [[11, "v0-2-0"]], "v0.1.0": [[11, "v0-1-0"]], "Release Notes": [[11, "release-notes"]], "Troubleshooting": [[12, "troubleshooting"]], "Vineyard Fails to Start": [[12, "vineyard-fails-to-start"]], "Vineyard Issues on Kubernetes": [[12, "vineyard-issues-on-kubernetes"]], "Getting Started": [[13, "getting-started"]], "Installing vineyard": [[13, "installing-vineyard"]], "Launching vineyard server": [[13, "launching-vineyard-server"]], "Connecting to vineyard": [[13, "connecting-to-vineyard"]], "Storing and Retrieving Python Objects": [[13, "storing-and-retrieving-python-objects"]], "Sharing objects between tasks": [[13, "sharing-objects-between-tasks"]], "Next steps": [[13, "next-steps"]], "Big-data on Vineyard": [[14, "big-data-on-vineyard"]], "Workflow orchestration": [[15, "workflow-orchestration"]], "Airflow on Vineyard": [[16, "airflow-on-vineyard"], [16, "id2"]], "Introducing Airflow": [[16, "introducing-airflow"]], "The Rationale for Airflow on Vineyard": [[16, "the-rationale-for-airflow-on-vineyard"]], "How Vineyard Enhances Airflow": [[16, "how-vineyard-enhances-airflow"]], "Addressing Distributed Deployment Challenges": [[16, "addressing-distributed-deployment-challenges"]], "Running Vineyard + Airflow": [[16, "running-vineyard-airflow"]], "Further Ahead": [[16, "further-ahead"]], "Dask on Vineyard": [[17, "dask-on-vineyard"]], "The Deployment": [[17, "the-deployment"]], "Preprocessing in Dask": [[17, "preprocessing-in-dask"]], "Training in Tensorflow": [[17, "training-in-tensorflow"]], "Transfer Learning": [[17, "transfer-learning"]], "Kedro Vineyard Plugin": [[18, "kedro-vineyard-plugin"]], "Kedro on Vineyard": [[18, "kedro-on-vineyard"]], "Requirements": [[18, "requirements"]], "Configuration": [[18, "configuration"]], "Usage": [[18, "usage"]], "Deploy to Kubernetes": [[18, "deploy-to-kubernetes"]], "Machine Learning with Vineyard": [[19, "machine-learning-with-vineyard"]], "TensorFlow": [[19, "tensorflow"]], "Using Numpy Data": [[19, "using-numpy-data"], [19, "id1"], [19, "id5"]], "Using Dataframe": [[19, "using-dataframe"], [19, "id2"], [19, "id6"]], "Using RecordBatch of Pyarrow": [[19, "using-recordbatch-of-pyarrow"], [19, "id3"], [19, "id7"]], "Using Tables of Pyarrow": [[19, "using-tables-of-pyarrow"], [19, "id4"], [19, "id8"]], "PyTorch": [[19, "pytorch"]], "MxNet": [[19, "mxnet"]], "XGBoost": [[19, "xgboost"]], "From Vineyard::Tensor": [[19, "from-vineyard-tensor"]], "From Vineyard::DataFrame": [[19, "from-vineyard-dataframe"]], "From Vineyard::RecordBatch": [[19, "from-vineyard-recordbatch"]], "From Vineyard::Table": [[19, "from-vineyard-table"]], "Nvidia-DALI": [[19, "nvidia-dali"]], "Ray on Vineyard": [[20, "ray-on-vineyard"]], "Key Concepts": [[21, "key-concepts"]], "Concepts": [[21, "concepts"]], "Data Accessing": [[22, "data-accessing"]], "IPCClient vs. RPCClient": [[22, "ipcclient-vs-rpcclient"]], "Local vs. Remote": [[22, "local-vs-remote"]], "Local Objects": [[22, "local-objects"]], "Accessing metadatas": [[22, "accessing-metadatas"]], "Using blobs": [[22, "using-blobs"]], "Remote Objects": [[22, "remote-objects"]], "Inspecting metadata": [[22, "inspecting-metadata"]], "Using remote blobs": [[22, "using-remote-blobs"]], "Utilizing Distributed Objects": [[22, "utilizing-distributed-objects"]], "I/O Drivers": [[23, "i-o-drivers"], [30, "i-o-drivers"]], "Objects": [[24, "objects"], [28, "objects"], [30, "objects"], [39, "objects"]], "Object = metadata + payloads": [[24, "object-metadata-payloads"]], "An example for the object metadata: a dataframe with two columns where each\n column is a tensor.": [[24, null]], "Separating metadata and payload": [[24, "separating-metadata-and-payload"]], "Data model": [[24, "data-model"]], "Composable": [[24, "composable"]], "Distributed objects": [[24, "distributed-objects"]], "Transient vs. Persistent": [[24, "transient-vs-persistent"]], "Builders and resolvers": [[24, "builders-and-resolvers"]], "Streams in Vineyard": [[25, "streams-in-vineyard"]], "Using streams": [[25, "using-streams"]], "Producer and consumer": [[25, "producer-and-consumer"]], "Streams between processes": [[25, "streams-between-processes"]], "Code Generation for Boilerplate": [[26, "code-generation-for-boilerplate"]], "API Reference": [[27, "api-reference"], [29, "api-reference"]], "C++ API Reference": [[28, "c-api-reference"]], "Metadata": [[28, "metadata"], [30, "metadata"]], "Vineyard Clients": [[28, "vineyard-clients"]], "Vineyard Server": [[28, "vineyard-server"]], "Blob": [[28, "blob"], [30, "blob"]], "Stream": [[28, "stream"]], "Basic Data Types": [[28, "basic-data-types"]], "Distributed Data Types": [[28, "distributed-data-types"]], "Packages": [[29, "packages"]], "k8s.v6d.io/v1alpha1": [[29, "k8s-v6d-io-v1alpha1"]], "Resource Types": [[29, "resource-types"]], "Backup": [[29, "backup"]], "BackupList": [[29, "backuplist"]], "BackupSpec": [[29, "backupspec"]], "CSIDriver": [[29, "csidriver"]], "CSIDriverList": [[29, "csidriverlist"]], "CSIDriverSpec": [[29, "csidriverspec"]], "CSISidecar": [[29, "csisidecar"]], "GlobalObjectList": [[29, "globalobjectlist"]], "GlobalObjectSpec": [[29, "globalobjectspec"]], "LocalObjectList": [[29, "localobjectlist"]], "LocalObjectSpec": [[29, "localobjectspec"]], "MetricConfig": [[29, "metricconfig"]], "Operation": [[29, "operation"]], "OperationList": [[29, "operationlist"]], "OperationSpec": [[29, "operationspec"]], "PluginImageConfig": [[29, "pluginimageconfig"]], "Recover": [[29, "recover"]], "RecoverList": [[29, "recoverlist"]], "RecoverSpec": [[29, "recoverspec"]], "ServiceConfig": [[29, "serviceconfig"]], "Sidecar": [[29, "sidecar"]], "SidecarList": [[29, "sidecarlist"]], "SidecarSpec": [[29, "sidecarspec"]], "SpillConfig": [[29, "spillconfig"]], "VineyardClusters": [[29, "vineyardclusters"]], "VineyardConfig": [[29, "vineyardconfig"]], "Vineyardd": [[29, "vineyardd"]], "VineyarddList": [[29, "vineyarddlist"]], "VineyarddSpec": [[29, "vineyarddspec"]], "VolumeConfig": [[29, "volumeconfig"]], "Python API Reference": [[30, "python-api-reference"]], "Vineyard client": [[30, "vineyard-client"]], "Vineyard cluster": [[30, "vineyard-cluster"]], "Resolvers and builders": [[30, "resolvers-and-builders"]], "Shared memory": [[30, "shared-memory"]], "Deployment": [[30, "deployment"]], "Streams": [[30, "streams"]], "Interacting with the CSI Driver": [[30, "interacting-with-the-csi-driver"]], "Vineyard Cli Tool": [[30, "vineyard-cli-tool"]], "Vineyard LLM KV Cache": [[30, "vineyard-llm-kv-cache"]], "Data processing": [[31, "data-processing"], [46, "data-processing"]], "Accelerate Data Sharing in Kedro": [[32, "accelerate-data-sharing-in-kedro"]], "Prepare the Kubernetes cluster": [[32, "prepare-the-kubernetes-cluster"]], "Deploy Argo Workflows": [[32, "deploy-argo-workflows"]], "Deploy Vineyard": [[32, "deploy-vineyard"]], "Prepare the S3 Service": [[32, "prepare-the-s3-service"]], "Prepare the Docker images": [[32, "prepare-the-docker-images"]], "Deploy the Kedro Pipelines": [[32, "deploy-the-kedro-pipelines"]], "Performance": [[32, "performance"]], "Distributed Learning with Vineyard": [[33, "Distributed-Learning-with-Vineyard"]], "An Example from Keras": [[33, "An-Example-from-Keras"]], "Setup": [[33, "Setup"]], "Preprocessing the data": [[33, "Preprocessing-the-data"]], "Training the model": [[33, "Training-the-model"]], "Conclusion": [[33, "Conclusion"]], "Sharing GPU Memory": [[34, "sharing-gpu-memory"]], "CUDA IPC and Unified Memory": [[34, "cuda-ipc-and-unified-memory"]], "Example": [[34, "example"]], "multiprocessing.shared_memory in Python": [[35, "multiprocessing-shared-memory-in-python"]], "Sharing Python Objects with Vineyard": [[36, "sharing-python-objects-with-vineyard"]], "Extending vineyard": [[37, "extending-vineyard"], [46, "extending-vineyard"]], "Defining Custom Data Types in C++": [[38, "defining-custom-data-types-in-c"]], "Object and ObjectBuilder": [[38, "object-and-objectbuilder"]], "Defining Your Custom Type": [[38, "defining-your-custom-type"]], "Registering C++ Types": [[38, "registering-c-types"]], "Builder": [[38, "builder"]], "Utilizing Custom Data Types with Vineyard": [[38, "utilizing-custom-data-types-with-vineyard"]], "Cross-Language Compatibility": [[38, "cross-language-compatibility"]], "Define Data Types in Python": [[39, "define-data-types-in-python"]], "Creating Builders and Resolvers": [[39, "creating-builders-and-resolvers"]], "Vineyard on Kubernetes": [[40, "vineyard-on-kubernetes"], [46, "vineyard-on-kubernetes"]], "Data sharing with Vineyard on Kubernetes": [[41, "data-sharing-with-vineyard-on-kubernetes"]], "Prerequisites": [[41, "prerequisites"], [42, "prerequisites"]], "Data sharing between different containers": [[41, "data-sharing-between-different-containers"]], "Data sharing between different pods": [[41, "data-sharing-between-different-pods"]], "Efficient data sharing in Kubeflow with Vineyard CSI Driver": [[42, "efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver"]], "Deploy the Vineyard Cluster": [[42, "deploy-the-vineyard-cluster"]], "Deploy the Vineyard CSI Driver": [[42, "deploy-the-vineyard-csi-driver"]], "Running the Kubeflow Pipeline example": [[42, "running-the-kubeflow-pipeline-example"]], "Preparations": [[42, "preparations"]], "Running KFP V1 Example": [[42, "running-kfp-v1-example"]], "Running KFP V2 Example": [[42, "running-kfp-v2-example"]], "KFP V1 Result Analysis": [[42, "kfp-v1-result-analysis"]], "Argo workflow duration": [[42, "argo-workflow-duration"]], "Actual execution time": [[42, "actual-execution-time"], [42, "id1"]], "Writing time": [[42, "writing-time"], [42, "id2"]], "Reading time": [[42, "reading-time"], [42, "id3"]], "KFP V2 Result Analysis": [[42, "kfp-v2-result-analysis"]], "Kubeflow dashboard duration": [[42, "kubeflow-dashboard-duration"]], "Clean up": [[42, "clean-up"]], "Machine learning with Vineyard on Kubernetes": [[43, "machine-learning-with-vineyard-on-kubernetes"]], "Use vineyard operator": [[44, "use-vineyard-operator"]], "Step 0: (optional) Initialize Kubernetes Cluster": [[44, "step-0-optional-initialize-kubernetes-cluster"]], "Step 1: Deploy the Vineyard Operator": [[44, "step-1-deploy-the-vineyard-operator"]], "Step 2: Deploy a Vineyard Cluster": [[44, "step-2-deploy-a-vineyard-cluster"]], "Step 3: Connect to Vineyard": [[44, "step-3-connect-to-vineyard"]], "Step 4: Cleanup": [[44, "step-4-cleanup"]], "Vineyard + Fluid in Action: Train a Linear Regression Model on ACK": [[45, "vineyard-fluid-in-action-train-a-linear-regression-model-on-ack"]], "Step 1: Create a dataset and upload it to OSS": [[45, "step-1-create-a-dataset-and-upload-it-to-oss"]], "Step 2: Install the Fluid control plane and Fluid Python SDK in the ACK cluster.": [[45, "step-2-install-the-fluid-control-plane-and-fluid-python-sdk-in-the-ack-cluster"]], "Step 3: Enable collaborative scheduling of data and tasks (optional)": [[45, "step-3-enable-collaborative-scheduling-of-data-and-tasks-optional"]], "Step 4: Use Fluid Python SDK to build and deploy linear regression data operation pipeline": [[45, "step-4-use-fluid-python-sdk-to-build-and-deploy-linear-regression-data-operation-pipeline"]]}, "indexentries": {"vineyard::array (c++ class)": [[28, "_CPPv4I0EN8vineyard5ArrayE"]], "vineyard::array::construct (c++ function)": [[28, "_CPPv4N8vineyard5Array9ConstructERK10ObjectMeta"]], "vineyard::array::create (c++ function)": [[28, "_CPPv4N8vineyard5Array6CreateEv"]], "vineyard::array::data (c++ function)": [[28, "_CPPv4NK8vineyard5Array4dataEv"]], "vineyard::array::operator[] (c++ function)": [[28, "_CPPv4NK8vineyard5ArrayixE6size_t"]], "vineyard::array::size (c++ function)": [[28, "_CPPv4NK8vineyard5Array4sizeEv"]], "vineyard::arraybuilder (c++ class)": [[28, "_CPPv4I0EN8vineyard12ArrayBuilderE"]], "vineyard::arraybuilder::arraybuilder (c++ function)": [[28, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6Client6size_t"], [28, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientPK1T6size_t"], [28, "_CPPv4N8vineyard12ArrayBuilder12ArrayBuilderER6ClientRKNSt6vectorI1TEE"]], "vineyard::arraybuilder::build (c++ function)": [[28, "_CPPv4N8vineyard12ArrayBuilder5BuildER6Client"]], "vineyard::arraybuilder::data (c++ function)": [[28, "_CPPv4N8vineyard12ArrayBuilder4dataEv"], [28, "_CPPv4NK8vineyard12ArrayBuilder4dataEv"]], "vineyard::arraybuilder::operator[] (c++ function)": [[28, "_CPPv4N8vineyard12ArrayBuilderixE6size_t"]], "vineyard::arraybuilder::size (c++ function)": [[28, "_CPPv4NK8vineyard12ArrayBuilder4sizeEv"]], "vineyard::arraybuilder::~arraybuilder (c++ function)": [[28, "_CPPv4N8vineyard12ArrayBuilderD0Ev"]], "vineyard::blob (c++ class)": [[28, "_CPPv4N8vineyard4BlobE"]], "vineyard::blob::arrowbuffer (c++ function)": [[28, "_CPPv4NK8vineyard4Blob11ArrowBufferEv"]], "vineyard::blob::arrowbufferorempty (c++ function)": [[28, "_CPPv4NK8vineyard4Blob18ArrowBufferOrEmptyEv"]], "vineyard::blob::buffer (c++ function)": [[28, "_CPPv4NK8vineyard4Blob6BufferEv"]], "vineyard::blob::bufferorempty (c++ function)": [[28, "_CPPv4NK8vineyard4Blob13BufferOrEmptyEv"]], "vineyard::blob::construct (c++ function)": [[28, "_CPPv4N8vineyard4Blob9ConstructERK10ObjectMeta"]], "vineyard::blob::create (c++ function)": [[28, "_CPPv4N8vineyard4Blob6CreateEv"]], "vineyard::blob::dump (c++ function)": [[28, "_CPPv4NK8vineyard4Blob4DumpEv"]], "vineyard::blob::fromallocator (c++ function)": [[28, "_CPPv4N8vineyard4Blob13FromAllocatorER6ClientK8ObjectIDK9uintptr_tK6size_t"]], "vineyard::blob::frompointer (c++ function)": [[28, "_CPPv4N8vineyard4Blob11FromPointerER6ClientK9uintptr_tK6size_t"]], "vineyard::blob::makeempty (c++ function)": [[28, "_CPPv4N8vineyard4Blob9MakeEmptyER6Client"]], "vineyard::blob::allocated_size (c++ function)": [[28, "_CPPv4NK8vineyard4Blob14allocated_sizeEv"]], "vineyard::blob::data (c++ function)": [[28, "_CPPv4NK8vineyard4Blob4dataEv"]], "vineyard::blob::size (c++ function)": [[28, "_CPPv4NK8vineyard4Blob4sizeEv"]], "vineyard::blobwriter (c++ class)": [[28, "_CPPv4N8vineyard10BlobWriterE"]], "vineyard::blobwriter::abort (c++ function)": [[28, "_CPPv4N8vineyard10BlobWriter5AbortER6Client"]], "vineyard::blobwriter::addkeyvalue (c++ function)": [[28, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard10BlobWriter11AddKeyValueERKNSt6stringERRNSt6stringE"]], "vineyard::blobwriter::buffer (c++ function)": [[28, "_CPPv4NK8vineyard10BlobWriter6BufferEv"]], "vineyard::blobwriter::build (c++ function)": [[28, "_CPPv4N8vineyard10BlobWriter5BuildER6Client"]], "vineyard::blobwriter::dump (c++ function)": [[28, "_CPPv4NK8vineyard10BlobWriter4DumpEv"]], "vineyard::blobwriter::shrink (c++ function)": [[28, "_CPPv4N8vineyard10BlobWriter6ShrinkER6ClientK6size_t"]], "vineyard::blobwriter::data (c++ function)": [[28, "_CPPv4N8vineyard10BlobWriter4dataEv"], [28, "_CPPv4NK8vineyard10BlobWriter4dataEv"]], "vineyard::blobwriter::id (c++ function)": [[28, "_CPPv4NK8vineyard10BlobWriter2idEv"]], "vineyard::blobwriter::size (c++ function)": [[28, "_CPPv4NK8vineyard10BlobWriter4sizeEv"]], "vineyard::bytestream (c++ class)": [[28, "_CPPv4N8vineyard10ByteStreamE"]], "vineyard::bytestream::create (c++ function)": [[28, "_CPPv4N8vineyard10ByteStream6CreateEv"]], "vineyard::bytestream::flushbuffer (c++ function)": [[28, "_CPPv4N8vineyard10ByteStream11FlushBufferEv"]], "vineyard::bytestream::readline (c++ function)": [[28, "_CPPv4N8vineyard10ByteStream8ReadLineERNSt6stringE"]], "vineyard::bytestream::setbuffersizelimit (c++ function)": [[28, "_CPPv4N8vineyard10ByteStream18SetBufferSizeLimitE6size_t"]], "vineyard::bytestream::writebytes (c++ function)": [[28, "_CPPv4N8vineyard10ByteStream10WriteBytesEPKc6size_t"]], "vineyard::bytestream::writeline (c++ function)": [[28, "_CPPv4N8vineyard10ByteStream9WriteLineERKNSt6stringE"]], "vineyard::client (c++ class)": [[28, "_CPPv4N8vineyard6ClientE"]], "vineyard::client::allocatedsize (c++ function)": [[28, "_CPPv4N8vineyard6Client13AllocatedSizeEK8ObjectIDR6size_t"]], "vineyard::client::client (c++ function)": [[28, "_CPPv4N8vineyard6Client6ClientEv"]], "vineyard::client::connect (c++ function)": [[28, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringE"], [28, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard6Client7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard6Client7ConnectEv"]], "vineyard::client::createarena (c++ function)": [[28, "_CPPv4N8vineyard6Client11CreateArenaEK6size_tRiR6size_tR9uintptr_tR9uintptr_t"]], "vineyard::client::createblob (c++ function)": [[28, "_CPPv4N8vineyard6Client10CreateBlobE6size_tRNSt10unique_ptrI10BlobWriterEE"]], "vineyard::client::createblobs (c++ function)": [[28, "_CPPv4N8vineyard6Client11CreateBlobsERKNSt6vectorI6size_tEERNSt6vectorINSt10unique_ptrI10BlobWriterEEEE"]], "vineyard::client::createbuffer (c++ function)": [[28, "_CPPv4N8vineyard6Client12CreateBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE"]], "vineyard::client::createbuffers (c++ function)": [[28, "_CPPv4N8vineyard6Client13CreateBuffersERKNSt6vectorI6size_tEERNSt6vectorI8ObjectIDEERNSt6vectorI7PayloadEERNSt6vectorINSt10shared_ptrI13MutableBufferEEEE"]], "vineyard::client::creatediskblob (c++ function)": [[28, "_CPPv4N8vineyard6Client14CreateDiskBlobE6size_tRKNSt6stringERNSt10unique_ptrI10BlobWriterEE"]], "vineyard::client::creategpubuffer (c++ function)": [[28, "_CPPv4N8vineyard6Client15CreateGPUBufferEK6size_tR8ObjectIDR7PayloadRNSt10shared_ptrI13MutableBufferEE"]], "vineyard::client::default (c++ function)": [[28, "_CPPv4N8vineyard6Client7DefaultEv"]], "vineyard::client::deldata (c++ function)": [[28, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKb"], [28, "_CPPv4N8vineyard6Client7DelDataEK8ObjectIDKbKbKb"], [28, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKb"], [28, "_CPPv4N8vineyard6Client7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb"]], "vineyard::client::disconnect (c++ function)": [[28, "_CPPv4N8vineyard6Client10DisconnectEv"]], "vineyard::client::dropbuffer (c++ function)": [[28, "_CPPv4N8vineyard6Client10DropBufferEK8ObjectIDKi"]], "vineyard::client::fetchandgetmetadata (c++ function)": [[28, "_CPPv4N8vineyard6Client19FetchAndGetMetaDataEK8ObjectIDR10ObjectMetaKb"]], "vineyard::client::fetchandgetobject (c++ function)": [[28, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb"], [28, "_CPPv4I0EN8vineyard6Client17FetchAndGetObjectENSt10shared_ptrI1TEEK8ObjectIDKb"], [28, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDKb"], [28, "_CPPv4N8vineyard6Client17FetchAndGetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb"]], "vineyard::client::fork (c++ function)": [[28, "_CPPv4N8vineyard6Client4ForkER6Client"]], "vineyard::client::getblob (c++ function)": [[28, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDRNSt10shared_ptrI4BlobEE"], [28, "_CPPv4N8vineyard6Client7GetBlobEK8ObjectIDbRNSt10shared_ptrI4BlobEE"]], "vineyard::client::getblobs (c++ function)": [[28, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI4BlobEEEE"], [28, "_CPPv4N8vineyard6Client8GetBlobsEKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI4BlobEEEE"]], "vineyard::client::getbuffer (c++ function)": [[28, "_CPPv4N8vineyard6Client9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE"]], "vineyard::client::getbuffersizes (c++ function)": [[28, "_CPPv4N8vineyard6Client14GetBufferSizesERKNSt3setI8ObjectIDEERNSt3mapI8ObjectID6size_tEE"]], "vineyard::client::getbuffers (c++ function)": [[28, "_CPPv4N8vineyard6Client10GetBuffersERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE"]], "vineyard::client::getdependency (c++ function)": [[28, "_CPPv4N8vineyard6Client13GetDependencyERK8ObjectIDRNSt3setI8ObjectIDEE"]], "vineyard::client::getgpubuffer (c++ function)": [[28, "_CPPv4N8vineyard6Client12GetGPUBufferEK8ObjectIDKbRNSt10shared_ptrI6BufferEE"]], "vineyard::client::getgpubuffers (c++ function)": [[28, "_CPPv4N8vineyard6Client13GetGPUBuffersERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI6BufferEEEE"]], "vineyard::client::getmetadata (c++ function)": [[28, "_CPPv4N8vineyard6Client11GetMetaDataEK8ObjectIDR10ObjectMetaKb"], [28, "_CPPv4N8vineyard6Client11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb"]], "vineyard::client::getnextstreamchunk (c++ function)": [[28, "_CPPv4N8vineyard6Client18GetNextStreamChunkEK8ObjectIDK6size_tRNSt10unique_ptrI13MutableBufferEE"]], "vineyard::client::getobject (c++ function)": [[28, "_CPPv4I0EN8vineyard6Client9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb"], [28, "_CPPv4I0EN8vineyard6Client9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb"], [28, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDKb"], [28, "_CPPv4N8vineyard6Client9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb"]], "vineyard::client::getobjects (c++ function)": [[28, "_CPPv4N8vineyard6Client10GetObjectsERKNSt6vectorI8ObjectIDEEKb"]], "vineyard::client::isipc (c++ function)": [[28, "_CPPv4NK8vineyard6Client5IsIPCEv"]], "vineyard::client::isinuse (c++ function)": [[28, "_CPPv4N8vineyard6Client7IsInUseERK8ObjectIDRb"]], "vineyard::client::issharedmemory (c++ function)": [[28, "_CPPv4NK8vineyard6Client14IsSharedMemoryEK9uintptr_t"], [28, "_CPPv4NK8vineyard6Client14IsSharedMemoryEK9uintptr_tR8ObjectID"], [28, "_CPPv4NK8vineyard6Client14IsSharedMemoryEPKv"], [28, "_CPPv4NK8vineyard6Client14IsSharedMemoryEPKvR8ObjectID"]], "vineyard::client::isspilled (c++ function)": [[28, "_CPPv4N8vineyard6Client9IsSpilledERK8ObjectIDRb"]], "vineyard::client::listobjectmeta (c++ function)": [[28, "_CPPv4N8vineyard6Client14ListObjectMetaERKNSt6stringEKbK6size_tb"]], "vineyard::client::listobjects (c++ function)": [[28, "_CPPv4N8vineyard6Client11ListObjectsERKNSt6stringEKbK6size_t"]], "vineyard::client::ondelete (c++ function)": [[28, "_CPPv4N8vineyard6Client8OnDeleteERK8ObjectID"]], "vineyard::client::onrelease (c++ function)": [[28, "_CPPv4N8vineyard6Client9OnReleaseERK8ObjectID"]], "vineyard::client::open (c++ function)": [[28, "_CPPv4N8vineyard6Client4OpenERKNSt6stringE"], [28, "_CPPv4N8vineyard6Client4OpenERKNSt6stringERKNSt6stringERKNSt6stringE"]], "vineyard::client::postseal (c++ function)": [[28, "_CPPv4N8vineyard6Client8PostSealERK10ObjectMeta"]], "vineyard::client::pullnextstreamchunk (c++ function)": [[28, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR10ObjectMeta"], [28, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDR8ObjectID"], [28, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE"], [28, "_CPPv4N8vineyard6Client19PullNextStreamChunkEK8ObjectIDRNSt10unique_ptrI6BufferEE"]], "vineyard::client::release (c++ function)": [[28, "_CPPv4N8vineyard6Client7ReleaseERK8ObjectID"], [28, "_CPPv4N8vineyard6Client7ReleaseERKNSt6vectorI8ObjectIDEE"]], "vineyard::client::releasearena (c++ function)": [[28, "_CPPv4N8vineyard6Client12ReleaseArenaEKiRKNSt6vectorI6size_tEERKNSt6vectorI6size_tEE"]], "vineyard::client::seal (c++ function)": [[28, "_CPPv4N8vineyard6Client4SealERK8ObjectID"]], "vineyard::client::shallowcopy (c++ function)": [[28, "_CPPv4N8vineyard6Client11ShallowCopyEK8ObjectIDR8ObjectIDR6Client"], [28, "_CPPv4N8vineyard6Client11ShallowCopyEK8PlasmaIDR8ObjectIDR12PlasmaClient"]], "vineyard::client::shrinkbuffer (c++ function)": [[28, "_CPPv4N8vineyard6Client12ShrinkBufferEK8ObjectIDK6size_t"]], "vineyard::client::tryacquirelock (c++ function)": [[28, "_CPPv4N8vineyard6Client14TryAcquireLockENSt6stringERbRNSt6stringE"]], "vineyard::client::tryreleaselock (c++ function)": [[28, "_CPPv4N8vineyard6Client14TryReleaseLockENSt6stringERb"]], "vineyard::client::~client (c++ function)": [[28, "_CPPv4N8vineyard6ClientD0Ev"]], "vineyard::clientbase (c++ class)": [[28, "_CPPv4N8vineyard10ClientBaseE"]], "vineyard::clientbase::clear (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase5ClearEv"]], "vineyard::clientbase::clientbase (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase10ClientBaseERK10ClientBase"], [28, "_CPPv4N8vineyard10ClientBase10ClientBaseERR10ClientBase"], [28, "_CPPv4N8vineyard10ClientBase10ClientBaseEv"]], "vineyard::clientbase::closesession (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase12CloseSessionEv"]], "vineyard::clientbase::clusterinfo (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase11ClusterInfoERNSt3mapI10InstanceID4jsonEE"]], "vineyard::clientbase::connected (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase9ConnectedEv"]], "vineyard::clientbase::createdata (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase10CreateDataERK4jsonR8ObjectIDR9SignatureR10InstanceID"], [28, "_CPPv4N8vineyard10ClientBase10CreateDataERKNSt6vectorI4jsonEERNSt6vectorI8ObjectIDEERNSt6vectorI9SignatureEERNSt6vectorI10InstanceIDEE"]], "vineyard::clientbase::createmetadata (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaR8ObjectID"], [28, "_CPPv4N8vineyard10ClientBase14CreateMetaDataER10ObjectMetaRK10InstanceIDR8ObjectID"], [28, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERK10InstanceIDRNSt6vectorI8ObjectIDEE"], [28, "_CPPv4N8vineyard10ClientBase14CreateMetaDataERNSt6vectorI10ObjectMetaEERNSt6vectorI8ObjectIDEE"]], "vineyard::clientbase::createstream (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase12CreateStreamERK8ObjectID"]], "vineyard::clientbase::debug (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase5DebugERK4jsonR4json"]], "vineyard::clientbase::deldata (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKb"], [28, "_CPPv4N8vineyard10ClientBase7DelDataEK8ObjectIDKbKbKb"], [28, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKb"], [28, "_CPPv4N8vineyard10ClientBase7DelDataERKNSt6vectorI8ObjectIDEEKbKbKb"]], "vineyard::clientbase::disconnect (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase10DisconnectEv"]], "vineyard::clientbase::dropname (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase8DropNameERKNSt6stringE"]], "vineyard::clientbase::dropstream (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase10DropStreamEK8ObjectID"]], "vineyard::clientbase::evict (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase5EvictERKNSt6vectorI8ObjectIDEE"]], "vineyard::clientbase::exists (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase6ExistsEK8ObjectIDRb"]], "vineyard::clientbase::getdata (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase7GetDataEK8ObjectIDR4jsonKbKb"], [28, "_CPPv4N8vineyard10ClientBase7GetDataERKNSt6vectorI8ObjectIDEERNSt6vectorI4jsonEEKbKb"]], "vineyard::clientbase::getmetadata (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase11GetMetaDataEK8ObjectIDR10ObjectMetaKb"]], "vineyard::clientbase::getname (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase7GetNameERKNSt6stringER8ObjectIDKb"]], "vineyard::clientbase::ipcsocket (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase9IPCSocketEv"]], "vineyard::clientbase::ifpersist (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase9IfPersistEK8ObjectIDRb"]], "vineyard::clientbase::instancestatus (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase14InstanceStatusERNSt10shared_ptrI14InstanceStatusEE"]], "vineyard::clientbase::instances (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase9InstancesERNSt6vectorI10InstanceIDEE"]], "vineyard::clientbase::isipc (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase5IsIPCEv"]], "vineyard::clientbase::isrpc (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase5IsRPCEv"]], "vineyard::clientbase::label (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt3mapINSt6stringENSt6stringEEE"], [28, "_CPPv4N8vineyard10ClientBase5LabelEK8ObjectIDRKNSt6stringERKNSt6stringE"]], "vineyard::clientbase::listdata (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase8ListDataERKNSt6stringEKbK6size_tRNSt13unordered_mapI8ObjectID4jsonEE"]], "vineyard::clientbase::listnames (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase9ListNamesERKNSt6stringEKbK6size_tRNSt3mapINSt6stringE8ObjectIDEE"]], "vineyard::clientbase::load (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase4LoadERKNSt6vectorI8ObjectIDEEKb"]], "vineyard::clientbase::memorytrim (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase10MemoryTrimERb"]], "vineyard::clientbase::migrateobject (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase13MigrateObjectEK8ObjectIDR8ObjectID"]], "vineyard::clientbase::open (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase4OpenERKNSt6stringE"]], "vineyard::clientbase::openstream (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase10OpenStreamERK8ObjectID14StreamOpenMode"]], "vineyard::clientbase::persist (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase7PersistEK8ObjectID"]], "vineyard::clientbase::pullnextstreamchunk (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR10ObjectMeta"], [28, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDR8ObjectID"], [28, "_CPPv4N8vineyard10ClientBase19PullNextStreamChunkEK8ObjectIDRNSt10shared_ptrI6ObjectEE"]], "vineyard::clientbase::pushnextstreamchunk (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase19PushNextStreamChunkEK8ObjectIDK8ObjectID"]], "vineyard::clientbase::putname (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase7PutNameEK8ObjectIDRKNSt6stringE"]], "vineyard::clientbase::rpcendpoint (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase11RPCEndpointEv"]], "vineyard::clientbase::release (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase7ReleaseERK8ObjectID"]], "vineyard::clientbase::shallowcopy (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDR8ObjectID"], [28, "_CPPv4N8vineyard10ClientBase11ShallowCopyEK8ObjectIDRK4jsonR8ObjectID"]], "vineyard::clientbase::stopstream (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase10StopStreamEK8ObjectIDb"]], "vineyard::clientbase::syncmetadata (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase12SyncMetaDataEv"]], "vineyard::clientbase::tryacquirelock (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase14TryAcquireLockENSt6stringERbRNSt6stringE"]], "vineyard::clientbase::tryreleaselock (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase14TryReleaseLockENSt6stringERb"]], "vineyard::clientbase::unpin (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase5UnpinERKNSt6vectorI8ObjectIDEE"]], "vineyard::clientbase::version (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase7VersionEv"]], "vineyard::clientbase::client_mutex_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase13client_mutex_E"]], "vineyard::clientbase::compression_enabled (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase19compression_enabledEv"]], "vineyard::clientbase::compression_enabled_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase20compression_enabled_E"]], "vineyard::clientbase::connected_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase10connected_E"]], "vineyard::clientbase::doread (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase6doReadER4json"], [28, "_CPPv4N8vineyard10ClientBase6doReadERNSt6stringE"]], "vineyard::clientbase::dowrite (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase7doWriteERKNSt6stringE"]], "vineyard::clientbase::instance_id (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase11instance_idEv"]], "vineyard::clientbase::instance_id_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase12instance_id_E"]], "vineyard::clientbase::ipc_socket_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase11ipc_socket_E"]], "vineyard::clientbase::operator= (c++ function)": [[28, "_CPPv4N8vineyard10ClientBaseaSERK10ClientBase"], [28, "_CPPv4N8vineyard10ClientBaseaSERR10ClientBase"]], "vineyard::clientbase::remote_instance_id (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase18remote_instance_idEv"]], "vineyard::clientbase::rpc_endpoint_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase13rpc_endpoint_E"]], "vineyard::clientbase::server_version_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase15server_version_E"]], "vineyard::clientbase::session_id (c++ function)": [[28, "_CPPv4NK8vineyard10ClientBase10session_idEv"]], "vineyard::clientbase::session_id_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase11session_id_E"]], "vineyard::clientbase::set_compression_enabled (c++ function)": [[28, "_CPPv4N8vineyard10ClientBase23set_compression_enabledEb"]], "vineyard::clientbase::support_rpc_compression_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase24support_rpc_compression_E"]], "vineyard::clientbase::vineyard_conn_ (c++ member)": [[28, "_CPPv4N8vineyard10ClientBase14vineyard_conn_E"]], "vineyard::clientbase::~clientbase (c++ function)": [[28, "_CPPv4N8vineyard10ClientBaseD0Ev"]], "vineyard::dataframe (c++ class)": [[28, "_CPPv4N8vineyard9DataFrameE"]], "vineyard::dataframe::asbatch (c++ function)": [[28, "_CPPv4NK8vineyard9DataFrame7AsBatchEb"]], "vineyard::dataframe::column (c++ function)": [[28, "_CPPv4NK8vineyard9DataFrame6ColumnERK4json"]], "vineyard::dataframe::columns (c++ function)": [[28, "_CPPv4NK8vineyard9DataFrame7ColumnsEv"]], "vineyard::dataframe::construct (c++ function)": [[28, "_CPPv4N8vineyard9DataFrame9ConstructERK10ObjectMeta"]], "vineyard::dataframe::create (c++ function)": [[28, "_CPPv4N8vineyard9DataFrame6CreateEv"]], "vineyard::dataframe::index (c++ function)": [[28, "_CPPv4NK8vineyard9DataFrame5IndexEv"]], "vineyard::dataframe::partition_index (c++ function)": [[28, "_CPPv4NK8vineyard9DataFrame15partition_indexEv"]], "vineyard::dataframe::shape (c++ function)": [[28, "_CPPv4NK8vineyard9DataFrame5shapeEv"]], "vineyard::dataframebuilder (c++ class)": [[28, "_CPPv4N8vineyard16DataFrameBuilderE"]], "vineyard::dataframebuilder::addcolumn (c++ function)": [[28, "_CPPv4N8vineyard16DataFrameBuilder9AddColumnERK4jsonNSt10shared_ptrI14ITensorBuilderEE"]], "vineyard::dataframebuilder::build (c++ function)": [[28, "_CPPv4N8vineyard16DataFrameBuilder5BuildER6Client"]], "vineyard::dataframebuilder::column (c++ function)": [[28, "_CPPv4NK8vineyard16DataFrameBuilder6ColumnERK4json"]], "vineyard::dataframebuilder::dataframebuilder (c++ function)": [[28, "_CPPv4N8vineyard16DataFrameBuilder16DataFrameBuilderER6Client"]], "vineyard::dataframebuilder::dropcolumn (c++ function)": [[28, "_CPPv4N8vineyard16DataFrameBuilder10DropColumnERK4json"]], "vineyard::dataframebuilder::partition_index (c++ function)": [[28, "_CPPv4NK8vineyard16DataFrameBuilder15partition_indexEv"]], "vineyard::dataframebuilder::set_index (c++ function)": [[28, "_CPPv4N8vineyard16DataFrameBuilder9set_indexENSt10shared_ptrI14ITensorBuilderEE"]], "vineyard::dataframebuilder::set_partition_index (c++ function)": [[28, "_CPPv4N8vineyard16DataFrameBuilder19set_partition_indexE6size_t6size_t"]], "vineyard::dataframebuilder::set_row_batch_index (c++ function)": [[28, "_CPPv4N8vineyard16DataFrameBuilder19set_row_batch_indexE6size_t"]], "vineyard::globaldataframe (c++ class)": [[28, "_CPPv4N8vineyard15GlobalDataFrameE"]], "vineyard::globaldataframe::create (c++ function)": [[28, "_CPPv4N8vineyard15GlobalDataFrame6CreateEv"]], "vineyard::globaldataframe::localpartitions (c++ function)": [[28, "_CPPv4NK8vineyard15GlobalDataFrame15LocalPartitionsER6Client"]], "vineyard::globaldataframe::postconstruct (c++ function)": [[28, "_CPPv4N8vineyard15GlobalDataFrame13PostConstructERK10ObjectMeta"]], "vineyard::globaldataframe::partition_shape (c++ function)": [[28, "_CPPv4NK8vineyard15GlobalDataFrame15partition_shapeEv"]], "vineyard::globaldataframebuilder (c++ class)": [[28, "_CPPv4N8vineyard22GlobalDataFrameBuilderE"]], "vineyard::globaldataframebuilder::addpartition (c++ function)": [[28, "_CPPv4N8vineyard22GlobalDataFrameBuilder12AddPartitionEK8ObjectID"]], "vineyard::globaldataframebuilder::addpartitions (c++ function)": [[28, "_CPPv4N8vineyard22GlobalDataFrameBuilder13AddPartitionsERKNSt6vectorI8ObjectIDEE"]], "vineyard::globaldataframebuilder::globaldataframebuilder (c++ function)": [[28, "_CPPv4N8vineyard22GlobalDataFrameBuilder22GlobalDataFrameBuilderER6Client"]], "vineyard::globaldataframebuilder::partition_shape (c++ function)": [[28, "_CPPv4NK8vineyard22GlobalDataFrameBuilder15partition_shapeEv"]], "vineyard::globaldataframebuilder::set_partition_shape (c++ function)": [[28, "_CPPv4N8vineyard22GlobalDataFrameBuilder19set_partition_shapeEK6size_tK6size_t"]], "vineyard::globaltensor (c++ class)": [[28, "_CPPv4N8vineyard12GlobalTensorE"]], "vineyard::globaltensor::create (c++ function)": [[28, "_CPPv4N8vineyard12GlobalTensor6CreateEv"]], "vineyard::globaltensor::localpartitions (c++ function)": [[28, "_CPPv4NK8vineyard12GlobalTensor15LocalPartitionsER6Client"]], "vineyard::globaltensor::postconstruct (c++ function)": [[28, "_CPPv4N8vineyard12GlobalTensor13PostConstructERK10ObjectMeta"]], "vineyard::globaltensor::partition_shape (c++ function)": [[28, "_CPPv4NK8vineyard12GlobalTensor15partition_shapeEv"]], "vineyard::globaltensor::shape (c++ function)": [[28, "_CPPv4NK8vineyard12GlobalTensor5shapeEv"]], "vineyard::globaltensorbuilder (c++ class)": [[28, "_CPPv4N8vineyard19GlobalTensorBuilderE"]], "vineyard::globaltensorbuilder::addpartition (c++ function)": [[28, "_CPPv4N8vineyard19GlobalTensorBuilder12AddPartitionEK8ObjectID"]], "vineyard::globaltensorbuilder::addpartitions (c++ function)": [[28, "_CPPv4N8vineyard19GlobalTensorBuilder13AddPartitionsERKNSt6vectorI8ObjectIDEE"]], "vineyard::globaltensorbuilder::globaltensorbuilder (c++ function)": [[28, "_CPPv4N8vineyard19GlobalTensorBuilder19GlobalTensorBuilderER6Client"]], "vineyard::globaltensorbuilder::partition_shape (c++ function)": [[28, "_CPPv4NK8vineyard19GlobalTensorBuilder15partition_shapeEv"]], "vineyard::globaltensorbuilder::set_partition_shape (c++ function)": [[28, "_CPPv4N8vineyard19GlobalTensorBuilder19set_partition_shapeERKNSt6vectorI7int64_tEE"]], "vineyard::globaltensorbuilder::set_shape (c++ function)": [[28, "_CPPv4N8vineyard19GlobalTensorBuilder9set_shapeERKNSt6vectorI7int64_tEE"]], "vineyard::globaltensorbuilder::shape (c++ function)": [[28, "_CPPv4NK8vineyard19GlobalTensorBuilder5shapeEv"]], "vineyard::hashmap (c++ class)": [[28, "_CPPv4I0000EN8vineyard7HashmapE"]], "vineyard::hashmap::construct (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap9ConstructERK10ObjectMeta"]], "vineyard::hashmap::create (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap6CreateEv"]], "vineyard::hashmap::entry (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap5EntryE"]], "vineyard::hashmap::entrypointer (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap12EntryPointerE"]], "vineyard::hashmap::equal (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap5EqualE"]], "vineyard::hashmap::hasher (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap6HasherE"], [28, "_CPPv4N8vineyard7Hashmap6hasherE"]], "vineyard::hashmap::keyequal (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap8KeyEqualE"]], "vineyard::hashmap::keyhash (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap7KeyHashE"]], "vineyard::hashmap::postconstruct (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap13PostConstructERK10ObjectMeta"]], "vineyard::hashmap::t (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap1TE"]], "vineyard::hashmap::at (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap2atERK1K"]], "vineyard::hashmap::begin (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap5beginEv"]], "vineyard::hashmap::bucket_count (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap12bucket_countEv"]], "vineyard::hashmap::const_pointer (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap13const_pointerE"]], "vineyard::hashmap::const_reference (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap15const_referenceE"]], "vineyard::hashmap::count (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap5countERK1K"]], "vineyard::hashmap::difference_type (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap15difference_typeE"]], "vineyard::hashmap::empty (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap5emptyEv"]], "vineyard::hashmap::end (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap3endEv"]], "vineyard::hashmap::find (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap4findERK1K"], [28, "_CPPv4NK8vineyard7Hashmap4findERK1K"]], "vineyard::hashmap::flat_hash_table_type (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap20flat_hash_table_typeE"]], "vineyard::hashmap::iterator (c++ struct)": [[28, "_CPPv4N8vineyard7Hashmap8iteratorE"]], "vineyard::hashmap::iterator::current (c++ member)": [[28, "_CPPv4N8vineyard7Hashmap8iterator7currentE"]], "vineyard::hashmap::iterator::iterator (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap8iterator8iteratorE12EntryPointer"], [28, "_CPPv4N8vineyard7Hashmap8iterator8iteratorEv"]], "vineyard::hashmap::iterator::operator!= (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap8iteratorneERK8iteratorRK8iterator"]], "vineyard::hashmap::iterator::operator* (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap8iteratormlEv"]], "vineyard::hashmap::iterator::operator++ (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap8iteratorppEi"], [28, "_CPPv4N8vineyard7Hashmap8iteratorppEv"]], "vineyard::hashmap::iterator::operator-> (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap8iteratorptEv"]], "vineyard::hashmap::iterator::operator== (c++ function)": [[28, "_CPPv4N8vineyard7Hashmap8iteratoreqERK8iteratorRK8iterator"]], "vineyard::hashmap::key_equal (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap9key_equalE"]], "vineyard::hashmap::load_factor (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap11load_factorEv"]], "vineyard::hashmap::pointer (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap7pointerE"]], "vineyard::hashmap::reference (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap9referenceE"]], "vineyard::hashmap::size (c++ function)": [[28, "_CPPv4NK8vineyard7Hashmap4sizeEv"]], "vineyard::hashmap::size_type (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap9size_typeE"]], "vineyard::hashmap::value_type (c++ type)": [[28, "_CPPv4N8vineyard7Hashmap10value_typeE"]], "vineyard::hashmapbuilder (c++ class)": [[28, "_CPPv4I0000EN8vineyard14HashmapBuilderE"]], "vineyard::hashmapbuilder::associatedatabuffer (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder19AssociateDataBufferENSt10shared_ptrI4BlobEE"]], "vineyard::hashmapbuilder::build (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder5BuildER6Client"]], "vineyard::hashmapbuilder::hashmapbuilder (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder14HashmapBuilderER6Client"], [28, "_CPPv4N8vineyard14HashmapBuilder14HashmapBuilderER6ClientRRN3ska13flat_hash_mapI1K1V1H1EEE"]], "vineyard::hashmapbuilder::at (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder2atERK1K"], [28, "_CPPv4NK8vineyard14HashmapBuilder2atERK1K"]], "vineyard::hashmapbuilder::begin (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder5beginEv"], [28, "_CPPv4NK8vineyard14HashmapBuilder5beginEv"]], "vineyard::hashmapbuilder::bucket_count (c++ function)": [[28, "_CPPv4NK8vineyard14HashmapBuilder12bucket_countEv"]], "vineyard::hashmapbuilder::cbegin (c++ function)": [[28, "_CPPv4NK8vineyard14HashmapBuilder6cbeginEv"]], "vineyard::hashmapbuilder::cend (c++ function)": [[28, "_CPPv4NK8vineyard14HashmapBuilder4cendEv"]], "vineyard::hashmapbuilder::emplace (c++ function)": [[28, "_CPPv4IDpEN8vineyard14HashmapBuilder7emplaceEbDpRR4Args"]], "vineyard::hashmapbuilder::empty (c++ function)": [[28, "_CPPv4NK8vineyard14HashmapBuilder5emptyEv"]], "vineyard::hashmapbuilder::end (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder3endEv"], [28, "_CPPv4NK8vineyard14HashmapBuilder3endEv"]], "vineyard::hashmapbuilder::find (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder4findERK1K"]], "vineyard::hashmapbuilder::load_factor (c++ function)": [[28, "_CPPv4NK8vineyard14HashmapBuilder11load_factorEv"]], "vineyard::hashmapbuilder::operator[] (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilderixERK1K"], [28, "_CPPv4N8vineyard14HashmapBuilderixERR1K"]], "vineyard::hashmapbuilder::reserve (c++ function)": [[28, "_CPPv4N8vineyard14HashmapBuilder7reserveE6size_t"]], "vineyard::hashmapbuilder::size (c++ function)": [[28, "_CPPv4NK8vineyard14HashmapBuilder4sizeEv"]], "vineyard::instancestatus (c++ struct)": [[28, "_CPPv4N8vineyard14InstanceStatusE"]], "vineyard::instancestatus::instancestatus (c++ function)": [[28, "_CPPv4N8vineyard14InstanceStatus14InstanceStatusERK4json"]], "vineyard::instancestatus::deferred_requests (c++ member)": [[28, "_CPPv4N8vineyard14InstanceStatus17deferred_requestsE"]], "vineyard::instancestatus::deployment (c++ member)": [[28, "_CPPv4N8vineyard14InstanceStatus10deploymentE"]], "vineyard::instancestatus::instance_id (c++ member)": [[28, "_CPPv4N8vineyard14InstanceStatus11instance_idE"]], "vineyard::instancestatus::ipc_connections (c++ member)": [[28, "_CPPv4N8vineyard14InstanceStatus15ipc_connectionsE"]], "vineyard::instancestatus::memory_limit (c++ member)": [[28, "_CPPv4N8vineyard14InstanceStatus12memory_limitE"]], "vineyard::instancestatus::memory_usage (c++ member)": [[28, "_CPPv4N8vineyard14InstanceStatus12memory_usageE"]], "vineyard::instancestatus::rpc_connections (c++ member)": [[28, "_CPPv4N8vineyard14InstanceStatus15rpc_connectionsE"]], "vineyard::object (c++ class)": [[28, "_CPPv4N8vineyard6ObjectE"]], "vineyard::object::build (c++ function)": [[28, "_CPPv4N8vineyard6Object5BuildER6Client"]], "vineyard::object::construct (c++ function)": [[28, "_CPPv4N8vineyard6Object9ConstructERK10ObjectMeta"]], "vineyard::object::isglobal (c++ function)": [[28, "_CPPv4NK8vineyard6Object8IsGlobalEv"]], "vineyard::object::islocal (c++ function)": [[28, "_CPPv4NK8vineyard6Object7IsLocalEv"]], "vineyard::object::ispersist (c++ function)": [[28, "_CPPv4NK8vineyard6Object9IsPersistEv"]], "vineyard::object::object (c++ function)": [[28, "_CPPv4N8vineyard6Object6ObjectEv"]], "vineyard::object::persist (c++ function)": [[28, "_CPPv4NK8vineyard6Object7PersistER10ClientBase"]], "vineyard::object::postconstruct (c++ function)": [[28, "_CPPv4N8vineyard6Object13PostConstructERK10ObjectMeta"]], "vineyard::object::_seal (c++ function)": [[28, "_CPPv4N8vineyard6Object5_SealER6Client"]], "vineyard::object::id (c++ function)": [[28, "_CPPv4NK8vineyard6Object2idEv"]], "vineyard::object::id_ (c++ member)": [[28, "_CPPv4N8vineyard6Object3id_E"]], "vineyard::object::meta (c++ function)": [[28, "_CPPv4NK8vineyard6Object4metaEv"]], "vineyard::object::meta_ (c++ member)": [[28, "_CPPv4N8vineyard6Object5meta_E"]], "vineyard::object::nbytes (c++ function)": [[28, "_CPPv4NK8vineyard6Object6nbytesEv"]], "vineyard::object::~object (c++ function)": [[28, "_CPPv4N8vineyard6ObjectD0Ev"]], "vineyard::objectbase (c++ class)": [[28, "_CPPv4N8vineyard10ObjectBaseE"]], "vineyard::objectbase::build (c++ function)": [[28, "_CPPv4N8vineyard10ObjectBase5BuildER6Client"]], "vineyard::objectbase::_seal (c++ function)": [[28, "_CPPv4N8vineyard10ObjectBase5_SealER6Client"]], "vineyard::objectbuilder (c++ class)": [[28, "_CPPv4N8vineyard13ObjectBuilderE"]], "vineyard::objectbuilder::build (c++ function)": [[28, "_CPPv4N8vineyard13ObjectBuilder5BuildER6Client"]], "vineyard::objectbuilder::seal (c++ function)": [[28, "_CPPv4N8vineyard13ObjectBuilder4SealER6Client"], [28, "_CPPv4N8vineyard13ObjectBuilder4SealER6ClientRNSt10shared_ptrI6ObjectEE"]], "vineyard::objectbuilder::_seal (c++ function)": [[28, "_CPPv4N8vineyard13ObjectBuilder5_SealER6Client"], [28, "_CPPv4N8vineyard13ObjectBuilder5_SealER6ClientRNSt10shared_ptrI6ObjectEE"]], "vineyard::objectbuilder::sealed (c++ function)": [[28, "_CPPv4NK8vineyard13ObjectBuilder6sealedEv"]], "vineyard::objectbuilder::set_sealed (c++ function)": [[28, "_CPPv4N8vineyard13ObjectBuilder10set_sealedEKb"]], "vineyard::objectbuilder::~objectbuilder (c++ function)": [[28, "_CPPv4N8vineyard13ObjectBuilderD0Ev"]], "vineyard::objectid (c++ type)": [[28, "_CPPv4N8vineyard8ObjectIDE"]], "vineyard::objectmeta (c++ class)": [[28, "_CPPv4N8vineyard10ObjectMetaE"]], "vineyard::objectmeta::addkeyvalue (c++ function)": [[28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapI4json5ValueE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK12UnorderedMapINSt6stringE5ValueE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK1T"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapI4json5ValueE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK3MapINSt6stringE5ValueE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERK5TupleI1TE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapI4json5ValueEE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt13unordered_mapINSt6stringE5ValueEE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapI4json5ValueEE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3mapINSt6stringE5ValueEE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt3setI1TEE"], [28, "_CPPv4I0EN8vineyard10ObjectMeta11AddKeyValueEvRKNSt6stringERKNSt6vectorI1TEE"], [28, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERK4json"], [28, "_CPPv4N8vineyard10ObjectMeta11AddKeyValueERKNSt6stringERKNSt6stringE"]], "vineyard::objectmeta::addmember (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEK8ObjectID"], [28, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringEPK6Object"], [28, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK10ObjectMeta"], [28, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERK6Object"], [28, "_CPPv4N8vineyard10ObjectMeta9AddMemberERKNSt6stringERKNSt10shared_ptrI6ObjectEE"]], "vineyard::objectmeta::addremoteblob (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta13AddRemoteBlobERK10RemoteBlob"]], "vineyard::objectmeta::forcelocal (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta10ForceLocalEv"]], "vineyard::objectmeta::getbuffer (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta9GetBufferEK8ObjectIDRNSt10shared_ptrI6BufferEE"]], "vineyard::objectmeta::getbufferset (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta12GetBufferSetEv"]], "vineyard::objectmeta::getclient (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta9GetClientEv"]], "vineyard::objectmeta::getid (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta5GetIdEv"]], "vineyard::objectmeta::getinstanceid (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta13GetInstanceIdEv"]], "vineyard::objectmeta::getkeyvalue (c++ function)": [[28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEK1TRKNSt6stringE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapI4json5ValueE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER12UnorderedMapINSt6stringE5ValueE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER1T"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapI4json5ValueE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER3MapINSt6stringE5ValueE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringER5TupleI1TE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapI4json5ValueEE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt13unordered_mapINSt6stringE5ValueEE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapI4json5ValueEE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3mapINSt6stringE5ValueEE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt3setI1TEE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta11GetKeyValueEvRKNSt6stringERNSt6vectorI1TEE"], [28, "_CPPv4IENK8vineyard10ObjectMeta11GetKeyValueEK4jsonRKNSt6stringE"], [28, "_CPPv4NK8vineyard10ObjectMeta11GetKeyValueERKNSt6stringE"], [28, "_CPPv4NK8vineyard10ObjectMeta11GetKeyValueERKNSt6stringER4json"]], "vineyard::objectmeta::getmember (c++ function)": [[28, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberE6StatusRKNSt6stringERNSt10shared_ptrI1TEE"], [28, "_CPPv4I0ENK8vineyard10ObjectMeta9GetMemberENSt10shared_ptrI1TEERKNSt6stringE"], [28, "_CPPv4NK8vineyard10ObjectMeta9GetMemberERKNSt6stringE"], [28, "_CPPv4NK8vineyard10ObjectMeta9GetMemberERKNSt6stringERNSt10shared_ptrI6ObjectEE"]], "vineyard::objectmeta::getmembermeta (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta13GetMemberMetaERKNSt6stringE"], [28, "_CPPv4NK8vineyard10ObjectMeta13GetMemberMetaERKNSt6stringER10ObjectMeta"]], "vineyard::objectmeta::getnbytes (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta9GetNBytesEv"]], "vineyard::objectmeta::getsignature (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta12GetSignatureEv"]], "vineyard::objectmeta::gettypename (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta11GetTypeNameEv"]], "vineyard::objectmeta::haskey (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta6HasKeyERKNSt6stringE"], [28, "_CPPv4NK8vineyard10ObjectMeta6HaskeyERKNSt6stringE"]], "vineyard::objectmeta::isglobal (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta8IsGlobalEv"]], "vineyard::objectmeta::islocal (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta7IsLocalEv"]], "vineyard::objectmeta::label (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta5LabelERKNSt6stringE"]], "vineyard::objectmeta::labels (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta6LabelsEv"]], "vineyard::objectmeta::memoryusage (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta11MemoryUsageER4jsonKb"], [28, "_CPPv4NK8vineyard10ObjectMeta11MemoryUsageEv"]], "vineyard::objectmeta::metadata (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta8MetaDataEv"]], "vineyard::objectmeta::mutmetadata (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta11MutMetaDataEv"]], "vineyard::objectmeta::objectmeta (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta10ObjectMetaERK10ObjectMeta"], [28, "_CPPv4N8vineyard10ObjectMeta10ObjectMetaEv"]], "vineyard::objectmeta::printmeta (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta9PrintMetaEv"]], "vineyard::objectmeta::reset (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta5ResetEv"]], "vineyard::objectmeta::resetkey (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta8ResetKeyERKNSt6stringE"]], "vineyard::objectmeta::resetsignature (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta14ResetSignatureEv"]], "vineyard::objectmeta::setbuffer (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta9SetBufferERK8ObjectIDRKNSt10shared_ptrI6BufferEE"]], "vineyard::objectmeta::setclient (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta9SetClientEP10ClientBase"]], "vineyard::objectmeta::setglobal (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta9SetGlobalEb"]], "vineyard::objectmeta::setid (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta5SetIdERK8ObjectID"]], "vineyard::objectmeta::setmetadata (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta11SetMetaDataEP10ClientBaseRK4json"]], "vineyard::objectmeta::setnbytes (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta9SetNBytesEK6size_t"]], "vineyard::objectmeta::settypename (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta11SetTypeNameERKNSt6stringE"]], "vineyard::objectmeta::timestamp (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta9TimestampEv"]], "vineyard::objectmeta::tostring (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta8ToStringEv"]], "vineyard::objectmeta::unsafe (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMeta6UnsafeE4json6size_tP8ObjectIDP9uintptr_tP6size_t"], [28, "_CPPv4N8vineyard10ObjectMeta6UnsafeENSt6stringE6size_tP8ObjectIDP9uintptr_tP6size_t"]], "vineyard::objectmeta::begin (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta5beginEv"]], "vineyard::objectmeta::const_iterator (c++ type)": [[28, "_CPPv4N8vineyard10ObjectMeta14const_iteratorE"]], "vineyard::objectmeta::end (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta3endEv"]], "vineyard::objectmeta::incomplete (c++ function)": [[28, "_CPPv4NK8vineyard10ObjectMeta10incompleteEv"]], "vineyard::objectmeta::operator= (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMetaaSERK10ObjectMeta"]], "vineyard::objectmeta::~objectmeta (c++ function)": [[28, "_CPPv4N8vineyard10ObjectMetaD0Ev"]], "vineyard::rpcclient (c++ class)": [[28, "_CPPv4N8vineyard9RPCClientE"]], "vineyard::rpcclient::connect (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE"], [28, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_t"], [28, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tK9SessionIDRKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringE8uint32_tRKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringEK9SessionIDRKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard9RPCClient7ConnectERKNSt6stringERKNSt6stringERKNSt6stringE"], [28, "_CPPv4N8vineyard9RPCClient7ConnectEv"]], "vineyard::rpcclient::createremoteblob (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient16CreateRemoteBlobERKNSt10shared_ptrI16RemoteBlobWriterEER10ObjectMeta"]], "vineyard::rpcclient::createremoteblobs (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient17CreateRemoteBlobsERKNSt6vectorINSt10shared_ptrI16RemoteBlobWriterEEEERNSt6vectorI10ObjectMetaEE"]], "vineyard::rpcclient::fork (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient4ForkER9RPCClient"]], "vineyard::rpcclient::getmetadata (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient11GetMetaDataEK8ObjectIDR10ObjectMetaKb"], [28, "_CPPv4N8vineyard9RPCClient11GetMetaDataERKNSt6vectorI8ObjectIDEERNSt6vectorI10ObjectMetaEEKb"]], "vineyard::rpcclient::getobject (c++ function)": [[28, "_CPPv4I0EN8vineyard9RPCClient9GetObjectE6StatusK8ObjectIDRNSt10shared_ptrI1TEEKb"], [28, "_CPPv4I0EN8vineyard9RPCClient9GetObjectENSt10shared_ptrI1TEEK8ObjectIDKb"], [28, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDKb"], [28, "_CPPv4N8vineyard9RPCClient9GetObjectEK8ObjectIDRNSt10shared_ptrI6ObjectEEKb"]], "vineyard::rpcclient::getobjects (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient10GetObjectsERKNSt6vectorI8ObjectIDEEKb"]], "vineyard::rpcclient::getremoteblob (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDKbRNSt10shared_ptrI10RemoteBlobEE"], [28, "_CPPv4N8vineyard9RPCClient13GetRemoteBlobERK8ObjectIDRNSt10shared_ptrI10RemoteBlobEE"]], "vineyard::rpcclient::getremoteblobs (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEEKbRNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE"], [28, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt3setI8ObjectIDEERNSt3mapI8ObjectIDNSt10shared_ptrI10RemoteBlobEEEE"], [28, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEEKbRNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE"], [28, "_CPPv4N8vineyard9RPCClient14GetRemoteBlobsERKNSt6vectorI8ObjectIDEERNSt6vectorINSt10shared_ptrI10RemoteBlobEEEE"]], "vineyard::rpcclient::isfetchable (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient11IsFetchableERK10ObjectMeta"]], "vineyard::rpcclient::isrpc (c++ function)": [[28, "_CPPv4NK8vineyard9RPCClient5IsRPCEv"]], "vineyard::rpcclient::listobjectmeta (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient14ListObjectMetaERKNSt6stringEKbK6size_tb"]], "vineyard::rpcclient::listobjects (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient11ListObjectsERKNSt6stringEKbK6size_t"]], "vineyard::rpcclient::tryacquirelock (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient14TryAcquireLockENSt6stringERbRNSt6stringE"]], "vineyard::rpcclient::tryreleaselock (c++ function)": [[28, "_CPPv4N8vineyard9RPCClient14TryReleaseLockENSt6stringERb"]], "vineyard::rpcclient::remote_instance_id (c++ function)": [[28, "_CPPv4NK8vineyard9RPCClient18remote_instance_idEv"]], "vineyard::rpcclient::~rpcclient (c++ function)": [[28, "_CPPv4N8vineyard9RPCClientD0Ev"]], "vineyard::scalar (c++ class)": [[28, "_CPPv4I0EN8vineyard6ScalarE"]], "vineyard::scalar::construct (c++ function)": [[28, "_CPPv4N8vineyard6Scalar9ConstructERK10ObjectMeta"]], "vineyard::scalar::create (c++ function)": [[28, "_CPPv4N8vineyard6Scalar6CreateEv"]], "vineyard::scalar::type (c++ function)": [[28, "_CPPv4NK8vineyard6Scalar4TypeEv"]], "vineyard::scalar::value (c++ function)": [[28, "_CPPv4NK8vineyard6Scalar5ValueEv"]], "vineyard::scalarbuilder (c++ class)": [[28, "_CPPv4I0EN8vineyard13ScalarBuilderE"]], "vineyard::scalarbuilder::scalarbuilder (c++ function)": [[28, "_CPPv4N8vineyard13ScalarBuilder13ScalarBuilderER6Client"], [28, "_CPPv4N8vineyard13ScalarBuilder13ScalarBuilderER6ClientRK1T"]], "vineyard::scalarbuilder::setvalue (c++ function)": [[28, "_CPPv4N8vineyard13ScalarBuilder8SetValueERK1T"]], "vineyard::sequence (c++ class)": [[28, "_CPPv4N8vineyard8SequenceE"]], "vineyard::sequence::at (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence2AtE6size_t"]], "vineyard::sequence::construct (c++ function)": [[28, "_CPPv4N8vineyard8Sequence9ConstructERK10ObjectMeta"]], "vineyard::sequence::create (c++ function)": [[28, "_CPPv4N8vineyard8Sequence6CreateEv"]], "vineyard::sequence::first (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence5FirstEv"]], "vineyard::sequence::second (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence6SecondEv"]], "vineyard::sequence::size (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence4SizeEv"]], "vineyard::sequence::begin (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence5beginEv"]], "vineyard::sequence::end (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence3endEv"]], "vineyard::sequence::iterator (c++ class)": [[28, "_CPPv4N8vineyard8Sequence8iteratorE"]], "vineyard::sequence::iterator::iterator (c++ function)": [[28, "_CPPv4N8vineyard8Sequence8iterator8iteratorEPK8Sequence6size_t"]], "vineyard::sequence::iterator::operator!= (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence8iteratorneE8iterator"]], "vineyard::sequence::iterator::operator* (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence8iteratormlEv"]], "vineyard::sequence::iterator::operator++ (c++ function)": [[28, "_CPPv4N8vineyard8Sequence8iteratorppEv"]], "vineyard::sequence::iterator::operator== (c++ function)": [[28, "_CPPv4NK8vineyard8Sequence8iteratoreqE8iterator"]], "vineyard::sequencebuilder (c++ class)": [[28, "_CPPv4N8vineyard15SequenceBuilderE"]], "vineyard::sequencebuilder::at (c++ function)": [[28, "_CPPv4N8vineyard15SequenceBuilder2AtE6size_t"]], "vineyard::sequencebuilder::sequencebuilder (c++ function)": [[28, "_CPPv4N8vineyard15SequenceBuilder15SequenceBuilderER6Client"], [28, "_CPPv4N8vineyard15SequenceBuilder15SequenceBuilderER6ClientK6size_t"]], "vineyard::sequencebuilder::setsize (c++ function)": [[28, "_CPPv4N8vineyard15SequenceBuilder7SetSizeE6size_t"]], "vineyard::sequencebuilder::setvalue (c++ function)": [[28, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI13ObjectBuilderEE"], [28, "_CPPv4N8vineyard15SequenceBuilder8SetValueE6size_tRKNSt10shared_ptrI6ObjectEE"]], "vineyard::sequencebuilder::size (c++ function)": [[28, "_CPPv4NK8vineyard15SequenceBuilder4SizeEv"]], "vineyard::tensor (c++ class)": [[28, "_CPPv4I0EN8vineyard6TensorE"]], "vineyard::tensor::arrowtensor (c++ function)": [[28, "_CPPv4N8vineyard6Tensor11ArrowTensorEv"]], "vineyard::tensor::arrowtensort (c++ type)": [[28, "_CPPv4N8vineyard6Tensor12ArrowTensorTE"]], "vineyard::tensor::construct (c++ function)": [[28, "_CPPv4N8vineyard6Tensor9ConstructERK10ObjectMeta"]], "vineyard::tensor::create (c++ function)": [[28, "_CPPv4N8vineyard6Tensor6CreateEv"]], "vineyard::tensor::auxiliary_buffer (c++ function)": [[28, "_CPPv4NK8vineyard6Tensor16auxiliary_bufferEv"]], "vineyard::tensor::buffer (c++ function)": [[28, "_CPPv4NK8vineyard6Tensor6bufferEv"]], "vineyard::tensor::data (c++ function)": [[28, "_CPPv4NK8vineyard6Tensor4dataEv"]], "vineyard::tensor::operator[] (c++ function)": [[28, "_CPPv4NK8vineyard6TensorixE6size_t"]], "vineyard::tensor::partition_index (c++ function)": [[28, "_CPPv4NK8vineyard6Tensor15partition_indexEv"]], "vineyard::tensor::shape (c++ function)": [[28, "_CPPv4NK8vineyard6Tensor5shapeEv"]], "vineyard::tensor::strides (c++ function)": [[28, "_CPPv4NK8vineyard6Tensor7stridesEv"]], "vineyard::tensor::value_const_pointer_t (c++ type)": [[28, "_CPPv4N8vineyard6Tensor21value_const_pointer_tE"]], "vineyard::tensor::value_pointer_t (c++ type)": [[28, "_CPPv4N8vineyard6Tensor15value_pointer_tE"]], "vineyard::tensor::value_t (c++ type)": [[28, "_CPPv4N8vineyard6Tensor7value_tE"]], "vineyard::tensor::value_type (c++ function)": [[28, "_CPPv4NK8vineyard6Tensor10value_typeEv"]], "vineyard::tensorbuilder (c++ class)": [[28, "_CPPv4I0EN8vineyard13TensorBuilderE"]], "vineyard::tensorbuilder::build (c++ function)": [[28, "_CPPv4N8vineyard13TensorBuilder5BuildER6Client"]], "vineyard::tensorbuilder::tensorbuilder (c++ function)": [[28, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEE"], [28, "_CPPv4N8vineyard13TensorBuilder13TensorBuilderER6ClientRKNSt6vectorI7int64_tEERKNSt6vectorI7int64_tEE"]], "vineyard::tensorbuilder::data (c++ function)": [[28, "_CPPv4NK8vineyard13TensorBuilder4dataEv"]], "vineyard::tensorbuilder::partition_index (c++ function)": [[28, "_CPPv4NK8vineyard13TensorBuilder15partition_indexEv"]], "vineyard::tensorbuilder::set_partition_index (c++ function)": [[28, "_CPPv4N8vineyard13TensorBuilder19set_partition_indexERKNSt6vectorI7int64_tEE"]], "vineyard::tensorbuilder::set_shape (c++ function)": [[28, "_CPPv4N8vineyard13TensorBuilder9set_shapeERKNSt6vectorI7int64_tEE"]], "vineyard::tensorbuilder::shape (c++ function)": [[28, "_CPPv4NK8vineyard13TensorBuilder5shapeEv"]], "vineyard::tensorbuilder::strides (c++ function)": [[28, "_CPPv4NK8vineyard13TensorBuilder7stridesEv"]], "vineyard::tensorbuilder::value_const_pointer_t (c++ type)": [[28, "_CPPv4N8vineyard13TensorBuilder21value_const_pointer_tE"]], "vineyard::tensorbuilder::value_pointer_t (c++ type)": [[28, "_CPPv4N8vineyard13TensorBuilder15value_pointer_tE"]], "vineyard::tensorbuilder::value_t (c++ type)": [[28, "_CPPv4N8vineyard13TensorBuilder7value_tE"]], "blob (class in vineyard)": [[30, "vineyard.Blob"]], "blobbuilder (class in vineyard)": [[30, "vineyard.BlobBuilder"]], "buildercontext (class in vineyard.core.builder)": [[30, "vineyard.core.builder.BuilderContext"]], "bytestream (class in vineyard.io.byte)": [[30, "vineyard.io.byte.ByteStream"]], "client (class in vineyard)": [[30, "vineyard.Client"]], "dataframestream (class in vineyard.io.dataframe)": [[30, "vineyard.io.dataframe.DataframeStream"]], "drivercontext (class in vineyard.core.driver)": [[30, "vineyard.core.driver.DriverContext"]], "ipcclient (class in vineyard)": [[30, "vineyard.IPCClient"]], "instancestatus (class in vineyard)": [[30, "vineyard.InstanceStatus"]], "object (class in vineyard)": [[30, "vineyard.Object"]], "objectbuilder (class in vineyard)": [[30, "vineyard.ObjectBuilder"]], "objectid (class in vineyard)": [[30, "vineyard.ObjectID"]], "objectmeta (class in vineyard)": [[30, "vineyard.ObjectMeta"]], "rpcclient (class in vineyard)": [[30, "vineyard.RPCClient"]], "recordbatchstream (class in vineyard.io.recordbatch)": [[30, "vineyard.io.recordbatch.RecordBatchStream"]], "remoteblob (class in vineyard)": [[30, "vineyard.RemoteBlob"]], "remoteblobbuilder (class in vineyard)": [[30, "vineyard.RemoteBlobBuilder"]], "resolvercontext (class in vineyard.core.resolver)": [[30, "vineyard.core.resolver.ResolverContext"]], "shareablelist (class in vineyard.shared_memory)": [[30, "vineyard.shared_memory.ShareableList"]], "sharedmemory (class in vineyard.shared_memory)": [[30, "vineyard.shared_memory.SharedMemory"]], "__contains__() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.__contains__"]], "__eq__() (vineyard.objectid method)": [[30, "vineyard.ObjectID.__eq__"]], "__getitem__() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.__getitem__"]], "__hash__() (vineyard.objectid method)": [[30, "vineyard.ObjectID.__hash__"]], "__init__() (vineyard.instancestatus method)": [[30, "vineyard.InstanceStatus.__init__"]], "__init__() (vineyard.objectid method)": [[30, "vineyard.ObjectID.__init__"]], "__init__() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.__init__"]], "__repr__() (vineyard.instancestatus method)": [[30, "vineyard.InstanceStatus.__repr__"]], "__repr__() (vineyard.objectid method)": [[30, "vineyard.ObjectID.__repr__"]], "__repr__() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.__repr__"]], "__setitem__() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.__setitem__"]], "__str__() (vineyard.instancestatus method)": [[30, "vineyard.InstanceStatus.__str__"]], "__str__() (vineyard.objectid method)": [[30, "vineyard.ObjectID.__str__"]], "__str__() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.__str__"]], "abort() (vineyard.blobbuilder method)": [[30, "vineyard.BlobBuilder.abort"]], "abort() (vineyard.remoteblobbuilder method)": [[30, "vineyard.RemoteBlobBuilder.abort"]], "add_member() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.add_member"]], "add_remote_blob() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.add_remote_blob"]], "address (vineyard.blob property)": [[30, "vineyard.Blob.address"]], "address (vineyard.blobbuilder property)": [[30, "vineyard.BlobBuilder.address"]], "address (vineyard.remoteblob property)": [[30, "vineyard.RemoteBlob.address"]], "address (vineyard.remoteblobbuilder property)": [[30, "vineyard.RemoteBlobBuilder.address"]], "allocated_size() (vineyard.client method)": [[30, "vineyard.Client.allocated_size"]], "allocated_size() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.allocated_size"]], "buf (vineyard.shared_memory.sharedmemory property)": [[30, "vineyard.shared_memory.SharedMemory.buf"]], "builder_context() (in module vineyard.core.builder)": [[30, "vineyard.core.builder.builder_context"]], "clear() (vineyard.client method)": [[30, "vineyard.Client.clear"]], "clear() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.clear"]], "clear() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.clear"]], "close() (vineyard.client method)": [[30, "vineyard.Client.close"]], "close() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.close"]], "close() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.close"]], "compression (vineyard.client property)": [[30, "vineyard.Client.compression"]], "connect() (in module vineyard)": [[30, "id0"], [30, "vineyard.connect"]], "connected (vineyard.client property)": [[30, "vineyard.Client.connected"]], "connected (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.connected"]], "connected (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.connected"]], "copy() (vineyard.blobbuilder method)": [[30, "vineyard.BlobBuilder.copy"]], "copy() (vineyard.remoteblobbuilder method)": [[30, "vineyard.RemoteBlobBuilder.copy"]], "create_blob() (vineyard.client method)": [[30, "vineyard.Client.create_blob"]], "create_blob() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.create_blob"]], "create_empty_blob() (vineyard.client method)": [[30, "vineyard.Client.create_empty_blob"]], "create_empty_blob() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.create_empty_blob"]], "create_metadata() (vineyard.client method)": [[30, "vineyard.Client.create_metadata"]], "create_metadata() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.create_metadata"]], "create_metadata() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.create_metadata"]], "create_remote_blob() (vineyard.client method)": [[30, "vineyard.Client.create_remote_blob"]], "create_remote_blob() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.create_remote_blob"]], "deferred_requests (vineyard.instancestatus property)": [[30, "vineyard.InstanceStatus.deferred_requests"]], "delete() (vineyard.client method)": [[30, "vineyard.Client.delete"]], "delete() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.delete"]], "delete() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.delete"]], "delete_kubernetes_objects() (in module vineyard.deploy.kubernetes)": [[30, "vineyard.deploy.kubernetes.delete_kubernetes_objects"]], "deployment (vineyard.instancestatus property)": [[30, "vineyard.InstanceStatus.deployment"]], "driver_context() (in module vineyard.core.driver)": [[30, "vineyard.core.driver.driver_context"]], "drop_name() (vineyard.client method)": [[30, "vineyard.Client.drop_name"]], "drop_name() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.drop_name"]], "drop_name() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.drop_name"]], "empty() (vineyard.blob static method)": [[30, "vineyard.Blob.empty"]], "exists() (vineyard.client method)": [[30, "vineyard.Client.exists"]], "exists() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.exists"]], "exists() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.exists"]], "find_shared_memory() (vineyard.client method)": [[30, "vineyard.Client.find_shared_memory"]], "find_shared_memory() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.find_shared_memory"]], "freeze() (vineyard.shared_memory.shareablelist method)": [[30, "vineyard.shared_memory.ShareableList.freeze"]], "freeze() (vineyard.shared_memory.sharedmemory method)": [[30, "vineyard.shared_memory.SharedMemory.freeze"]], "from_() (vineyard.object static method)": [[30, "vineyard.Object.from_"]], "get() (vineyard.client method)": [[30, "vineyard.Client.get"]], "get() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get"]], "get() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.get"]], "get() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get"]], "get_blob() (vineyard.client method)": [[30, "vineyard.Client.get_blob"]], "get_blob() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get_blob"]], "get_blobs() (vineyard.client method)": [[30, "vineyard.Client.get_blobs"]], "get_blobs() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get_blobs"]], "get_current_builders() (in module vineyard.core.builder)": [[30, "vineyard.core.builder.get_current_builders"]], "get_current_drivers() (in module vineyard.core.driver)": [[30, "vineyard.core.driver.get_current_drivers"]], "get_current_resolvers() (in module vineyard.core.resolver)": [[30, "vineyard.core.resolver.get_current_resolvers"]], "get_current_socket() (in module vineyard)": [[30, "vineyard.get_current_socket"]], "get_member() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.get_member"]], "get_meta() (vineyard.client method)": [[30, "vineyard.Client.get_meta"]], "get_meta() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get_meta"]], "get_meta() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get_meta"]], "get_metas() (vineyard.client method)": [[30, "vineyard.Client.get_metas"]], "get_metas() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get_metas"]], "get_metas() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get_metas"]], "get_name() (vineyard.client method)": [[30, "vineyard.Client.get_name"]], "get_name() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get_name"]], "get_name() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get_name"]], "get_object() (vineyard.client method)": [[30, "vineyard.Client.get_object"]], "get_object() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get_object"]], "get_object() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get_object"]], "get_objects() (vineyard.client method)": [[30, "vineyard.Client.get_objects"]], "get_objects() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.get_objects"]], "get_objects() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get_objects"]], "get_remote_blob() (vineyard.client method)": [[30, "vineyard.Client.get_remote_blob"]], "get_remote_blob() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get_remote_blob"]], "get_remote_blobs() (vineyard.client method)": [[30, "vineyard.Client.get_remote_blobs"]], "get_remote_blobs() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.get_remote_blobs"]], "id (vineyard.blobbuilder property)": [[30, "vineyard.BlobBuilder.id"]], "id (vineyard.object property)": [[30, "vineyard.Object.id"]], "id (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.id"]], "id (vineyard.remoteblob property)": [[30, "vineyard.RemoteBlob.id"]], "instance_id (vineyard.client property)": [[30, "vineyard.Client.instance_id"]], "instance_id (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.instance_id"]], "instance_id (vineyard.instancestatus property)": [[30, "vineyard.InstanceStatus.instance_id"]], "instance_id (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.instance_id"]], "instance_id (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.instance_id"]], "instance_id (vineyard.remoteblob property)": [[30, "vineyard.RemoteBlob.instance_id"]], "ipc_connections (vineyard.instancestatus property)": [[30, "vineyard.InstanceStatus.ipc_connections"]], "ipc_socket (vineyard.client property)": [[30, "vineyard.Client.ipc_socket"]], "ipc_socket (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.ipc_socket"]], "ipc_socket (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.ipc_socket"]], "is_empty (vineyard.blob property)": [[30, "vineyard.Blob.is_empty"]], "is_empty (vineyard.remoteblob property)": [[30, "vineyard.RemoteBlob.is_empty"]], "is_fetchable() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.is_fetchable"]], "is_ipc (vineyard.client property)": [[30, "vineyard.Client.is_ipc"]], "is_ipc (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.is_ipc"]], "is_ipc (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.is_ipc"]], "is_rpc (vineyard.client property)": [[30, "vineyard.Client.is_rpc"]], "is_rpc (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.is_rpc"]], "is_rpc (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.is_rpc"]], "is_shared_memory() (vineyard.client method)": [[30, "vineyard.Client.is_shared_memory"]], "is_shared_memory() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.is_shared_memory"]], "isglobal (vineyard.object property)": [[30, "vineyard.Object.isglobal"]], "isglobal (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.isglobal"]], "islocal (vineyard.object property)": [[30, "vineyard.Object.islocal"]], "islocal (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.islocal"]], "ispersist (vineyard.object property)": [[30, "vineyard.Object.ispersist"]], "list_metadatas() (vineyard.client method)": [[30, "vineyard.Client.list_metadatas"]], "list_metadatas() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.list_metadatas"]], "list_metadatas() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.list_metadatas"]], "list_names() (vineyard.client method)": [[30, "vineyard.Client.list_names"]], "list_names() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.list_names"]], "list_names() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.list_names"]], "list_objects() (vineyard.client method)": [[30, "vineyard.Client.list_objects"]], "list_objects() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.list_objects"]], "list_objects() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.list_objects"]], "member() (vineyard.object method)": [[30, "vineyard.Object.member"]], "member() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.member"]], "memory_limit (vineyard.instancestatus property)": [[30, "vineyard.InstanceStatus.memory_limit"]], "memory_trim() (vineyard.client method)": [[30, "vineyard.Client.memory_trim"]], "memory_trim() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.memory_trim"]], "memory_trim() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.memory_trim"]], "memory_usage (vineyard.instancestatus property)": [[30, "vineyard.InstanceStatus.memory_usage"]], "memory_usage (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.memory_usage"]], "meta (vineyard.client property)": [[30, "vineyard.Client.meta"]], "meta (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.meta"]], "meta (vineyard.object property)": [[30, "vineyard.Object.meta"]], "meta (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.meta"]], "name (vineyard.shared_memory.sharedmemory property)": [[30, "vineyard.shared_memory.SharedMemory.name"]], "nbytes (vineyard.object property)": [[30, "vineyard.Object.nbytes"]], "nbytes (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.nbytes"]], "open() (in module vineyard.io)": [[30, "vineyard.io.open"]], "persist() (vineyard.client method)": [[30, "vineyard.Client.persist"]], "persist() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.persist"]], "persist() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.persist"]], "put() (vineyard.client method)": [[30, "vineyard.Client.put"]], "put() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.put"]], "put() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.put"]], "put_name() (vineyard.client method)": [[30, "vineyard.Client.put_name"]], "put_name() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.put_name"]], "put_name() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.put_name"]], "read() (in module vineyard.csi)": [[30, "vineyard.csi.read"]], "read() (in module vineyard.io)": [[30, "vineyard.io.read"]], "register() (vineyard.core.builder.buildercontext method)": [[30, "vineyard.core.builder.BuilderContext.register"]], "remote_instance_id (vineyard.client property)": [[30, "vineyard.Client.remote_instance_id"]], "remote_instance_id (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.remote_instance_id"]], "reset() (vineyard.client method)": [[30, "vineyard.Client.reset"]], "reset() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.reset"]], "reset() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.reset"]], "resolver_context() (in module vineyard.core.resolver)": [[30, "vineyard.core.resolver.resolver_context"]], "rpc_connections (vineyard.instancestatus property)": [[30, "vineyard.InstanceStatus.rpc_connections"]], "rpc_endpoint (vineyard.client property)": [[30, "vineyard.Client.rpc_endpoint"]], "rpc_endpoint (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.rpc_endpoint"]], "rpc_endpoint (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.rpc_endpoint"]], "run() (vineyard.core.builder.buildercontext method)": [[30, "vineyard.core.builder.BuilderContext.run"]], "set_global() (vineyard.objectmeta method)": [[30, "vineyard.ObjectMeta.set_global"]], "shallow_copy() (vineyard.client method)": [[30, "vineyard.Client.shallow_copy"]], "shallow_copy() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.shallow_copy"]], "shallow_copy() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.shallow_copy"]], "shrink() (vineyard.blobbuilder method)": [[30, "vineyard.BlobBuilder.shrink"]], "signature (vineyard.object property)": [[30, "vineyard.Object.signature"]], "signature (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.signature"]], "size (vineyard.blob property)": [[30, "vineyard.Blob.size"]], "size (vineyard.blobbuilder property)": [[30, "vineyard.BlobBuilder.size"]], "size (vineyard.remoteblob property)": [[30, "vineyard.RemoteBlob.size"]], "size (vineyard.remoteblobbuilder property)": [[30, "vineyard.RemoteBlobBuilder.size"]], "size (vineyard.shared_memory.sharedmemory property)": [[30, "vineyard.shared_memory.SharedMemory.size"]], "spread (vineyard.client property)": [[30, "vineyard.Client.spread"]], "start_vineyardd() (in module vineyard.deploy.distributed)": [[30, "vineyard.deploy.distributed.start_vineyardd"]], "start_vineyardd() (in module vineyard.deploy.kubernetes)": [[30, "vineyard.deploy.kubernetes.start_vineyardd"]], "start_vineyardd() (in module vineyard.deploy.local)": [[30, "vineyard.deploy.local.start_vineyardd"]], "status (vineyard.client property)": [[30, "vineyard.Client.status"]], "status (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.status"]], "status (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.status"]], "sync_meta() (vineyard.client method)": [[30, "vineyard.Client.sync_meta"]], "sync_meta() (vineyard.ipcclient method)": [[30, "vineyard.IPCClient.sync_meta"]], "sync_meta() (vineyard.rpcclient method)": [[30, "vineyard.RPCClient.sync_meta"]], "typename (vineyard.object property)": [[30, "vineyard.Object.typename"]], "typename (vineyard.objectmeta property)": [[30, "vineyard.ObjectMeta.typename"]], "unlink() (vineyard.shared_memory.sharedmemory method)": [[30, "vineyard.shared_memory.SharedMemory.unlink"]], "version (vineyard.client property)": [[30, "vineyard.Client.version"]], "version (vineyard.ipcclient property)": [[30, "vineyard.IPCClient.version"]], "version (vineyard.rpcclient property)": [[30, "vineyard.RPCClient.version"]], "with_compression() (vineyard.client method)": [[30, "vineyard.Client.with_compression"]], "with_spread() (vineyard.client method)": [[30, "vineyard.Client.with_spread"]], "write() (in module vineyard.csi)": [[30, "vineyard.csi.write"]], "write() (in module vineyard.io)": [[30, "vineyard.io.write"]]}})
\ No newline at end of file
diff --git a/summer.html b/summer.html
new file mode 100644
index 0000000000..87128c0439
--- /dev/null
+++ b/summer.html
@@ -0,0 +1,7 @@
+
+
+
+ Vineyard • Summer of Code
+
+
+
diff --git a/tutorials/data-processing.html b/tutorials/data-processing.html
new file mode 100644
index 0000000000..22e606ca55
--- /dev/null
+++ b/tutorials/data-processing.html
@@ -0,0 +1,555 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Data processing - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Data processing
+
+
+In these comprehensive case studies, we demonstrate how to seamlessly integrate vineyard’s
+capabilities with existing data-intensive tasks. By incorporating vineyard into complex
+workflows involving multiple computing engines, users can experience significant
+improvements in both performance and ease of use.
+
+
+
+
+
+
+
Effortlessly share Python objects between processes using vineyard’s intuitive and efficient approach.
+
+
+
+
+
+
+
+
Utilize vineyard as an elegant alternative to multiprocessing.shared_memory
in Python.
+
+
+
+
+
+
+
+
Discover how vineyard enhances distributed machine learning training workflows by
+seamlessly integrating with various computing engines for improved efficiency and elegance.
+
+
+
+
+
+
+
+
Vineyard serves as the DataSet
backend for Kedro pipelines, enabling
+efficient data sharing between tasks without intrusive code modification, even
+when the pipeline is deployed to Kubernetes.
+
+
+
+
+
+
+
+
Vineyard supports sharing GPU memory in zero-copy manner, enabling efficient data sharing
+between GPU-accelerated tasks.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/data-processing/accelerate-data-sharing-in-kedro.html b/tutorials/data-processing/accelerate-data-sharing-in-kedro.html
new file mode 100644
index 0000000000..3d02e4bcba
--- /dev/null
+++ b/tutorials/data-processing/accelerate-data-sharing-in-kedro.html
@@ -0,0 +1,832 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Accelerate Data Sharing in Kedro - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Accelerate Data Sharing in Kedro
+This is a tutorial that shows how Vineyard accelerate the intermediate data
+sharing between tasks in Kedro pipelines using our
+vineyard-kedro plugin, when data
+scales and the pipeline are deployed on Kubernetes.
+
+
+Prepare the Kubernetes cluster
+To deploy Kedro pipelines on Kubernetes, you must have a kubernetes cluster.
+
+
Tip
+
If you already have a K8s cluster, just skip this section and continue
+on deploying.
+
+We recommend kind v0.20.0 to create a multi-node
+Kubernetes cluster on your local machine as follows:
+ $ cat <<EOF | kind create cluster --config=-
+kind: Cluster
+apiVersion: kind.x-k8s.io/v1alpha4
+nodes:
+- role: control-plane
+ image: kindest/node:v1.25.11
+- role: worker
+ image: kindest/node:v1.25.11
+- role: worker
+ image: kindest/node:v1.25.11
+- role: worker
+ image: kindest/node:v1.25.11
+EOF
+
+
+
+
+Deploy Argo Workflows
+Install the argo operator on Kubernetes:
+ $ kubectl create namespace argo
+$ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.4.8/install.yaml
+
+
+When the deployment becomes ready, you can see the following pods:
+ $ kubectl get pod -n argo
+NAME READY STATUS RESTARTS AGE
+argo-server-7698c96655-jg2ds 1 /1 Running 0 11s
+workflow-controller-b888f4458-x4qf2 1 /1 Running 0 11s
+
+
+
+
+Deploy Vineyard
+
+Install the vineyard operator:
+ $ helm repo add vineyard https://vineyard.oss-ap-southeast-1.aliyuncs.com/charts/
+$ helm repo update
+$ helm install vineyard-operator vineyard/vineyard-operator \
+ --namespace vineyard-system \
+ --create-namespace
+
+
+
+Create a vineyard cluster:
+
+
Tip
+
+To handle the large data, we set the memory of vineyard cluster to 8G and the shared memory to 8G.
+
+
+
+ $ python3 -m vineyard.ctl deploy vineyardd --vineyardd.memory= 8Gi --vineyardd.size= 8Gi
+
+
+
+
Note
+
The above command will try to create a vineyard cluster with 3 replicas
+by default. If you are working with Minikube, Kind, or other Kubernetes
+that has less nodes available, try reduce the replicas by
+
$ python3 -m vineyard.ctl deploy vineyardd --replicas= 1 --vineyardd.memory= 8Gi --vineyardd.size= 8Gi
+
+
+
+
+
+
+
+Prepare the S3 Service
+
+Deploy the Minio cluster:
+
+
Tip
+
If you already have the AWS S3 service, just skip this section and jump to
+the next section.
+
+ $ kubectl apply -f python/vineyard/contrib/kedro/benchmark/mlops/minio-dev.yaml
+
+
+
+
Tip
+
The default access key and secret key of the minio cluster are minioadmin
+and minioadmin
.
+
+
+Create the S3 bucket:
+
+If you are working with AWS S3, you can create a bucket named
+aws-s3-benchmark-bucket
with the following command:
+ $ aws s3api create-bucket --bucket aws-s3-benchmark-bucket --region <Your AWS Region Name>
+
+
+
+If you are working with Minio, you first need to expose the services
+and then create the bucket:
+
+Forward minio-artifacts service:
+ $ kubectl port-forward service/minio -n minio-dev 9000 :9000
+
+
+
+Install the minio client:
+ $ wget https://dl.min.io/client/mc/release/linux-amd64/mc
+$ chmod +x mc
+$ sudo mv mc /usr/local/bin
+
+
+
+Configure the minio client:
+ $ mc alias set minio http://localhost:9000
+Enter Access Key: <Your Access Key>
+Enter Secret Key: <Your Secret Key>
+
+
+
+Finally, create the bucket minio-s3-benchmark-bucket
:
+ $ mc mb minio/minio-s3-benchmark-bucket
+Bucket created successfully ` minio/minio-s3-benchmark-bucket` .
+
+
+
+
+
+
+
+
+
+
+Prepare the Docker images
+
+Vineyard has delivered a benchmark project
+to test Kedro pipelines on Vineyard and S3:
+ $ cd python/vineyard/contrib/kedro/benchmark/mlops
+
+
+
+Configure the credentials configurations of AWS S3:
+ $ cat conf/aws-s3/credentials.yml
+benchmark_aws_s3:
+ client_kwargs:
+ aws_access_key_id: Your AWS/Minio Access Key ID
+ aws_secret_access_key: Your AWS/Minio Secret Access Key
+ region_name: Your AWS Region Name
+
+
+
+To deploy pipelines to Kubernetes, you first need to build the Docker image for the
+benchmark project.
+To show how vineyard can accelerate the data sharing along with the dataset
+scales, Docker images for different data size will be generated:
+
+
+To make those images available for your Kubernetes cluster, they need to be
+pushed to your registry (or load to kind cluster if you setup your Kubernetes
+cluster using kind):
+
+Push to registry:
+ $ docker tag mlops-benchmark:latest <Your Registry>/mlops-benchmark:latest
+$ docker push <Your Registry>/mlops-benchmark:latest
+
+
+
+Load to kind cluster:
+ $ kind load docker-image mlops-benchmark:latest
+
+
+
+
+
+
+
+
+Deploy the Kedro Pipelines
+
+Deploy the Kedro pipeline with vineyard for intermediate data sharing:
+ $ kubectl create namespace vineyard
+$ for multiplier in 1 10 100 500 ; do \
+ argo submit -n vineyard --watch argo-vineyard-benchmark.yml -p multiplier = ${ multiplier } ; \
+ done
+
+
+
+Similarly, using AWS S3 or Minio for intermediate data sharing:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/data-processing/distributed-learning.html b/tutorials/data-processing/distributed-learning.html
new file mode 100644
index 0000000000..9cf8d9da31
--- /dev/null
+++ b/tutorials/data-processing/distributed-learning.html
@@ -0,0 +1,907 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Distributed Learning with Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Distributed Learning with Vineyard
+With the growth of data, distributed learning is becoming a must in real-world machine learning applications, as the data size can easily exceed the memory limit of a single machine. Thus, many distributed systems addressing different workloads are developed and they share the same objective of extending users’ single machine prototypes to distributed settings with as few modifications to the code as possible.
+For example, dask.dataframe mimics the API of pandas which is the de-facto standard library for single-machine structured data processing, so that users can apply their pandas code for data preprocessing in the dask cluster with few modifications. Similarly, horovod provides easy-to-use APIs for users to transfer their single-machine code in machine learning frameworks (e.g., TensorFlow, PyTorch, MXNet) to the distributed settings with only a few additional lines of code.
+However, when extending to distributed learning, the data sharing between libraries within the same python process (e.g., pandas and tensorflow) becomes inter-process sharing between engines (e.g., dask and horovod), not to mention in the distributed fashion. Existing solutions using external distributed file systems are less than optimal for the huge I/O overheads.
+Vineyard shares the same design principle with the aforementioned distributed systems, which aims to provide efficient cross-engine data sharing with few modifications to the existing code. Next, we demonstrate how to transfer a single-machine learning example in keras to distributed learning with dask, horovod and Vineyard.
+
+An Example from Keras
+This example uses the Covertype dataset from the UCI Machine Learning Repository. The task is to predict forest cover type from cartographic variables. The dataset includes 506,011 instances with 12 input features: 10 numerical features and 2 categorical features. Each instance is categorized into 1 of 7 classes.
+The solution contains three steps:
+
+preprocess the data in pandas to extract the 12 features and the label
+store the preprocessed data in files
+define and train the model in keras
+
+Mapping the solution to distributed learning, we have:
+
+preprocess the data in dask.dataframe
+share the preprocessed data using Vineyard
+train the model in horovod.keras
+
+We will walk through the code as follows.
+
+
+Setup
+The distributed deployment of vineyard and dask is as follows: on each machine, we launch a vineyard daemon process to handle the local data storage on that machine; and we also launch a dask worker on that machine for the computation accordingly. In this notebook, we limit the machine number as 1 (i.e., the local machine) just for demonstration.
+
+
+
+Preprocessing the data
+To read the data, we replace pd.read_csv by dd.read_csv , which will automatically read the data in parallel.
+
+Then we preprocess the data using the same code from the example, except the replacement of pd.concat to dd.concat only.
+
+Finally, instead of saving the preprocessed data into files, we store them in Vineyard.
+
+We saved the preprocessed data as a global dataframe in Vineyard with the ObjectID above.
+
+
+Training the model
+In the single machine solution from the example. A get_dataset_from_csv function is defined to load the dataset from the files of the preprocessed data as follows:
+def get_dataset_from_csv ( csv_file_path , batch_size , shuffle = False ):
+
+ dataset = tf . data . experimental . make_csv_dataset (
+ csv_file_path ,
+ batch_size = batch_size ,
+ column_names = CSV_HEADER ,
+ column_defaults = COLUMN_DEFAULTS ,
+ label_name = TARGET_FEATURE_NAME ,
+ num_epochs = 1 ,
+ header = True ,
+ shuffle = shuffle ,
+ )
+ return dataset . cache ()
+
+
+while in the training procedure, it loads the train_dataset and test_dataset separately from two files as:
+def run_experiment ( model ):
+
+ model . compile (
+ optimizer = keras . optimizers . Adam ( learning_rate = learning_rate ),
+ loss = keras . losses . SparseCategoricalCrossentropy (),
+ metrics = [ keras . metrics . SparseCategoricalAccuracy ()],
+ )
+
+ train_dataset = get_dataset_from_csv ( train_data_file , batch_size , shuffle = True )
+
+ test_dataset = get_dataset_from_csv ( test_data_file , batch_size )
+
+ print ( "Start training the model..." )
+ history = model . fit ( train_dataset , epochs = num_epochs )
+ print ( "Model training finished" )
+
+ _ , accuracy = model . evaluate ( test_dataset , verbose = 0 )
+
+ print ( f "Test accuracy: { round ( accuracy * 100 , 2 ) } %" )
+
+
+In our solution, we provide a function to load dataset from the global dataframe generated in the last step.
+
+And modify the training procedure with a few lines of horovod code.
+
+All the other parts of training procedure are the same as the single machine solution.
+
+Let’s run it:
+
+We clear the environments in the end.
+
+Finally, we can use horovodrun to run the above code distributedly in a cluster for distributed learning on big datasets.
+
+
+Conclusion
+From this example, we can see that with the help of Vineyard, users can easily extend their single machine solutions to distributed learning using dedicated systems without worrying about the cross-system data sharing issues.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/data-processing/distributed-learning.ipynb b/tutorials/data-processing/distributed-learning.ipynb
new file mode 100644
index 0000000000..d428eda05b
--- /dev/null
+++ b/tutorials/data-processing/distributed-learning.ipynb
@@ -0,0 +1,536 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Distributed Learning with Vineyard\n",
+ "==================================\n",
+ "\n",
+ "With the growth of data, distributed learning is becoming a must in real-world machine learning\n",
+ "applications, as the data size can easily exceed the memory limit of a single machine.\n",
+ "Thus, many distributed systems addressing different workloads are developed\n",
+ "and they share the same objective of extending users' single machine prototypes \n",
+ "to distributed settings with as few modifications to the code as possible.\n",
+ "\n",
+ "For example, **dask.dataframe** mimics the API of **pandas** which is the de-facto standard\n",
+ "library for single-machine structured data processing, so that users can apply their\n",
+ "pandas code for data preprocessing in the dask cluster with few modifications.\n",
+ "Similarly, **horovod** provides easy-to-use APIs for users to transfer their single-machine\n",
+ "code in machine learning frameworks (e.g., TensorFlow, PyTorch, MXNet) to the distributed settings\n",
+ "with only a few additional lines of code.\n",
+ "\n",
+ "However, when extending to distributed learning, the data sharing between libraries within the same\n",
+ "python process (e.g., pandas and tensorflow) becomes inter-process sharing between engines (e.g.,\n",
+ "dask and horovod), not to mention in the distributed fashion. Existing solutions using external\n",
+ "distributed file systems are less than optimal for the huge I/O overheads.\n",
+ "\n",
+ "Vineyard shares the same design principle with the aforementioned distributed systems, which aims to\n",
+ "provide efficient cross-engine data sharing with few modifications to the existing code.\n",
+ "Next, we demonstrate how to transfer a single-machine learning example in **keras** to\n",
+ "distributed learning with dask, horovod and Vineyard.\n",
+ "\n",
+ "An Example from Keras\n",
+ "---------------------\n",
+ "\n",
+ "This [example](https://keras.io/examples/structured_data/wide_deep_cross_networks/)\n",
+ "uses the Covertype dataset from the UCI Machine Learning Repository.\n",
+ "The task is to predict forest cover type from cartographic variables.\n",
+ "The dataset includes 506,011 instances with 12 input features:\n",
+ "10 numerical features and 2 categorical features.\n",
+ "Each instance is categorized into 1 of 7 classes.\n",
+ "\n",
+ "The solution contains three steps:\n",
+ "\n",
+ "1. preprocess the data in pandas to extract the 12 features and the label\n",
+ "2. store the preprocessed data in files\n",
+ "3. define and train the model in keras\n",
+ "\n",
+ "\n",
+ "Mapping the solution to distributed learning, we have:\n",
+ "\n",
+ "1. preprocess the data in dask.dataframe\n",
+ "2. share the preprocessed data using Vineyard\n",
+ "3. train the model in horovod.keras\n",
+ "\n",
+ "\n",
+ "We will walk through the code as follows.\n",
+ "\n",
+ "Setup\n",
+ "-------\n",
+ "\n",
+ "The distributed deployment of vineyard and dask is as follows: on each machine, we launch a vineyard daemon process to handle the local data storage on that machine; and we also launch a dask worker on that machine for the computation accordingly. In this notebook, we limit the machine number as 1 (i.e., the local machine) just for demonstration."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import vineyard\n",
+ "import subprocess as sp\n",
+ "\n",
+ "# launch local vineyardd\n",
+ "client = vineyard.connect()\n",
+ "\n",
+ "# launch dask scheduler and worker\n",
+ "dask_scheduler = sp.Popen(['dask-scheduler', '--host', 'localhost'])\n",
+ "dask_worker = sp.Popen(['dask-worker', 'tcp://localhost:8786'])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Preprocessing the data\n",
+ "----------------------\n",
+ "\n",
+ "To read the data, we replace\n",
+ "**pd.read_csv** by **dd.read_csv**, which will automatically\n",
+ "read the data in parallel."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import dask.dataframe as dd\n",
+ "raw_data = dd.read_csv('covtype.data', header=None)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Then we preprocess the data using the same code from the example,\n",
+ "except the replacement of **pd.concat** to **dd.concat** only."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\"\"\"\n",
+ "The two categorical features in the dataset are binary-encoded.\n",
+ "We will convert this dataset representation to the typical representation, where each\n",
+ "categorical feature is represented as a single integer value.\n",
+ "\"\"\"\n",
+ "import warnings\n",
+ "warnings.filterwarnings('ignore')\n",
+ "\n",
+ "soil_type_values = [f\"soil_type_{idx+1}\" for idx in range(40)]\n",
+ "wilderness_area_values = [f\"area_type_{idx+1}\" for idx in range(4)]\n",
+ "\n",
+ "soil_type = raw_data.loc[:, 14:53].apply(\n",
+ " lambda x: soil_type_values[0::1][x.to_numpy().nonzero()[0][0]], axis=1\n",
+ ")\n",
+ "wilderness_area = raw_data.loc[:, 10:13].apply(\n",
+ " lambda x: wilderness_area_values[0::1][x.to_numpy().nonzero()[0][0]], axis=1\n",
+ ")\n",
+ "\n",
+ "CSV_HEADER = [\n",
+ " \"Elevation\",\n",
+ " \"Aspect\",\n",
+ " \"Slope\",\n",
+ " \"Horizontal_Distance_To_Hydrology\",\n",
+ " \"Vertical_Distance_To_Hydrology\",\n",
+ " \"Horizontal_Distance_To_Roadways\",\n",
+ " \"Hillshade_9am\",\n",
+ " \"Hillshade_Noon\",\n",
+ " \"Hillshade_3pm\",\n",
+ " \"Horizontal_Distance_To_Fire_Points\",\n",
+ " \"Wilderness_Area\",\n",
+ " \"Soil_Type\",\n",
+ " \"Cover_Type\",\n",
+ "]\n",
+ "\n",
+ "data = dd.concat(\n",
+ " [raw_data.loc[:, 0:9], wilderness_area, soil_type, raw_data.loc[:, 54]],\n",
+ " axis=1,\n",
+ " ignore_index=True,\n",
+ ")\n",
+ "data.columns = CSV_HEADER\n",
+ "\n",
+ "# Convert the target label indices into a range from 0 to 6 (there are 7 labels in total).\n",
+ "data[\"Cover_Type\"] = data[\"Cover_Type\"] - 1"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Finally, instead of saving the preprocessed data into files, we store them in Vineyard.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import vineyard\n",
+ "from vineyard.core.builder import builder_context\n",
+ "from vineyard.contrib.dask.dask import register_dask_types\n",
+ "\n",
+ "with builder_context() as builder:\n",
+ " register_dask_types(builder, None) # register dask builders\n",
+ " gdf_id = client.put(data, dask_scheduler='tcp://localhost:8786')\n",
+ " print(gdf_id)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We saved the preprocessed data as a global dataframe\n",
+ "in Vineyard with the ObjectID above."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Training the model\n",
+ "------------------\n",
+ "\n",
+ "In the single machine solution from the example. A **get_dataset_from_csv** function \n",
+ "is defined to load the dataset from the files of the preprocessed data as follows:\n",
+ "```python\n",
+ "def get_dataset_from_csv(csv_file_path, batch_size, shuffle=False):\n",
+ "\n",
+ " dataset = tf.data.experimental.make_csv_dataset(\n",
+ " csv_file_path,\n",
+ " batch_size=batch_size,\n",
+ " column_names=CSV_HEADER,\n",
+ " column_defaults=COLUMN_DEFAULTS,\n",
+ " label_name=TARGET_FEATURE_NAME,\n",
+ " num_epochs=1,\n",
+ " header=True,\n",
+ " shuffle=shuffle,\n",
+ " )\n",
+ " return dataset.cache()\n",
+ "```\n",
+ "while in the training procedure, it loads the train_dataset and test_dataset\n",
+ "separately from two files as:\n",
+ "```python\n",
+ "def run_experiment(model):\n",
+ "\n",
+ " model.compile(\n",
+ " optimizer=keras.optimizers.Adam(learning_rate=learning_rate),\n",
+ " loss=keras.losses.SparseCategoricalCrossentropy(),\n",
+ " metrics=[keras.metrics.SparseCategoricalAccuracy()],\n",
+ " )\n",
+ "\n",
+ " train_dataset = get_dataset_from_csv(train_data_file, batch_size, shuffle=True)\n",
+ "\n",
+ " test_dataset = get_dataset_from_csv(test_data_file, batch_size)\n",
+ "\n",
+ " print(\"Start training the model...\")\n",
+ " history = model.fit(train_dataset, epochs=num_epochs)\n",
+ " print(\"Model training finished\")\n",
+ "\n",
+ " _, accuracy = model.evaluate(test_dataset, verbose=0)\n",
+ "\n",
+ " print(f\"Test accuracy: {round(accuracy * 100, 2)}%\")\n",
+ "```\n",
+ "In our solution, we provide a function to load dataset from the global dataframe\n",
+ "generated in the last step."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vineyard.core.resolver import resolver_context\n",
+ "from vineyard.contrib.ml.tensorflow import register_tf_types\n",
+ "\n",
+ "def get_dataset_from_vineyard(object_id, batch_size, shuffle=False):\n",
+ " with resolver_context() as resolver:\n",
+ " register_tf_types(None, resolver) # register tf resolvers\n",
+ " ds = vineyard.connect().get(object_id, label=TARGET_FEATURE_NAME) # specify the label column\n",
+ "\n",
+ " if shuffle:\n",
+ " ds = ds.shuffle(len(ds))\n",
+ "\n",
+ " len_test = int(len(ds) * 0.15)\n",
+ " test_dataset = ds.take(len_test).batch(batch_size)\n",
+ " train_dataset = ds.skip(len_test).batch(batch_size)\n",
+ "\n",
+ " return train_dataset, test_dataset"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "And modify the training procedure with a few lines of horovod code."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import horovod.keras as hvd\n",
+ "\n",
+ "def run_experiment(model):\n",
+ "\n",
+ " hvd.init()\n",
+ "\n",
+ " model.compile(\n",
+ " optimizer=hvd.DistributedOptimizer(keras.optimizers.Adam(learning_rate=learning_rate)),\n",
+ " loss=keras.losses.SparseCategoricalCrossentropy(),\n",
+ " metrics=[keras.metrics.SparseCategoricalAccuracy()],\n",
+ " )\n",
+ "\n",
+ " callbacks = [\n",
+ " # Horovod: broadcast initial variable states from rank 0 to all other processes.\n",
+ " # This is necessary to ensure consistent initialization of all workers when\n",
+ " # training is started with random weights or restored from a checkpoint.\n",
+ " hvd.callbacks.BroadcastGlobalVariablesCallback(0),\n",
+ " ]\n",
+ "\n",
+ " train_dataset, test_dataset = get_dataset_from_vineyard(gdf_id, batch_size, shuffle=True)\n",
+ "\n",
+ " print(\"Start training the model...\")\n",
+ " history = model.fit(train_dataset, epochs=num_epochs, callbacks=callbacks)\n",
+ " print(\"Model training finished\")\n",
+ "\n",
+ " _, accuracy = model.evaluate(test_dataset, verbose=0)\n",
+ "\n",
+ " print(f\"Test accuracy: {round(accuracy * 100, 2)}%\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "All the other parts of training procedure are the same as the single machine solution."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "TARGET_FEATURE_NAME = \"Cover_Type\"\n",
+ "\n",
+ "TARGET_FEATURE_LABELS = [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]\n",
+ "\n",
+ "NUMERIC_FEATURE_NAMES = [\n",
+ " \"Aspect\",\n",
+ " \"Elevation\",\n",
+ " \"Hillshade_3pm\",\n",
+ " \"Hillshade_9am\",\n",
+ " \"Hillshade_Noon\",\n",
+ " \"Horizontal_Distance_To_Fire_Points\",\n",
+ " \"Horizontal_Distance_To_Hydrology\",\n",
+ " \"Horizontal_Distance_To_Roadways\",\n",
+ " \"Slope\",\n",
+ " \"Vertical_Distance_To_Hydrology\",\n",
+ "]\n",
+ "\n",
+ "CATEGORICAL_FEATURES_WITH_VOCABULARY = {\n",
+ " \"Soil_Type\": soil_type_values,\n",
+ " \"Wilderness_Area\": wilderness_area_values,\n",
+ "}\n",
+ "\n",
+ "CATEGORICAL_FEATURE_NAMES = list(CATEGORICAL_FEATURES_WITH_VOCABULARY.keys())\n",
+ "\n",
+ "FEATURE_NAMES = NUMERIC_FEATURE_NAMES + CATEGORICAL_FEATURE_NAMES\n",
+ "\n",
+ "NUM_CLASSES = len(TARGET_FEATURE_LABELS)\n",
+ "\n",
+ "learning_rate = 0.001\n",
+ "dropout_rate = 0.1\n",
+ "batch_size = 265\n",
+ "num_epochs = 5\n",
+ "\n",
+ "hidden_units = [32, 32]\n",
+ "\n",
+ "\"\"\"\n",
+ "## Create model inputs\n",
+ "Now, define the inputs for the models as a dictionary, where the key is the feature name,\n",
+ "and the value is a `keras.layers.Input` tensor with the corresponding feature shape\n",
+ "and data type.\n",
+ "\"\"\"\n",
+ "import tensorflow as tf\n",
+ "\n",
+ "def create_model_inputs():\n",
+ " inputs = {}\n",
+ " for feature_name in FEATURE_NAMES:\n",
+ " if feature_name in NUMERIC_FEATURE_NAMES:\n",
+ " inputs[feature_name] = layers.Input(\n",
+ " name=feature_name, shape=(), dtype=tf.float32\n",
+ " )\n",
+ " else:\n",
+ " inputs[feature_name] = layers.Input(\n",
+ " name=feature_name, shape=(), dtype=tf.string\n",
+ " )\n",
+ " return inputs\n",
+ "\n",
+ "\n",
+ "\"\"\"\n",
+ "## Encode features\n",
+ "We create two representations of our input features: sparse and dense:\n",
+ "1. In the **sparse** representation, the categorical features are encoded with one-hot\n",
+ "encoding using the `CategoryEncoding` layer. This representation can be useful for the\n",
+ "model to *memorize* particular feature values to make certain predictions.\n",
+ "2. In the **dense** representation, the categorical features are encoded with\n",
+ "low-dimensional embeddings using the `Embedding` layer. This representation helps\n",
+ "the model to *generalize* well to unseen feature combinations.\n",
+ "\"\"\"\n",
+ "\n",
+ "\n",
+ "from tensorflow.keras.layers import StringLookup\n",
+ "\n",
+ "\n",
+ "def encode_inputs(inputs, use_embedding=False):\n",
+ " encoded_features = []\n",
+ " for feature_name in inputs:\n",
+ " if feature_name in CATEGORICAL_FEATURE_NAMES:\n",
+ " vocabulary = CATEGORICAL_FEATURES_WITH_VOCABULARY[feature_name]\n",
+ " # Create a lookup to convert string values to an integer indices.\n",
+ " # Since we are not using a mask token nor expecting any out of vocabulary\n",
+ " # (oov) token, we set mask_token to None and num_oov_indices to 0.\n",
+ " lookup = StringLookup(\n",
+ " vocabulary=vocabulary,\n",
+ " mask_token=None,\n",
+ " num_oov_indices=0,\n",
+ " output_mode=\"int\" if use_embedding else \"binary\",\n",
+ " )\n",
+ " if use_embedding:\n",
+ " # Convert the string input values into integer indices.\n",
+ " encoded_feature = lookup(inputs[feature_name])\n",
+ " embedding_dims = int(math.sqrt(len(vocabulary)))\n",
+ " # Create an embedding layer with the specified dimensions.\n",
+ " embedding = layers.Embedding(\n",
+ " input_dim=len(vocabulary), output_dim=embedding_dims\n",
+ " )\n",
+ " # Convert the index values to embedding representations.\n",
+ " encoded_feature = embedding(encoded_feature)\n",
+ " else:\n",
+ " # Convert the string input values into a one hot encoding.\n",
+ " encoded_feature = lookup(tf.expand_dims(inputs[feature_name], -1))\n",
+ " else:\n",
+ " # Use the numerical features as-is.\n",
+ " encoded_feature = tf.expand_dims(inputs[feature_name], -1)\n",
+ "\n",
+ " encoded_features.append(encoded_feature)\n",
+ "\n",
+ " all_features = layers.concatenate(encoded_features)\n",
+ " return all_features\n",
+ "\n",
+ "\n",
+ "\"\"\"\n",
+ "## Experiment 1: a baseline model\n",
+ "In the first experiment, let's create a multi-layer feed-forward network,\n",
+ "where the categorical features are one-hot encoded.\n",
+ "\"\"\"\n",
+ "from tensorflow import keras\n",
+ "from tensorflow.keras import layers\n",
+ "\n",
+ "def create_baseline_model():\n",
+ " inputs = create_model_inputs()\n",
+ " features = encode_inputs(inputs)\n",
+ "\n",
+ " for units in hidden_units:\n",
+ " features = layers.Dense(units)(features)\n",
+ " features = layers.BatchNormalization()(features)\n",
+ " features = layers.ReLU()(features)\n",
+ " features = layers.Dropout(dropout_rate)(features)\n",
+ "\n",
+ " outputs = layers.Dense(units=NUM_CLASSES, activation=\"softmax\")(features)\n",
+ " model = keras.Model(inputs=inputs, outputs=outputs)\n",
+ " return model\n",
+ "\n",
+ "\n",
+ "baseline_model = create_baseline_model()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Let's run it:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "run_experiment(baseline_model)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We clear the environments in the end."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dask_worker.terminate()\n",
+ "dask_scheduler.terminate()\n",
+ "\n",
+ "vineyard.shutdown()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Finally, we can use **horovodrun** to run the above code distributedly in a cluster for distributed learning on big datasets."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Conclusion\n",
+ "----------\n",
+ "\n",
+ "From this example, we can see that with the help of Vineyard, users can easily extend\n",
+ "their single machine solutions to distributed learning using dedicated systems without\n",
+ "worrying about the cross-system data sharing issues."
+ ]
+ }
+ ],
+ "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.8.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/tutorials/data-processing/gpu-memory-sharing.html b/tutorials/data-processing/gpu-memory-sharing.html
new file mode 100644
index 0000000000..79b7869ea4
--- /dev/null
+++ b/tutorials/data-processing/gpu-memory-sharing.html
@@ -0,0 +1,605 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sharing GPU Memory - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Sharing GPU Memory
+Vineyard supports sharing both CPU memory and GPU memory between different
+processes and different compute engines. The sharing of GPU memory is archived
+by using the CUDA IPC mechanism
+and provides a flexible unified memory interfaces.
+
+CUDA IPC and Unified Memory
+The CUDA IPC memory handle allows GPU memory to be shared between different
+processes via IPC. In vineyard, the GPU memory is allocated by the vineyardd
+instance when CreateGPUBuffer()
, then an IPC handle is transferred to the
+client process and the GPU memory can be accessed by the client process after
+calling cudaIpcOpenMemHandle()
. For readers, the GPU memory can be accessed
+like a normal CPU shared memory object with GetGPUBuffers()
.
+Like CUDA unified memory ,
+vineyard’s provides a unified memory interface which can be adapted to different
+kinds of implementation (GPU, PPU, etc.) as the abstraction to share GPU memory
+between different processes, as well as sharing memory between the host and
+device.
+The unified memory abstraction is able to automatically synchronize the memory
+between host and devices by leverage the RAII mechanism of C++.
+
+
+Example
+
+
Note
+
The GPU shared memory is still under development and the APIs may change in
+the future.
+
+
+Creating a GPU buffer:
+ObjectID object_id ;
+Payload object ;
+std :: shared_ptr < MutableBuffer > buffer = nullptr ;
+RETURN_ON_ERROR ( client . CreateGPUBuffer ( data_size (), object_id , object , buffer ));
+
+CHECK ( ! buffer -> is_cpu ());
+CHECK ( buffer -> is_mutable ());
+
+
+The result buffer’s data buffer->mutable_data()
is a GPU memory pointer,
+which can be directly passed to GPU kernels, e.g.,
+printKernel <<< 1 , 1 >>> ( buffer -> data ());
+
+
+
+Composing the buffer content from host code like Unified Memory:
+{
+ CUDABufferMirror mirror ( * buffer , false );
+ memcpy ( mirror . mutable_data (), "hello world" , 12 );
+}
+
+
+Here the mirror
’s data()
and mutable_data()
are host memory pointers
+allocated using the cudaHostAlloc()
API. When CUDABufferMirror
destructing,
+the host memory will be copied back to the GPU memory automatically.
+The second argument of CUDABufferMirror
indicates whether the initial memory of the
+GPU buffer needs to be copied to the host memory. Defaults to false
.
+
+Accessing the GPU buffer from another process:
+ObjectID object_id = ...;
+std :: shared_ptr < Buffer > buffer = nullptr ;
+RETURN_ON_ERROR ( client . GetGPUBuffer ( object_id , true , buffer ));
+CHECK ( ! buffer -> is_cpu ());
+CHECK ( ! buffer -> is_mutable ());
+
+
+The result buffer’s data buffer->data()
is a GPU memory pointer, which can be directly
+passed to GPU kernels, e.g.,
+printKernel <<< 1 , 1 >>> ( buffer -> data ());
+
+
+
+Accessing the shared GPU buffer from CPU:
+{
+ CUDABufferMirror mirror ( * buffer , true );
+ printf ( "CPU data from GPU is: %s \n " ,
+ reinterpret_cast < const char *> ( mirror . data ()));
+}
+
+
+Using the CUDABufferMirror
to access the GPU buffer from CPU, the mirror’s data()
+is a host memory pointer allocated using the cudaHostAlloc()
API. For immutable Buffer
,
+the second argument of CUDABufferMirror
must be true
, and the GPU memory will be
+copied to the host memory when the mirror is constructed.
+
+Freeing the shared GPU buffer:
+ObjectID object_id = ...;
+RETURN_ON_ERROR ( client . DelData ( object_id ));
+
+
+
+
+For complete example about GPU memory sharing, please refer to
+gpumalloc_test.cu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/data-processing/python-sharedmemory.html b/tutorials/data-processing/python-sharedmemory.html
new file mode 100644
index 0000000000..7d4a2d79a8
--- /dev/null
+++ b/tutorials/data-processing/python-sharedmemory.html
@@ -0,0 +1,521 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ multiprocessing.shared_memory in Python - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+multiprocessing.shared_memory
in Python
+Vineyard offers a shared memory interface through SharedMemory
and
+ShareableList
classes, ensuring compatibility with Python’s multiprocessing.shared_memory .
+Utilize the shared memory interface as demonstrated below:
+>>> from vineyard import shared_memory
+>>> value = shared_memory . ShareableList ( client , [ b "a" , "bb" , 1234 , 56.78 , True ])
+>>> value
+ShareableList([b'a', 'bb', 1234, 56.78, True], name='o8000000119aa10c0')
+>>> value [ 4 ] = False
+>>> value
+ShareableList([b'a', 'bb', 1234, 56.78, False], name='o8000000119aa10c0')
+
+
+
+
Caution
+
Please be aware that the semantics of Vineyard’s shared_memory
differ slightly
+from those of Python’s multiprocessing module’s shared_memory
. In Vineyard,
+shared memory cannot be modified once it becomes visible to other clients.
+
+We have added a freeze
method to make such transformation happen:
+
+After being frozen, the shared memory (aka. the ShareableList
in this case)
+is available for other clients:
+>>> value1 = shared_memory . ShareableList ( client , name = value . shm . name )
+>>> value1
+ShareableList([b'a', 'bb', 1234, 56.78, False], name='o8000000119aa10c0')
+
+
+For more details, see Shared memory .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/data-processing/using-objects-python.html b/tutorials/data-processing/using-objects-python.html
new file mode 100644
index 0000000000..cc2454f9bb
--- /dev/null
+++ b/tutorials/data-processing/using-objects-python.html
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sharing Python Objects with Vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Sharing Python Objects with Vineyard
+As discussed in Objects , each object in Vineyard consists of two parts:
+
+The data payload, which is stored locally in the corresponding Vineyard instance
+The hierarchical metadata, which is shared across the entire Vineyard cluster
+
+Specifically, a Blob
represents the unit where the data payload resides within a
+Vineyard instance. A blob object holds a segment of memory in the bulk store of the
+Vineyard instance, allowing users to save their local buffer into a blob and later
+retrieve the blob in another process using a zero-copy approach through memory mapping.
+>>> payload = b "Hello, World!"
+>>> blob_id = client . put ( payload )
+>>> blob = client . get_object ( blob_id )
+>>> print ( blob . typename , blob . size , blob )
+
+
+vineyard::Blob 28 Object <"o800000011cfa7040": vineyard::Blob>
+
+
+On the other hand, the hierarchical metadata of Vineyard objects is shared across
+the entire cluster. In the following example, for the sake of simplicity, we
+launch a Vineyard cluster consisting of two Vineyard instances on the same machine.
+However, in real-world scenarios, these Vineyard instances would be distributed
+across multiple machines within the cluster.
+$ python3 -m vineyard --socket /var/run/vineyard.sock1
+$ python3 -m vineyard --socket /var/run/vineyard.sock2
+
+
+With this setup, we can create a distributed pair of arrays in Vineyard, where
+the first array is stored in the first Vineyard instance listening to the IPC socket
+/var/run/vineyard.sock1
, and the second array is stored in the second instance
+listening to the IPC socket /var/run/vineyard.sock2
.
+>>> import numpy as np
+>>> import vineyard
+>>> import vineyard.data.tensor
+
+>>> # build the first array in the first vineyard instance
+>>> client1 = vineyard . connect ( '/var/run/vineyard.sock1' )
+>>> id1 = client1 . put ( np . zeros ( 8 ))
+>>> # persist the object to make it visible to form the global object
+>>> client1 . persist ( id1 )
+
+>>> # build the second array in the second vineyard instance
+>>> client2 = vineyard . connect ( '/var/run/vineyard.sock2' )
+>>> id2 = client2 . put ( np . ones ( 4 ))
+>>> # persist the object to make it visible to form the global object
+>>> client2 . persist ( id2 )
+
+>>> # build the pair from client1
+>>> obj1 = client1 . get_object ( id1 )
+>>> obj2 = client2 . get_object ( id2 )
+>>> id_pair = client1 . put (( obj1 , obj2 ))
+
+>>> # get the pair object from client2
+>>> obj_pair = client2 . get_object ( id_pair )
+>>> print ( obj_pair . first . typename , obj_pair . first . size (), obj_pair . second . size ())
+
+
+
+>>> # get the pair value from client2
+>>> value_pair = client2.get(id_pair)
+>>> print(value_pair)
+
+
+
+In this example, we can access the metadata of the pair object from client2
+even though it was created by client1
. However, we cannot retrieve the payload
+of the first element of the pair from client2
because it is stored locally
+in the first Vineyard instance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/extending.html b/tutorials/extending.html
new file mode 100644
index 0000000000..d0d414de01
--- /dev/null
+++ b/tutorials/extending.html
@@ -0,0 +1,522 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Extending vineyard - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Extending vineyard
+
+
+Vineyard offers a collection of efficient data structures tailored for data-intensive tasks,
+such as tensors, data frames, tables, and graphs. These data types can be easily extended
+to accommodate custom requirements. By registering user-defined types in the vineyard type
+registry, computing engines built on top of vineyard can instantly leverage the advantages
+provided by these custom data structures.
+
+
+
+
+
+
+
Craft builders and resolvers for custom Python data types.
+
+
+
+
+
+
+
+
Implement and register custom data types in C++ for seamless integration with vineyard’s ecosystem.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/extending/define-datatypes-cpp.html b/tutorials/extending/define-datatypes-cpp.html
new file mode 100644
index 0000000000..2dc4f13e73
--- /dev/null
+++ b/tutorials/extending/define-datatypes-cpp.html
@@ -0,0 +1,791 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Defining Custom Data Types in C++ - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Defining Custom Data Types in C++
+Vineyard provides an extensive set of efficient built-in data types in
+its C++ SDK, such as Vector
, HashMap
, Tensor
,
+DataFrame
, Table
, and Graph
(refer to Objects ).
+However, there may be situations where users need to develop their
+own data structures and share the data efficiently with Vineyard. This
+step-by-step tutorial guides you through the process of adding custom
+C++ data types with ease.
+
+
Note
+
This tutorial includes code snippets that could be auto-generated to
+provide a clear understanding of the design internals and to help
+developers grasp the overall functionality of the Vineyard client.
+
+
+Object
and ObjectBuilder
+Vineyard has a base class vineyard::Objects
, and a corresponding
+base class Vineyard::ObjectBuilder
for builders as follows,
+class Object {
+ public :
+ static std :: unique_ptr < Object > Create () {
+ ...
+ }
+
+ virtual void Construct ( const ObjectMeta & meta );
+}
+
+
+and the builder
+class ObjectBuilder {
+ virtual Status Build ( Client & client ) override = 0 ;
+
+ virtual std :: shared_ptr < Object > _Seal ( Client & client ) = 0 ;
+}
+
+
+Where the object is the base class for user-defined data types, and the
+builders is responsible for placing the data into vineyard.
+
+
+Defining Your Custom Type
+Let’s take the example of defining a custom Vector type. Essentially,
+a Vector consists of a vineyard::Blob as its payload, along with
+metadata such as dtype and size .
+The class definition for the Vector type typically appears as follows:
+template < typename T >
+class Vector {
+private :
+ size_t size ;
+ const T * data = nullptr ;
+public :
+ Vector () : size ( 0 ), data ( nullptr ) {
+ }
+
+ Vector ( const int size , const T * data ) : size ( size ), data ( data ) {
+ }
+
+ size_t length () const {
+ return size ;
+ }
+
+ const T & operator []( size_t index ) {
+ assert ( index < size );
+ return data [ index ];
+ }
+};
+
+
+
+
+Registering C++ Types
+First, we need to adapt the existing Vector<T>
to become a Vineyard
+Object
,
+ template <typename T>
+-class Vector {
++class Vector: public vineyard::Registered<Vector<T>> {
+ private:
+ size_t size;
+ T *data = nullptr;
+ public:
++ static std::unique_ptr<Object> Create() __attribute__((used)) {
++ return std::static_pointer_cast<Object>(
++ std::unique_ptr<Vector<T>>{
++ new Vector<T>()});
++ }
++
+ Vector(): size(0), data(nullptr) {
+ }
+
+ Vector(const int size, const T *data): size(size), data(data) {
+ }
+
+ ...
+ }
+
+
+Observe the two key modifications above:
+
+Inheriting from vineyard::Registered<Vector<T>>
:
+vineyard::Registered<T>
serves as a helper to generate static
+initialization stubs, registering the data type T
with the type
+resolving factory and associating the type T
with its typename.
+The typename is an auto-generated, human-readable name for C++ types, e.g.,
+"Vector<int32>"
for Vector<int32_t>
.
+
+Implementing the zero-parameter static constructor Create()
:
+Create()
is a static function registered with the
+resolving factory by the helper vineyard::Registered<T>
. It is
+used to construct an instance of type T
when retrieving objects
+from Vineyard.
+The Vineyard client locates the static constructor using the typename
+found in the metadata of Vineyard objects stored in the daemon server.
+
+
+To retrieve the object Vector<T>
from Vineyard’s metadata, we need to
+implement a Construct method as well. The Construct
method takes
+a vineyard::ObjectMeta
as input and extracts metadata and
+members from it to populate its own data members. The memory in the member
+buffer
(a vineyard::Blob
) is shared using memory mapping,
+eliminating the need for copying.
+ template <typename T>
+ class Vector: public vineyard::Registered<Vector<T>> {
+ public:
+ ...
+
++ void Construct(const ObjectMeta& meta) override {
++ this->size = meta.GetKeyValue<size_t>("size");
++
++ auto buffer = std::dynamic_pointer_cast<Blob>(meta.GetMember("buffer"));
++ this->data = reinterpret_cast<const T *>(buffer->data());
++ }
++
+ ...
+ }
+
+
+
+
+Builder
+Moving on to the builder section, the vineyard::ObjectBuilder
consists of two parts:
+
+Build()
: This method is responsible for storing the blobs of custom data
+structures into Vineyard.
+_Seal()
: This method is responsible for generating the corresponding metadata
+and inserting the metadata into Vineyard.
+
+For our Vector<T>
type, let’s first define a general vector builder:
+template < typename T >
+class VectorBuilder {
+ private :
+ std :: unique_ptr < BlobWriter > buffer_builder ;
+ std :: size_t size ;
+ T * data ;
+
+ public :
+ VectorBuilder ( size_t size ) : size ( size ) {
+ data = static_cast < T *> ( malloc ( sizeof ( T ) * size ));
+ }
+
+ T & operator []( size_t index ) {
+ assert ( index < size );
+ return data [ index ];
+ }
+};
+
+
+The builder allocates the necessary memory based on the specified size
to accommodate
+the elements and provides a [] operator to populate the data.
+Next, we adapt the above builder as a ObjectBuilder in Vineyard,
+ template <typename T>
+-class VectorBuilder {
++class VectorBuilder: public vineyard::ObjectBuilder {
+ private:
+ std::unique_ptr<BlobWriter> buffer_builder;
+ std::size_t size;
+ T *data;
+
+ public:
+ VectorBuilder(size_t size): size(size) {
+ data = static_cast<T *>(malloc(sizeof(T) * size));
+ }
+
++ Status Build(Client& client) override {
++ RETURN_ON_ERROR(client.CreateBlob(size * sizeof(T), buffer_builder));
++ memcpy(buffer_builder->data(), data, size * sizeof(T));
++ return Status::OK();
++ }
++
++ Status _Seal(Client& client, std::shared_ptr<Object> &object) override {
++ RETURN_ON_ERROR(this->Build(client));
++
++ auto vec = std::make_shared<Vector<int>>();
+ object = vec;
++ std::shared_ptr<Object> buffer_object;
++ RETURN_ON_ERROR(this->buffer_builder->Seal(client, buffer_object));
++ auto buffer = std::dynamic_pointer_cast<Blob>(buffer_object);
++ vec->size = size;
++ vec->data = reinterpret_cast<const T *>(buffer->data());
++
++ vec->meta_.SetTypeName(vineyard::type_name<Vector<T>>());
++ vec->meta_.SetNBytes(size * sizeof(T));
++ vec->meta_.AddKeyValue("size", size);
++ vec->meta_.AddMember("buffer", buffer);
++ return client.CreateMetaData(vec->meta_, vec->id_);
++ }
++
+ T& operator[](size_t index) {
+ assert(index < size);
+ return data[index];
+ }
+ };
+
+
+To access private member fields and methods, the builder may need to be
+added as a friend class of the original type declaration.
+
+
Note
+
Since the builder requires direct access to the private data members of
+Vector<T>
, it is necessary to declare the builder as a friend class
+of our vector type,
+
+ template <typename T>
+ class Vector: public vineyard::Registered<Vector<T>> {
+
+ const T& operator[](size_t index) {
+ assert(index < size);
+ return data[index];
+ }
++
++ friend class VectorBuilder<T>;
+ };
+
+
+In the example above, you may notice that the builder and constructor contain numerous
+boilerplate snippets. These can be auto-generated based on the layout of the class
+Vector<T>
through static analysis of the user’s source code, streamlining
+the process and enhancing readability.
+
+
+Utilizing Custom Data Types with Vineyard
+At this point, we have successfully defined our custom data types and integrated them
+with Vineyard. Now, we can demonstrate how to build these custom data types using the
+Vineyard client and retrieve them for further processing.
+int main ( int argc , char ** argv ) {
+ std :: string ipc_socket = std :: string ( argv [ 1 ]);
+
+ Client client ;
+ VINEYARD_CHECK_OK ( client . Connect ( ipc_socket ));
+ LOG ( INFO ) << "Connected to IPCServer: " << ipc_socket ;
+
+ auto builder = VectorBuilder < int > ( 3 );
+ builder [ 0 ] = 1 ;
+ builder [ 1 ] = 2 ;
+ builder [ 2 ] = 3 ;
+ auto result = builder . Seal ( client );
+
+ auto vec = std :: dynamic_pointer_cast < Vector < int >> ( client . GetObject ( result -> id ()));
+ for ( size_t index = 0 ; index < vec -> length (); ++ index ) {
+ std :: cout << "element at " << index << " is: " << ( * vec )[ index ] << std :: endl ;
+ }
+}
+
+
+
+
+Cross-Language Compatibility
+Vineyard maintains consistent design principles across SDKs in various languages,
+such as Java and Python. For an example of Vineyard objects and their builders in
+Python, please refer to Builders and resolvers .
+As demonstrated in the example above, there is a significant amount of boilerplate
+code involved in defining constructors and builders. To simplify the integration
+with Vineyard, we are developing a code generator that will automatically produce
+SDKs in different languages based on a C++-like Domain Specific Language (DSL).
+Stay tuned for updates!
+For a sneak peek at how the code generator works, please refer to array.vineyard-mod
+and arrow.vineyard-mod .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/extending/define-datatypes-python.html b/tutorials/extending/define-datatypes-python.html
new file mode 100644
index 0000000000..7bc5bbd886
--- /dev/null
+++ b/tutorials/extending/define-datatypes-python.html
@@ -0,0 +1,654 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Define Data Types in Python - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Define Data Types in Python
+
+Objects
+As discussed in Objects , each object in vineyard comprises two components:
+
+The data payload, which is stored locally within the corresponding vineyard instance
+The hierarchical meta data, which is shared across the entire vineyard cluster
+
+Specifically, a Blob
represents the unit where the data payload resides in a vineyard
+instance. A blob object contains a segment of memory in the bulk store of the vineyard
+instance, allowing users to save their local buffer into a blob and later retrieve the
+blob in another process using a zero-copy approach through memory mapping.
+>>> payload = b "Hello, World!"
+>>> blob_id = client . put ( payload )
+>>> blob = client . get_object ( blob_id )
+>>> print ( blob . typename , blob . size , blob )
+
+
+vineyard::Blob 28 Object <"o800000011cfa7040": vineyard::Blob>
+
+
+On the other hand, vineyard objects’ hierarchical meta data is shared across the entire
+cluster. In the following example, for the sake of simplicity, we will launch a vineyard
+cluster with two vineyard instances on the same machine. However, in real-world scenarios,
+these vineyard instances would typically be distributed across multiple machines within
+the cluster.
+$ python3 -m vineyard --socket /var/run/vineyard.sock1
+$ python3 -m vineyard --socket /var/run/vineyard.sock2
+
+
+With this setup, we can create a distributed pair of arrays in vineyard, where the first
+array is stored in the first vineyard instance (listening to ipc_socket at /var/run/vineyard.sock1 ),
+and the second array is stored in the second instance (listening to ipc_socket at
+/var/run/vineyard.sock2 ).
+>>> import numpy as np
+>>> import vineyard
+>>> import vineyard.data.tensor
+
+>>> # build the first array in the first vineyard instance
+>>> client1 = vineyard . connect ( '/var/run/vineyard.sock1' )
+>>> id1 = client1 . put ( np . zeros ( 8 ))
+>>> # persist the object to make it visible to form the global object
+>>> client1 . persist ( id1 )
+
+>>> # build the second array in the second vineyard instance
+>>> client2 = vineyard . connect ( '/var/run/vineyard.sock2' )
+>>> id2 = client2 . put ( np . ones ( 4 ))
+>>> # persist the object to make it visible to form the global object
+>>> client2 . persist ( id2 )
+
+>>> # build the pair from client1
+>>> obj1 = client1 . get_object ( id1 )
+>>> obj2 = client2 . get_object ( id2 )
+>>> id_pair = client1 . put (( obj1 , obj2 ))
+
+>>> # get the pair object from client2
+>>> obj_pair = client2 . get_object ( id_pair )
+>>> print ( obj_pair . first . typename , obj_pair . first . size (), obj_pair . second . size ())
+
+
+
+>>> # get the pair value from client2
+>>> value_pair = client2.get(id_pair)
+>>> print(value_pair)
+
+
+
+In this example, we can access the metadata of the pair object from client2 even
+though it was created by client1 . However, we cannot retrieve the payload of the
+first element of the pair from client2 , as it is stored locally within the first
+vineyard instance.
+
+
+Creating Builders and Resolvers
+As demonstrated in Builders and resolvers , vineyard enables users to register
+builders and resolvers for constructing and resolving vineyard objects from/to
+client-side data types based on specific computational requirements.
+For instance, if we use pyarrow
types in our context, we can define the builder and
+resolver for the conversion between vineyard::NumericArray
and pyarrow.NumericArray
+as follows:
+>>> def numeric_array_builder ( client , array , builder ):
+>>> meta = ObjectMeta ()
+>>> meta [ 'typename' ] = 'vineyard::NumericArray< %s >' % array . type
+>>> meta [ 'length_' ] = len ( array )
+>>> meta [ 'null_count_' ] = array . null_count
+>>> meta [ 'offset_' ] = array . offset
+>>>
+>>> null_bitmap = buffer_builder ( client , array . buffers ()[ 0 ], builder )
+>>> buffer = buffer_builder ( client , array . buffers ()[ 1 ], builder )
+>>>
+>>> meta . add_member ( 'buffer_' , buffer )
+>>> meta . add_member ( 'null_bitmap_' , null_bitmap )
+>>> meta [ 'nbytes' ] = array . nbytes
+>>> return client . create_metadata ( meta )
+
+>>> def numeric_array_resolver ( obj ):
+>>> meta = obj . meta
+>>> typename = obj . typename
+>>> value_type = normalize_dtype ( re . match ( r 'vineyard::NumericArray<([^>]+)>' , typename ) . groups ()[ 0 ])
+>>> dtype = pa . from_numpy_dtype ( value_type )
+>>> buffer = as_arrow_buffer ( obj . member ( 'buffer_' ))
+>>> null_bitmap = as_arrow_buffer ( obj . member ( 'null_bitmap_' ))
+>>> length = int ( meta [ 'length_' ])
+>>> null_count = int ( meta [ 'null_count_' ])
+>>> offset = int ( meta [ 'offset_' ])
+>>> return pa . lib . Array . from_buffers ( dtype , length , [ null_bitmap , buffer ], null_count , offset )
+
+
+Finally, we register the builder and resolver for automatic building and resolving:
+.. code:: python
+>>> builder_ctx . register ( pa . NumericArray , numeric_array_builder )
+>>> resolver_ctx . register ( 'vineyard::NumericArray' , numeric_array_resolver )
+
+
+In some cases, we may have multiple resolvers or builders for a specific type.
+For instance, the vineyard::Tensor object can be resolved as either numpy.ndarray or
+xgboost::DMatrix . To accommodate this, we could have:
+>>> resolver_ctx . register ( 'vineyard::Tensor' , numpy_resolver )
+>>> resolver_ctx . register ( 'vineyard::Tensor' , xgboost_resolver )
+
+
+This flexibility enables seamless integration with various libraries and frameworks by
+effectively handling different data types and their corresponding resolvers or builders.
+def xgboost_resolver ( obj ):
+ ...
+
+default_resolver_context . register ( 'vineyard::Tensor' , xgboost_resolver )
+
+
+at the same time. The stackable resolver_context
could help there,
+with resolver_context ({ 'vineyard::Tensor' , xgboost_resolver }):
+ ...
+
+
+Assuming the default context resolves vineyard::Tensor to numpy.ndarray , the
+with resolver_context allows for temporary resolution of vineyard::Tensor to
+xgboost::DMatrix . Upon exiting the context, the global environment reverts to
+its default state.
+The with resolver_context can be nested for additional flexibility.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/kubernetes.html b/tutorials/kubernetes.html
new file mode 100644
index 0000000000..479f0acff0
--- /dev/null
+++ b/tutorials/kubernetes.html
@@ -0,0 +1,522 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vineyard on Kubernetes - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Vineyard on Kubernetes
+
+
+Vineyard can be seamlessly deployed on Kubernetes, managed by the Vineyard Operator ,
+to enhance big-data workflows through its data-aware scheduling policy. This policy
+orchestrates shared objects and routes jobs to where their input data resides. In the
+following tutorials, you will learn how to deploy Vineyard and effectively integrate it
+with Kubernetes.
+
+
+
+
+
+
+
The Vineyard operator serves as the central component for seamless integration with Kubernetes.
+
+
+
+
+
+
+
+
Vineyard functions as an efficient intermediate data storage solution for machine learning pipelines on Kubernetes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes.html b/tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes.html
new file mode 100644
index 0000000000..c1242267b8
--- /dev/null
+++ b/tutorials/kubernetes/data-sharing-with-vineyard-on-kubernetes.html
@@ -0,0 +1,751 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Data sharing with Vineyard on Kubernetes - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Data sharing with Vineyard on Kubernetes
+If you want to share data between different workloads(pods or containers) on kubernetes, it’s a good idea to
+use vineyard as the data-sharing service. In this tutorial, we will show you how to
+share data between different containers or pods on kubernetes step by step.
+
+
+
+Data sharing between containers
+
+
+From the above figure, the vineyardctl inject command will inject vineyard container into the app pod and
+the app containers will connect to the vineyard container to share the vineyard data.
+
+
+
+Data sharing on the vineyard deployment
+
+
+From the above figure, the vineyardctl deploy vineyard-deployment command will deploy a vineyard deployment
+on the kubernetes cluster (default is 3 replicas) and the app pods will be scheduled to the vineyard deployment
+to share the vineyard data via the command vineyardctl schedule workload .
+
+
+Data sharing between different containers
+In this section, we will show you how to share data between different containers on kubernetes.
+Assuming you have a pod with two containers, one is a producer and the other is a consumer.
+The producer will generate some data and write it to vineyard, and the consumer will read the data
+from vineyard and do some computation.
+Save the following yaml as pod.yaml .
+$ cat << EOF >> pod.yaml
+apiVersion : v1
+kind : Pod
+metadata :
+ name : vineyard-producer-consumer
+ namespace : vineyard-test
+spec :
+ containers :
+ - name : producer
+ image : python:3.10
+ command :
+ - bash
+ - -c
+ - |
+ pip install vineyard numpy pandas;
+ cat << EOF >> producer.py
+ import vineyard;
+ import numpy as np;
+ import pandas as pd;
+ client = vineyard.connect();
+ # put a pandas dataframe to vineyard
+ client.put(pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')), persist=True, name="test_dataframe");
+ # put a basic data unit to vineyard
+ client.put((1, 1.2345, 'xxxxabcd'), persist=True, name="test_basic_data_unit");
+ client.close()
+ EOF
+ python producer.py;
+ sleep infinity;
+ - name : consumer
+ image : python:3.10
+ command :
+ - bash
+ - -c
+ - |
+ # wait for the producer to finish
+ sleep 10;
+ pip install vineyard numpy pandas;
+ cat << EOF >> consumer.py
+ import vineyard;
+ client = vineyard.connect();
+ # get the pandas dataframe from vineyard
+ print(client.get(name="test_dataframe").sum())
+ # get the basic data unit from vineyard
+ print(client.get(name="test_basic_data_unit"))
+ client.close()
+ EOF
+ python consumer.py;
+ sleep infinity;
+EOF
+
+
+Use the vineyardctl to inject vineyard into the pod and apply them to the kubernetes cluster
+as follows.
+# create the namespace
+$ kubectl create ns vineyard-test
+# get all injected resources
+$ python3 -m vineyard.ctl inject -f pod.yaml | kubectl apply -f -
+pod/vineyard-sidecar-etcd-0 created
+service/vineyard-sidecar-etcd-0 created
+service/vineyard-sidecar-etcd-service created
+service/vineyard-sidecar-rpc created
+pod/vineyard-producer-consumer created
+
+
+Then you can get the logs of the consumer containers as follows.
+# get the logs of the consumer container
+$ kubectl logs -f vineyard-producer-consumer -n test -c consumer
+A -30.168469
+B -19.269489
+C 6 .332533
+D -9.714950
+dtype: float64
+( 1 , 1 .2345000505447388, 'xxxxabcd' )
+
+
+
+
+Data sharing between different pods
+In this section, we will show you how to share data between different workloads on kubernetes.
+You are supposed to create a vineyard deployment and then deploy the application pods on
+the nodes where the vineyard deployment is running.
+Deploy the vineyard deployment (default is 3 replicas) as follows.
+# create the namespace if not exists
+$ kubectl create ns vineyard-test
+# create the vineyard deployment
+$ python3 -m vineyard.ctl deploy vineyard-deployment --name vineyardd-sample -n vineyard-test
+2023 -07-21T15:42:25.981+0800 INFO vineyard cluster deployed successfully
+
+
+Check the vineyard deployment status and the three vineyardd pods should run on the different nodes.
+# check the pods status
+$ kubectl get pod -lapp.vineyard.io/name= vineyardd-sample -n vineyard-test -owide
+NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
+vineyardd-sample-5fd45fdd66-fq55z 1 /1 Running 0 3m37s 10 .244.1.17 kind-worker3 <none> <none>
+vineyardd-sample-5fd45fdd66-qjr5c 1 /1 Running 0 3m37s 10 .244.3.35 kind-worker <none> <none>
+vineyardd-sample-5fd45fdd66-ssqb7 1 /1 Running 0 3m37s 10 .244.2.29 kind-worker2 <none> <none>
+vineyardd-sample-etcd-0 1 /1 Running 0 3m53s 10 .244.1.16 kind-worker3 <none> <none>
+
+
+Assume we have two pods, one is a producer and the other is a consumer.
+The producer yaml file is as follows.
+ $ cat << EOF >> producer.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: producer
+ namespace: vineyard-test
+spec:
+ selector:
+ matchLabels:
+ app: producer
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: producer
+ spec:
+ containers:
+ - name: producer
+ image: python:3.10
+ command:
+ - bash
+ - -c
+ - |
+ pip install vineyard numpy pandas;
+ cat << EOF >> producer.py
+ import vineyard
+ import numpy as np
+ import pandas as pd
+ client = vineyard.connect()
+ client.put( pd.DataFrame( np.random.randn( 100 , 4 ) , columns = list( 'ABCD' )) , persist = True, name = "test_dataframe" )
+ client.put(( 1 , 1 .2345, 'xxxxabcd' ) , persist = True, name = "test_basic_data_unit" ) ;
+ client.close()
+ EOF
+ python producer.py;
+ sleep infinity;
+EOF
+
+
+The consumer yaml file is as follows.
+ $ cat << EOF >> consumer.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: consumer
+ namespace: vineyard-test
+spec:
+ selector:
+ matchLabels:
+ app: consumer
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: consumer
+ spec:
+ containers:
+ - name: consumer
+ image: python:3.10
+ command:
+ - bash
+ - -c
+ - |
+ pip install vineyard numpy pandas;
+ cat << EOF >> consumer.py
+ import vineyard
+ client = vineyard.connect()
+ dataframe_obj = client.get_name( "test_dataframe" )
+ print( client.get( dataframe_obj,fetch= True) .sum())
+ unit_obj = client.get_name( "test_basic_data_unit" )
+ print( client.get( unit_obj,fetch= True))
+ client.close()
+ EOF
+ python consumer.py;
+ sleep infinity;
+EOF
+
+
+Use the vineyardctl to schedule the two workloads on the vineyard cluster.
+# schedule the producer workload to the vineyard cluster and apply it to the kubernetes cluster
+$ python3 -m vineyard.ctl schedule workload -f producer.yaml --vineyardd-name vineyardd-sample \
+--vineyardd-namespace vineyard-test -o yaml | kubectl apply -f -
+deployment.apps/producer created
+
+# schedule the consumer workload to the vineyard cluster and apply it to the kubernetes cluster
+$ python3 -m vineyard.ctl schedule workload -f consumer.yaml --vineyardd-name vineyardd-sample \
+--vineyardd-namespace vineyard-test -o yaml | kubectl apply -f -
+deployment.apps/consumer created
+
+
+Check the logs of the consumer pods as follows.
+ $ kubectl logs -f $( kubectl get pod -lapp= consumer -n vineyard-test -o jsonpath = '{.items[0].metadata.name}' ) -n vineyard-test
+A 11 .587912
+B 12 .059792
+C 4 .863514
+D -2.682567
+dtype: float64
+( 1 , 1 .2345000505447388, 'xxxxabcd' )
+
+
+From the above example, we can see the code of the consumer is quiet different from the previous sidecar example.
+As the consumer may be scheduled to different node from the producer with the default kubernetes scheduler, the client
+should get the remote object id by name and then fetch it from other vineyard nodes. For more details, please refer to
+the vineyard objects .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.html b/tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.html
new file mode 100644
index 0000000000..239a71190c
--- /dev/null
+++ b/tutorials/kubernetes/efficient-data-sharing-in-kubeflow-with-vineyard-csi-driver.html
@@ -0,0 +1,1152 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Efficient data sharing in Kubeflow with Vineyard CSI Driver - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Efficient data sharing in Kubeflow with Vineyard CSI Driver
+If you are using Kubeflow Pipeline or Argo Workflow to manage your machine learning workflow,
+you may find that the data saving/loading to the volumes is slow.
+To speed up the data saving/loading within these volumes, we design the Vineyard CSI Driver to
+map each vineyard object to a volume, and the data saving/loading is handled by vineyard.
+Next, we will show you how to use the Vineyard CSI Driver to speed up a kubeflow pipeline.
+
+Prerequisites
+
+A kubernetes cluster with version >= 1.25.10. If you don’t have one by hand, you can refer to the guide Initialize Kubernetes Cluster to create one.
+Install the Vineyardctl by following the official guide.
+Install the argo workflow cli >= 3.4.8.
+Install the kfp package <= 1.8.0 for kubeflow v1 or >= 2.0.1 for kubeflow v2 .
+
+
+
+Deploy the Vineyard Cluster
+ $ python3 -m vineyard.ctl deploy vineyard-cluster --create-namespace
+
+
+This command will create a vineyard cluster in the namespace vineyard-system .
+You can check as follows:
+ $ kubectl get pod -n vineyard-system
+NAME READY STATUS RESTARTS AGE
+vineyard-controller-manager-648fc9b7bf-zwnhd 2 /2 Running 0 4d3h
+vineyardd-sample-79c8ffb879-6k8mk 1 /1 Running 0 4d3h
+vineyardd-sample-79c8ffb879-f9kkr 1 /1 Running 0 4d3h
+vineyardd-sample-79c8ffb879-lzgwz 1 /1 Running 0 4d3h
+vineyardd-sample-etcd-0 1 /1 Running 0 4d3h
+
+
+
+
+Deploy the Vineyard CSI Driver
+Before deploying the Vineyard CSI Driver, you are supposed to check the vineyard
+deployment is ready as follows:
+ $ kubectl get deployment -n vineyard-system
+NAME READY UP-TO-DATE AVAILABLE AGE
+vineyard-controller-manager 1 /1 1 1 4d3h
+vineyardd-sample 3 /3 3 3 4d3h
+
+
+Then deploy the vineyard csi driver which specifies the vineyard cluster to use:
+
+
Tip
+
If you want to look into the debug logs of the vineyard csi driver, you can add a
+flag --verbose
in the following command.
+
+ $ python3 -m vineyard.ctl deploy csidriver --clusters vineyard-system/vineyardd-sample
+
+
+Then check the status of the Vineyard CSI Driver:
+ $ kubectl get pod -n vineyard-system
+NAME READY STATUS RESTARTS AGE
+vineyard-controller-manager-648fc9b7bf-zwnhd 2 /2 Running 0 4d3h
+vineyard-csi-sample-csi-driver-fb7cb5b5d-nlrxs 4 /4 Running 0 4m23s
+vineyard-csi-sample-csi-nodes-69j77 3 /3 Running 0 4m23s
+vineyard-csi-sample-csi-nodes-k85hb 3 /3 Running 0 4m23s
+vineyard-csi-sample-csi-nodes-zhfz4 3 /3 Running 0 4m23s
+vineyardd-sample-79c8ffb879-6k8mk 1 /1 Running 0 4d3h
+vineyardd-sample-79c8ffb879-f9kkr 1 /1 Running 0 4d3h
+vineyardd-sample-79c8ffb879-lzgwz 1 /1 Running 0 4d3h
+vineyardd-sample-etcd-0 1 /1 Running 0 4d3h
+
+
+
+
+Running the Kubeflow Pipeline example
+We provide two examples using different versions of Kubeflow Pipeline: v1 and v2 .
+To use the Vineyard CSI Driver, we need to do two modifications:
+
+Change APIs like pd.read_pickle/write_pickle to vineyard.csi.write/read in the source code.
+
+2. Add the vineyard object
VolumeOp to the pipeline’s dependencies. The path in the API changed
+in the first step will be mapped to a volume. Notice, the volume used in any task needs to be
+explicitly mounted to the corresponding path in the source code, and the storageclass_name
+format of each VolumeOp is {vineyard-deployment-namespace}.{vineyard-deployment-name}.csi
.
+There are two ways to add the vineyard object
VolumeOp to the pipeline’s dependencies:
+
+Each path in the source code is mapped to a volume, and each volume is mounted to the actual path
+in the source code. The benefit is that the source path does not need to be modified.
+Create a volume for the paths with the same prefix in the source code. You can add the prefix /vineyard
for
+the paths in the source code, and mount a volume to the path /vineyard
. In this way, you can
+only create one volume for multiple paths/vineyard objects.
+
+You may get some insights from the modified pipeline pipeline-with-vineyard.py
and pipeline-kfp-v2-with-vineyard
.
+
+Preparations
+Before running the kubflow examples, we need to do some common preparations, and then
+you can choose to run KFP V1 or KFP V2 example.
+
+First of all, we need to build the docker images for the pipeline:
+
+ $ cd k8s/examples/vineyard-csidriver
+$ make docker-build
+
+
+Or build the docker images with your docker registry:
+ $ make docker-build REGISTRY = <your-docker-registry>
+
+
+
+Check the images built successfully:
+
+ $ docker images
+train-data latest 5628953ffe08 14 seconds ago 1 .47GB
+test-data latest 94c8c75b960a 14 seconds ago 1 .47GB
+prepare-data latest 5aab1b120261 15 seconds ago 1 .47GB
+preprocess-data latest 5246d09e6f5e 15 seconds ago 1 .47GB
+
+
+
+Push the image to a docker registry that your kubernetes cluster can access.
+
+ $ make push-images REGISTRY = <your-docker-registry>
+
+
+
+Create the namespace for the pipeline:
+
+ $ kubectl create namespace kubeflow
+
+
+5. To simulate the data loading/saving of the actual pipeline, we use the nfs volume
+to store the data. The nfs volume is mounted to the /mnt/data
directory of the
+kind cluster. Then apply the data volume as follows:
+
+
Tip
+
If you already have nfs volume that can be accessed by the kubernetes cluster,
+you can update the prepare-data.yaml
to use your nfs volume.
+
+ $ kubectl apply -f prepare-data.yaml
+
+
+
+Deploy the rbac for the pipeline:
+
+ $ kubectl apply -f rbac.yaml
+
+
+
+(important) Download all need images to all kind workers:
+
+registry = "ghcr.io/v6d-io/v6d/kubeflow-example"
+kubeflow_registry = "gcr.io/ml-pipeline"
+worker =( $( docker ps | grep kind-worker | awk -F ' ' '{print $1}' ) )
+for c in ${ worker [@] } ; do
+ docker exec -it $c sh -c "
+ crictl pull ${ registry } /preprocess-data && \
+ crictl pull ${ registry } /train-data && \
+ crictl pull ${ registry } /test-data &&\
+ # change the following image to compatible with the installed kubeflow version
+ crictl pull ${ kubeflow_registry } /argoexec:v3.3.10-license-compliance && \
+ crictl pull ${ kubeflow_registry } /kfp-driver@sha256:0ce9bf20ac9cbb21e84ff0762d5ae508d21e9c85fde2b14b51363bd1b8cd7528
+ # change the following image to compatible with the installed argo workflow version
+ crictl pull quay.io/argoproj/argoexec:v3.4.8
+ "
+done
+
+
+
+
+Running KFP V1 Example
+
+
Tip
+
If you want to run the KFP V2 example, you can skip this section.
+
+The original KFP V1 code is shown in pipeline.py
under the directory k8s/examples/vineyard-csidriver
and the
+pipeline-with-vineyard.py
is modified to be compatible with the Vineyard CSI Driver. As we use the argo workflow to
+run the KFP v1 pipeline, we need to install the argo workflow server as follows.
+
+Install the argo server on Kubernetes:
+
+ $ kubectl create namespace argo
+$ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.4.8/install.yaml
+
+
+
+Check the status of the argo server:
+
+ $ kubectl get pod -n argo
+NAME READY STATUS RESTARTS AGE
+argo-server-7698c96655-ft6sj 1 /1 Running 0 4d1h
+workflow-controller-b888f4458-sfrjd 1 /1 Running 0 4d1h
+
+
+
+Submit the kubeflow example without vineyard to the argo server:
+
+ $ for data_multiplier in 4000 5000 6000 ; do \
+ # clean the previous argo workflow
+ argo delete --all -n kubeflow; \
+ # submit the pipeline without vineyard
+ argo submit --watch pipeline.yaml -n kubeflow \
+ -p data_multiplier = ${ data_multiplier } -p registry = "ghcr.io/v6d-io/v6d/kubeflow-example" ; \
+ # sleep 60s to record the actual execution time
+ sleep 60 ; \
+done
+
+
+
+Clear the previous resources:
+
+ $ argo delete --all -n kubeflow
+
+
+
+Submit the kubeflow example with vineyard to the argo server:
+
+ $ for data_multiplier in 3000 4000 5000 ; do \
+ # clean the previous argo workflow
+ argo delete --all -n kubeflow; \
+ # submit the pipeline without vineyard
+ argo submit --watch pipeline-with-vineyard.yaml -n kubeflow \
+ -p data_multiplier = ${ data_multiplier } -p registry = "ghcr.io/v6d-io/v6d/kubeflow-example" ; \
+ # sleep 60s to record the actual execution time
+ sleep 60 ; \
+done
+
+
+
+
+Running KFP V2 Example
+
+
Tip
+
If you have installed the argo workflow server, you need to delete it first. As the KFP resources
+contain the argo workflow server, and the argo workflow server will conflict with the KFP resources.
+
+The original KFP V2 code is shown in pipeline-kfp-v2.py
under the directory k8s/examples/vineyard-csidriver
and the
+pipeline-kfp-v2-with-vineyard.py
is modified to be compatible with the Vineyard CSI Driver. As it can only be compiled to
+the IR YAML, which only recognized by the kubeflow server. Thus, we need to install the kubeflow server as follows.
+
+Install a KFP standalone instance on Kubernetes:
+
+export PIPELINE_VERSION = 2 .0.1
+
+kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/cluster-scoped-resources?ref= $PIPELINE_VERSION "
+kubectl wait --for condition = established --timeout= 60s crd/applications.app.k8s.io
+kubectl apply -k "github.com/kubeflow/pipelines/manifests/kustomize/env/dev?ref= $PIPELINE_VERSION "
+
+
+
+Check the status of the KFP instance:
+
+ $ kubectl get pod -n kubeflow
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+cache-deployer-deployment-5c95fc7fdd-d65cf 1 /1 Running 0 49m
+cache-server-6c84679764-k8q6j 1 /1 Running 0 49m
+controller-manager-86bf69dc54-2brxq 1 /1 Running 0 49m
+metadata-envoy-deployment-6448d544f5-z4sc8 1 /1 Running 0 49m
+metadata-grpc-deployment-784b8b5fb4-8mtm7 1 /1 Running 2 ( 49m ago) 49m
+metadata-writer-79c5499dd8-6jjmm 1 /1 Running 0 49m
+minio-65dff76b66-tdtx5 1 /1 Running 0 49m
+ml-pipeline-6546dcc959-k8t84 1 /1 Running 0 48m
+ml-pipeline-persistenceagent-79479cdb74-q6lq9 1 /1 Running 0 49m
+ml-pipeline-scheduledworkflow-5cbdc7d885-lx9r7 1 /1 Running 0 49m
+ml-pipeline-ui-7c94d6f4b7-z2tvs 1 /1 Running 0 49m
+ml-pipeline-viewer-crd-685f449686-bz55g 1 /1 Running 0 49m
+ml-pipeline-visualizationserver-7c8f97864d-sp8p6 1 /1 Running 0 49m
+mysql-c999c6c8-nwp9d 1 /1 Running 0 49m
+proxy-agent-77d7b57c99-plrpb 0 /1 CrashLoopBackOff 14 ( 2m17s ago) 49m
+workflow-controller-6c85bc4f95-dw889 1 /1 Running 0 49m
+
+
+
+
+
+Delete the proxy deployment as it’s not used in the example and will slow down the pipeline:
+
+ $ kubectl delete deployment proxy-agent -n kubeflow
+
+
+
+Open a terminal to portforward the KFP UI to your local machine:
+
+ $ kubectl port-forward -n kubeflow svc/ml-pipeline-ui 8088 :80
+
+
+
+Upload the pipeline-kfp-v2.yaml
and pipeline-kfp-v2-with-vineyard.yaml
to the KFP instance:
+
+
+
Tip
+
If you use the custom docker registry, you need to update the docker image
+in the pipeline-kfp-v2.yaml
and pipeline-kfp-v2-with-vineyard.yaml
.
+
+
+
+
+Upload pipeline in the kubeflow Dashboard
+
+
+
+(Important) Clean the file system cache of the kubeflow server.
+
+As the KFP V2 doesn’t support to configure the SecurityContext
of the container, which means
+we can’t run the command sync; echo 3 > /proc/sys/vm/drop_caches
in the container to clean the
+file system cache. Thus before creating a new run, we need to clean the file system cache manually
+as follows:
+# clean all the file system cache and image cache of all kind workers
+$ worker =( $( docker ps | grep kind-worker | awk -F ' ' '{print $1}' ) ) ; \
+ for c in ${ worker [@] } ; do docker exec --privileged -it $c \
+ sh -c 'sync && echo 3 > /proc/sys/vm/drop_caches' ; done ;
+
+
+If you use the actual kubernetes cluster, you can login to the kubernetes node and clean the file
+system cache manually.
+
+Create the runs using the previously uploaded pipelines:
+
+
+
+
+Create runs in the kubeflow Dashboard
+
+
+
+
+KFP V1 Result Analysis
+The data scale are 14000 Mi, 18000 Mi and 21000 Mi, which correspond to
+the 4000, 5000 and 6000 in the previous data_multiplier respectively,
+and the time of argo workflow execution of the pipeline is as follows:
+
+Argo workflow duration
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+14000 Mi
+317s
+270s
+
+18000 Mi
+403s
+331s
+
+21000 Mi
+504s
+389s
+
+
+
+
+Actually, the cost time of argo workflow is affected by lots of factors,
+such as the network, the cpu and memory of the cluster, the data volume, etc.
+So the time of argo workflow execution of the pipeline is not stable.
+But we can still find that the time of argo workflow execution of the pipeline
+with vineyard reduced by 15%~25%.
+Also, we record the whole execution time via logs. The result is as follows:
+
+
+Actual execution time
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+14000 Mi
+215.1s
+140.3s
+
+18000 Mi
+298.2s
+198.1s
+
+21000 Mi
+398.7s
+257.5s
+
+
+
+
+According to the above results, we can find that the time of actual
+execution of the pipeline with vineyard reduced by 30%~40%. To be specific,
+we record the write/read time of the following steps:
+
+
+Writing time
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+14000 Mi
+33.2s
+8.8s
+
+18000 Mi
+40.8s
+11.6s
+
+21000 Mi
+48.6s
+13.9s
+
+
+
+
+From the above results, we can find that the writing time the pipeline
+with vineyard reduced by 70%~75%. The reason is that the data is stored
+in the vineyard cluster, so it’s actually a memory copy operation, which
+is faster than the write operation of the nfs volume.
+
+
+Reading time
+We delete the time of init data loading, and the results are as follows:
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+14000 Mi
+56.6s
+0.02s
+
+18000 Mi
+76.3s
+0.02s
+
+21000 Mi
+93.7s
+0.02s
+
+
+
+
+Based on the above results, we can find that the read time of vineyard is
+nearly a constant, which is not affected by the data scale.
+The reason is that the data is stored in the shared memory of vineyard cluster,
+so it’s actually a pointer copy operation.
+As a result, we can find that with vineyard, the argo workflow
+duration of the pipeline is reduced by 15%~25% and the actual
+execution time of the pipeline is reduced by about 30%~40%.
+
+
+
+KFP V2 Result Analysis
+Different with the previous KFP V1, the KFP V2 will compile the pipeline to the IR YAML,
+and the IR YAML will be submitted to the kubeflow server. Before each component of the
+pipeline is executed, the kubeflow server will create a preprocess container to parse
+the IR YAML and generate the relevant kubernetes resources. That means the kubeflow server
+will create more pods than the previous argo workflow, thereby slowing down the execution
+speed of the entire pipeline.
+The execution time of the pipeline shown in the kubeflow dashboard is as follows:
+
+Kubeflow dashboard duration
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+14000 Mi
+276s
+229s
+
+18000 Mi
+365s
+291s
+
+21000 Mi
+440s
+352s
+
+
+
+
+Based on the above result, we can find that the execution time of kubeflow pipeline with vineyard
+is reduced by 15%~20% on the dashboard. Compared to the kfp v1, the vineyard effect is slightly
+reduced. The reason is that in the kfp v2, CreateVolume and DeleteVolume are regarded as two components,
+and that means more worker pods will be created. The time to create these pods is the main factor
+that reduces vineyard efficiency.
+
+
+Actual execution time
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+14000 Mi
+213s
+133.4s
+
+18000 Mi
+302.7s
+208.1s
+
+21000 Mi
+377.6s
+265.9s
+
+
+
+
+From the above results, we can find that the actual execution time of the pipeline with vineyard
+is reduced by 30%~40%. To be specific, we record the write/read time of the following steps:
+
+
+Writing time
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+14000 Mi
+33.2s
+8.1s
+
+18000 Mi
+41s
+10.8s
+
+21000 Mi
+48.3s
+13.7s
+
+
+
+
+Similarly, since writing to vineyard is just a memory copy operation, its execution time
+will be greatly reduced.
+
+
+Reading time
+We delete the time of init data loading, and the results are as follows:
+
+
+
+data scale
+without vineyard
+with vineyard
+
+
+
+8500 Mi
+54.5s
+0.04s
+
+12000 Mi
+73.5s
+0.02s
+
+15000 Mi
+88.9s
+0.02s
+
+
+
+
+As the result in kfp v1, reading the vineyard data only requires a
+single operation to get the memory pointer. So the reading time of
+vineyard is almost 0.
+In summary, regardless of whether you are using KFP V1 or KFP V2, and whether the backend
+is Argo server or Kubeflow manifests, integrating Vineyard can effectively optimize the data
+sharing among Kubeflow components. This optimization, in turn, leads to a significant reduction
+in the overall execution time of the Kubeflow pipeline.
+
+
+
+
+Clean up
+Delete the rbac for the kubeflow example:
+ $ kubectl delete -f rbac.yaml
+
+
+Delete all argo workflow
+
+Delete the argo server:
+ $ kubectl delete ns argo
+
+
+Delete the vineyard cluster:
+ $ python3 -m vineyard.ctl delete vineyard-cluster
+
+
+Delete the data volume:
+ $ kubectl delete -f prepare-data.yaml
+
+
+Delete the kubeflow namespace:
+ $ kubectl delete ns kubeflow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/kubernetes/ml-pipeline-mars-pytorch.html b/tutorials/kubernetes/ml-pipeline-mars-pytorch.html
new file mode 100644
index 0000000000..3608bf1509
--- /dev/null
+++ b/tutorials/kubernetes/ml-pipeline-mars-pytorch.html
@@ -0,0 +1,679 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Machine learning with Vineyard on Kubernetes - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Machine learning with Vineyard on Kubernetes
+In this demonstration, we will build a fraudulent transaction classifier for
+fraudulent transaction data. The process consists of the following
+three main steps:
+
+prepare-data
: Utilize Vineyard to read and store data in a distributed manner.
+process-data
: Employ Mars to process the data across multiple nodes.
+train-data
: Use Pytorch to train the model on the distributed data.
+
+We have three tables: user table, product table, and transaction table.
+The user and product tables primarily contain user and product IDs, along with
+their respective Feature
vectors. Each record in the transaction table indicates
+a user purchasing a product, with a Fraud
label identifying whether the
+transaction is fraudulent. Additional features related to these transactions are also
+stored in the transaction table. You can find the three tables in the dataset repo .
+Follow the steps below to reproduce the demonstration. First, create a vineyard cluster
+with 3 worker nodes.
+ $ cd k8s && make -C k8s/test/e2e install-vineyard-cluster
+
+
+
+
Expected output
+
+ the kubeconfig path is /tmp/e2e-k8s.config
+Creating the kind cluster with local registry
+a16c878c5091c1e5c9eff0a1fca065665f47edb4c8c75408b3d33e22f0ec0d05
+Creating cluster "kind" ...
+✓ Ensuring node image ( kindest/node:v1.24.0) 🖼
+✓ Preparing nodes 📦 📦 📦 📦
+✓ Writing configuration 📜
+✓ Starting control-plane 🕹️
+✓ Installing CNI 🔌
+✓ Installing StorageClass 💾
+✓ Joining worker nodes 🚜
+Set kubectl context to "kind-kind"
+You can now use your cluster with:
+
+kubectl cluster-info --context kind-kind --kubeconfig /tmp/e2e-k8s.config
+
+Thanks for using kind! 😊
+configmap/local-registry-hosting created
+Installing vineyard-operator...
+The push refers to repository [ localhost:5001/vineyard-operator]
+c3a672704524: Pushed
+b14a7037d2e7: Pushed
+8d7366c22fd8: Pushed
+latest: digest: sha256:ea06c833351f19c5db28163406c55e2108676c27fdafea7652500c55ce333b9d size: 946
+make[ 1 ] : Entering directory '/opt/caoye/v6d/k8s'
+go: creating new go.mod: module tmp
+/home/gsbot/go/bin/controller-gen rbac:roleName= manager-role crd:maxDescLen= 0 webhook paths = "./..." output:crd:artifacts:config= config/crd/bases
+cd config/manager && /usr/local/bin/kustomize edit set image controller = localhost:5001/vineyard-operator:latest
+/usr/local/bin/kustomize build config/default | kubectl apply -f -
+namespace/vineyard-system created
+customresourcedefinition.apiextensions.k8s.io/backups.k8s.v6d.io created
+customresourcedefinition.apiextensions.k8s.io/globalobjects.k8s.v6d.io created
+customresourcedefinition.apiextensions.k8s.io/localobjects.k8s.v6d.io created
+customresourcedefinition.apiextensions.k8s.io/operations.k8s.v6d.io created
+customresourcedefinition.apiextensions.k8s.io/recovers.k8s.v6d.io created
+customresourcedefinition.apiextensions.k8s.io/sidecars.k8s.v6d.io created
+customresourcedefinition.apiextensions.k8s.io/vineyardds.k8s.v6d.io created
+serviceaccount/vineyard-manager created
+role.rbac.authorization.k8s.io/vineyard-leader-election-role created
+clusterrole.rbac.authorization.k8s.io/vineyard-manager-role created
+clusterrole.rbac.authorization.k8s.io/vineyard-metrics-reader created
+clusterrole.rbac.authorization.k8s.io/vineyard-proxy-role created
+clusterrole.rbac.authorization.k8s.io/vineyard-scheduler-plugin-role created
+rolebinding.rbac.authorization.k8s.io/vineyard-leader-election-rolebinding created
+clusterrolebinding.rbac.authorization.k8s.io/vineyard-kube-scheduler-rolebinding created
+clusterrolebinding.rbac.authorization.k8s.io/vineyard-manager-rolebinding created
+clusterrolebinding.rbac.authorization.k8s.io/vineyard-proxy-rolebinding created
+clusterrolebinding.rbac.authorization.k8s.io/vineyard-scheduler-plugin-rolebinding created
+clusterrolebinding.rbac.authorization.k8s.io/vineyard-scheduler-rolebinding created
+clusterrolebinding.rbac.authorization.k8s.io/vineyard-volume-scheduler-rolebinding created
+service/vineyard-controller-manager-metrics-service created
+service/vineyard-webhook-service created
+deployment.apps/vineyard-controller-manager created
+mutatingwebhookconfiguration.admissionregistration.k8s.io/vineyard-mutating-webhook-configuration created
+validatingwebhookconfiguration.admissionregistration.k8s.io/vineyard-validating-webhook-configuration created
+make[ 1 ] : Leaving directory '/opt/caoye/v6d/k8s'
+deployment.apps/vineyard-controller-manager condition met
+Vineyard-Operator Ready
+Installing vineyard cluster...
+vineyardd.k8s.v6d.io/vineyardd-sample created
+vineyardd.k8s.v6d.io/vineyardd-sample condition met
+Vineyard cluster Ready
+
+
+
+
+Verify that all Vineyard pods are running.
+ $ KUBECONFIG = /tmp/e2e-k8s.config kubectl get pod -n vineyard-system
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+etcd0 1 /1 Running 0 68s
+etcd1 1 /1 Running 0 68s
+etcd2 1 /1 Running 0 68s
+vineyard-controller-manager-7f569b57c5-46tgq 2 /2 Running 0 92s
+vineyardd-sample-6ffcb96cbc-gs2v9 1 /1 Running 0 67s
+vineyardd-sample-6ffcb96cbc-n59gg 1 /1 Running 0 67s
+vineyardd-sample-6ffcb96cbc-xwpzd 1 /1 Running 0 67s
+
+
+
+
+First, let’s prepare the dataset and download it into the kind worker nodes as follows.
+ $ worker =( $( docker ps | grep kind-worker | awk -F ' ' '{print $1}' ) )
+$ for c in ${ worker [@] } ; do \
+ docker exec $c sh -c "\
+ mkdir -p /datasets; \
+ cd /datasets/; \
+ curl -OL https://raw.githubusercontent.com/GraphScope/gstest/master/vineyard-mars-showcase-dataset/{item,txn,user}.csv" \
+ done
+
+
+The prepare-data job primarily reads the datasets and distributes them across different
+Vineyard nodes. For more information, please refer to the prepare data code . To apply
+the job, follow the steps below:
+
+
Note
+
The prepare-data job needs to exec into the other pods. Therefore, you need to
+create a service account and bind it to the role under the namespace.
+Please make sure you can have permission to create the following role.
+
- apiGroups: [""]
+ resources: ["pods", "pods/log", "pods/exec"]
+ verbs: ["get", "patch", "delete", "create", "watch", "list"]
+
+
+
+ $ kubectl create ns vineyard-job && \
+kubectl apply -f showcase/vineyard-mars-pytorch/prepare-data/resources && \
+kubectl wait job -n vineyard-job -l app = prepare-data --for condition = complete --timeout= 1200s
+
+
+
+
Expected output
+
+ namespace/vineyard-job created
+clusterrolebinding.rbac.authorization.k8s.io/prepare-data-rolebinding created
+clusterrole.rbac.authorization.k8s.io/prepare-data-role created
+job.batch/prepare-data created
+serviceaccount/prepare-data created
+job.batch/prepare-data condition met
+
+
+
+
+
+
Note
+
The process-data job needs to create a new namespace and deploy several kubernetes
+resources in it. Please make sure you can have permission to create the following role.
+
- apiGroups: [""]
+ resources: ["pods", "pods/exec", "pods/log", "endpoints", "services"]
+ verbs: ["get", "patch", "delete", "create", "watch", "list"]
+- apiGroups: [""]
+ resources: ["namespaces"]
+ verbs: ["get", "create", "delete"]
+- apiGroups: [""]
+ resources: ["nodes"]
+ verbs: ["get", "list"]
+- apiGroups: ["rbac.authorization.k8s.io"]
+ resources: ["roles", "rolebindings"]
+ verbs: ["patch", "get", "create", "delete"]
+- apiGroups: ["apps"]
+ resources: ["deployments"]
+ verbs: ["create"]
+
+
+
Notice, the process-data job will require lots of permissions to deal
+kubernetes resources, so please check the image of process-data job
+if it is an official one.
+
+The prepare-data job creates numerous dataframes in Vineyard. To combine these dataframes,
+we use the appropriate join method in mars . For more details, refer to the process data
+code . Apply the process-data job as follows:
+ $ kubectl apply -f showcase/vineyard-mars-pytorch/process-data/resources && \
+ kubectl wait job -n vineyard-job -l app = process-data --for condition = complete --timeout= 1200s
+
+
+Finally, apply the train-data job to obtain the fraudulent transaction classifier. You can
+also view the train data code .
+ $ kubectl apply -f k8s/showcase/vineyard-mars-pytorch/train-data/resources && \
+ kubectl wait pods -n vineyard-job -l app = train-data --for condition = Ready --timeout= 1200s
+
+
+If any of the above steps fail, please refer to the mars showcase e2e test for further guidance.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/kubernetes/using-vineyard-operator.html b/tutorials/kubernetes/using-vineyard-operator.html
new file mode 100644
index 0000000000..dff2b69105
--- /dev/null
+++ b/tutorials/kubernetes/using-vineyard-operator.html
@@ -0,0 +1,952 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use vineyard operator - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Use vineyard operator
+Vineyard operator has been designed to manage vineyard components within Kubernetes.
+This tutorial provides a step-by-step guide on how to effectively utilize the vineyard
+operator. For more details, please refer to Vineyard Operator .
+
+Step 0: (optional) Initialize Kubernetes Cluster
+If you don’t have a Kubernetes cluster readily available, we highly recommend using kind to
+create one. Before setting up the Kubernetes cluster, please ensure you have the following
+tools installed:
+
+Utilize kind (v0.14.0) to create a Kubernetes cluster consisting of 4 nodes (1 master node and 3
+worker nodes):
+ $ cat > kind-config.yaml <<EOF
+# four node (three workers) cluster config
+kind: Cluster
+apiVersion: kind.x-k8s.io/v1alpha4
+nodes:
+- role: control-plane
+- role: worker
+- role: worker
+- role: worker
+EOF
+$ kind create cluster --config kind-config.yaml
+
+
+
+
Expected output
+
+ Creating cluster "kind" ...
+ ✓ Ensuring node image ( kindest/node:v1.24.0) 🖼
+ ✓ Preparing nodes 📦
+ ✓ Writing configuration 📜
+ ✓ Starting control-plane 🕹️
+ ✓ Installing CNI 🔌
+ ✓ Installing StorageClass 💾
+ Set kubectl context to "kind-kind"
+ You can now use your cluster with:
+
+ kubectl cluster-info --context kind-kind
+
+ Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
+
+
+
+
+
+
Note
+
The kind cluster’s config file is stored in ~/.kube/config, so you can use
+the kubectl directly as it’s the default config path.
+
+Check all kubernetes pods.
+
+
+
Expected output
+
+ NAMESPACE NAME READY STATUS RESTARTS AGE
+kube-system coredns-6d4b75cb6d-k2sk2 1 /1 Running 0 38s
+kube-system coredns-6d4b75cb6d-xm4dt 1 /1 Running 0 38s
+kube-system etcd-kind-control-plane 1 /1 Running 0 52s
+kube-system kindnet-fp24b 1 /1 Running 0 19s
+kube-system kindnet-h6swp 1 /1 Running 0 39s
+kube-system kindnet-mtkd4 1 /1 Running 0 19s
+kube-system kindnet-zxxpd 1 /1 Running 0 19s
+kube-system kube-apiserver-kind-control-plane 1 /1 Running 0 52s
+kube-system kube-controller-manager-kind-control-plane 1 /1 Running 0 53s
+kube-system kube-proxy-6zgq2 1 /1 Running 0 19s
+kube-system kube-proxy-8vghn 1 /1 Running 0 39s
+kube-system kube-proxy-c7vz5 1 /1 Running 0 19s
+kube-system kube-proxy-kd4zz 1 /1 Running 0 19s
+kube-system kube-scheduler-kind-control-plane 1 /1 Running 0 52s
+local-path-storage local-path-provisioner-9cd9bd544-2vrtq 1 /1 Running 0 38s
+
+
+
+
+Check all kubernetes nodes.
+
+
+
Expected output
+
+ NAME STATUS ROLES AGE VERSION
+kind-control-plane Ready control-plane 2m30s v1.24.0
+kind-worker Ready <none> 114s v1.24.0
+kind-worker2 Ready <none> 114s v1.24.0
+kind-worker3 Ready <none> 114s v1.24.0
+
+
+
+
+
+
+Step 1: Deploy the Vineyard Operator
+Create a dedicated namespace for the Vineyard Operator.
+ $ kubectl create namespace vineyard-system
+
+
+
+
Expected output
+
+ namespace/vineyard-system created
+
+
+
+
+The Vineyard CRDs、Controllers、Webhooks and Scheduler are packaged by helm , you could
+deploy all resources as follows.
+
+
Note
+
The vineyard operator needs permission to create several CRDs and kubernetes
+resources, before deploying the vineyard operator, please ensure you can create
+the clusterrole .
+
+ $ helm repo add vineyard https://vineyard.oss-ap-southeast-1.aliyuncs.com/charts/
+
+
+
+
Expected output
+
+"vineyard" has been added to your repositories
+
+
+
+
+Update the vineyard operator chart to the newest one.
+
+
+
Expected output
+
+ Hang tight while we grab the latest from your chart repositories...
+ ...Successfully got an update from the "vineyard" chart repository
+Update Complete. ⎈Happy Helming!⎈
+
+
+
+
+Deploy the vineyard operator in the namespace vineyard-system
.
+ $ helm install vineyard-operator vineyard/vineyard-operator -n vineyard-system
+
+
+
+
Expected output
+
+ NAME: vineyard-operator
+LAST DEPLOYED: Wed Jan 4 16 :41:45 2023
+NAMESPACE: vineyard-system
+STATUS: deployed
+REVISION: 1
+TEST SUITE: None
+NOTES:
+Thanks for installing VINEYARD-OPERATOR, release at namespace: vineyard-system, name: vineyard-operator.
+
+To learn more about the release, try:
+
+$ helm status vineyard-operator -n vineyard-system # get status of running vineyard operator
+$ helm get all vineyard-operator -n vineyard-system # get all deployment yaml of vineyard operator
+
+To uninstall the release, try:
+
+$ helm uninstall vineyard-operator -n vineyard-system
+
+
+
+
+You could get all details about vineyard operator in the doc Vineyard Operator , just have fun with vineyard operator!
+Check the status of all vineyard resources created by helm:
+ $ kubectl get all -n vineyard-system
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+pod/vineyard-operator-controller-manager-5bcbb75fb6-cfdpk 2 /2 Running 0 2m30s
+
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT( S) AGE
+service/vineyard-operator-controller-manager-metrics-service ClusterIP 10 .96.153.134 <none> 8443 /TCP 2m30s
+service/vineyard-operator-webhook-service ClusterIP 10 .96.9.101 <none> 443 /TCP 2m30s
+
+NAME READY UP-TO-DATE AVAILABLE AGE
+deployment.apps/vineyard-operator-controller-manager 1 /1 1 1 2m30s
+
+NAME DESIRED CURRENT READY AGE
+replicaset.apps/vineyard-operator-controller-manager-5bcbb75fb6 1 1 1 2m30s
+
+
+
+
+
+
+Step 2: Deploy a Vineyard Cluster
+After successfully installing the Vineyard operator as described in the previous step,
+you can now proceed to deploy a Vineyard cluster. To create a cluster with two Vineyard
+instances, simply create a Vineyardd Custom Resource (CR) as shown below.
+ $ cat <<EOF | kubectl apply -f -
+apiVersion: k8s.v6d.io/v1alpha1
+kind: Vineyardd
+metadata:
+ name: vineyardd-sample
+ namespace: vineyard-system
+spec:
+ # vineyard instances
+ replicas: 2
+EOF
+
+
+
+
Expected output
+
+ vineyardd.k8s.v6d.io/vineyardd-sample created
+
+
+
+
+Check the status of all relevant resources managed by the vineyardd-sample
cr.
+ $ kubectl get all -l app.kubernetes.io/instance= vineyard-system-vineyardd-sample -n vineyard-system
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+pod/vineyardd-sample-879798cb6-qpvtw 1 /1 Running 0 2m59s
+pod/vineyardd-sample-879798cb6-x4m2x 1 /1 Running 0 2m59s
+
+NAME READY UP-TO-DATE AVAILABLE AGE
+deployment.apps/vineyardd-sample 2 /2 2 2 2m59s
+
+NAME DESIRED CURRENT READY AGE
+replicaset.apps/vineyardd-sample-879798cb6 2 2 2 2m59s
+
+
+
+
+
+
+Step 3: Connect to Vineyard
+Vineyard currently supports clients in various languages, including mature support
+for C++ and Python, as well as experimental support for Java, Golang, and Rust. In
+this tutorial, we will demonstrate how to connect to a Vineyard cluster using the
+Python client. Vineyard provides two connection methods: IPC and RPC . In the
+following sections, we will explore both methods.
+First, let’s deploy the Python client on two Vineyard nodes as follows.
+ $ cat <<EOF | kubectl apply -f -
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: vineyard-python-client
+ namespace: vineyard-system
+spec:
+ selector:
+ matchLabels:
+ app: vineyard-python-client
+ replicas: 2
+ template:
+ metadata:
+ labels:
+ app: vineyard-python-client
+ # related to which vineyard cluster
+ scheduling.k8s.v6d.io/vineyardd-namespace: vineyard-system
+ scheduling.k8s.v6d.io/vineyardd: vineyardd-sample
+ scheduling.k8s.v6d.io/job: v6d-workflow-demo-job1
+ spec:
+ # use the vineyard scheduler to deploy the pod on the vineyard cluster.
+ schedulerName: vineyard-scheduler
+ containers:
+ - name: vineyard-python
+ imagePullPolicy: IfNotPresent
+ image: python:3.10
+ command:
+ - /bin/bash
+ - -c
+ - pip3 install vineyard && sleep infinity
+ volumeMounts:
+ - mountPath: /var/run
+ name: vineyard-sock
+ volumes:
+ - name: vineyard-sock
+ hostPath:
+ path: /var/run/vineyard-kubernetes/vineyard-system/vineyardd-sample
+EOF
+
+
+
+
Expected output
+
+ pod/vineyard-python-client created
+
+
+
+
+Wait for the vineyard python client pod ready.
+ $ kubectl get pod -l app = vineyard-python-client -n vineyard-system
+
+
+
+
Expected output
+
+ NAME READY STATUS RESTARTS AGE
+vineyard-python-client-6fd84bc897-27glp 1 /1 Running 0 93s
+vineyard-python-client-6fd84bc897-tlb22 1 /1 Running 0 93s
+
+
+
+
+Use the kubectl exec command to enter the first vineyard python client pod.
+ $ kubectl exec -it $( kubectl get pod -l app = vineyard-python-client -n vineyard-system -oname | head -n 1 | awk -F '/' '{print $2}' ) -n vineyard-system /bin/bash
+
+
+After entering the shell, you can connect to the vineyard cluster,
+In [ 1 ]: import numpy as np
+In [ 2 ]: import vineyard
+
+In [ 3 ]: client = vineyard . connect ( '/var/run/vineyard.sock' )
+
+In [ 4 ]: objid = client . put ( np . zeros ( 8 ))
+
+In [ 5 ]: # persist the object to make it visible to form the global object
+In [ 6 ]: client . persist ( objid )
+
+In [ 7 ]: objid
+Out [ 7 ]: o001027d7c86a49f0
+
+In [ 8 ]: # get meta info
+In [ 9 ]: meta = client . get_meta ( objid )
+In [ 10 ]: meta
+Out [ 10 ]:
+{
+ "buffer_" : {
+ "id" : "o801027d7c85c472e" ,
+ "instance_id" : 1 ,
+ "length" : 0 ,
+ "nbytes" : 0 ,
+ "transient" : true ,
+ "typename" : "vineyard::Blob"
+ },
+ "global" : false ,
+ "id" : "o001027d7c86a49f0" ,
+ "instance_id" : 1 ,
+ "nbytes" : 64 ,
+ "order_" : " \" C \" " ,
+ "partition_index_" : "[]" ,
+ "shape_" : "[8]" ,
+ "signature" : 4547407361228035 ,
+ "transient" : false ,
+ "typename" : "vineyard::Tensor<double>" ,
+ "value_type_" : "float64" ,
+ "value_type_meta_" : "<f8"
+}
+
+
+Open another terminal and enter the second vineyard python client pod.
+ $ kubectl exec -it $( kubectl get pod -l app = vineyard-python-client -n vineyard-system -oname | tail -n 1 | awk -F '/' '{print $2}' ) -n vineyard-system /bin/bash
+
+
+
+
Expected output
+
+ kubectl exec [ POD] [ COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [ POD] -- [ COMMAND] instead.
+
+
+
+
+Also, you can connect to the vineyard cluster by RPC and get the metadata of
+above object as follows.
+In [ 1 ]: import vineyard
+
+In [ 2 ]: rpc_client = vineyard . connect ( 'vineyardd-sample-rpc.vineyard-system' , 9600 )
+
+In [ 3 ]: # use the object id created by another vineyard instance here
+In [ 4 ]: meta = rpc_client . get_meta ( vineyard . _C . ObjectID ( 'o001027d7c86a49f0' ))
+In [ 5 ]: meta
+Out [ 5 ]:
+{
+ "buffer_" : {
+ "id" : "o801027d7c85c472e" ,
+ "instance_id" : 1 ,
+ "length" : 0 ,
+ "nbytes" : 0 ,
+ "transient" : true ,
+ "typename" : "vineyard::Blob"
+ },
+ "global" : false ,
+ "id" : "o001027d7c86a49f0" ,
+ "instance_id" : 1 ,
+ "nbytes" : 64 ,
+ "order_" : " \" C \" " ,
+ "partition_index_" : "[]" ,
+ "shape_" : "[8]" ,
+ "signature" : 4547407361228035 ,
+ "transient" : false ,
+ "typename" : "vineyard::Tensor<double>" ,
+ "value_type_" : "float64" ,
+ "value_type_meta_" : "<f8"
+}
+
+
+For more examples, please refer the vineyard data accessing .
+
+
+Step 4: Cleanup
+
+ $ helm uninstall vineyard-operator -n vineyard-system
+
+
+
+
Expected output
+
+ release "vineyard-operator" uninstalled
+
+
+
+
+
+ $ kubectl delete namespace vineyard-system
+
+
+
+
Expected output
+
+ namespace "vineyard-system" deleted
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/kubernetes/vineyard-on-fluid.html b/tutorials/kubernetes/vineyard-on-fluid.html
new file mode 100644
index 0000000000..a518f0199c
--- /dev/null
+++ b/tutorials/kubernetes/vineyard-on-fluid.html
@@ -0,0 +1,797 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Vineyard + Fluid in Action: Train a Linear Regression Model on ACK - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Vineyard + Fluid in Action: Train a Linear Regression Model on ACK
+In this tutorial, we will demonstrate how to train a linear regression
+model on ACK (Alibaba Cloud Kubernetes) using VineyardRuntime,
+please follow the steps below.
+
+Step 1: Create a dataset and upload it to OSS
+The prepare-dataset.py
code introduced below shows how to use the
+numpy and pandas libraries in Python to generate a data set of about 22GB
+and upload the files to the OSS service through ossutil . The whole process is
+divided into two main parts:
+
+
Note
+
If your ACK node machine memory is insufficient to generate a 22GB dataset,
+please reduce the number of rows (num_rows) in the dataset.
+
+1. Dataset creation : This code uses the pandas library to create a DataFrame
+containing multiple random number columns that simulate various attributes of
+the real estate market.
+2. Serialize the dataset : This line of code serializes the dataset into
+the local file df.pkl
.
+import numpy as np
+import pandas as pd
+
+# generate the dataframe with a size of about 22G
+num_rows = 6000 * 10000
+df = pd . DataFrame ({
+ 'Id' : np . random . randint ( 1 , 100000 , num_rows ),
+ 'MSSubClass' : np . random . randint ( 20 , 201 , size = num_rows ),
+ 'LotFrontage' : np . random . randint ( 50 , 151 , size = num_rows ),
+ 'LotArea' : np . random . randint ( 5000 , 20001 , size = num_rows ),
+ 'OverallQual' : np . random . randint ( 1 , 11 , size = num_rows ),
+ 'OverallCond' : np . random . randint ( 1 , 11 , size = num_rows ),
+ 'YearBuilt' : np . random . randint ( 1900 , 2022 , size = num_rows ),
+ 'YearRemodAdd' : np . random . randint ( 1900 , 2022 , size = num_rows ),
+ 'MasVnrArea' : np . random . randint ( 0 , 1001 , size = num_rows ),
+ 'BsmtFinSF1' : np . random . randint ( 0 , 2001 , size = num_rows ),
+ 'BsmtFinSF2' : np . random . randint ( 0 , 1001 , size = num_rows ),
+ 'BsmtUnfSF' : np . random . randint ( 0 , 2001 , size = num_rows ),
+ 'TotalBsmtSF' : np . random . randint ( 0 , 3001 , size = num_rows ),
+ '1stFlrSF' : np . random . randint ( 500 , 4001 , size = num_rows ),
+ '2ndFlrSF' : np . random . randint ( 0 , 2001 , size = num_rows ),
+ 'LowQualFinSF' : np . random . randint ( 0 , 201 , size = num_rows ),
+ 'GrLivArea' : np . random . randint ( 600 , 5001 , size = num_rows ),
+ 'BsmtFullBath' : np . random . randint ( 0 , 4 , size = num_rows ),
+ 'BsmtHalfBath' : np . random . randint ( 0 , 3 , size = num_rows ),
+ 'FullBath' : np . random . randint ( 0 , 5 , size = num_rows ),
+ 'HalfBath' : np . random . randint ( 0 , 3 , size = num_rows ),
+ 'BedroomAbvGr' : np . random . randint ( 0 , 11 , size = num_rows ),
+ 'KitchenAbvGr' : np . random . randint ( 0 , 4 , size = num_rows ),
+ 'TotRmsAbvGrd' : np . random . randint ( 0 , 16 , size = num_rows ),
+ 'Fireplaces' : np . random . randint ( 0 , 4 , size = num_rows ),
+ 'GarageYrBlt' : np . random . randint ( 1900 , 2022 , size = num_rows ),
+ 'GarageCars' : np . random . randint ( 0 , 5 , num_rows ),
+ 'GarageArea' : np . random . randint ( 0 , 1001 , num_rows ),
+ 'WoodDeckSF' : np . random . randint ( 0 , 501 , num_rows ),
+ 'OpenPorchSF' : np . random . randint ( 0 , 301 , num_rows ),
+ 'EnclosedPorch' : np . random . randint ( 0 , 201 , num_rows ),
+ '3SsnPorch' : np . random . randint ( 0 , 101 , num_rows ),
+ 'ScreenPorch' : np . random . randint ( 0 , 201 , num_rows ),
+ 'PoolArea' : np . random . randint ( 0 , 301 , num_rows ),
+ 'MiscVal' : np . random . randint ( 0 , 5001 , num_rows ),
+ 'TotalRooms' : np . random . randint ( 2 , 11 , num_rows ),
+ "GarageAge" : np . random . randint ( 1 , 31 , num_rows ),
+ "RemodAge" : np . random . randint ( 1 , 31 , num_rows ),
+ "HouseAge" : np . random . randint ( 1 , 31 , num_rows ),
+ "TotalBath" : np . random . randint ( 1 , 5 , num_rows ),
+ "TotalPorchSF" : np . random . randint ( 1 , 1001 , num_rows ),
+ "TotalSF" : np . random . randint ( 1000 , 6001 , num_rows ),
+ "TotalArea" : np . random . randint ( 1000 , 6001 , num_rows ),
+ 'MoSold' : np . random . randint ( 1 , 13 , num_rows ),
+ 'YrSold' : np . random . randint ( 2006 , 2022 , num_rows ),
+ 'SalePrice' : np . random . randint ( 50000 , 800001 , num_rows ),
+})
+
+# Save the dataframe to the current directory
+df . to_pickle ( "df.pkl" )
+
+
+3. Upload the data set to OSS : Follow the following command to use ossutil to
+upload the current file to the OSS service.
+# Upload the current dataset df.pkl to the OSS service through the ossutil cp command.
+# Refer to https://help.aliyun.com/zh/oss/developer-reference/upload-objects-6?spm=a2c4g.11186623.0.i3
+$ ossutil cp ./df.pkl oss://your-bucket-name/your-path
+
+
+
+
+Step 2: Install the Fluid control plane and Fluid Python SDK in the ACK cluster.
+Option 1: Install ack-fluid. Refer to the document: Install the cloud native AI suite
+Option 2: Using the open-source version, we will use Kubectl to create a
+namespace named fluid-system
, and then use Helm to install Fluid.
+This process only needs to be completed through the following simple Shell commands.
+# Create the fluid-system namespace
+$ kubectl create ns fluid-system
+
+# Add the Fluid repository to the Helm repository
+$ helm repo add fluid https://fluid-cloudnative.github.io/charts
+# Get the latest Fluid repository
+$ helm repo update
+# Find the development version in the Fluid repository
+$ helm search repo fluid --devel
+# Deploy the corresponding version of the Fluid chart on ACK
+$ helm install fluid fluid/fluid --devel
+
+
+After we deploy the Fluid platform on ACK, we need to execute the following pip
+command to install the Fluid Python SDK.
+ $ pip install git+https://github.com/fluid-cloudnative/fluid-client-python.git
+
+
+
+
+Step 3: Enable collaborative scheduling of data and tasks (optional)
+In cloud environments, end-to-end data operation pipelines often contain multiple subtasks.
+When these tasks are scheduled by Kubernetes, the system only considers the required resource
+constraints and cannot guarantee that two consecutively executed tasks can run on the same node.
+This results in additional network overhead due to data migration when the two use Vineyard to
+share intermediate results.
+If you want to schedule tasks and vineyard to the same node to achieve the best performance,
+you can modify the configmap configuration as follows to enable fuse affinity scheduling.
+In this way, system scheduling will give priority to associated tasks to access memory on the
+same node to reduce data migration. The network overhead incurred.
+# Update the webhook-plugins configuration according to the following command
+# and enable fuse affinity scheduling
+$ kubectl edit configmap webhook-plugins -n fluid-system
+data:
+pluginsProfile: |
+ pluginConfig:
+ - args: |
+ preferred:
+ # Enable fuse affinity scheduling
+ - name: fluid.io/fuse
+ weight: 100
+ ...
+
+# Restart the fluid-webhook pod
+$ kubectl delete pod -lcontrol-plane= fluid-webhook -n fluid-system
+
+
+
+
+Step 4: Use Fluid Python SDK to build and deploy linear regression data operation pipeline
+In the linear-regression-with-vineyard.py
script below, we will explore an example
+of building and deploying a machine learning workflow using Python and the Fluid library.
+The dataset is generated by the code in the appendix. The workflow covers data preprocessing,
+The whole process of model training and model testing.
+import fluid
+
+from fluid import constants
+from fluid import models
+
+# Create a Fluid client instance by connecting to the Fluid control plane
+# using the default kubeconfig file
+client_config = fluid . ClientConfig ()
+fluid_client = fluid . FluidClient ( client_config )
+
+# Create a dataset named vineyard in the default namespace
+fluid_client . create_dataset (
+ dataset_name = "vineyard" ,
+)
+
+# Get the vineyard dataset instance
+dataset = fluid_client . get_dataset ( dataset_name = "vineyard" )
+
+# Initialize the configuration of the vineyard runtime and bind the
+# vineyard dataset instance to the runtime.
+# The number of replicas is 2, and the memory is 30Gi
+dataset . bind_runtime (
+ runtime_type = constants . VINEYARD_RUNTIME_KIND ,
+ replicas = 2 ,
+ cache_capacity_GiB = 30 ,
+ cache_medium = "MEM" ,
+ wait = True
+)
+
+# define the data preprocessing task
+def preprocess ():
+ from sklearn.model_selection import train_test_split
+
+ import pandas as pd
+ import vineyard
+
+ df = pd . read_pickle ( '/data/df.pkl' )
+
+ # Preprocess Data
+ df = df . drop ( df [( df [ 'GrLivArea' ] > 4800 )] . index )
+ X = df . drop ( 'SalePrice' , axis = 1 ) # Features
+ y = df [ 'SalePrice' ] # Target variable
+
+ del df
+
+ X_train , X_test , y_train , y_test = train_test_split ( X , y , test_size = 0.2 )
+
+ del X , y
+
+ vineyard . put ( X_train , name = "x_train" , persist = True )
+ vineyard . put ( X_test , name = "x_test" , persist = True )
+ vineyard . put ( y_train , name = "y_train" , persist = True )
+ vineyard . put ( y_test , name = "y_test" , persist = True )
+
+# define the model training task
+def train ():
+ from sklearn.linear_model import LinearRegression
+
+ import joblib
+ import pandas as pd
+ import vineyard
+
+ x_train_data = vineyard . get ( name = "x_train" , fetch = True )
+ y_train_data = vineyard . get ( name = "y_train" , fetch = True )
+
+ model = LinearRegression ()
+ model . fit ( x_train_data , y_train_data )
+
+ joblib . dump ( model , '/data/model.pkl' )
+
+# define the model testing task
+def test ():
+ from sklearn.linear_model import LinearRegression
+ from sklearn.metrics import mean_squared_error
+
+ import vineyard
+ import joblib
+ import pandas as pd
+
+ x_test_data = vineyard . get ( name = "x_test" , fetch = True )
+ y_test_data = vineyard . get ( name = "y_test" , fetch = True )
+
+ model = joblib . load ( "/data/model.pkl" )
+ y_pred = model . predict ( x_test_data )
+
+ err = mean_squared_error ( y_test_data , y_pred )
+
+ with open ( '/data/output.txt' , 'a' ) as f :
+ f . write ( str ( err ))
+
+packages_to_install = [ "numpy" , "pandas" , "pyarrow" , "requests" , "vineyard" , "scikit-learn==1.4.0" , "joblib==1.3.2" ]
+pip_index_url = "https://pypi.tuna.tsinghua.edu.cn/simple"
+
+preprocess_processor = create_processor ( preprocess , packages_to_install , pip_index_url )
+train_processor = create_processor ( train , packages_to_install , pip_index_url )
+test_processor = create_processor ( test , packages_to_install , pip_index_url )
+
+# Create a linear regression model task workflow: data preprocessing -> model training -> model testing
+# The following mount path "/var/run/vineyard" is the default path of the vineyard configuration file
+flow = dataset . process ( processor = preprocess_processor , dataset_mountpath = "/var/run/vineyard" ) \
+ . process ( processor = train_processor , dataset_mountpath = "/var/run/vineyard" ) \
+ . process ( processor = test_processor , dataset_mountpath = "/var/run/vineyard" )
+
+# Submit the data processing task workflow of the linear regression model and wait for it to run to completion
+run = flow . run ( run_id = "linear-regression-with-vineyard" )
+run . wait ()
+
+
+Here’s an overview of each part of the code:
+1. Create Fluid client : This code is responsible for establishing
+a connection with the Fluid control platform using the default kubeconfig file and
+creating a Fluid client instance.
+2. Create and configure the vineyard dataset and runtime environment : Next, the code
+creates a dataset named Vineyard
, then obtains the dataset instance, initializes the vineyard
+runtime configuration, and sets up a copy number and memory size to bind the dataset to the
+runtime environment.
+3. Define the data preprocessing function : This part defines a python function for data
+preprocessing, which includes splitting the training set and the test set, as well as
+data filtering and other operations.
+4. Define model training function : As the name suggests, this code defines another
+python function for training a linear regression model.
+5. Define the model testing function : This section contains the model testing logic
+for evaluating the trained model.
+6. Create a task template and define task workflow : The code encapsulates a task
+template function named create_processor, which uses the previously defined python functions
+to build data preprocessing, model training and model testing steps respectively.
+These steps are designed to be executed sequentially, forming a complete workflow in which
+data preprocessing is the first step, followed by model training, and finally model testing.
+This serial execution sequence ensures that the output of each stage can be used as the input
+of the next stage, thereby achieving a coherent and orderly machine learning process.
+7. [Optional] Enable data affinity scheduling : After enabling fuse affinity scheduling,
+add the tag "fuse.serverful.fluid.io/inject": "true"
to ensure that related tasks run on the
+same node first through scheduling. to achieve the best performance in data processing.
+8. Submit and execute the task workflow : Submit the entire linear regression model task
+workflow to the Fluid platform for execution through the run command.
+
+Resource Cleanup : Finally, clean up all resources created on the Fluid platform.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tutorials/tutorials.html b/tutorials/tutorials.html
new file mode 100644
index 0000000000..888dd34c5b
--- /dev/null
+++ b/tutorials/tutorials.html
@@ -0,0 +1,587 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Data processing - Vineyard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Contents
+
+
+
+
+
+
+ Expand
+
+
+
+
+
+ Light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dark mode
+
+
+
+
+
+
+ Auto light/dark mode
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in light mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Auto light/dark, in dark mode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hide table of contents sidebar
+
+
+Skip to content
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back to top
+
+
+
+
+ Toggle Light / Dark / Auto color theme
+
+
+
+
+
+
+
+ Toggle table of contents sidebar
+
+
+
+
+
+Data processing
+
+
+In these comprehensive case studies, we demonstrate how to seamlessly integrate vineyard’s
+capabilities with existing data-intensive tasks. By incorporating vineyard into complex
+workflows involving multiple computing engines, users can experience significant
+improvements in both performance and ease of use.
+
+
+
+
+
+
+
Effortlessly share Python objects between processes using vineyard’s intuitive and efficient approach.
+
+
+
+
+
+
+
+
Utilize vineyard as an elegant alternative to multiprocessing.shared_memory
in Python.
+
+
+
+
+
+
+
+
Discover how vineyard enhances distributed machine learning training workflows by
+seamlessly integrating with various computing engines for improved efficiency and elegance.
+
+
+
+
+
+
+
+
Vineyard serves as the DataSet
backend for Kedro pipelines, enabling
+efficient data sharing between tasks without intrusive code modification, even
+when the pipeline is deployed to Kubernetes.
+
+
+
+
+
+
+
+
Vineyard supports sharing GPU memory in zero-copy manner, enabling efficient data sharing
+between GPU-accelerated tasks.
+
+
+
+
+
+
+
+Vineyard on Kubernetes
+
+
+Vineyard can be seamlessly deployed on Kubernetes, managed by the Vineyard Operator ,
+to enhance big-data workflows through its data-aware scheduling policy. This policy
+orchestrates shared objects and routes jobs to where their input data resides. In the
+following tutorials, you will learn how to deploy Vineyard and effectively integrate it
+with Kubernetes.
+
+
+
+
+
+
+
The Vineyard operator serves as the central component for seamless integration with Kubernetes.
+
+
+
+
+
+
+
+
Vineyard functions as an efficient intermediate data storage solution for machine learning pipelines on Kubernetes.
+
+
+
+
+
+
+
+Extending vineyard
+
+
+Vineyard offers a collection of efficient data structures tailored for data-intensive tasks,
+such as tensors, data frames, tables, and graphs. These data types can be easily extended
+to accommodate custom requirements. By registering user-defined types in the vineyard type
+registry, computing engines built on top of vineyard can instantly leverage the advantages
+provided by these custom data structures.
+
+
+
+
+
+
+
Craft builders and resolvers for custom Python data types.
+
+
+
+
+
+
+
+
Implement and register custom data types in C++ for seamless integration with vineyard’s ecosystem.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Copyright © 2020-2023, The Vineyard Authors
+
+ Rendered with
Sphinx and
Furo
+
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
+ please see our Trademark Usage page .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vineyard-sigmod-2023.pdf b/vineyard-sigmod-2023.pdf
new file mode 100644
index 0000000000..d2c13b208b
Binary files /dev/null and b/vineyard-sigmod-2023.pdf differ