|
181 | 181 | " index into arrays. A typical use case is when arrays are accessed\n", |
182 | 182 | " indirectly via the ``condition`` expression.\n", |
183 | 183 | "relation: Or/And, default=And\n", |
184 | | - " How this ConditionalDimension will be combined with other ones.\n", |
| 184 | + " How this ConditionalDimension will be combined with other ones during\n", |
| 185 | + " lowering for example combining Function's ConditionalDimension with\n", |
| 186 | + " and Equation's implicit_dim. All dimensions within an equation \n", |
| 187 | + " must have `Or` relation for the final combined condition to be Or.\n", |
185 | 188 | "\n", |
186 | 189 | "Examples\n", |
187 | 190 | "--------\n", |
|
251 | 254 | { |
252 | 255 | "cell_type": "code", |
253 | 256 | "execution_count": 5, |
254 | | - "metadata": {}, |
| 257 | + "metadata": { |
| 258 | + "scrolled": true |
| 259 | + }, |
255 | 260 | "outputs": [ |
256 | 261 | { |
257 | 262 | "name": "stderr", |
|
825 | 830 | " assert all(g.data[:, i] == ids_np[i])" |
826 | 831 | ] |
827 | 832 | }, |
| 833 | + { |
| 834 | + "cell_type": "markdown", |
| 835 | + "metadata": {}, |
| 836 | + "source": [ |
| 837 | + "# Example C: Combining ConditionaDimension\n", |
| 838 | + "\n", |
| 839 | + "In some cases, a `ConditionaDimension` might be used in combination with an implicit_dim to handle specific cases. This combination can be made mutually exclusive (And) or inclusive (Or).\n", |
| 840 | + "\n", |
| 841 | + "As an example, let's consider the following case:\n", |
| 842 | + "\n", |
| 843 | + "- Set all even x indices to 1 using the standard subsampling `factor` ConditionaDimension\n", |
| 844 | + "- Set the edges to 2" |
| 845 | + ] |
| 846 | + }, |
| 847 | + { |
| 848 | + "cell_type": "code", |
| 849 | + "execution_count": 13, |
| 850 | + "metadata": {}, |
| 851 | + "outputs": [ |
| 852 | + { |
| 853 | + "name": "stdout", |
| 854 | + "output_type": "stream", |
| 855 | + "text": [ |
| 856 | + "/* Devito generated code for Operator `Kernel` */\n", |
| 857 | + "\n", |
| 858 | + "#define _POSIX_C_SOURCE 200809L\n", |
| 859 | + "#define START(S) struct timeval start_ ## S , end_ ## S ; gettimeofday(&start_ ## S , NULL);\n", |
| 860 | + "#define STOP(S,T) gettimeofday(&end_ ## S, NULL); T->S += (double)(end_ ## S .tv_sec-start_ ## S.tv_sec)+(double)(end_ ## S .tv_usec-start_ ## S .tv_usec)/1000000;\n", |
| 861 | + "\n", |
| 862 | + "#include \"stdlib.h\"\n", |
| 863 | + "#include \"math.h\"\n", |
| 864 | + "#include \"sys/time.h\"\n", |
| 865 | + "#include \"omp.h\"\n", |
| 866 | + "\n", |
| 867 | + "struct dataobj\n", |
| 868 | + "{\n", |
| 869 | + " void *restrict data;\n", |
| 870 | + " int * size;\n", |
| 871 | + " unsigned long nbytes;\n", |
| 872 | + " unsigned long * npsize;\n", |
| 873 | + " unsigned long * dsize;\n", |
| 874 | + " int * hsize;\n", |
| 875 | + " int * hofs;\n", |
| 876 | + " int * oofs;\n", |
| 877 | + " void * dmap;\n", |
| 878 | + "} ;\n", |
| 879 | + "\n", |
| 880 | + "struct profiler\n", |
| 881 | + "{\n", |
| 882 | + " double section0;\n", |
| 883 | + "} ;\n", |
| 884 | + "\n", |
| 885 | + "\n", |
| 886 | + "int Kernel(const int cevenf, struct dataobj *restrict f_vec, const int x_M, const int x_m, const int y_M, const int y_m, const int nthreads, struct profiler * timers)\n", |
| 887 | + "{\n", |
| 888 | + " float (*restrict f)[f_vec->size[1]] __attribute__ ((aligned (64))) = (float (*)[f_vec->size[1]]) f_vec->data;\n", |
| 889 | + "\n", |
| 890 | + " START(section0)\n", |
| 891 | + " #pragma omp parallel num_threads(nthreads)\n", |
| 892 | + " {\n", |
| 893 | + " #pragma omp for schedule(static,1)\n", |
| 894 | + " for (int x = x_m; x <= x_M; x += 1)\n", |
| 895 | + " {\n", |
| 896 | + " if (x == x_M || (x)%(cevenf) == 0)\n", |
| 897 | + " {\n", |
| 898 | + " #pragma omp simd aligned(f:16)\n", |
| 899 | + " for (int y = y_m; y <= y_M; y += 1)\n", |
| 900 | + " {\n", |
| 901 | + " f[x / cevenf][y] = 1;\n", |
| 902 | + " }\n", |
| 903 | + " }\n", |
| 904 | + " }\n", |
| 905 | + " }\n", |
| 906 | + " STOP(section0,timers)\n", |
| 907 | + "\n", |
| 908 | + " return 0;\n", |
| 909 | + "}\n", |
| 910 | + "\n" |
| 911 | + ] |
| 912 | + } |
| 913 | + ], |
| 914 | + "source": [ |
| 915 | + "from sympy import Or\n", |
| 916 | + "from devito import CondEq\n", |
| 917 | + "\n", |
| 918 | + "x, y = grid.dimensions\n", |
| 919 | + "c_even = ConditionalDimension(name='ceven', parent=x, factor=2, relation=Or)\n", |
| 920 | + "c_edge = ConditionalDimension(name='cedge', parent=grid.dimensions[0], condition=CondEq(x, x.symbolic_max), relation=Or)\n", |
| 921 | + "c_edge_a = ConditionalDimension(name='cedge', parent=grid.dimensions[0], condition=CondEq(x, x.symbolic_max-1))\n", |
| 922 | + "\n", |
| 923 | + "f = Function(name=\"f\", grid=grid, dimensions=(c_even, y), shape=(5, 10), space_order=0)\n", |
| 924 | + "\n", |
| 925 | + "op = Operator(Eq(f, 1, implicit_dims=c_edge))\n", |
| 926 | + "print(op)" |
| 927 | + ] |
| 928 | + }, |
| 929 | + { |
| 930 | + "cell_type": "code", |
| 931 | + "execution_count": 14, |
| 932 | + "metadata": {}, |
| 933 | + "outputs": [ |
| 934 | + { |
| 935 | + "name": "stderr", |
| 936 | + "output_type": "stream", |
| 937 | + "text": [ |
| 938 | + "Operator `Kernel` ran in 0.01 s\n" |
| 939 | + ] |
| 940 | + }, |
| 941 | + { |
| 942 | + "data": { |
| 943 | + "text/plain": [ |
| 944 | + "Data([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],\n", |
| 945 | + " [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],\n", |
| 946 | + " [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],\n", |
| 947 | + " [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],\n", |
| 948 | + " [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)" |
| 949 | + ] |
| 950 | + }, |
| 951 | + "execution_count": 14, |
| 952 | + "metadata": {}, |
| 953 | + "output_type": "execute_result" |
| 954 | + } |
| 955 | + ], |
| 956 | + "source": [ |
| 957 | + "op()\n", |
| 958 | + "f.data" |
| 959 | + ] |
| 960 | + }, |
| 961 | + { |
| 962 | + "cell_type": "code", |
| 963 | + "execution_count": 15, |
| 964 | + "metadata": {}, |
| 965 | + "outputs": [ |
| 966 | + { |
| 967 | + "name": "stdout", |
| 968 | + "output_type": "stream", |
| 969 | + "text": [ |
| 970 | + "/* Devito generated code for Operator `Kernel` */\n", |
| 971 | + "\n", |
| 972 | + "#define _POSIX_C_SOURCE 200809L\n", |
| 973 | + "#define START(S) struct timeval start_ ## S , end_ ## S ; gettimeofday(&start_ ## S , NULL);\n", |
| 974 | + "#define STOP(S,T) gettimeofday(&end_ ## S, NULL); T->S += (double)(end_ ## S .tv_sec-start_ ## S.tv_sec)+(double)(end_ ## S .tv_usec-start_ ## S .tv_usec)/1000000;\n", |
| 975 | + "\n", |
| 976 | + "#include \"stdlib.h\"\n", |
| 977 | + "#include \"math.h\"\n", |
| 978 | + "#include \"sys/time.h\"\n", |
| 979 | + "#include \"omp.h\"\n", |
| 980 | + "\n", |
| 981 | + "struct dataobj\n", |
| 982 | + "{\n", |
| 983 | + " void *restrict data;\n", |
| 984 | + " int * size;\n", |
| 985 | + " unsigned long nbytes;\n", |
| 986 | + " unsigned long * npsize;\n", |
| 987 | + " unsigned long * dsize;\n", |
| 988 | + " int * hsize;\n", |
| 989 | + " int * hofs;\n", |
| 990 | + " int * oofs;\n", |
| 991 | + " void * dmap;\n", |
| 992 | + "} ;\n", |
| 993 | + "\n", |
| 994 | + "struct profiler\n", |
| 995 | + "{\n", |
| 996 | + " double section0;\n", |
| 997 | + "} ;\n", |
| 998 | + "\n", |
| 999 | + "\n", |
| 1000 | + "int Kernel(const int cevenf, struct dataobj *restrict f_vec, const int x_M, const int x_m, const int y_M, const int y_m, const int nthreads, struct profiler * timers)\n", |
| 1001 | + "{\n", |
| 1002 | + " float (*restrict f)[f_vec->size[1]] __attribute__ ((aligned (64))) = (float (*)[f_vec->size[1]]) f_vec->data;\n", |
| 1003 | + "\n", |
| 1004 | + " START(section0)\n", |
| 1005 | + " #pragma omp parallel num_threads(nthreads)\n", |
| 1006 | + " {\n", |
| 1007 | + " #pragma omp for schedule(static,1)\n", |
| 1008 | + " for (int x = x_m; x <= x_M; x += 1)\n", |
| 1009 | + " {\n", |
| 1010 | + " if (x == x_M - 1 && (x)%(cevenf) == 0)\n", |
| 1011 | + " {\n", |
| 1012 | + " #pragma omp simd aligned(f:16)\n", |
| 1013 | + " for (int y = y_m; y <= y_M; y += 1)\n", |
| 1014 | + " {\n", |
| 1015 | + " f[x / cevenf][y] = 1;\n", |
| 1016 | + " }\n", |
| 1017 | + " }\n", |
| 1018 | + " }\n", |
| 1019 | + " }\n", |
| 1020 | + " STOP(section0,timers)\n", |
| 1021 | + "\n", |
| 1022 | + " return 0;\n", |
| 1023 | + "}\n", |
| 1024 | + "\n" |
| 1025 | + ] |
| 1026 | + } |
| 1027 | + ], |
| 1028 | + "source": [ |
| 1029 | + "op = Operator(Eq(f, 1, implicit_dims=c_edge_a))\n", |
| 1030 | + "print(op)" |
| 1031 | + ] |
| 1032 | + }, |
| 1033 | + { |
| 1034 | + "cell_type": "code", |
| 1035 | + "execution_count": 16, |
| 1036 | + "metadata": {}, |
| 1037 | + "outputs": [ |
| 1038 | + { |
| 1039 | + "name": "stderr", |
| 1040 | + "output_type": "stream", |
| 1041 | + "text": [ |
| 1042 | + "Operator `Kernel` ran in 0.01 s\n" |
| 1043 | + ] |
| 1044 | + }, |
| 1045 | + { |
| 1046 | + "data": { |
| 1047 | + "text/plain": [ |
| 1048 | + "Data([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", |
| 1049 | + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", |
| 1050 | + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", |
| 1051 | + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", |
| 1052 | + " [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)" |
| 1053 | + ] |
| 1054 | + }, |
| 1055 | + "execution_count": 16, |
| 1056 | + "metadata": {}, |
| 1057 | + "output_type": "execute_result" |
| 1058 | + } |
| 1059 | + ], |
| 1060 | + "source": [ |
| 1061 | + "f.data.fill(0)\n", |
| 1062 | + "op()\n", |
| 1063 | + "f.data" |
| 1064 | + ] |
| 1065 | + }, |
828 | 1066 | { |
829 | 1067 | "cell_type": "markdown", |
830 | 1068 | "metadata": {}, |
|
0 commit comments