## 1. Project Overview & Quickstart (rapidsai/cuml) ## File: README.md # NVIDIA cuML: GPU-Accelerated Machine Learning NVIDIA cuML is an open-source CUDA-X Data Science library for GPU-accelerated machine learning. It provides two ways to run machine learning workloads on NVIDIA GPUs: - The `cuml` Python API provides GPU-native estimators with familiar scikit-learn-style APIs and direct control over machine learning workflows. - `cuml.accel` accelerates existing scikit-learn, UMAP, and HDBSCAN code without changing the Python code that uses those libraries. On representative benchmarks, cuML can accelerate scikit-learn workflows by up to 50x. Performance depends on the algorithm, dataset, and hardware. See the [cuML benchmarks](https://docs.nvidia.com/cuml/26.08/cuml-accel/benchmarks/) for results and methodology. ## Use the GPU-native `cuml` API The `cuml` Python API follows the familiar scikit-learn fit-predict-transform pattern while keeping data and computation on the GPU. The following example generates sample data and computes DBSCAN clusters on the GPU: ```python from cuml.datasets import make_blobs from cuml.cluster import DBSCAN # Create sample data X, y = make_blobs(n_samples=100, centers=3, n_features=2, random_state=42) # Fit clustering model dbscan = DBSCAN(eps=1.0, min_samples=5) dbscan.fit(X) print(dbscan.labels_) ``` `cuml` supports clustering, dimensionality reduction, regression, classification, preprocessing, model selection, time series, model explanation, and nearest-neighbor workflows. Browse the [API reference](https://docs.nvidia.com/cuml/26.08/api/) for the current list of estimators and functions. ## Accelerate existing code with `cuml.accel` Run an existing Python script through the [`cuml.accel` module](https://docs.nvidia.com/cuml/26.08/cuml-accel/): ```console python -m cuml.accel script.py ``` Or load the extension in a Jupyter notebook before importing scikit-learn, UMAP, or HDBSCAN: ```python %load_ext cuml.accel ``` Supported operations run on the GPU. When an estimator or configuration cannot be accelerated, `cuml.accel` uses the original CPU implementation so the rest of the workflow can continue. See the [`cuml.accel` compatibility documentation](https://docs.nvidia.com/cuml/26.08/cuml-accel/compatibility/) for current coverage and fallback conditions. Use the [logging and profiling tools](https://docs.nvidia.com/cuml/26.08/cuml-accel/logging-and-profiling/) to check which operations ran on the GPU. ## Scale beyond one GPU The `cuml.dask` API provides distributed implementations of selected algorithms for multi-GPU and multi-node execution with [Dask](https://www.dask.org). See the [multi-GPU guide](https://docs.nvidia.com/cuml/26.08/dask_multigpu_guide/) for cluster setup, supported algorithms, and examples. ## Installation Use the [installation selector](https://docs.rapids.ai/install#selector) to generate a command for installing nightly or release cuML packages with conda, pip, or Docker. Additional resources: - [NVIDIA cuML documentation](https://docs.nvidia.com/cuml/) - [NVIDIA cuML product page](https://developer.nvidia.com/topics/ai/data-science/cuda-x-data-science-libraries/cuml) - [Walkthrough notebooks](https://github.com/NVIDIA/cuml/tree/main/notebooks) - [CUDA-X Data Science libraries](https://developer.nvidia.com/topics/ai/data-science/cuda-x-for-data-science) ## Build and install from source See the [build guide](BUILD.md). ## Scikit-learn compatibility cuML is compatible with scikit-learn version 1.6 or higher. ## Model serialization and security cuML models can be serialized with `pickle` or `joblib` and loaded later for inference. cuML uses cloudpickle so that models trained with `cuml.accel` can be loaded and used with scikit-learn. **Only unpickle or deserialize from trusted sources.** The `pickle` module (and by extension `joblib`) is not secure: malicious payloads can execute arbitrary code during deserialization and compromise your system. **Do not unpickle or load data from untrusted or tampered sources.** This applies to `pickle.load()`, `pickle.loads()`, `joblib.load()`, and any file-based model loading. For details and patterns, see the [Model Serialization and Persistence](docs/source/pickling_cuml_models.ipynb) notebook and the [Python pickle security documentation](https://docs.python.org/3/library/pickle.html). ## Contributing and support See the [contributing guide](CONTRIBUTING.md) to contribute to cuML. Report bugs and request features through [GitHub issues](https://github.com/NVIDIA/cuml/issues). Join the broader community through the [CUDA-X Data Science libraries page](https://developer.nvidia.com/topics/ai/data-science/cuda-x-for-data-science#join-the-community). ## Citation For additional details on the technologies behind cuML and the broader Python machine learning landscape, see [_Machine Learning in Python: Main developments and technology trends in data science, machine learning, and artificial intelligence_ (2020)](https://arxiv.org/abs/2002.04803) by Sebastian Raschka, Joshua Patterson, and Corey Nolet. Please consider citing this work when using cuML in a project: ```bibtex @article{raschka2020machine, title={Machine Learning in Python: Main developments and technology trends in data science, machine learning, and artificial intelligence}, author={Raschka, Sebastian and Patterson, Joshua and Nolet, Corey}, journal={arXiv preprint arXiv:2002.04803}, year={2020} } ``` --- ## File: .devcontainer/README.md # cuML Development Containers This directory contains [devcontainer configurations](https://containers.dev/implementors/json_reference/) for using VSCode to [develop in a container](https://code.visualstudio.com/docs/devcontainers/containers) via the `Remote Containers` [extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) or [GitHub Codespaces](https://github.com/codespaces). This container is a turnkey development environment for building and testing the cuML C++ and Python libraries. ## Table of Contents * [Prerequisites](#prerequisites) * [Host bind mounts](#host-bind-mounts) * [Launch a Dev Container](#launch-a-dev-container) ## Prerequisites * [VSCode](https://code.visualstudio.com/download) * [VSCode Remote Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) ## Host bind mounts By default, the following directories are bind-mounted into the devcontainer: * `${repo}:/home/coder/cuml` * `${repo}/../.aws:/home/coder/.aws` * `${repo}/../.local:/home/coder/.local` * `${repo}/../.cache:/home/coder/.cache` * `${repo}/../.conda:/home/coder/.conda` * `${repo}/../.config:/home/coder/.config` This ensures caches, configurations, dependencies, and your commits are persisted on the host across container runs. ## Launch a Dev Container To launch a devcontainer from VSCode, open the cuML repo and select the "Reopen in Container" button in the bottom right: Alternatively, open the VSCode command palette (typically `cmd/ctrl + shift + P`) and run the "Rebuild and Reopen in Container" command. --- ## File: cpp/examples/dbscan/README.md # DBSCAN This example code demonstrates use of C++ API of cuML DBSCAN. It requires `libcuml.so` in order to build. ## Build The example can be build either as part of cuML or can also be build as a standalone. Two separate `CMakeLists.txt` files are provided for these two cases. 1. `CMakeLists.txt` - To be used when example is build as part of cuML 2. `CMakeLists_standalone.txt` - To be used for building example standalone ### Standalone build While building standalone use `CMakeLists_standalone.txt` and configure with: ```bash $ cmake .. -Dcuml_ROOT=/path/to/cuml ``` then build with `make` ```bash $ make [ 50%] Building CXX object CMakeFiles/dbscan_example.dir/dbscan_example.cpp.o [100%] Linking CUDA executable dbscan_example [100%] Built target dbscan_example ``` On successful build, example should build `dbscan_example` binary. ## Run 1. Run with trivial dataset: When `dbscan_example` is invoked without any options, it loads a default trivial dataset and runs DBSCAN algorithm on that. The output should appear as shown below, ``` Samples file not specified. (-input option) Running with default dataset: Running DBSCAN with following parameters: Number of samples - 25 Number of features - 3 min_pts - 2 eps - 1 Histogram of samples Cluster id, Number samples 0, 13 1, 12 Total number of clusters: 2 Noise samples: 0 ``` 2. Run with non-trivial dataset: To use `dbscan_example` on non-trivial datasets, first input file needs to be prepared. If the dataset has N samples with M features each, the input file needs to be and ASCII file with N\*M rows with features linearized as below, ``` sample-0-feature-0 sample-0-feature-1 ... sample-0-feature-(M-1) sample-1-feature-0 sample-1-feature-1 ... sample-1-feature-(M-1) ... ... sample-(N-1)-feature-0 sample-(N-1)-feature-1 ... sample-(N-1)-feature-(M-1) ``` All the features must be single precision floating point numbers. The example demonstrates single precision DBSCAN, but the cuML DBSCAN works equally well with double precision floating point numbers. Once input file is ready, the `dbscan_example` can be invoked as below, ``` $ ./dbscan_example -input -num_samples <#samples> -num_features <#features> [-min_pts ] [-eps ] ``` The output would look similar to, ``` Trying to read samples from synthetic-10000x25-clusters-15.txt Running DBSCAN with following parameters: Number of samples - 10000 Number of features - 25 min_pts - 5 eps - 0.6 Histogram of samples Cluster id, Number samples 0, 665 1, 664 2, 663 3, 666 4, 665 5, 666 6, 662 7, 664 8, 666 9, 666 10, 663 11, 662 12, 665 13, 667 14, 666 Total number of clusters: 15 Noise samples: 30 ``` The output of the example is a histogram of sample count in each cluster. Number of noise samples are also reported. ### Details of command line options * `-dev_id`: The id of the CUDA GPU to use (default 0) * `-num_samples`: Number of samples * `-num_features`: Number of features * `-input`: Plain text input file with samples in row major order * `-min_pts`: Minimum number of samples in a cluster (default 3) * `-eps`: Maximum distance between any two samples of a cluster (default 1.0) If `-input` is specified, `-num_samples` and `-num_features` must be specified. ## Synthetic dataset generator For convenience, a synthetic dataset generator `gen_dataset.py` is included with the example. It can be used as shown below, ``` ./gen_dataset.py --num_samples 1000 --num_features 16 --num_clusters 10 --filename_prefix synthetic Dataset file: synthetic-1000x16-clusters-10.txt Generated total 1000 samples with 16 features each Number of clusters = 10 ``` Command line options * `--num_samples` or `-ns`: Number of samples * `--num_features` or `-nf`: Number of features * `--num_clusters` or `-nc`: Number of clusters * `--filename_prefix`: Prefix used for dataset output file. Number of samples, features and clusters are appended as shown in above example. * `--standard_dev` or `-sd`: Standard deviation of samples generated (default 0.1) * `--random_state` of `-rs`: Random state used for seeding the pseudo-random number generator (default 123456) --- ## File: cpp/examples/kmeans/README.md # kmeans This subfolder contains an example on how to use cuML kmeans from C++ application There are two `CMakeLists.txt` in this folder: 1. `CMakeLists.txt` (default) which is included when building cuML 2. `CMakeLists_standalone.txt` as an example for a stand alone project linking to `libcuml.so` ## Build `kmeans_example` is build as part of cuML. If it should be build as a standalone executable use `CMakeLists_standalone.txt` and configure with: ```bash $ cmake .. -Dcuml_ROOT=/path/to/cuml ``` then build with `make` ```bash $ make Scanning dependencies of target kmeans_example [ 50%] Building CXX object CMakeFiles/kmeans_example.dir/kmeans_example.cpp.o [100%] Linking CUDA executable kmeans_example [100%] Built target kmeans_example ``` ## Run 1. With tiny test input: ``` ./kmeans_example Run KMeans with k=2, max_iterations=300 ``` 2. With larger test data from Kaggle 1. Prepare input: Download Homesite Quote Conversion data from https://www.kaggle.com/c/homesite-quote-conversion/data and use `./prepare_input.py [train_file=train.csv] [test_file=test.csv] [output=output.txt]`: ``` $ unzip all.zip $ ./prepare_input.py [train_file=train.csv] [test_file=test.csv] [output=output.txt] Reading Input from train_file = train.csv and test_file = test.csv Training dataset dimension: (260753, 299) Test dataset dimension: (173836, 298) Output dataset dimension: (260753, 298) Wrote 77704394 values in row major order to output output.txt ``` 2. Run ``` $ ./kmeans_example -num_rows 260753 -num_cols 298 -input output.txt Reading input with 260753 rows and 298 columns from output.txt. Run KMeans with k=10, max_iterations=300 num_pts inertia 0 18615 7.749915e+12 1 18419 7.592070e+12 2 30842 1.815066e+13 3 31247 1.832832e+13 4 31272 1.887647e+13 5 18362 7.749335e+12 6 31028 1.821217e+13 7 31040 1.869879e+13 8 18652 7.681686e+12 9 31276 1.877210e+13 Global inertia = 1.418115e+14 ``` To run with other inputs the executable `kmeans_example` has the following commandline options * `-dev_id`: The id of the CUDA GPU to use (default 0) * `-num_rows`: Number of rows in the input file (default 0) * `-num_cols`: Number of columns in the input file (default 0) * `-input`: Input file name with input values as text in row major order (default empty string) * `-k`: Number of clusters (default 10) * `-max_iterations`: Maximum number of iterations to execute (default 300) --- ## File: cpp/examples/symreg/README.md # symbolic regression This subfolder contains an example on how perform symbolic regression in cuML (from C++) There are two `CMakeLists.txt` in this folder: 1. `CMakeLists.txt` (default) which is included when building cuML 2. `CMakeLists_standalone.txt` as an example for a stand alone project linking to `libcuml.so` ## Build `symreg_example` is built as a part of cuML. To build it as a standalone executable, do ```bash $ cmake .. -DCUML_LIBRARY_DIR=/path/to/directory/with/libcuml.so -DCUML_INCLUDE_DIR=/path/to/cuml/headers ``` Then build with `make` or `ninja` ``` $ make Scanning dependencies of target raft [ 10%] Creating directories for 'raft' [ 20%] Performing download step (git clone) for 'raft' Cloning into 'raft'... [ 30%] Performing update step for 'raft' [ 40%] No patch step for 'raft' [ 50%] No configure step for 'raft' [ 60%] No build step for 'raft' [ 70%] No install step for 'raft' [ 80%] Completed 'raft' [ 80%] Built target raft Scanning dependencies of target symreg_example [ 90%] Building CXX object CMakeFiles/symreg_example.dir/symreg_example.cpp.o [100%] Linking CUDA executable symreg_example [100%] Built target symreg_example ``` `CMakeLists_standalone.txt` also loads a minimal set of header dependencies(namely [raft](https://github.com/rapidsai/raft) and [cub](https://github.com/NVIDIA/cub)) if they are not detected in the system. ## Run 1. Generate a toy training and test dataset ``` $ python prepare_input.py Training set has n_rows=250 n_cols=2 Test set has n_rows=50 n_cols=2 Wrote 500 values to train_data.txt Wrote 100 values to test_data.txt Wrote 250 values to train_labels.txt Wrote 50 values to test_labels.txt ``` 2. Run the symbolic regressor using the 4 files as inputs. An example query is given below ```bash $ ./symreg_example -n_cols 2 \ -n_train_rows 250 \ -n_test_rows 50 \ -random_state 21 \ -population_size 4000 \ -generations 20 \ -stopping_criteria 0.01 \ -p_crossover 0.7 \ -p_subtree 0.1 \ -p_hoist 0.05 \ -p_point 0.1 \ -parsimony_coefficient 0.01 ``` 3. The corresponding output for the above query is given below : ``` Reading input with 250 rows and 2 columns from train_data.txt. Reading input with 250 rows from train_labels.txt. Reading input with 50 rows and 2 columns from test_data.txt. Reading input with 50 rows from test_labels.txt. *************************************** Allocating device memory... Allocation time = 0.259072ms *************************************** Beginning training on given dataset... Finished training for 4 generations. Best AST index : 1855 Best AST depth : 3 Best AST length : 13 Best AST equation :( add( sub( mult( X0, X0) , div( X1, X1) ) , sub( X1, mult( X1, X1) ) ) ) Training time = 626.658ms *************************************** Beginning Inference on Test dataset... Inference score on test set = 5.29271e-08 Inference time = 0.35248ms Some Predicted test values: -1.65061;-1.64081;-0.91711;-2.28976;-0.280688; Corresponding Actual test values: -1.65061;-1.64081;-0.91711;-2.28976;-0.280688; ``` --- ## File: cpp/README.md # cuML C++ This folder contains the C++ and CUDA code of the algorithms and ML primitives of cuML. The build system uses CMake for build configuration, and an out-of-source build is recommended. ## Source Code Folders The source code of cuML is divided mainly into `src` and `src_prims`. - `src` contains the source code of the Machine Learning algorithms, and the main cuML C++ API. The main consumable is the shared library `libcuml`, that can be used stand alone by C++ consumers or is consumed by our Python package `cuml` to provide a Python API. - `src_prims` contains most of the common components and computational primitives that form part of the machine learning algorithms in cuML, and can be used individually as well in the form of a header only library. Multi-GPU communication is provided through RAFT communicator APIs; cuML does not build separate `std` or `mpi` communicator libraries. The `tests` directory contains single-GPU, multi-GPU, and primitive tests. ## Setup ### Dependencies 1. cmake (>= 3.26.4) 2. CUDA (>= 12.2) 3. gcc (>=13.0) 4. clang-format (= 20.1.8) - enforces uniform C++ coding style; required to build cuML from source. The packages `clang=20` and `clang-tools=20` from the conda-forge channel should be sufficient, if you are on conda. If not using conda, install the right version using your OS package manager. ### Building cuML: The main artifact produced by the build system is the shared library `libcuml`. Additionally, executables to run tests for the algorithms can be built. To see detailed steps see the [BUILD](../BUILD.md) document of the repository. Current cmake offers the following configuration options: - Build Configuration Options: | Flag | Possible Values | Default Value | Behavior | | --- | --- | --- | --- | | BUILD_CUML_CPP_LIBRARY | [ON, OFF] | ON | Enable/disable building the `libcuml` shared library. Setting this variable to `OFF` also forces `BUILD_CUML_TESTS`, `BUILD_CUML_MG_TESTS`, `BUILD_CUML_EXAMPLES`, `BUILD_PRIMS_TESTS`, and `BUILD_CUML_BENCH` to `OFF` | | BUILD_CUML_TESTS | [ON, OFF] | ON | Enable/disable building cuML single-GPU C++ test targets. | | BUILD_CUML_MG_TESTS | [ON, OFF] | OFF | Enable/disable building cuML multi-GPU C++ test targets. Requires MPI and RAFT distributed dependencies. See section about additional requirements. | | BUILD_PRIMS_TESTS | [ON, OFF] | ON | Enable/disable building cuML primitive C++ test targets. | | BUILD_CUML_EXAMPLES | [ON, OFF] | ON | Enable/disable building cuML C++ API usage examples. | | BUILD_CUML_BENCH | [ON, OFF] | ON | Enable/disable building of cuML C++ benchmark. | | SINGLEGPU | [ON, OFF] | OFF | Disable cuML MNMG C++ sources and tests, and build cuVS without multi-GPU algorithms. Forces `BUILD_CUML_MG_TESTS` to `OFF`. | | DISABLE_OPENMP | [ON, OFF] | OFF | Set to `ON` to disable OpenMP | | CMAKE_CUDA_ARCHITECTURES | List of GPU architectures, semicolon-separated | Empty | List the GPU architectures to compile the GPU targets for. Set to "NATIVE" to auto detect GPU architecture of the system, set to "ALL" to compile for all RAPIDS supported archs: ["60" "62" "70" "72" "75" "80" "86"]. | | USE_CCACHE | [ON, OFF] | ON | Cache build artifacts with ccache. | - Debug configuration options: | Flag | Possible Values | Default Value | Behavior | | --- | --- | --- | --- | | KERNEL_INFO | [ON, OFF] | OFF | Enable/disable kernel resource usage info in nvcc. | | LINE_INFO | [ON, OFF] | OFF | Enable/disable lineinfo in nvcc. | | NVTX | [ON, OFF] | OFF | Enable/disable nvtx markers in libcuml. | After running CMake in a `build` directory, if the `BUILD_*` options were not turned `OFF`, the following targets can be built: ```bash $ cmake --build . -j # Build libcuml and enabled C++ test targets $ cmake --build . -j --target sg_benchmark # Build C++ cuML single-GPU benchmark $ cmake --build . -j --target cuml # Build libcuml # Test executables are generated as individual CTest targets with SG_, MG_, or PRIMS_ prefixes. ``` ### MultiGPU Tests Requirements Note: To build the MultiGPU tests (CMake option `BUILD_CUML_MG_TESTS`), the following dependencies are required: - MPI (OpenMPI recommended) - RAFT distributed dependencies, including NCCL and UCXX/UCX. See RAFT's build documentation for the current requirements. ### Third Party Modules The external folder contains submodules that cuML depends on. Current external submodules are: 1. [CUB](https://github.com/NVlabs/cub) 2. [Faiss](https://github.com/facebookresearch/faiss) 3. [Google Test](https://github.com/google/googletest) ## Using cuML libraries After building cuML, you can use its functionality in other C++ applications by linking against the generated libraries, or from Python via the `cuml` package. The following trivial example shows how to make external use of cuML's logger: ```cpp // main.cpp #include int main(int argc, char *argv[]) { CUML_LOG_WARN("This is a warning from the cuML logger!"); return 0; } ``` To compile this example, we must point the compiler to where cuML was installed. Assuming you did not provide a custom `$CMAKE_INSTALL_PREFIX`, this will default to the `$CONDA_PREFIX` environment variable. ```bash $ export LD_LIBRARY_PATH="${CONDA_PREFIX}/lib" $ nvcc \ main.cpp \ -o cuml_logger_example \ "-L${CONDA_PREFIX}/lib" \ "-I${CONDA_PREFIX}/include" \ "-I${CONDA_PREFIX}/include/cuml/raft" \ -lcuml $ ./cuml_logger_example [W] [13:26:43.503068] This is a warning from the cuML logger! ``` --- ## File: docs/source/_templates/autosummary/base.rst {{ objname | escape | underline(line="=") }} {% if objtype == "module" -%} .. automodule:: {{ fullname }} {%- elif objtype == "function" -%} .. currentmodule:: {{ module }} .. autofunction:: {{ objname }} {%- elif objtype == "class" -%} .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} :members: {%- else -%} .. currentmodule:: {{ module }} .. auto{{ objtype }}:: {{ objname }} {%- endif -%} --- ## File: docs/source/api/cuml.accel.rst cuml.accel ========== .. automodule:: cuml.accel .. currentmodule:: cuml.accel .. autosummary:: :nosignatures: :toctree: generated/ :template: base.rst install enabled profile is_proxy --- ## File: docs/source/api/cuml.benchmark.rst cuml.benchmark ============== Algorithms ---------- .. automodule:: cuml.benchmark.algorithms :members: Runners ------- .. automodule:: cuml.benchmark.runners :members: Data Generation --------------- .. automodule:: cuml.benchmark.datagen :members: --- ## File: docs/source/api/cuml.cluster.rst cuml.cluster ============ .. automodule:: cuml.cluster .. currentmodule:: cuml.cluster .. autosummary:: :nosignatures: :toctree: generated/ :template: base.rst AgglomerativeClustering DBSCAN KMeans SpectralClustering spectral_clustering hdbscan.HDBSCAN hdbscan.all_points_membership_vectors hdbscan.membership_vector hdbscan.approximate_predict ## 2. Official Technical Reference & Guides (rapidsai/docs) # NVIDIA RAPIDS Documentation This repository contains the source for the [NVIDIA RAPIDS documentation site](https://docs.rapids.ai/). The site is built with Sphinx and the NVIDIA Sphinx theme. ## Build the site Install [uv](https://docs.astral.sh/uv/), then run: ```shell make html make serve ``` The rendered site is written to `_site`. The server uses port 8000 by default; override it with `PORT` (for example, `make serve PORT=8080`). ## Build the full site The complete docs site imports versioned API documentation and the deployment documentation from the private `rapidsai-docs` S3 bucket. Configure a read-only AWS profile named `rapids-docs`, then run: ```shell AWS_PROFILE=rapids-docs make full ``` This applies the RAPIDS library/version selectors to the imported documentation. ## Validation ```shell make check ``` Run checks including linting, tests, and a local build. Pull requests opened against `rapidsai/docs` are copied to a `pull-request/` branch by the RAPIDS copy-PR bot. That branch runs the same validation and dry-runs assembly of the complete S3-backed documentation tree without deploying it. Netlify's repository integration separately creates a site preview. Merges to `main` deploy the production site. ## Repository layout - `sphinx/` contains the Sphinx configuration, templates, and theme overrides. - `extensions/` contains custom code extending Sphinx for this site. - `ci/` contains code used by automated testing and deployment jobs. - `scripts/` and `tests/` validate rendered routes, content, and publication behavior.