"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Monte Carlo Approximation of $\\pi$ - NVSHMEM with Distributed Work"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this notebook you will use NVSHMEM in the monte-carlo approximation of $\\pi$ program, but this time distributing the work across GPUs."
]
},
{
"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 distribute work across multiple GPUs using NVSHMEM."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exercise: Distribute Work Across PEs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this exercise you will have each GPU divide the $N$ sample points by the number $M$ of PEs. We can use the API `nvshmem_n_pes()` to obtain this:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```cpp\n",
"int n_pes = nvshmem_n_pes();\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then it's simple to divide up $N$ by `n_pes`. As an additional step to make this more interesting, also have each GPU do *different* work by choosing the random seed to be unique for each PE:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```cpp\n",
"int seed = nvshmem_my_pe();\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Please work in [exercises/nvshmem_pi_step2.cpp](exercises/nvshmem_pi_step2.cpp). As before, deal with any `FIXME` locations, then come back and compile and run. What you should observe is that each PE gets a slightly different answer, and the answer should be less accurate because we're using fewer sample points.\n",
"\n",
"Check the [solution](solutions/nvshmem_pi_step2.cpp) if you're stuck."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!nvcc -x cu -arch=sm_70 -rdc=true -I $NVSHMEM_HOME/include -L $NVSHMEM_HOME/lib -lnvshmem -lcuda -o nvshmem_pi_step2 exercises/nvshmem_pi_step2.cpp\n",
"!nvshmrun -np $NUM_DEVICES ./nvshmem_pi_step2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the next notebook you will learn about one of the key features on NVSHMEM, *symmetric memory*, which allows for fine-grained inter-GPU communications from device-side code.\n",
"\n",
"Please open the next notebook: [_The NVSHMEM Memory Model_](09_MCπ-NVSHMEM-Sym.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.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}