Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions .github/workflows/deploy-jupyterlite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Jupyterlite deployment

on:
workflow_dispatch:
pull_request:
paths:
# Since we do not deploy in PRs and that this is only copying file from the repo
# the CI file is the only relevant change to watch for in CI on PRs
- .github/workflows/deploy-jupyterlite.yml
push:
branches:
- master

permissions:
contents: read
pages: write
id-token: write

jobs:
build:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6
- uses: mamba-org/setup-micromamba@v3
with:
cache-environment: true
post-cleanup: 'all'
environment-name: jupyterlite-builder
create-args: jupyter jupyterlite-core jupyterlite-xeus
- name: Build WASM environment
run: |
micromamba create -p ./wasm-env \
--platform=emscripten-wasm32 \
--channel https://prefix.dev/emscripten-forge-4x \
--channel https://prefix.dev/conda-forge \
xeus-cpp=0.10
- name: Build Jupyterlite distribution
run: |
micromamba run -n jupyterlite-builder \
jupyter lite build \
--XeusAddon.prefix=./wasm-env \
--contents include/ \
--contents notebooks/ \
--output-dir ./dist
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./dist

deploy:
needs: build
if: github.ref == 'refs/heads/master'
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-24.04
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
207 changes: 207 additions & 0 deletions notebooks/simple.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "2efd7be2-5ea7-42cb-a2e2-9ddb409bc893",
"metadata": {},
"outputs": [],
"source": [
"#include <cstddef>\n",
"#include <vector>\n",
"#include <random>\n",
"#include <iostream>\n",
"\n",
"#include <xsimd/xsimd.hpp>"
]
},
{
"cell_type": "markdown",
"id": "6f498bff-4366-4e1c-ab25-3d3589740e78",
"metadata": {},
"source": [
"Comparing two implementation of element wise mean."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cf6b2c85-1427-49a3-8bef-0340601319e8",
"metadata": {},
"outputs": [],
"source": [
"std::vector<double> random_vector(std::size_t n)\n",
"{\n",
" static std::mt19937 gen(42);\n",
" std::uniform_real_distribution<double> dist(0.0, 1.0);\n",
" std::vector<double> v(n);\n",
" for (auto& x : v)\n",
" {\n",
" x = dist(gen);\n",
" }\n",
" return v;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a2ab6177-60e2-4d65-b323-51a6a21ad530",
"metadata": {},
"outputs": [],
"source": [
"std::vector<double> mean_scalar(const std::vector<double>& a, const std::vector<double>& b)\n",
"{\n",
" std::size_t size = a.size();\n",
" std::vector<double> res(size);\n",
" for (std::size_t i = 0; i < size; ++i)\n",
" {\n",
" res[i] = (a[i] + b[i]) / 2;\n",
" }\n",
" return res;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "082ed2cd-273a-4c3c-a206-03b1efe49482",
"metadata": {},
"outputs": [],
"source": [
"std::vector<double> mean_simd(const std::vector<double>& a, const std::vector<double>& b)\n",
"{\n",
" using b_type = xsimd::batch<double>;\n",
" std::size_t inc = b_type::size;\n",
" std::size_t size = a.size();\n",
" std::vector<double> res(size);\n",
"\n",
" // size for which the vectorization is possible\n",
" std::size_t vec_size = size - size % inc;\n",
" for (std::size_t i = 0; i < vec_size; i += inc)\n",
" {\n",
" b_type avec = b_type::load_unaligned(&a[i]);\n",
" b_type bvec = b_type::load_unaligned(&b[i]);\n",
" b_type rvec = (avec + bvec) / 2;\n",
" rvec.store_unaligned(&res[i]);\n",
" }\n",
" // Remaining part that cannot be vectorize\n",
" for (std::size_t i = vec_size; i < size; ++i)\n",
" {\n",
" res[i] = (a[i] + b[i]) / 2;\n",
" }\n",
" return res;\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5959864d",
"metadata": {},
"outputs": [],
"source": [
"// Print v[begin:end] as grayscale ASCII blocks (dark = 0, light = 1).\n",
"void print_grayscale(const std::vector<double>& v, std::size_t begin, std::size_t end)\n",
"{\n",
" for (std::size_t i = begin; i < end; ++i)\n",
" {\n",
" // map value in [0, 1] to a 24-bit truecolor gray (256 levels)\n",
" int gray = static_cast<int>(v[i] * 255);\n",
" std::cout << \"\\033[38;2;\" << gray << \";\" << gray << \";\" << gray << \"m█\";\n",
" }\n",
" std::cout << \"\\033[0m\\n\";\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2068e201",
"metadata": {},
"outputs": [],
"source": [
"std::size_t n = 1000;\n",
"std::vector<double> const a = random_vector(n);\n",
"std::vector<double> const b = random_vector(n);"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9d5a7adc-5b55-4224-a4ca-5e438d1fc4d4",
"metadata": {},
"outputs": [],
"source": [
"auto const res_simd = mean_simd(a, b);"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d279cd74-c397-4ea8-af15-3745f043f656",
"metadata": {},
"outputs": [],
"source": [
"auto const res_scalar = mean_scalar(a, b);"
]
},
{
"cell_type": "markdown",
"id": "a04ae145",
"metadata": {},
"source": [
"Each block is a value in `[0, 1]` shown as a grayscale shade (dark = low, light = high). The vector is drawn in chunks of 100, each chunk stacking input `a`, the SIMD mean, the scalar mean, and input `b`. The two mean rows should look identical, each sitting between its inputs."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "59ca84ad-8b97-4523-af0d-d3eca01b41d0",
"metadata": {},
"outputs": [],
"source": [
"std::size_t const width = 100;\n",
"for (std::size_t begin = 0; begin < n; begin += width)\n",
"{\n",
" std::size_t end = std::min(begin + width, n);\n",
" std::cout << \"a: \";\n",
" print_grayscale(a, begin, end);\n",
" std::cout << \"simd: \";\n",
" print_grayscale(res_simd, begin, end);\n",
" std::cout << \"scalar: \";\n",
" print_grayscale(res_scalar, begin, end);\n",
" std::cout << \"b: \";\n",
" print_grayscale(b, begin, end);\n",
" std::cout << \"\\n\";\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "90b86fb4-0426-43fd-b5fc-8626ef8732a5",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "C++17",
"language": "cpp",
"name": "xcpp17"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"name": "C++",
"nbconvert_exporter": "",
"pygments_lexer": "",
"version": "cxx17"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading