The hist tree method can use a special data structure `ExtMemQuantileDMatrix` for faster initialization and lower memory usage.
(
worker_idx: int,
tmpdir: str,
device: str,
rabit_args: dict,
)
| 195 | |
| 196 | @try_run |
| 197 | def hist_train( |
| 198 | worker_idx: int, |
| 199 | tmpdir: str, |
| 200 | device: str, |
| 201 | rabit_args: dict, |
| 202 | ) -> None: |
| 203 | """The hist tree method can use a special data structure `ExtMemQuantileDMatrix` for |
| 204 | faster initialization and lower memory usage. |
| 205 | |
| 206 | """ |
| 207 | |
| 208 | # Make sure XGBoost is using the configured memory pool for all allocations. |
| 209 | with ( |
| 210 | coll.CommunicatorContext(**rabit_args), |
| 211 | xgboost.config_context( |
| 212 | use_cuda_async_pool=device == "cuda", |
| 213 | ), |
| 214 | ): |
| 215 | print("Worker: ", worker_idx) |
| 216 | # Generate the data for demonstration. The synthetic data is sharded by workers. |
| 217 | files = make_batches( |
| 218 | n_samples_per_batch=4096, |
| 219 | n_features=16, |
| 220 | n_batches=17, |
| 221 | tmpdir=tmpdir, |
| 222 | rank=coll.get_rank(), |
| 223 | ) |
| 224 | # Since we are running two workers on a single node, we should divide the number |
| 225 | # of threads between workers. |
| 226 | n_threads = os.cpu_count() |
| 227 | assert n_threads is not None |
| 228 | n_threads = max(n_threads // coll.get_world_size(), 1) |
| 229 | it = Iterator(device, files) |
| 230 | Xy = xgboost.ExtMemQuantileDMatrix( |
| 231 | it, missing=np.nan, enable_categorical=False, nthread=n_threads |
| 232 | ) |
| 233 | # Check the device is correctly set. |
| 234 | if device == "cuda": |
| 235 | # Check the first device |
| 236 | assert ( |
| 237 | int(os.environ["CUDA_VISIBLE_DEVICES"].split(",")[0]) |
| 238 | < coll.get_world_size() |
| 239 | ) |
| 240 | booster = xgboost.train( |
| 241 | { |
| 242 | "tree_method": "hist", |
| 243 | "max_depth": 4, |
| 244 | "device": it.device, |
| 245 | "nthread": n_threads, |
| 246 | }, |
| 247 | Xy, |
| 248 | evals=[(Xy, "Train")], |
| 249 | num_boost_round=10, |
| 250 | ) |
| 251 | booster.predict(Xy) |
| 252 | |
| 253 | |
| 254 | def launch_workers(tmpdir: str, args: argparse.Namespace) -> None: |
nothing calls this directly
no test coverage detected