/ concept-collection / libflame2wasm
Sign in
concept-collection / libflame2wasm
libflame2wasm / build-blis-wasm.sh
79 lines · 3.3 KBBlameHistoryRaw
1#!/bin/bash
2# Build BLIS (generic config) as a WebAssembly static library to serve as a
3# fast BLAS backend for the WASM libflame build.
4#
5# Link order matters: put libblis.a BEFORE libflame.a so the linker resolves
6# BLAS symbols from BLIS; libflame's built-in f2c BLAS members are then never
7# pulled in (they remain only as fallback for routines BLIS doesn't provide,
8# e.g. banded/packed level-2).
9#
10# Usage: ./build-blis-wasm.sh (single-threaded)
11# THREADING=pthreads ./build-blis-wasm.sh (wasm-threads build;
12# link apps with -pthread -sPTHREAD_POOL_SIZE=N, and all other
13# linked objects must also be compiled with -pthread)
14set -euo pipefail
16THREADING=${THREADING:-single}
17EXTRA_CFLAGS=""
18if [ "$THREADING" = "pthreads" ]; then
19 EXTRA_CFLAGS="-pthread"
20fi
22cd "$(dirname "$0")"
24if ! command -v emcc >/dev/null 2>&1; then
25 source ~/emsdk/emsdk_env.sh
26fi
28if [ ! -d blis ]; then
29 git clone --depth 1 https://github.com/flame/blis
30fi
31cd blis
33# --- Patches to make BLIS's BLAS interface WASM-compatible with libflame ---
35# WASM requires call sites and definitions to agree on exact signatures.
36# libflame's f2c-derived code declares BLAS subroutines returning int and
37# calls lsame_/xerbla_ with 2 args (no hidden Fortran string lengths).
38# Stock BLIS uses void returns and 4-arg lsame_ / 3-arg xerbla_.
40# 1. Drop BLIS's f2c-derived compat sources (banded/packed level-2 routines,
41# lsame_, xerbla_). libflame.a already provides all of them in the
42# 2-arg/int f2c convention. Keep cabs1 (no conflicts) and all headers.
43ls frame/compat/f2c/*.c | grep -v cabs1 | xargs rm -f
44rm -f frame/compat/f2c/bla_xerbla_array.h
45sed -i '/#include "bla_xerbla_array.h"/d' frame/compat/bli_blas_defs.h
47# 2. Prototype lsame_/xerbla_ with 2 args to match libflame's definitions.
48sed -i 's/, long ca_len, long cb_len//; s/, int ca_len, int cb_len//' frame/compat/f2c/bla_lsame.h
49sed -i 's/, ftnlen srname_len//' frame/compat/f2c/bla_xerbla.h
51# 3. Strip hidden string-length args from BLIS's internal lsame_/xerbla_ calls.
52sed -i 's/, *(ftnlen)[0-9]*//g' frame/compat/check/*.h
54# 4. Give every BLAS interface function an int return (f2c convention), so
55# signatures match libflame's declarations. Bare `return;` must become
56# `return 0;` (a hard error in C23 otherwise).
57sed -i 's/void PASTEF77/int PASTEF77/g' \
58 frame/compat/*.c frame/compat/*.h frame/compat/f2c/*.h \
59 frame/compat/extra/*.c frame/compat/extra/*.h frame/compat/amd/*.c
60sed -i 's/\breturn; \\/return 0; \\/g; s/^\( *\)return;$/\1return 0;/' \
61 frame/compat/*.c frame/compat/check/*.h frame/compat/extra/*.c frame/compat/amd/*.c
63# 5. BLIS tests the obsolete EMSCRIPTEN macro; modern emcc defines __EMSCRIPTEN__.
64sed -i 's/defined(EMSCRIPTEN)/defined(__EMSCRIPTEN__)/' frame/include/bli_system.h
66# --- Configure and build ---
67# -msimd128 lets the generic C kernels autovectorize to wasm SIMD.
68CC=emcc AR=emar RANLIB=emranlib CFLAGS="-msimd128 $EXTRA_CFLAGS" ./configure \
69 --disable-shared --enable-static \
70 --enable-blas --disable-cblas \
71 --int-size=32 --blas-int-size=32 \
72 --complex-return=gnu \
73 --enable-threading="$THREADING" \
74 generic
76# The generic make_defs.mk rejects the "emcc" vendor string; emcc is clang.
77make -j"$(nproc)" CC_VENDOR=clang
79echo "Done. Library: $(pwd)/lib/generic/libblis.a"
moveopenescclose