{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Monte Carlo Method\n", "\n", "As a simple example of a Monte Carlo method, we will approximate the value of $\\pi$:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "import pyopencl as cl\n", "import pyopencl.array\n", "import pyopencl.clrandom\n", "import loopy as lp" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "ctx = cl.create_some_context()\n", "queue = cl.CommandQueue(ctx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sample generation" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "knl = lp.make_kernel(\n", " \"{ [i, j]: 0<=i key2 = make_uint2(i, k1)\n", " <> ctr = make_uint4(0, 1, 2, 3)\n", " <> rng_res, <> dummy = philox4x32_f32(ctr, key2)\n", " \n", " samples[i,0] = rng_res.s0 + 1j*rng_res.s1\n", " samples[i,1] = rng_res.s2 + 1j*rng_res.s3\n", "\n", " accepted[i,j] = real(samples[i,j] * conj(samples[i,j])) < 1\n", " \"\"\") \n", "\n", "knl = lp.split_iname(knl, \"i\", 128, outer_tag=\"g.0\", inner_tag=\"l.0\")\n", "knl = lp.set_options(knl, return_dict=True)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "knl = lp.set_options(knl, write_cl=True)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "#define lid(N) ((int) get_local_id(N))\n", "#define gid(N) ((int) get_group_id(N))\n", "#include \n", "#include \n", "\n", "\n", "\n", "typedef union {\n", " uint4 v;\n", " philox4x32_ctr_t c;\n", "} philox4x32_ctr_vec_union;\n", "\n", "\n", "uint4 philox4x32_bump(uint4 ctr)\n", "{\n", " if (++ctr.x == 0)\n", " if (++ctr.y == 0)\n", " ++ctr.z;\n", " return ctr;\n", "}\n", "\n", "uint4 philox4x32_gen(\n", " uint4 ctr,\n", " uint2 key,\n", " uint4 *new_ctr)\n", "{\n", " philox4x32_ctr_vec_union result;\n", " result.c = philox4x32(\n", " *(philox4x32_ctr_t *) &ctr,\n", " *(philox4x32_key_t *) &key);\n", " *new_ctr = philox4x32_bump(ctr);\n", " return result.v;\n", "}\n", "\n", "float4 philox4x32_f32(\n", " uint4 ctr,\n", " uint2 key,\n", " uint4 *new_ctr)\n", "{\n", " *new_ctr = ctr;\n", " return\n", " convert_float4(philox4x32_gen(*new_ctr, key, new_ctr))\n", " * 2.3283064365386963e-10f;\n", "}\n", "\n", "double4 philox4x32_f64(\n", " uint4 ctr,\n", " uint2 key,\n", " uint4 *new_ctr)\n", "{\n", " *new_ctr = ctr;\n", " return\n", " convert_double4(philox4x32_gen(*new_ctr, key, new_ctr))\n", " * 2.3283064365386963e-10\n", " +\n", " convert_double4(philox4x32_gen(*new_ctr, key, new_ctr))\n", " * 5.421010862427522e-20;\n", "\n", "}\n", "\n", "__kernel void __attribute__ ((reqd_work_group_size(128, 1, 1))) loopy_kernel(__global int *restrict accepted, int const k1, int const n, __global cfloat_t *restrict samples)\n", "{\n", " uint4 ctr;\n", " uint4 dummy;\n", " uint2 key2;\n", " float4 rng_res;\n", "\n", " ctr = (uint4) (0, 1, 2, 3);\n", " if (-1 + -128 * gid(0) + -1 * lid(0) + n >= 0)\n", " {\n", " key2 = (uint2) (lid(0) + gid(0) * 128, k1);\n", " rng_res = philox4x32_f32(ctr, key2, &(dummy));\n", " samples[2 * (lid(0) + gid(0) * 128) + 1] = cfloat_radd(rng_res.s2, cfloat_rmul(rng_res.s3, cfloat_new(0.0, 1.0)));\n", " samples[2 * (lid(0) + gid(0) * 128)] = cfloat_radd(rng_res.s0, cfloat_rmul(rng_res.s1, cfloat_new(0.0, 1.0)));\n", " for (int j = 0; j <= 1; ++j)\n", " accepted[2 * (lid(0) + gid(0) * 128) + j] = cfloat_real(cfloat_mul(samples[2 * (lid(0) + gid(0) * 128) + j], cfloat_conj(samples[2 * (lid(0) + gid(0) * 128) + j]))) < 1;\n", " }\n", "}\n" ] } ], "source": [ "evt, result = knl(queue, n=100000, k1=np.int32(99123))\n", "\n", "samples = result[\"samples\"].reshape(-1)\n", "accepted = result[\"accepted\"].reshape(-1)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as pt\n", "\n", "samples_host = samples.get()\n", "accepted_host = accepted.get() != 0\n", "\n", "pt.gca().set_aspect(\"equal\")\n", "pt.plot(\n", " samples_host[accepted_host].real,\n", " samples_host[accepted_host].imag, \"o\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lastly, we compute the ratio of accepted to the total number of samples to get our approximate value of $\\pi$:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3.1429200000000002" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "4 * cl.array.sum(accepted).get() / len(samples)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We (roughly) expect convergence as $1/\\sqrt N$, so this gives an idea of the relative error to expect:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.0022360679774997899" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1/np.sqrt(len(samples))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Direct Reduction" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[36m#\u001b[39;49;00m\u001b[36mdefine lid(N) ((int) get_local_id(N))\u001b[39;49;00m\u001b[36m\u001b[39;49;00m\n", "\u001b[36m#\u001b[39;49;00m\u001b[36mdefine gid(N) ((int) get_group_id(N))\u001b[39;49;00m\u001b[36m\u001b[39;49;00m\n", "\u001b[36m#\u001b[39;49;00m\u001b[36mdefine int_floor_div_pos_b(a,b) ( ( (a) - ( ((a)<0) ? ((b)-1) : 0 ) ) \u001b[39;49;00m\u001b[36m/\u001b[39;49;00m\u001b[36m (b) )\u001b[39;49;00m\u001b[36m\u001b[39;49;00m\n", "\u001b[36m#\u001b[39;49;00m\u001b[36minclude\u001b[39;49;00m \u001b[37m\u001b[39;49;00m\u001b[36m\u001b[39;49;00m\n", "\u001b[36m#\u001b[39;49;00m\u001b[36minclude\u001b[39;49;00m \u001b[37m\u001b[39;49;00m\u001b[36m\u001b[39;49;00m\n", "\n", "\n", "\n", "\u001b[34mtypedef\u001b[39;49;00m \u001b[34munion\u001b[39;49;00m {\n", " uint4 v;\n", " philox4x32_ctr_t c;\n", "} philox4x32_ctr_vec_union;\n", "\n", "\n", "uint4 \u001b[32mphilox4x32_bump\u001b[39;49;00m(uint4 ctr)\n", "{\n", " \u001b[34mif\u001b[39;49;00m (++ctr.x == \u001b[34m0\u001b[39;49;00m)\n", " \u001b[34mif\u001b[39;49;00m (++ctr.y == \u001b[34m0\u001b[39;49;00m)\n", " ++ctr.z;\n", " \u001b[34mreturn\u001b[39;49;00m ctr;\n", "}\n", "\n", "uint4 \u001b[32mphilox4x32_gen\u001b[39;49;00m(\n", " uint4 ctr,\n", " uint2 key,\n", " uint4 *new_ctr)\n", "{\n", " philox4x32_ctr_vec_union result;\n", " result.c = philox4x32(\n", " *(philox4x32_ctr_t *) &ctr,\n", " *(philox4x32_key_t *) &key);\n", " *new_ctr = philox4x32_bump(ctr);\n", " \u001b[34mreturn\u001b[39;49;00m result.v;\n", "}\n", "\n", "float4 \u001b[32mphilox4x32_f32\u001b[39;49;00m(\n", " uint4 ctr,\n", " uint2 key,\n", " uint4 *new_ctr)\n", "{\n", " *new_ctr = ctr;\n", " \u001b[34mreturn\u001b[39;49;00m\n", " convert_float4(philox4x32_gen(*new_ctr, key, new_ctr))\n", " * \u001b[34m2.3283064365386963e-10\u001b[39;49;00mf;\n", "}\n", "\n", "double4 \u001b[32mphilox4x32_f64\u001b[39;49;00m(\n", " uint4 ctr,\n", " uint2 key,\n", " uint4 *new_ctr)\n", "{\n", " *new_ctr = ctr;\n", " \u001b[34mreturn\u001b[39;49;00m\n", " convert_double4(philox4x32_gen(*new_ctr, key, new_ctr))\n", " * \u001b[34m2.3283064365386963e-10\u001b[39;49;00m\n", " +\n", " convert_double4(philox4x32_gen(*new_ctr, key, new_ctr))\n", " * \u001b[34m5.421010862427522e-20\u001b[39;49;00m;\n", "\n", "}\n", "\n", "__kernel \u001b[36mvoid\u001b[39;49;00m \u001b[32m__attribute__\u001b[39;49;00m ((reqd_work_group_size(\u001b[34m128\u001b[39;49;00m, \u001b[34m1\u001b[39;49;00m, \u001b[34m1\u001b[39;49;00m))) loopy_kernel(\u001b[36mint\u001b[39;49;00m \u001b[34mconst\u001b[39;49;00m nl, __global \u001b[36mint\u001b[39;49;00m *\u001b[34mrestrict\u001b[39;49;00m result, __global \u001b[36mint\u001b[39;49;00m *\u001b[34mrestrict\u001b[39;49;00m tmp)\n", "{\n", " __local \u001b[36mint\u001b[39;49;00m acc_j[\u001b[34m50\u001b[39;49;00m];\n", " __local \u001b[36mint\u001b[39;49;00m acc_l_inner[\u001b[34m128\u001b[39;49;00m];\n", " \u001b[36mint\u001b[39;49;00m acc_l_outer;\n", " \u001b[36mint\u001b[39;49;00m accepted[\u001b[34m2\u001b[39;49;00m];\n", " uint4 ctr;\n", " uint4 dummy;\n", " uint2 key2;\n", " float4 rng_res;\n", " cfloat_t samples[\u001b[34m2\u001b[39;49;00m];\n", "\n", " \u001b[34mif\u001b[39;49;00m (-\u001b[34m1\u001b[39;49;00m + nl >= \u001b[34m0\u001b[39;49;00m)\n", " {\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m49\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = \u001b[34m0\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (-\u001b[34m1\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) + nl >= \u001b[34m0\u001b[39;49;00m)\n", " acc_l_outer = \u001b[34m0\u001b[39;49;00m;\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = \u001b[34m0\u001b[39;49;00m;\n", " ctr = (uint4) (\u001b[34m0\u001b[39;49;00m, \u001b[34m1\u001b[39;49;00m, \u001b[34m2\u001b[39;49;00m, \u001b[34m3\u001b[39;49;00m);\n", " \u001b[34mif\u001b[39;49;00m (-\u001b[34m1\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) + nl >= \u001b[34m0\u001b[39;49;00m)\n", " {\n", " \u001b[34mfor\u001b[39;49;00m (\u001b[36mint\u001b[39;49;00m l_outer = \u001b[34m0\u001b[39;49;00m; l_outer <= -\u001b[34m1\u001b[39;49;00m + int_floor_div_pos_b(\u001b[34m127\u001b[39;49;00m + nl, \u001b[34m128\u001b[39;49;00m); ++l_outer)\n", " \u001b[34mif\u001b[39;49;00m (-\u001b[34m1\u001b[39;49;00m + -\u001b[34m128\u001b[39;49;00m * l_outer + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) + nl >= \u001b[34m0\u001b[39;49;00m)\n", " {\n", " key2 = (uint2) (nl * gid(\u001b[34m0\u001b[39;49;00m) + lid(\u001b[34m0\u001b[39;49;00m) + l_outer * \u001b[34m128\u001b[39;49;00m, \u001b[34m1234\u001b[39;49;00m);\n", " rng_res = philox4x32_f32(ctr, key2, &(dummy));\n", " samples[\u001b[34m1\u001b[39;49;00m] = cfloat_radd(rng_res.s2, cfloat_rmul(rng_res.s3, cfloat_new(\u001b[34m0.0\u001b[39;49;00m, \u001b[34m1.0\u001b[39;49;00m)));\n", " samples[\u001b[34m0\u001b[39;49;00m] = cfloat_radd(rng_res.s0, cfloat_rmul(rng_res.s1, cfloat_new(\u001b[34m0.0\u001b[39;49;00m, \u001b[34m1.0\u001b[39;49;00m)));\n", " \u001b[34mfor\u001b[39;49;00m (\u001b[36mint\u001b[39;49;00m isamp = \u001b[34m0\u001b[39;49;00m; isamp <= \u001b[34m1\u001b[39;49;00m; ++isamp)\n", " accepted[isamp] = cfloat_real(cfloat_mul(samples[isamp], cfloat_conj(samples[isamp]))) < \u001b[34m1\u001b[39;49;00m;\n", " acc_l_outer = acc_l_outer + accepted[\u001b[34m0\u001b[39;49;00m] + accepted[\u001b[34m1\u001b[39;49;00m];\n", " }\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_outer;\n", " }\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_l_inner (red_l_inner_stage_0 depends on insn_3_l_inner_init) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m63\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] + acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m64\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_l_inner (red_l_inner_stage_1 depends on red_l_inner_stage_0) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m31\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] + acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m32\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_l_inner (red_l_inner_stage_2 depends on red_l_inner_stage_1) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m15\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] + acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m16\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_l_inner (red_l_inner_stage_3 depends on red_l_inner_stage_2) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m7\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] + acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m8\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_l_inner (red_l_inner_stage_4 depends on red_l_inner_stage_3) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m3\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] + acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m4\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_l_inner (red_l_inner_stage_5 depends on red_l_inner_stage_4) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m1\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] + acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m2\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_l_inner (red_l_inner_stage_6 depends on red_l_inner_stage_5) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (lid(\u001b[34m0\u001b[39;49;00m) == \u001b[34m0\u001b[39;49;00m)\n", " {\n", " acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m)] + acc_l_inner[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m1\u001b[39;49;00m];\n", " tmp[gid(\u001b[34m0\u001b[39;49;00m)] = acc_l_inner[\u001b[34m0\u001b[39;49;00m];\n", " }\n", " }\n", "}\n", "\n", "__kernel \u001b[36mvoid\u001b[39;49;00m \u001b[32m__attribute__\u001b[39;49;00m ((reqd_work_group_size(\u001b[34m128\u001b[39;49;00m, \u001b[34m1\u001b[39;49;00m, \u001b[34m1\u001b[39;49;00m))) loopy_kernel_0(\u001b[36mint\u001b[39;49;00m \u001b[34mconst\u001b[39;49;00m nl, __global \u001b[36mint\u001b[39;49;00m *\u001b[34mrestrict\u001b[39;49;00m result, __global \u001b[36mint\u001b[39;49;00m *\u001b[34mrestrict\u001b[39;49;00m tmp)\n", "{\n", " __local \u001b[36mint\u001b[39;49;00m acc_j[\u001b[34m50\u001b[39;49;00m];\n", " __local \u001b[36mint\u001b[39;49;00m acc_l_inner[\u001b[34m128\u001b[39;49;00m];\n", " \u001b[36mint\u001b[39;49;00m acc_l_outer;\n", " \u001b[36mint\u001b[39;49;00m accepted[\u001b[34m2\u001b[39;49;00m];\n", " uint4 ctr;\n", " uint4 dummy;\n", " uint2 key2;\n", " float4 rng_res;\n", " cfloat_t samples[\u001b[34m2\u001b[39;49;00m];\n", "\n", " \u001b[34mif\u001b[39;49;00m (-\u001b[34m1\u001b[39;49;00m + nl >= \u001b[34m0\u001b[39;49;00m && \u001b[34m49\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = tmp[lid(\u001b[34m0\u001b[39;49;00m)];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_j (red_j_stage_0 depends on insn_4_j_transfer) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m17\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = acc_j[lid(\u001b[34m0\u001b[39;49;00m)] + acc_j[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m32\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_j (red_j_stage_1 depends on red_j_stage_0) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m15\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = acc_j[lid(\u001b[34m0\u001b[39;49;00m)] + acc_j[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m16\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_j (red_j_stage_2 depends on red_j_stage_1) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m7\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = acc_j[lid(\u001b[34m0\u001b[39;49;00m)] + acc_j[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m8\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_j (red_j_stage_3 depends on red_j_stage_2) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m3\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = acc_j[lid(\u001b[34m0\u001b[39;49;00m)] + acc_j[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m4\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_j (red_j_stage_4 depends on red_j_stage_3) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (\u001b[34m1\u001b[39;49;00m + -\u001b[34m1\u001b[39;49;00m * lid(\u001b[34m0\u001b[39;49;00m) >= \u001b[34m0\u001b[39;49;00m)\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = acc_j[lid(\u001b[34m0\u001b[39;49;00m)] + acc_j[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m2\u001b[39;49;00m];\n", " barrier(CLK_LOCAL_MEM_FENCE) \u001b[37m/* for acc_j (red_j_stage_5 depends on red_j_stage_4) */\u001b[39;49;00m;\n", " \u001b[34mif\u001b[39;49;00m (lid(\u001b[34m0\u001b[39;49;00m) == \u001b[34m0\u001b[39;49;00m)\n", " {\n", " acc_j[lid(\u001b[34m0\u001b[39;49;00m)] = acc_j[lid(\u001b[34m0\u001b[39;49;00m)] + acc_j[lid(\u001b[34m0\u001b[39;49;00m) + \u001b[34m1\u001b[39;49;00m];\n", " *result = acc_j[\u001b[34m0\u001b[39;49;00m];\n", " }\n", "}\n", "\n", "3.14172144 0.1 billion samples\n" ] } ], "source": [ "knl = lp.make_kernel(\n", " \"{ [l, g, j, isamp]: 0<=l key2 = make_uint2(l + nl*g, 1234)\n", " <> ctr = make_uint4(0, 1, 2, 3)\n", " <> rng_res, <> dummy = philox4x32_f32(ctr, key2)\n", " \n", " <> samples[0] = rng_res.s0 + 1j*rng_res.s1 {id=samp1}\n", " samples[1] = rng_res.s2 + 1j*rng_res.s3 {id=samp2}\n", "\n", " <> accepted[isamp] = real(samples[isamp] * conj(samples[isamp])) < 1 \\\n", " {dep=samp1:samp2} \n", " \n", " <> tmp[g] = sum(l, accepted[0] + accepted[1]) \n", " \n", " result = sum(j, tmp[j]) \n", " \"\"\") \n", "\n", "size = 1000000\n", "ng = 50\n", "\n", "knl = lp.fix_parameters(knl, ng=ng) \n", "\n", "knl = lp.set_options(knl, write_cl=True, highlight_cl=True) \n", "\n", "ref_knl = knl \n", "\n", "knl = lp.split_iname(knl, \"l\", 128, inner_tag=\"l.0\")\n", "knl = lp.split_reduction_outward(knl, \"l_inner\")\n", "knl = lp.tag_inames(knl, \"g:g.0,j:l.0\")\n", "\n", "evt, (result,) = knl(queue, nl=size) \n", "\n", "nsamples = size*2*ng\n", "print(4*result.get()/nsamples, nsamples/1e9, \"billion samples\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.5.1+" } }, "nbformat": 4, "nbformat_minor": 0 }