chore: import upstream snapshot with attribution
Lint / lint (push) Has been cancelled
CI / MacOS (push) Has been cancelled
CI / Windows (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:36:25 +08:00
commit 26446540fa
3151 changed files with 974126 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
"""Namespace of executables python files that directly run throw cmd"""
@@ -0,0 +1,36 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# pylint: disable=invalid-name
# ruff: noqa: F401
"""Launch disco session in the remote node and connect to the server."""
import sys
import tvm
from . import disco_worker as _ # pylint: disable=unused-import
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: <server_host> <server_port> <num_workers>")
sys.exit(1)
server_host = sys.argv[1]
server_port = int(sys.argv[2])
num_workers = int(sys.argv[3])
func = tvm.get_global_func("runtime.disco.RemoteSocketSession")
func(server_host, server_port, num_workers)
+127
View File
@@ -0,0 +1,127 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# pylint: disable=invalid-name
# ruff: noqa: RUF005
"""Internal DiscoWorker for Disco ProcessSession."""
import os
import sys
from collections.abc import Callable
from tvm_ffi import Shape, get_global_func, register_global_func
from tvm_ffi.core import String
import tvm
from tvm.runtime import Tensor, tensor
@register_global_func("tests.disco.add_one", override=True)
def _add_one(x: int) -> int:
return x + 1
@register_global_func("tests.disco.add_one_float", override=True)
def _add_one_float(x: float):
return x + 0.5
@register_global_func("tests.disco.add_one_tensor", override=True)
def _add_one_tensor(x: Tensor) -> Tensor:
return tensor(x.numpy() + 1)
@register_global_func("tests.disco.str", override=True)
def _str_func(x: str):
return x + "_suffix"
@register_global_func("tests.disco.str_obj", override=True)
def _str_obj_func(x: str):
assert isinstance(x, str)
return String(x + "_suffix")
@register_global_func("tests.disco.shape_tuple", override=True)
def _shape_tuple_func(x: Shape):
assert isinstance(x, Shape)
return Shape(list(x) + [4, 5])
@register_global_func("tests.disco.test_callback", override=True)
def _make_callback(device: tvm.runtime.Device) -> Callable[[str, int], Tensor]:
"""For use in tests/python/disco/test_callback.py
This function simulates a callback to be used for lazy parameter
loading.
Parameters
----------
device: tvm.runtime.Device
The device on which parameters should be located, when
returned by the callback function.
Returns
-------
fget_item: Callable[[str,int], Tensor]
A callback function that accepts a parameter's name and index,
and returns the specified parameter.
"""
import numpy as np # pylint: disable=import-outside-toplevel
def fget_item(param_name: str, param_index: int) -> Tensor:
if param_index == 0:
assert param_name == "A"
arr = np.arange(16).reshape([4, 4]).astype("int32")
elif param_index == 1:
assert param_name == "B"
arr = np.arange(4).reshape([2, 2]).astype("float32")
else:
raise ValueError(f"Unexpected index {param_index}")
return tvm.runtime.tensor(arr, device=device)
return fget_item
def main():
"""Main worker function"""
if len(sys.argv) != 6:
print("Usage: <worker_id> <num_workers> <num_groups> <read_fd> <write_fd>")
return
worker_id = int(sys.argv[1])
num_workers = int(sys.argv[2])
num_groups = int(sys.argv[3])
if sys.platform == "win32":
import msvcrt # pylint: disable=import-outside-toplevel,import-error
reader = msvcrt.open_osfhandle(int(sys.argv[4]), os.O_BINARY)
writer = msvcrt.open_osfhandle(int(sys.argv[5]), os.O_BINARY)
else:
reader = int(sys.argv[4])
writer = int(sys.argv[5])
worker_func = get_global_func("runtime.disco.WorkerProcess")
worker_func(worker_id, num_workers, num_groups, reader, writer)
if __name__ == "__main__":
try:
main()
except (OSError, KeyboardInterrupt):
pass
+262
View File
@@ -0,0 +1,262 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# ruff: noqa: E501, F821
"""A script to measure GPU memory bandwidth"""
import argparse
import itertools
import numpy as np
import tvm
from tvm import te
from tvm.s_tir.meta_schedule.runner import EvaluatorConfig, RPCConfig
from tvm.testing import local_run, rpc_run
def _parse_args() -> argparse.Namespace:
def _parse_list_int(source: str):
return [int(i) for i in source.split(",")]
parser = argparse.ArgumentParser(
prog="GPU memory bandwidth testing",
description="""Example for host GPU:
python -m tvm.exec.gpu_memory_bandwidth "nvidia/geforce-rtx-3090-ti" \
--dtype "float32"
--bx "8,16,32,64,128,256" \
--tx "32,64,128,256,512,1024" \
--vec "1,2,4" \
Example for Android GPU: \
python -m tvm.exec.gpu_memory_bandwidth "opencl" --target_host '{"kind": "llvm", "mtriple": "arm64-linux-android"}' \
--rpc_host "127.0.0.1" \
--rpc_port 9190 \
--rpc_key "android" \
--export_func "ndk" \
--dtype "float32" \
--bx "8,16,32,64,128,256" \
--tx "32,64,128,256,512,1024" \
--vec "1,2,4" \
""",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"target",
type=str,
help="The target to be benchmarked",
)
parser.add_argument(
"--target_host",
type=str,
default=None,
help="The target host for build",
)
parser.add_argument(
"--xo",
type=int,
default=1024,
help="The value of `XO` in [XO, K, XI] => [XO, XI] reduction",
)
parser.add_argument(
"--k",
type=int,
default=64,
help="The value of `K` in [XO, K, XI] => [XO, XI] reduction",
)
parser.add_argument(
"--xi",
type=int,
default=4096,
help="The value of `XI` in [XO, K, XI] -> [XO, XI] reduction",
)
parser.add_argument(
"--dtype",
type=str,
default="float32",
help="The data type to be used in the workload",
)
parser.add_argument(
"--bx",
type=_parse_list_int,
default=[8, 16, 32, 64, 128, 256],
help="The value to be used to split `XO` into [BX, _]",
)
parser.add_argument(
"--tx",
type=_parse_list_int,
default=[32, 64, 128, 256, 512, 1024],
help="Number of threads to be used",
)
parser.add_argument(
"--vec",
type=_parse_list_int,
default=[1, 2, 4],
help="Vector length to be used in vectorized load",
)
parser.add_argument(
"--rpc_host",
type=str,
default=None,
help="The address of RPC host (default: None, that means that RPC is not used)",
)
parser.add_argument(
"--rpc_port",
type=int,
default=None,
help="The port of RPC connection (default: None, that means that RPC is not used)",
)
parser.add_argument(
"--rpc_key",
type=str,
default=None,
help="The device key in RPC tracker (default: None, that means that RPC is not used)",
)
parser.add_argument(
"--export_func",
type=str,
default="tar",
help="Export function, actual only for RPC",
choices=["tar", "ndk"],
)
return parser.parse_args()
def _workload(
len_xo: int,
len_k: int,
len_xi: int,
dtype: str,
):
# pylint: disable=invalid-name
A = te.placeholder((len_xo, len_k, len_xi), dtype=dtype, name="A")
k = te.reduce_axis((0, len_k), "k")
B = te.compute(
(len_xo, len_xi),
lambda i, j: te.sum(A[i, k, j], axis=k),
name="B",
)
# pylint: enable=invalid-name
return te.create_prim_func([A, B])
def _schedule(
sch: s_tir.Schedule,
len_bx: int,
len_tx: int,
len_vec: int,
):
# pylint: disable=invalid-name
block = sch.get_sblock("B")
xo, xi, k = sch.get_loops(block)
bx, xo = sch.split(xo, factors=[len_bx, None])
xi, tx, vec = sch.split(xi, factors=[None, len_tx, len_vec])
sch.reorder(bx, xi, tx, xo, k, vec)
bx = sch.fuse(bx, xi)
sch.bind(bx, "blockIdx.x")
sch.bind(tx, "threadIdx.x")
ldg = sch.cache_read(block, 0, "local")
sch.compute_at(ldg, k, preserve_unit_loops=True)
sch.vectorize(sch.get_loops(ldg)[-1])
sch.decompose_reduction(block, k)
# pylint: enable=invalid-name
def main(): # pylint: disable=too-many-locals
"""Entry point"""
args = _parse_args()
# pylint: disable=invalid-name
target = tvm.target.Target(args.target)
if args.target_host is not None:
target = tvm.target.Target(args.target, host=args.target_host)
dtype = args.dtype
rpcConfig = None
if args.rpc_host is not None and args.rpc_port is not None and args.rpc_key is not None:
rpcConfig = RPCConfig(
tracker_host=args.rpc_host,
tracker_port=args.rpc_port,
tracker_key=args.rpc_key,
session_priority=1,
session_timeout_sec=600,
)
a = np.random.uniform(-1, 1, (args.xo, args.k, args.xi)).astype(dtype)
b = np.zeros((args.xo, args.xi), dtype=dtype)
num_bytes = a.size * a.itemsize + b.size * b.itemsize
print("###### Bandwidth Test ######")
print(
f"Workload [XO, K, XI] => [XO, XI]. "
f"[{args.xo}, {args.k}, {args.xi}] => [{args.xo}, {args.xi}]"
)
print(f"Input size: {num_bytes / 1048576} MB")
print(f"Target: {target}")
# pylint: enable=invalid-name
best_bandwidth = -1
for len_bx, len_tx, len_vec in itertools.product(
args.bx,
args.tx,
args.vec,
):
func = _workload(
len_xo=args.xo,
len_k=args.k,
len_xi=args.xi,
dtype=dtype,
)
sch = tvm.s_tir.Schedule(func)
_schedule(sch, len_bx, len_tx, len_vec)
if rpcConfig is None:
_, profile_result = local_run(
tvm.compile(sch.mod, target=target),
target.kind.name,
[a, b],
evaluator_config=EvaluatorConfig(
number=10,
repeat=1,
min_repeat_ms=100,
enable_cpu_cache_flush=False,
),
)
else:
_, profile_result = rpc_run(
tvm.compile(sch.mod, target=target),
target.kind.name,
[a, b],
evaluator_config=EvaluatorConfig(
number=10,
repeat=1,
min_repeat_ms=100,
enable_cpu_cache_flush=False,
),
rpc_config=rpcConfig,
export_func=args.export_func,
)
bandwidth = num_bytes / profile_result.mean / (1024**3)
bx = len_bx * args.xi // (len_tx * len_vec) # pylint: disable=invalid-name
mbs = num_bytes / 1024 / 1024
print(
f"bandwidth = {bandwidth:.3f} GB/s, bx = {bx}, tx = {len_tx}, "
f"len_vec = {len_vec}, bytes = {mbs} MB"
)
if bandwidth > best_bandwidth:
best_bandwidth = bandwidth
print(f"peak bandwidth: {best_bandwidth:.3f} GB/s")
if __name__ == "__main__":
main()
+126
View File
@@ -0,0 +1,126 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# pylint: disable=invalid-name
# ruff: noqa: RUF012
"""Internal PopenWorker for PopenPool."""
import logging
import os
import pickle
import struct
import sys
import threading
import traceback
import cloudpickle
from tvm.support.popen_pool import StatusKind
class TimeoutStatus:
__slot__ = ["status"]
def __init__(self):
self.status = StatusKind.RUNNING
def main():
"""Main worker function"""
if len(sys.argv) != 3:
print("Usage: <read_fd> <write_fd>")
return
if sys.platform == "win32":
# pylint: disable=import-outside-toplevel
import msvcrt
reader = os.fdopen(msvcrt.open_osfhandle(int(sys.argv[1]), os.O_BINARY), "rb")
writer = os.fdopen(msvcrt.open_osfhandle(int(sys.argv[2]), os.O_BINARY), "wb")
else:
reader = os.fdopen(int(sys.argv[1]), "rb")
writer = os.fdopen(int(sys.argv[2]), "wb")
logging.basicConfig(level=logging.INFO)
lock = threading.Lock()
def _respond(ret_value):
"""Send data back to the client."""
data = cloudpickle.dumps(ret_value, protocol=pickle.HIGHEST_PROTOCOL)
writer.write(struct.pack("<i", len(data)))
writer.write(data)
writer.flush()
def _cancel_run(status):
lock.acquire()
if status.status == StatusKind.RUNNING:
_respond((StatusKind.TIMEOUT, TimeoutError()))
status.status = StatusKind.TIMEOUT
lock.release()
while True:
raw_bytes_size = reader.read(4)
if len(raw_bytes_size) != 4:
# the parent exited
return
bytes_size = struct.unpack("<i", raw_bytes_size)[0]
fn, args, kwargs, timeout = cloudpickle.loads(reader.read(bytes_size))
status = TimeoutStatus()
if timeout is not None:
watcher = threading.Timer(timeout, _cancel_run, [status])
watcher.daemon = True
watcher.start()
# pylint: disable=broad-except
try:
result = fn(*args, **kwargs)
ret_value = (StatusKind.COMPLETE, result)
except Exception as exception:
msg = traceback.format_exc()
ret_value = (StatusKind.EXCEPTION, type(exception)(msg))
if timeout is not None:
watcher.cancel()
lock.acquire()
if status.status == StatusKind.RUNNING:
_respond(ret_value)
status.status = StatusKind.COMPLETE
lock.release()
if __name__ == "__main__":
try:
main()
except (OSError, KeyboardInterrupt):
pass
+48
View File
@@ -0,0 +1,48 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
"""Tool to query RPC tracker status"""
import argparse
import logging
import os
from .. import rpc
def main():
"""Main function"""
parser = argparse.ArgumentParser()
parser.add_argument("--host", type=str, default="", help="the hostname of the tracker")
parser.add_argument("--port", type=int, default=None, help="The port of the RPC")
args = parser.parse_args()
logging.basicConfig(level=logging.INFO)
# default to local host or environment variable
if not args.host:
args.host = os.environ.get("TVM_TRACKER_HOST", "127.0.0.1")
if not args.port:
args.port = int(os.environ.get("TVM_TRACKER_PORT", "9190"))
conn = rpc.connect_tracker(args.host, args.port)
# pylint: disable=superfluous-parens
print(f"Tracker address {args.host}:{args.port}\n")
print(f"{conn.text_summary()}")
if __name__ == "__main__":
main()
+113
View File
@@ -0,0 +1,113 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# pylint: disable=redefined-outer-name, invalid-name
"""RPC web proxy, allows redirect to websocket based RPC servers(browsers)"""
import argparse
import glob
import logging
import os
from tvm.rpc.proxy import Proxy
def find_example_resource():
"""Find resource examples."""
curr_path = os.path.dirname(os.path.realpath(os.path.expanduser(__file__)))
base_path = os.path.abspath(os.path.join(curr_path, "..", "..", ".."))
index_page = os.path.join(base_path, "web", "apps", "browser", "rpc_server.html")
default_plugin_page = os.path.join(base_path, "web", "apps", "browser", "rpc_plugin.html")
resource_files = [
("/", os.path.join(base_path, "web", "dist", "tvmjs.bundle.js")),
("/", os.path.join(base_path, "web", "dist", "wasm", "tvmjs_runtime.wasi.js")),
("/", index_page),
]
allow_format = ("json", "bin", "js", "wasm", "html", "css", "model")
# recursively apend things in www, up to two levels
resource_bases = [
os.path.join(base_path, "web", "dist", "www"),
os.path.join(base_path, "web", ".tensor_cache"),
]
for base in resource_bases:
if not os.path.isdir(base):
continue
for full_name in glob.glob(f"{base}/**", recursive=True):
fname = os.path.relpath(full_name, base)
dirname = os.path.dirname(fname)
fmt = fname.rsplit(".", 1)[-1]
if os.path.isfile(full_name) and fmt in allow_format:
resource_files.append((dirname, full_name))
for item in resource_files:
fname = item[-1]
if not os.path.exists(fname):
raise RuntimeError(f"Cannot find {fname}")
if not any(item[-1].endswith("rpc_plugin.html") for item in resource_files):
resource_files.append(("/", default_plugin_page))
return index_page, resource_files
def main(args):
"""Main function"""
if args.tracker:
url, port = args.tracker.split(":")
port = int(port)
tracker_addr = (url, port)
else:
tracker_addr = None
if args.example_rpc:
index, js_files = find_example_resource()
prox = Proxy(
args.host,
port=args.port,
port_end=args.port_end,
web_port=args.web_port,
index_page=index,
resource_files=js_files,
tracker_addr=tracker_addr,
)
else:
prox = Proxy(
args.host,
port=args.port,
port_end=args.port_end,
web_port=args.web_port,
tracker_addr=tracker_addr,
)
prox.proc.join()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--host", type=str, default="127.0.0.1", help="the hostname of the server")
parser.add_argument("--port", type=int, default=9090, help="The port of the RPC")
parser.add_argument("--port-end", type=int, default=9199, help="The end search port of the RPC")
parser.add_argument(
"--web-port", type=int, default=8888, help="The port of the http/websocket server"
)
parser.add_argument(
"--example-rpc", type=bool, default=False, help="Whether to switch on example rpc mode"
)
parser.add_argument("--tracker", type=str, default="", help="Report to RPC tracker")
args = parser.parse_args()
logging.basicConfig(level=logging.INFO)
main(args)
+104
View File
@@ -0,0 +1,104 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# pylint: disable=redefined-outer-name, invalid-name
"""Start an RPC server"""
import argparse
import logging
from .. import rpc
def main(args):
"""Main function
Parameters
----------
args : argparse.Namespace
parsed args from command-line invocation
"""
if args.tracker:
url, port = args.tracker.rsplit(":", 1)
port = int(port)
tracker_addr = (url, port)
if not args.key:
raise RuntimeError("Need key to present type of resource when tracker is available")
else:
tracker_addr = None
server = rpc.Server(
args.host,
args.port,
args.port_end,
is_proxy=args.through_proxy,
key=args.key,
tracker_addr=tracker_addr,
load_library=args.load_library,
custom_addr=args.custom_addr,
silent=args.silent,
no_fork=not args.fork,
)
server.proc.join()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--host", type=str, default="0.0.0.0", help="The host IP address the tracker binds to"
)
parser.add_argument("--port", type=int, default=9090, help="The port of the RPC")
parser.add_argument(
"--through-proxy",
dest="through_proxy",
action="store_true",
help=(
"Whether this server provide service through a proxy. If this is true, the host and"
"port actually is the address of the proxy."
),
)
parser.add_argument("--port-end", type=int, default=9199, help="The end search port of the RPC")
parser.add_argument(
"--tracker",
type=str,
help=("The address of RPC tracker in host:port format. e.g. (10.77.1.234:9190)"),
)
parser.add_argument(
"--key", type=str, default="", help="The key used to identify the device type in tracker."
)
parser.add_argument("--silent", action="store_true", help="Whether run in silent mode.")
parser.add_argument("--load-library", type=str, help="Additional library to load")
parser.add_argument(
"--no-fork",
dest="fork",
action="store_false",
help="Use spawn mode to avoid fork. This option \
is able to avoid potential fork problems with Metal, OpenCL \
and ROCM compilers.",
)
parser.add_argument(
"--custom-addr", type=str, help="Custom IP Address to Report to RPC Tracker"
)
parser.set_defaults(fork=True)
args = parser.parse_args()
logging.basicConfig(level=logging.INFO)
if args.fork is not False and not args.silent:
logging.info(
"If you are running ROCM/Metal, fork will cause "
"compiler internal error. Try to launch with arg ```--no-fork```"
)
main(args)
+42
View File
@@ -0,0 +1,42 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# pylint: disable=redefined-outer-name, invalid-name
"""Tool to start RPC tracker"""
import argparse
import logging
from ..rpc.tracker import Tracker
def main(args):
"""Main function"""
tracker = Tracker(args.host, port=args.port, port_end=args.port_end, silent=args.silent)
tracker.proc.join()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--host", type=str, default="0.0.0.0", help="The host IP address the tracker binds to"
)
parser.add_argument("--port", type=int, default=9190, help="The port of the RPC")
parser.add_argument("--port-end", type=int, default=9199, help="The end search port of the RPC")
parser.add_argument("--silent", action="store_true", help="Whether run in silent mode.")
args = parser.parse_args()
logging.basicConfig(level=logging.INFO)
main(args)