Skip to content

Commit e4af2d6

Browse files
committed
Add OpenMP kernels
1 parent 27a9f21 commit e4af2d6

File tree

19 files changed

+923
-1
lines changed

19 files changed

+923
-1
lines changed

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ endif()
107107

108108
find_package(argparse REQUIRED)
109109
find_package(pugixml REQUIRED)
110+
find_package(OpenMP)
110111

111112
# Configuration
112113
# =============
@@ -127,6 +128,9 @@ function(configure_kernel kernel)
127128
set(XEUS_CPP_PATH "$ENV{PATH}")
128129
set(XEUS_CPP_LD_LIBRARY_PATH "$ENV{LD_LIBRARY_PATH}")
129130
set(XEUS_CPP_INCLUDE_DIR ${CMAKE_INSTALL_PREFIX}/include)
131+
if(${kernel} MATCHES "omp/$")
132+
set(XEUS_CPP_OMP "${OpenMP_CXX_FLAGS}")
133+
endif()
130134
endif()
131135
if (WIN32)
132136
string(REPLACE "\\" "/" kernel "${kernel}")
@@ -163,6 +167,11 @@ configure_kernel("/share/jupyter/kernels/xcpp23/")
163167
configure_kernel("/share/jupyter/kernels/xc11/")
164168
configure_kernel("/share/jupyter/kernels/xc17/")
165169
configure_kernel("/share/jupyter/kernels/xc23/")
170+
if(NOT EMSCRIPTEN)
171+
configure_kernel("/share/jupyter/kernels/xcpp17-omp/")
172+
configure_kernel("/share/jupyter/kernels/xcpp20-omp/")
173+
configure_kernel("/share/jupyter/kernels/xcpp23-omp/")
174+
endif()
166175

167176
# Source files
168177
# ============

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ micromamba activate xeus-cpp
3838
You are now in a position to install xeus-cpp into this environment. You can do this by executing
3939

4040
```bash
41+
export LD_LIBRARY_PATH="$CONDA_PREFIX/lib/:$LD_LIBRARY_PATH"
4142
mkdir build
4243
cd build
4344
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_PREFIX_PATH=$CONDA_PREFIX -D CMAKE_INSTALL_PREFIX=$CONDA_PREFIX -D CMAKE_INSTALL_LIBDIR=lib ..

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ micromamba install jupyterlab -c conda-forge
5959
```
6060
Now you can compile the kernel from the source by executing (replace `$CONDA_PREFIX` with a custom installation prefix if need be)
6161
```bash
62+
export LD_LIBRARY_PATH="$CONDA_PREFIX/lib/:$LD_LIBRARY_PATH"
6263
mkdir build
6364
cd build
6465
cmake .. -D CMAKE_PREFIX_PATH=$CONDA_PREFIX -D CMAKE_INSTALL_PREFIX=$CONDA_PREFIX -D CMAKE_INSTALL_LIBDIR=lib

docs/source/InstallationAndUsage.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ with a custom installation prefix if need be)
3030

3131
.. code-block:: bash
3232
33+
export LD_LIBRARY_PATH="$CONDA_PREFIX/lib/:$LD_LIBRARY_PATH"
3334
mkdir build && cd build
3435
cmake .. -D CMAKE_PREFIX_PATH=$CONDA_PREFIX -D CMAKE_INSTALL_PREFIX=$CONDA_PREFIX
3536
-D CMAKE_INSTALL_LIBDIR=lib

environment-dev.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ dependencies:
1414
- CppInterOp
1515
- pugixml
1616
- cpp-argparse
17+
- llvm-openmp
1718
# Test dependencies
1819
- pytest
1920
- jupyter_kernel_test<0.8
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "73cbab37-71dd-477d-981b-f2ec28c01bd6",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"#include <stdio.h>\n",
11+
"#include <omp.h>\n",
12+
"#include <clang/Interpreter/CppInterOp.h>"
13+
]
14+
},
15+
{
16+
"cell_type": "code",
17+
"execution_count": 2,
18+
"id": "ef1cd58a-672c-4a6f-843a-6c88fc4911f3",
19+
"metadata": {},
20+
"outputs": [],
21+
"source": [
22+
"Cpp::LoadLibrary(\"libomp\");\n",
23+
" "
24+
]
25+
},
26+
{
27+
"cell_type": "code",
28+
"execution_count": 3,
29+
"id": "c2b754ad-9553-4a42-b990-f990a9a269ed",
30+
"metadata": {},
31+
"outputs": [],
32+
"source": [
33+
"int main() {\n",
34+
" int max_threads = omp_get_max_threads();\n",
35+
"\n",
36+
" printf(\"max threads: %d\\n\", max_threads);\n",
37+
" omp_set_num_threads(max_threads);\n",
38+
"\n",
39+
"#pragma omp parallel\n",
40+
" {\n",
41+
" int id = omp_get_thread_num();\n",
42+
" printf(\"Hello World from thread = %d with %d threads\\n\", id, omp_get_num_threads());\n",
43+
" }\n",
44+
"\n",
45+
" printf(\"all done, with hopefully %d threads\\n\", max_threads);\n",
46+
"}"
47+
]
48+
},
49+
{
50+
"cell_type": "code",
51+
"execution_count": 4,
52+
"id": "a37a13d4-fc82-496e-8f42-9e718a8c2aa0",
53+
"metadata": {},
54+
"outputs": [
55+
{
56+
"name": "stdout",
57+
"output_type": "stream",
58+
"text": [
59+
"max threads: 8\n",
60+
"Hello World from thread = 0 with 8 threads\n",
61+
"Hello World from thread = 3 with 8 threads\n",
62+
"Hello World from thread = 4 with 8 threads\n",
63+
"Hello World from thread = 2 with 8 threads\n",
64+
"Hello World from thread = 7 with 8 threads\n",
65+
"Hello World from thread = 1 with 8 threads\n",
66+
"Hello World from thread = 6 with 8 threads\n",
67+
"Hello World from thread = 5 with 8 threads\n",
68+
"all done, with hopefully 8 threads\n"
69+
]
70+
}
71+
],
72+
"source": [
73+
"main();"
74+
]
75+
}
76+
],
77+
"metadata": {
78+
"kernelspec": {
79+
"display_name": "C++17 (xcpp+OpenMP)",
80+
"language": "cpp",
81+
"name": "xcpp17-omp"
82+
},
83+
"language_info": {
84+
"codemirror_mode": "text/x-c++src",
85+
"file_extension": ".cpp",
86+
"mimetype": "text/x-c++src",
87+
"name": "C++",
88+
"version": "17"
89+
}
90+
},
91+
"nbformat": 4,
92+
"nbformat_minor": 5
93+
}
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "156447d2-9279-45a0-890b-4e519d2c796b",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"#include <stdlib.h>\n",
11+
"#include <stdio.h>\n",
12+
"#include <omp.h>\n",
13+
"#include <clang/Interpreter/CppInterOp.h>"
14+
]
15+
},
16+
{
17+
"cell_type": "code",
18+
"execution_count": 2,
19+
"id": "c96fdeb0-817d-48c0-af8e-20a52947d60b",
20+
"metadata": {},
21+
"outputs": [],
22+
"source": [
23+
"#ifndef N\n",
24+
"#define N 5\n",
25+
"#endif\n",
26+
"#ifndef FS\n",
27+
"#define FS 38\n",
28+
"#endif"
29+
]
30+
},
31+
{
32+
"cell_type": "code",
33+
"execution_count": 3,
34+
"id": "8da842e1-db02-49e0-929d-4e67cbc08172",
35+
"metadata": {},
36+
"outputs": [],
37+
"source": [
38+
"Cpp::LoadLibrary(\"libomp\");"
39+
]
40+
},
41+
{
42+
"cell_type": "code",
43+
"execution_count": 4,
44+
"id": "22f97c49-78d1-496e-ac7c-978aed95331a",
45+
"metadata": {},
46+
"outputs": [],
47+
"source": [
48+
"struct node {\n",
49+
" int data;\n",
50+
" int fibdata;\n",
51+
" struct node *next;\n",
52+
"};"
53+
]
54+
},
55+
{
56+
"cell_type": "code",
57+
"execution_count": 5,
58+
"id": "b16b1e8a-8831-4b8d-9d57-09deeaaa88ee",
59+
"metadata": {},
60+
"outputs": [],
61+
"source": [
62+
"struct node *init_list(struct node *p);\n",
63+
"void processwork(struct node *p);\n",
64+
"int fib(int n);"
65+
]
66+
},
67+
{
68+
"cell_type": "code",
69+
"execution_count": 6,
70+
"id": "0ef8af6c-1d6f-4c68-84bc-3dd1d8092b06",
71+
"metadata": {},
72+
"outputs": [],
73+
"source": [
74+
"int fib(int n) {\n",
75+
" int x, y;\n",
76+
" if (n < 2) {\n",
77+
" return (n);\n",
78+
" } else {\n",
79+
" x = fib(n - 1);\n",
80+
" y = fib(n - 2);\n",
81+
" return (x + y);\n",
82+
" }\n",
83+
"}"
84+
]
85+
},
86+
{
87+
"cell_type": "code",
88+
"execution_count": 7,
89+
"id": "1fa0307d-fdc9-4503-95cb-1c6448791354",
90+
"metadata": {},
91+
"outputs": [],
92+
"source": [
93+
"void processwork(struct node *p) {\n",
94+
" int n, temp;\n",
95+
" n = p->data;\n",
96+
" temp = fib(n);\n",
97+
"\n",
98+
" p->fibdata = temp;\n",
99+
"}"
100+
]
101+
},
102+
{
103+
"cell_type": "code",
104+
"execution_count": 8,
105+
"id": "03acb599-9329-49ff-8aff-c0902adb6c3c",
106+
"metadata": {},
107+
"outputs": [],
108+
"source": [
109+
"struct node *init_list(struct node *p) {\n",
110+
" int i;\n",
111+
" struct node *head = NULL;\n",
112+
" struct node *temp = NULL;\n",
113+
"\n",
114+
" head = (struct node*) malloc(sizeof(struct node));\n",
115+
" p = head;\n",
116+
" p->data = FS;\n",
117+
" p->fibdata = 0;\n",
118+
" for (i = 0; i < N; i++) {\n",
119+
" temp = (struct node*) malloc(sizeof(struct node));\n",
120+
" p->next = temp;\n",
121+
" p = temp;\n",
122+
" p->data = FS + i + 1;\n",
123+
" p->fibdata = i + 1;\n",
124+
" }\n",
125+
"\n",
126+
" p->next = NULL;\n",
127+
" return head;\n",
128+
"}"
129+
]
130+
},
131+
{
132+
"cell_type": "code",
133+
"execution_count": 9,
134+
"id": "f2dfb41b-e55f-43c0-b7f6-546a1697acb1",
135+
"metadata": {},
136+
"outputs": [],
137+
"source": [
138+
"int main() {\n",
139+
" double start, end;\n",
140+
" struct node *p = NULL;\n",
141+
" struct node *temp = NULL;\n",
142+
" struct node *head = NULL;\n",
143+
"\n",
144+
" printf(\"Process linked list\\n\");\n",
145+
" printf(\" Each linked list node will be processed by function 'processwork()'\\n\");\n",
146+
" printf(\" Each ll node will compute %d fibonacci numbers beginning with %d\\n\", N, FS);\n",
147+
"\n",
148+
" omp_set_num_threads(omp_get_max_threads());\n",
149+
"\n",
150+
" p = init_list(p);\n",
151+
" head = p;\n",
152+
"\n",
153+
" start = omp_get_wtime();\n",
154+
"\n",
155+
"#pragma omp parallel\n",
156+
" {\n",
157+
"#pragma omp master\n",
158+
" printf(\"Threads: %d\\n\", omp_get_num_threads());\n",
159+
"\n",
160+
"#pragma omp single\n",
161+
" {\n",
162+
" p = head;\n",
163+
" while (p) {\n",
164+
"#pragma omp task firstprivate(p) // first private is required\n",
165+
" {\n",
166+
" processwork(p);\n",
167+
" }\n",
168+
" p = p->next;\n",
169+
" }\n",
170+
" }\n",
171+
" }\n",
172+
"\n",
173+
" end = omp_get_wtime();\n",
174+
" p = head;\n",
175+
" while (p != NULL) {\n",
176+
" printf(\"%d : %d\\n\", p->data, p->fibdata);\n",
177+
" temp = p->next;\n",
178+
" free(p);\n",
179+
" p = temp;\n",
180+
" }\n",
181+
"\n",
182+
" free(p);\n",
183+
" printf(\"Compute Time: %f seconds\\n\", end - start);\n",
184+
"\n",
185+
" return 0;\n",
186+
"}"
187+
]
188+
},
189+
{
190+
"cell_type": "code",
191+
"execution_count": 10,
192+
"id": "353e5dfd-fcae-43e6-97e3-ec98070811a1",
193+
"metadata": {},
194+
"outputs": [
195+
{
196+
"name": "stdout",
197+
"output_type": "stream",
198+
"text": [
199+
"Process linked list\n",
200+
" Each linked list node will be processed by function 'processwork()'\n",
201+
" Each ll node will compute 5 fibonacci numbers beginning with 38\n",
202+
"Threads: 8\n",
203+
"38 : 39088169\n",
204+
"39 : 63245986\n",
205+
"40 : 102334155\n",
206+
"41 : 165580141\n",
207+
"42 : 267914296\n",
208+
"43 : 433494437\n",
209+
"Compute Time: 2.617225 seconds\n"
210+
]
211+
}
212+
],
213+
"source": [
214+
"main();"
215+
]
216+
}
217+
],
218+
"metadata": {
219+
"kernelspec": {
220+
"display_name": "C++17 (xcpp+OpenMP)",
221+
"language": "cpp",
222+
"name": "xcpp17-omp"
223+
},
224+
"language_info": {
225+
"codemirror_mode": "text/x-c++src",
226+
"file_extension": ".cpp",
227+
"mimetype": "text/x-c++src",
228+
"name": "C++",
229+
"version": "17"
230+
}
231+
},
232+
"nbformat": 4,
233+
"nbformat_minor": 5
234+
}

0 commit comments

Comments
 (0)