Skip to content
Open
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
6 changes: 3 additions & 3 deletions .github/workflows/haskell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
ghc: ["9.12.2", "9.10.2", "9.8.4", "9.6.7"]
os: [ubuntu-latest, windows-latest]
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest]

env:
# Modify this value to "invalidate" the cabal cache.
Expand Down Expand Up @@ -56,7 +56,7 @@ jobs:
dist-dir: dist-newstyle
store-path: ${{ steps.setup-haskell.outputs.cabal-store }}
threads: 16
archive-uri: ${{ secrets.BINARY_CACHE_URI }}/${{ env.CABAL_CACHE_VERSION }}/${{ runner.os }}/${{ matrix.cabal }}/${{ matrix.ghc }}
archive-uri: ${{ secrets.BINARY_CACHE_URI }}/${{ env.CABAL_CACHE_VERSION }}/${{ runner.os }}/${{ runner.arch }}/${{ matrix.cabal }}/${{ matrix.ghc }}
skip: "${{ secrets.BINARY_CACHE_URI == '' }}"

- name: Cabal cache over HTTPS
Expand All @@ -65,7 +65,7 @@ jobs:
dist-dir: dist-newstyle
store-path: ${{ steps.setup-haskell.outputs.cabal-store }}
threads: 16
archive-uri: https://cache.haskellworks.io/${{ env.CABAL_CACHE_VERSION }}/${{ runner.os }}/${{ matrix.cabal }}/${{ matrix.ghc }}
archive-uri: https://cache.haskellworks.io/${{ env.CABAL_CACHE_VERSION }}/${{ runner.os }}/${{ runner.arch }}/${{ matrix.cabal }}/${{ matrix.ghc }}
skip: "${{ secrets.BINARY_CACHE_URI != '' }}"

- name: Build
Expand Down
8 changes: 8 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# Changelog for hw-simd

## 0.1.3.0

- Support non-x86 architectures (e.g. `aarch64` / `arm`, such as AWS Graviton).
The x86-specific instruction-set flags (`-mavx2`, `-mbmi2`, `-msse4.2`) are now
only emitted for x86 targets, and the x86 intrinsic C code is guarded
accordingly. On non-x86 architectures the library builds and runs using the
pure-Haskell "Stock" implementations.
10 changes: 8 additions & 2 deletions cbits/simd_avx2.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
#include "simd.h"

#include <immintrin.h>
#include <mmintrin.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

// The x86 intrinsic headers only exist on x86 targets. Every function body in
// this file is guarded by AVX2_ENABLED (defined only for x86 builds), so on
// other architectures this translation unit compiles to empty no-ops.
#if defined(AVX2_ENABLED)
#include <immintrin.h>
#include <mmintrin.h>
#endif

void avx2_memcpy(
uint8_t *target,
uint8_t *source,
Expand Down
10 changes: 8 additions & 2 deletions cbits/simd_sse2.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#include "simd.h"

#include <immintrin.h>
#include <mmintrin.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

// sse_cmpeq8 uses x86 SSE intrinsics and is not bound from Haskell. The x86
// intrinsic headers only exist on x86 targets, so this whole translation unit
// is compiled to an empty no-op on other architectures (e.g. aarch64 / arm).
#if defined(__x86_64__) || defined(__i386__)
#include <immintrin.h>
#include <mmintrin.h>

void sse_cmpeq8(
uint8_t byte,
uint64_t *target,
Expand All @@ -28,3 +33,4 @@ void sse_cmpeq8(
target16[i] = mask;
}
}
#endif
34 changes: 19 additions & 15 deletions hw-simd.cabal
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cabal-version: 2.2

name: hw-simd
version: 0.1.2.2
version: 0.1.3.0
synopsis: SIMD library
description: Please see the README on Github at <https://github.com/haskell-works/hw-simd#readme>
category: Data, Bit, SIMD
Expand Down Expand Up @@ -66,22 +66,26 @@ common vector { build-depends: vector >=
common config
default-language: Haskell2010
ghc-options: -O2 -Wall
if (flag(avx2)) && (impl(ghc >=8.4.1))
ghc-options: -mbmi2 -msse4.2
cpp-options: -DBMI2_ENABLED -DAVX2_ENABLED
if (impl(ghc >=8.0.1))
ghc-options: -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints
if flag(avx2)
cc-options: -mavx2 -DAVX2_ENABLED
if (flag(bmi2)) && (impl(ghc >=8.4.1))
ghc-options: -mbmi2 -msse4.2
if flag(bmi2)
cc-options: -mbmi2 -DBMI2_ENABLED
if flag(sse42)
ghc-options: -msse4.2
cc-options: -msse4.2
if (arch(aarch64) || arch(arm))
build-depends: base < 0
-- The avx2/bmi2/sse42 instruction sets and their associated compiler flags
-- (-mavx2, -mbmi2, -msse4.2) are x86-specific. Only emit them when building
-- for an x86 target so that the library also builds on other architectures
-- (e.g. aarch64 / arm), where it falls back to the pure-Haskell "Stock"
-- implementations.
if (arch(x86_64) || arch(i386))
if (flag(avx2)) && (impl(ghc >=8.4.1))
ghc-options: -mbmi2 -msse4.2
cpp-options: -DBMI2_ENABLED -DAVX2_ENABLED
if flag(avx2)
cc-options: -mavx2 -DAVX2_ENABLED
if (flag(bmi2)) && (impl(ghc >=8.4.1))
ghc-options: -mbmi2 -msse4.2
if flag(bmi2)
cc-options: -mbmi2 -DBMI2_ENABLED
if flag(sse42)
ghc-options: -msse4.2
cc-options: -msse4.2

common hw-simd
build-depends: hw-simd
Expand Down