|
| 1 | +Using Ray core Tasks |
| 2 | +=========================== |
| 3 | + |
| 4 | +This example will show you how to use one of Ray's core abstractions. |
| 5 | +Namely how to create Ray `Tasks <a href="https://docs.ray.io/en/latest/ray-core/tasks.html">`_, |
| 6 | + |
| 7 | +With Ray we can execute arbitrary functions on separate workers. |
| 8 | +These functions are called Ray tasks. The code snippet below shows |
| 9 | +you how to create a Ray Task: |
| 10 | + |
| 11 | +.. code-block:: |
| 12 | +
|
| 13 | + // we need to include the Ray API |
| 14 | + #include <ray/api.h> |
| 15 | + |
| 16 | + // This is the C++ function we want to execute |
| 17 | + int do_sth() { |
| 18 | + return 1; |
| 19 | + } |
| 20 | + |
| 21 | + // In order to be able to execute this function |
| 22 | + // we need to register it using `RAY_REMOTE`. |
| 23 | + RAY_REMOTE(do_sth); |
| 24 | + |
| 25 | + int main(int argc, char **argv) { |
| 26 | + |
| 27 | + // We need to initialize Ray before using it |
| 28 | + ray::Init(); |
| 29 | +
|
| 30 | + // Invoke the above method as a Ray task. |
| 31 | + // This will immediately return an object ref (a future) and then create |
| 32 | + // a task that will be executed on a worker process. |
| 33 | + auto res = ray::Task(do_sth).Remote(); |
| 34 | + |
| 35 | + // The result can be retrieved with ``ray::ObjectRef::Get``. |
| 36 | + auto result = *res.Get(); |
| 37 | + |
| 38 | + // shutodown Ray |
| 39 | + ray::Shutdown(); |
| 40 | + |
| 41 | + std::cout<<"Result is: "<<result<<std::endl; |
| 42 | + std::cout<<"Running normal C++ stuff here..."<<std::endl; |
| 43 | + |
| 44 | + result = do_sth(); |
| 45 | + std::cout<<"Result is: "<<result<<std::endl; |
| 46 | + |
| 47 | + |
| 48 | + return 0; |
| 49 | + } |
| 50 | +
|
| 51 | +You can build the code using the ``cmake`` toolchain, but Ray favors `Bazel <https://bazel.build/>`_ |
| 52 | +for building and running jobs. Let's see how we can use this to build the example. |
| 53 | +Copy the following files and directories from ``external/ray`` directory: |
| 54 | + |
| 55 | +- ``run.sh`` |
| 56 | +- ``BUILD.bazel`` |
| 57 | +- ``WORKSPACE`` |
| 58 | +- ``thirdparty`` |
| 59 | + |
| 60 | +into the directory where the ``ray_example_1`` is located. |
| 61 | +Edit the ``run.sh`` file and change the line where the ``bazel`` executable is called to this: |
| 62 | + |
| 63 | +.. code-block:: |
| 64 | +
|
| 65 | + bazel build //:ray_example_1 |
| 66 | + |
| 67 | +In addition you need to change where the Ray library is located. |
| 68 | +Edit the line where the ``LD_LIBRARY_PATH`` variable is declared. This should |
| 69 | +point to ``external/ray/thirdparty/lib`` path. |
| 70 | + |
| 71 | +.. code-block:: |
| 72 | +
|
| 73 | + LD_LIBRARY_PATH="thirdparty/lib" "${ROOT_DIR}"/bazel-bin/ray_example_1 |
| 74 | +
|
| 75 | +Edit the ``BUILD.bazel`` file and change accordingly the variables: |
| 76 | + |
| 77 | +.. code-block:: |
| 78 | +
|
| 79 | + cc_binary( |
| 80 | + name = "ray_example_1", |
| 81 | + srcs = glob([ |
| 82 | + "*.cpp", |
| 83 | + ]), |
| 84 | + data = [ |
| 85 | + "ray_example_1.so", |
| 86 | + ], |
| 87 | + linkstatic = True, |
| 88 | + deps = [ |
| 89 | + ":ray_api", |
| 90 | + ], |
| 91 | + ) |
| 92 | +
|
| 93 | + cc_binary( |
| 94 | + name = "ray_example_1.so", |
| 95 | + srcs = glob([ |
| 96 | + "*.cpp", |
| 97 | + ]), |
| 98 | + linkopts = ["-shared"], |
| 99 | + linkstatic = True, |
| 100 | + deps = [ |
| 101 | + ":ray_api", |
| 102 | + ], |
| 103 | + ) |
| 104 | +
|
| 105 | + cc_library( |
| 106 | + name = "ray_api", |
| 107 | + srcs = [ |
| 108 | + "thirdparty/lib/libray_api.so", |
| 109 | + ], |
| 110 | + hdrs = glob([ |
| 111 | + "thirdparty/include/**/*.h", |
| 112 | + "thirdparty/include/**/*.hpp", |
| 113 | + ]), |
| 114 | + linkopts = ["-Wl,-rpath,./"], |
| 115 | + strip_include_prefix = "thirdparty/include", |
| 116 | + visibility = ["//visibility:public"], |
| 117 | + ) |
| 118 | +
|
| 119 | +In order to build and run the example execute the ``run.sh`` script. This should |
| 120 | +produce the following output: |
| 121 | + |
| 122 | +.. code-block:: |
| 123 | +
|
| 124 | + INFO: Analyzed target //:ray_example_2 (1 packages loaded, 3440 targets configured). |
| 125 | + INFO: Found 1 target... |
| 126 | + Target //:ray_example_2 up-to-date: |
| 127 | + bazel-bin/ray_example_2 |
| 128 | + INFO: Elapsed time: 2.509s, Critical Path: 2.15s |
| 129 | + INFO: 4 processes: 4 linux-sandbox. |
| 130 | + INFO: Build completed successfully, 6 total actions |
| 131 | + [2025-04-05 12:13:21,602 I 24601 24601] config_internal.cc:216: No code search path found yet. The program location path "/home/alex/.cache/bazel/_bazel_alex/25a018d10ef2129864cd574bc2dbc5b9/execroot/__main__/bazel-out/k8-fastbuild/bin" will be added for searching dynamic libraries by default. And you can add some search paths by '--ray_code_search_path' |
| 132 | + [2025-04-05 12:13:21,603 I 24601 24601] process_helper.cc:51: ray start --head --port 6379 --redis-username default --redis-password 5241590000000000 --node-ip-address '192.168.0.129' |
| 133 | + 2025-04-05 12:13:22,376 - INFO - NumExpr defaulting to 8 threads. |
| 134 | + Usage stats collection is enabled. To disable this, add `--disable-usage-stats` to the command that starts the cluster, or run the following command: `ray disable-usage-stats` before starting the cluster. See https://docs.ray.io/en/master/cluster/usage-stats.html for more details. |
| 135 | + |
| 136 | + Local node IP: 192.168.0.129 |
| 137 | +
|
| 138 | + -------------------- |
| 139 | + Ray runtime started. |
| 140 | + -------------------- |
| 141 | +
|
| 142 | + Next steps |
| 143 | + To add another node to this Ray cluster, run |
| 144 | + ray start --address='192.168.0.129:6379' |
| 145 | + |
| 146 | + To connect to this Ray cluster: |
| 147 | + import ray |
| 148 | + ray.init(_node_ip_address='192.168.0.129') |
| 149 | + |
| 150 | + To submit a Ray job using the Ray Jobs CLI: |
| 151 | + RAY_ADDRESS='http://127.0.0.1:8265' ray job submit --working-dir . -- python my_script.py |
| 152 | + |
| 153 | + See https://docs.ray.io/en/latest/cluster/running-applications/job-submission/index.html |
| 154 | + for more information on submitting Ray jobs to the Ray cluster. |
| 155 | + |
| 156 | + To terminate the Ray runtime, run |
| 157 | + ray stop |
| 158 | + |
| 159 | + To view the status of the cluster, use |
| 160 | + ray status |
| 161 | + |
| 162 | + To monitor and debug Ray, view the dashboard at |
| 163 | + 127.0.0.1:8265 |
| 164 | + |
| 165 | + If connection to the dashboard fails, check your firewall settings and network configuration. |
| 166 | + [2025-04-05 12:13:25,278 I 24601 24601] gcs_client.cc:98: GcsClient has no Cluster ID set, and won't fetch from GCS. |
| 167 | + [2025-04-05 12:13:25,292 I 24601 24601] gcs_client.cc:98: GcsClient has no Cluster ID set, and won't fetch from GCS. |
| 168 | + 2025-04-05 12:13:26,854 - INFO - NumExpr defaulting to 8 threads. |
| 169 | + Stopped all 5 Ray processes. |
| 170 | + Result is: 1 |
| 171 | + Running normal C++ stuff here... |
| 172 | + Result is: 1 |
| 173 | +
|
| 174 | +
|
| 175 | +
|
0 commit comments