chickadee » crunch-simd

cruch-simd

Description

SIMD datatypes and operations for use in CRUNCHed code.

Author

felix winkelmann

Requirements

crunch, matchable and srfi-1.

Repository

This egg is hosted on Codeberg:

https://codeberg.org/Bunny351/crunch-simd

Usage

This extension provides the (crunch simd) module and can only be used in code compiled with CRUNCH. It utilizes the portable interface to numeric vectors provided by gcc and clang and allows defining vector types of various sizes, automatically providing an overloaded set of operations available for these types.

Consult the https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html and [clang|https://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vectors]] manuals for additional information, since this extension just maps operators to the underlying C/C++ operators and compiler builtins.

Note that this egg is currently experimental and may be extended or changed in the future.

Note also that the available SIMD instructions vary greatly for different CPUs, so target-specific C compiler options may be required to generate meaningful and efficient binaries from code generated by CRUNCH using this extension.

Procedures and macros

(define-vector-type TYPENAME CTYPE SIZE [CTOR])syntax

Defines a vector type of SIZE elements of type CTYPE. SIZE must be a positive integer, and CTYPE must be a symbol naming an integral or floating point numeric C type (like int, short, float, etc.).

Note that this "vector" type represents a fixed size SIMD number vector, not a Scheme vector.

If CTOR is given, it should be the name of a zero-argument constructor procedure that creates an uninitialized vector of the defined type.

TYPENAME should be a symbol and will map to a C SIMD vector type.

SIMD vectors are passed by value, not by reference, and can be stored in and loaded from SRFI-4 numerical vectors.

Every vector-type defined allows the use of the following operations, overloaded variants are created on demand. In the following, arguments X and Y designate vector or numeric arguments, at least one of them must be a vector. If both are vectors they must be of the same type.

v+ X Yprocedure
v- X #!optional Yprocedure
v* X Yprocedure
v/ X Yprocedure

Perform arithmetic on vectors or vectors and scalar numbers. The result will be a vector of the same type.

v= X Yprocedure
v!= X Yprocedure
v> X Yprocedure
v< X Yprocedure
v>= X Yprocedure
v<= X Yprocedure

Compare vectors elementwise and return a vector with int elements, of the same size as the argument vector(s), holding -1 or 0, dpeending on whether the corresponding elements matched or not. If no such type has been defined yet, it will be created automatically.

vector-bitwise-and X Yprocedure
vector-bitwise-xor X Yprocedure
vector-bitwise-xor X Yprocedure
vector-bitwise-not Xprocedure

Perform bitwise combination of the argument vector elements and return a vector of the same type.

vref X Iprocedure

Return the I-th element of the given vector. I should be a non-negative integer index.

vset X I Nprocedure

Returns a new vector with the elements of X and the I-th element being replaced with N. I should be a non-negative integer index.

(vassign X I N ...)syntax

Like vset, but assigns consecutive elements to the result, starting at index I.

vlength Xprocedure

Returns the number of elements of X.

vector-shuffle X Y I ...procedure

Returns a new vector with as many elements as indices given by I ... and the same element type as X. Elements are taken from X and Y (which may be the same) at the given non-negative indices and a new vector is returned. A suitable vector type must have been defined previously.

At most 16 indices may be given.

(vector-convert TYPENAME X)syntax

Converts the vector X to a vector of a different typem as given by TYPENAME.

(vector-array-ref TYPENAME NUMVECTOR I)syntax

Extracts bytes from the SRFI-4 numeric vector NUMVECTOR at index I, which should be a non-negative integer. NUMVECTOR may be of any valid numerical vector type as defined by SRFI-4 or the (chicken number-vector) module, it will be interpreted as a sequence of SIMD vectors of the appropriate size. A vector of the type designated by TYPENAME will be returned.

Note that no bounds checking is currently done.

vector-array-set! NUMVECTOR I Xprocedure

Copies X into the SRFI-4 numeric vector NUMVECTOR at index I, interpreting NUMVECTOR as a sequence of SIMD vectors of the same type as X.

Note that no bounds checking is currently done.

Example

;; totally pointless code, just demonstrating usage

(import (scheme base) (scheme write) (crunch simd) srfi-4)

(define-vector-type v4i int 4 make-v4i)
(define-vector-type v2i int 2)
(define-vector-type v4f float 4)

(define (add a b) (v+ a b))

(define (main)
  ; define locally, so can be cloned for multiple data types
  (define (vprint v)
    (do ((i 0 (+ i 1)))
        ((>= i (vlength v)))
      (display (vref v i)) (write-char #\space))
    (newline))
  (let ((a (make-v4i))
        (b (make-v4i))
        (v (make-s32vector 4 0)))
    (do ((i 0 (+ i 1)))
        ((>= i 4))
      (set! a (vset a i i))
      (set! b (vset b i (+ i 10))))
    (vprint a)                          ; => "0 1 2 3"
    (vprint b)                          ; => "10 11 12 13"
    (let ((c (add a b)))
      (vprint c))                       ; => "10 12 14 16"
    (vector-array-set! v 0 a)
    (write v) (newline)                 ; => "#s32(0 1 2 3)"
    (vprint (vector-array-ref v4i v 0)) ; => "0 1 2 3"
    (vprint (vector-shuffle b b 0 3))   ; => "10 13"
    (vprint (vector-convert v4f b))     ; => "10.0 11.0 12.0 13.0"
    (vprint (v+ a 2))                   ; => "2 3 4 5"
    (vprint (v> a (vector-shuffle a a 3 2 1 0)))))  ; => "0 0 -1 -1"

Changelog

License

 Copyright (c) 2026, Felix L. Winkelmann
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
 conditions are met:

   Redistributions of source code must retain the above copyright notice, this list of conditions and the following
     disclaimer.
   Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
     disclaimer in the documentation and/or other materials provided with the distribution.
   Neither the name of the author nor the names of its contributors may be used to endorse or promote
     products derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICESLOSS OF USE, DATA, OR PROFITSOR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.

Contents »