{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Monte Carlo Approximation of $\\pi$ - Multiple GPUs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this notebook we will refactor the single GPU implementation of the monte carlo approximation of $\\pi$ algorithm to run on multiple GPUs using a technique of looping over available GPU devices to perform work on each. While this is a perfectly valid technique, we hope to begin demonstrating that it can quickly add significant complexity to your code." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Objectives" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By the time you complete this notebook you will:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Be able to utilize multiple GPUs by looping over them to perform work on each." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extending to Multiple GPUs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A simple way to extend our example to multiple GPUs is to use a single host process that manages multiple GPUs. If we have *M* GPUs and *N* sample points to evaluate, we can distribute *N/M* to each GPU, and in principle calculate the result up to *M* times more quickly.\n", "\n", "To enact this approach, we:\n", "- Use `cudaGetDeviceCount` to ascertain the number of available GPUs.\n", "- Loop over the number of GPUs, using `cudaSetDevice` in each loop iteration.\n", "- Perform the correct fraction of the work for the set GPU." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```cpp\n", "int device_count;\n", "cudaGetDeviceCount(&device_count);\n", "\n", "for (int i = 0; i < device_count; ++i) {\n", " cudaSetDevice(i);\n", " # Do single GPU worth of work.\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise: Complete the Refactor to Multiple GPUs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[exercises/monte_carlo_mgpu_cuda.cpp](exercises/monte_carlo_mgpu_cuda.cpp) is an incomplete example of this approach. Note that in this example we are giving each GPU a different seed for the random number generator so that each GPU is doing different work. As a result our answer will change a little.\n", "\n", "We've given you a few simple tasks to do in the code focused on the extra work this approach requires to give a single GPU the correct amount of work. Look for locations denoted by `FIXME` for where you should work.\n", "\n", "If you get stuck, you can consult [the solution](solutions/monte_carlo_mgpu_cuda.cpp)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Run the Code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After completing your work, compile and run the code using the following cells." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!nvcc -x cu -arch=sm_70 -o monte_carlo_mgpu_cuda exercises/monte_carlo_mgpu_cuda.cpp" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "!./monte_carlo_mgpu_cuda" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Next" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the next notebook you will refactor this loop-over-the-GPUs code to utilize _GPUDirect Peer-to-Peer_ which enables GPU-to-GPU memory copies as well as loads and stores directly over the memory fabric. Its use can really boost application performance, and as you will see, can also simplify memory management in your code by allowing each of several GPUs to work with a single allocation of memory.\n", "\n", "Please open the next notebook: [_Monte Carlo Approximation of $\\pi$ - Multiple GPUs with Peer Access_](04_MCπ-P2P.ipynb)." ] } ], "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.10.9" } }, "nbformat": 4, "nbformat_minor": 4 }