diff options
author | Pjotr Prins | 2025-02-11 02:24:30 -0600 |
---|---|---|
committer | Pjotr Prins | 2025-02-11 02:24:30 -0600 |
commit | fd714598394a36d94846a5c2cfa1dc6a7e4bcced (patch) | |
tree | 9b89ad45f6e357de32bb0219e7b534053484675d | |
parent | 83d5d1535754016500af6854aab26c1fbdde73d0 (diff) | |
download | presentations-fd714598394a36d94846a5c2cfa1dc6a7e4bcced.tar.gz |
Add FOSDEM 2025 talk
23 files changed, 1690 insertions, 0 deletions
diff --git a/prescheme-nim-local/avx.c b/prescheme-nim-local/avx.c new file mode 100644 index 0000000..d69dddc --- /dev/null +++ b/prescheme-nim-local/avx.c @@ -0,0 +1,48 @@ +// compile +// gcc -Icontrib/simde -mavx -o avx-test avx.c && ./avx-test + +// #include <immintrin.h> // native instructions +#include <simde/x86/avx512.h> +#include <stdio.h> + +int main() { + + /* Initialize the two argument vectors */ + __m256 evens = _mm256_set_ps(2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 17.0); + __m256 odds = _mm256_set_ps(1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0); + /* Display the elements of the result vector */ + __m256 result = _mm256_sub_ps(evens, odds); + float* f = (float *)&result; + printf("float %f %f %f %f %f %f %f %f\n", + f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]); + + // try doubles + __m256d evens1 = _mm256_set_pd(2.0, 4.0, 6.0, 8.0); + __m256d odds1 = _mm256_set_pd(1.0, 3.0, 5.0, 6.0); + /* Compute the difference between the two vectors */ + __m256d result1 = _mm256_sub_pd(evens1, odds1); + + /* Display the elements of the result vector */ + double* d = (double*)&result1; + printf("double %f %f %f %f\n", + d[0], d[1], d[2], d[3]); + + // initialize from RAM + double l1[] = { 2.0, 4.0, 6.0, 8.8 }; + double l2[] = { 0.0, 3.0, 5.0, 7.0 }; + __m256d evens3 = _mm256_loadu_pd(l1); // pd — “packed double” — 4 doubles + __m256d odds3 = _mm256_loadu_pd(l2); + __m256d result3 = _mm256_sub_pd(evens3, odds3); + double* d3 = (double*)&result3; + printf("double %f %f %f %f\n", + d3[0], d3[1], d3[2], d3[3]); + + simde__m256d evens4 = simde_mm256_loadu_pd(l1); // pd — “packed double” — 4 doubles + simde__m256d odds4 = simde_mm256_loadu_pd(l2); + simde__m256d result4 = simde_mm256_sub_pd(evens3, odds3); + double* d4 = (double*)&result4; + printf("double %f %f %f %f\n", + d4[0], d4[1], d4[2], d4[3]); + + return 0; +} diff --git a/prescheme-nim-local/build.sh b/prescheme-nim-local/build.sh new file mode 100755 index 0000000..86129e4 --- /dev/null +++ b/prescheme-nim-local/build.sh @@ -0,0 +1,28 @@ +# Load guix shell first with +# +# . .guix-shell + +export prescheme=/home/wrk/iwrk/opensource/lisp/contrib/prescheme/bin/prescheme +$prescheme < prescheme-compile.scm # return value is meaningless + +# gcc hello.c $LIBRARY_PATH/scheme48-1.9.2/libprescheme.a +# gcc -g vec.c $LIBRARY_PATH/scheme48-1.9.2/libprescheme.a +sed -i '/struct gsl_vector {$/{n;s/^};//;}' openblas.c +sed -i 's/struct gsl_vector {//' openblas.c +sed -i 's/struct //g' openblas.c + +sed -i '/struct m256d {$/{n;s/^};//;}' simde.c +sed -i 's/struct m256d {//' simde.c +sed -i 's/struct m256d \*/simde__m256d /' simde.c +sed -i 's/struct //g' simde.c + +rm -f openblas-test +rm -f simde-test +gcc -g openblas.c $LIBRARY_PATH/scheme48-1.9.2/libprescheme.a -lgsl -lgslcblas -oopenblas-test || exit 2 +./openblas-test +# simde and avx512 +gcc -Icontrib/simde -mavx -o avx-test avx.c && ./avx-test +gcc -g -mavx simde.c -Icontrib/simde/ $LIBRARY_PATH/scheme48-1.9.2/libprescheme.a -osimde-test || exit 2 +./openblas-test + +./simde-test diff --git a/prescheme-nim-local/contrib/.gitignore b/prescheme-nim-local/contrib/.gitignore new file mode 100644 index 0000000..f31fd9f --- /dev/null +++ b/prescheme-nim-local/contrib/.gitignore @@ -0,0 +1,7 @@ +simde-test +*-test +contrib/ +a.out +avic +nim/simd +openblas-test diff --git a/prescheme-nim-local/contrib/.guix-shell b/prescheme-nim-local/contrib/.guix-shell new file mode 100644 index 0000000..be88b32 --- /dev/null +++ b/prescheme-nim-local/contrib/.guix-shell @@ -0,0 +1,2 @@ + +guix shell coreutils make scheme48-prescheme gcc-toolchain which gdb gsl sed --share=/home/wrk/iwrk/opensource/lisp/contrib/prescheme/ diff --git a/prescheme-nim-local/contrib/simde b/prescheme-nim-local/contrib/simde new file mode 160000 +Subproject b331ea2f7e3635868b31da54b3b671ab02a5b3c diff --git a/prescheme-nim-local/lib/ps-string.scm b/prescheme-nim-local/lib/ps-string.scm new file mode 100644 index 0000000..6e72793 --- /dev/null +++ b/prescheme-nim-local/lib/ps-string.scm @@ -0,0 +1,25 @@ +;;; ps-string: string utilities for Pre-Scheme + +(define (string-copy! target offset source start end) + (do ((tgt offset (+ tgt 1)) + (src start (+ src 1))) + ((= src end)) + (string-set! target tgt (string-ref source src))) + (unspecific)) + +(define (string-append a b) + (let* ((len-a (string-length a)) + (len-b (string-length b)) + (target (make-string (+ len-a len-b)))) + (string-copy! target 0 a 0 len-a) + (string-copy! target len-a b 0 len-b) + target)) + +(define (string-repeat source n) + (let* ((len (string-length source)) + (total (* len n)) + (target (make-string total))) + (do ((ix 0 (+ ix len))) + ((= ix total)) + (string-copy! target ix source 0 len)) + target)) diff --git a/prescheme-nim-local/lib/ps-utils.scm b/prescheme-nim-local/lib/ps-utils.scm new file mode 100644 index 0000000..574bb04 --- /dev/null +++ b/prescheme-nim-local/lib/ps-utils.scm @@ -0,0 +1,32 @@ +;;; ps-utils --- Utilities for Pre-Scheme + +(define-syntax when + (syntax-rules () + ((_ condition consequent ...) + (if condition + (begin consequent ...))))) + +(define-syntax unless + (syntax-rules () + ((_ condition antecedent ...) + (if (not condition) + (begin antecedent ...))))) + +(define-syntax define-wrapper-type + (lambda (exp rename compare) + (define (symbol-append . args) + (string->symbol + (apply string-append (map (lambda (s) + (if (string? s) s (symbol->string s))) + args)))) + (let* ((name (cadr exp)) + (type-id (symbol-append ":" name)) + (constructor (rename (symbol-append "make-" name))) + (%begin (rename 'begin)) + (%define-record-type (rename 'define-record-type)) + (%define-external (rename 'define-external))) + `(,%define-record-type ,name ,type-id + (,constructor))))) + +(define (zero? n) (= n 0)) +(define (one? n) (= n 1)) diff --git a/prescheme-nim-local/lib/ps-vector.scm b/prescheme-nim-local/lib/ps-vector.scm new file mode 100644 index 0000000..369040f --- /dev/null +++ b/prescheme-nim-local/lib/ps-vector.scm @@ -0,0 +1,204 @@ +;;; ps-vector: vector utilities for Pre-Scheme +;;; +;;; These routines are based on SRFI-43 for Scheme, with some +;;; adjustments to account for the limitations of Pre-Scheme. +;;; +;;; Pre-Scheme's native vectors don't support vector-length at runtime, +;;; so we take an additional length argument, as is common practice in C. +;;; +;;; Pre-Scheme doesn't support variadic functions, so we have a variant +;;; for each arity, as you might do in C. It should be possible to +;;; generate these with a macro, but that's not yet implemented. + +;;; vector-unfold + +(define-syntax vector-unfold + (syntax-rules () + ((_ proc len) + (vector-unfold0 proc len)) + ((_ proc len seed) + (vector-unfold1 proc len seed)) + ((_ proc len seed1 seed2) + (vector-unfold2 proc len seed1 seed2)) + ((_ proc len seed1 seed2 seed3) + (vector-unfold3 proc len seed1 seed2 seed3)))) + +(define (vector-unfold0 proc len) + ;; FIXME get proc's return type without calling it + (let ((result (make-vector len (proc 0)))) + (let loop ((i 0)) + (if (= i len) + result + (begin + (vector-set! result i (proc i)) + (loop (+ i 1))))))) + +(define (vector-unfold1 proc len seed) + (let ((result (receive (val next) + (proc 0 seed) + (make-vector len val)))) + (let loop ((i 0) (seed seed)) + (if (= i len) + result + (receive (val next) + (proc i seed) + (vector-set! result i val) + (loop (+ i 1) next)))))) + +(define (vector-unfold2 proc len seed1 seed2) + (let ((result (receive (val next1 next2) + (proc 0 seed1 seed2) + (make-vector len val)))) + (let loop ((i 0) (seed1 seed1) (seed2 seed2)) + (if (= i len) + result + (receive (val next1 next2) + (proc i seed1 seed2) + (vector-set! result i val) + (loop (+ i 1) next1 next2)))))) + +(define (vector-unfold3 proc len seed1 seed2 seed3) + (let ((result (receive (val next1 next2 next3) + (proc 0 seed1 seed2 seed3) + (make-vector len val)))) + (let loop ((i 0) (seed1 seed1) (seed2 seed2) (seed3 seed3)) + (if (= i len) + result + (receive (val next1 next2 next3) + (proc i seed1 seed2 seed3) + (vector-set! result i val) + (loop (+ i 1) next1 next2 next3)))))) + +;;; vector-fold + +(define-syntax vector-fold + (syntax-rules () + ((_ proc init vec len) + (vector-fold1 proc init vec len)) + ((_ proc init vec1 len1 vec2 len2) + (vector-fold2 proc init vec1 len1 vec2 len2)) + ((_ proc init vec1 len1 vec2 len2 vec3 len3) + (vector-fold3 proc init vec1 len1 vec2 len2 vec3 len3)))) + +(define (vector-fold1 proc init vec len) + (let loop ((i 0) (result init)) + (if (= i len) + result + (loop (+ i 1) (proc i result (vector-ref vec i)))))) + +(define (vector-fold2 proc init vec1 len1 vec2 len2) + (let ((len (min len1 len2))) + (let loop ((i 0) (result init)) + (if (= i len) + result + (loop (+ i 1) (proc i result + (vector-ref vec1 i) + (vector-ref vec2 i))))))) + +(define (vector-fold3 proc init vec1 len1 vec2 len2 vec3 len3) + (let ((len (min len1 len2 len3))) + (let loop ((i 0) (result init)) + (if (= i len) + result + (loop (+ i 1) (proc i result + (vector-ref vec1 i) + (vector-ref vec2 i) + (vector-ref vec3 i))))))) + +;;; vector-map! + +(define-syntax vector-map! + (syntax-rules () + ((_ proc vec len) + (vector-map1! proc vec len)) + ((_ proc vec1 len1 vec2 len2) + (vector-map2! proc vec1 len1 vec2 len2)) + ((_ proc vec1 len1 vec2 len2 vec3 len3) + (vector-map3! proc vec1 len1 vec2 len2 vec3 len3)))) + +(define (vector-map1! proc vec len) + (vector-fold (lambda (i vec val) + (vector-set! vec i (proc i val)) + vec) + vec vec len)) + +(define (vector-map2! proc vec1 len1 vec2 len2) + (vector-fold (lambda (i vec val1 val2) + (vector-set! vec i (proc i val1 val2)) + vec) + vec1 vec1 len1 vec2 len2)) + +(define (vector-map3! proc vec1 len1 vec2 len2 vec3 len3) + (vector-fold (lambda (i vec val1 val2 val3) + (vector-set! vec i (proc i val1 val2 val3)) + vec) + vec1 vec1 len1 vec2 len2 vec3 len3)) + +;;; vector-map1 + +(define-syntax vector-map + (syntax-rules () + ((_ proc vec len) + (vector-map1 proc vec len)) + ((_ proc vec1 len1 vec2 len2) + (vector-map2 proc vec1 len1 vec2 len2)) + ((_ proc vec1 len1 vec2 len2 vec3 len3) + (vector-map3 proc vec1 len1 vec2 len2 vec3 len3)))) + +(define (vector-map1 proc vec len) + ;; FIXME get proc's return type without calling it + (let ((res (make-vector len (proc 0 (vector-ref vec 0))))) + (vector-fold (lambda (i res val) + (vector-set! res i (proc i val)) + res) + res vec len))) + +(define (vector-map2 proc vec1 len1 vec2 len2) + (let* ((len (min len1 len2)) + (res (make-vector len (proc 0 + (vector-ref vec1 0) + (vector-ref vec2 0))))) + (vector-fold (lambda (i res val1 val2) + (vector-set! res i (proc i val1 val2)) + res) + res vec1 len1 vec2 len2))) + +(define (vector-map3 proc vec1 len1 vec2 len2 vec3 len3) + (let* ((len (min len1 len2 len3)) + (res (make-vector len (proc 0 + (vector-ref vec1 0) + (vector-ref vec2 0) + (vector-ref vec3 0))))) + (vector-fold (lambda (i res val1 val2 val3) + (vector-set! res i (proc i val1 val2 val3)) + res) + res vec1 len1 vec2 len2 vec3 len3))) + +;;; vector-for-each + +(define-syntax vector-for-each + (syntax-rules () + ((_ proc vec len) + (vector-for-each1 proc vec len)) + ((_ proc vec1 len1 vec2 len2) + (vector-for-each2 proc vec1 len1 vec2 len2)) + ((_ proc vec1 len1 vec2 len2 vec3 len3) + (vector-for-each3 proc vec1 len1 vec2 len2 vec3 len3)))) + +(define (vector-for-each1 proc vec len) + (vector-fold (lambda (i res val) + (proc i val) + res) + (unspecific) vec len)) + +(define (vector-for-each2 proc vec1 len1 vec2 len2) + (vector-fold (lambda (i res val1 val2) + (proc i val1 val2) + res) + (unspecific) vec1 len1 vec2 len2)) + +(define (vector-for-each3 proc vec1 len1 vec2 len2 vec3 len3) + (vector-fold (lambda (i res val1 val2 val3) + (proc i val1 val2 val3) + res) + (unspecific) vec1 len1 vec2 len2 vec3 len3)) diff --git a/prescheme-nim-local/nim/.guix-shell b/prescheme-nim-local/nim/.guix-shell new file mode 100644 index 0000000..7c87f25 --- /dev/null +++ b/prescheme-nim-local/nim/.guix-shell @@ -0,0 +1,2 @@ +guix shell -C --network nim gcc-toolchain which gdb gsl coreutils openssl nss-certs nss + diff --git a/prescheme-nim-local/nim/@mexample.nim.c b/prescheme-nim-local/nim/@mexample.nim.c new file mode 100644 index 0000000..54d0b01 --- /dev/null +++ b/prescheme-nim-local/nim/@mexample.nim.c @@ -0,0 +1,529 @@ +/* Generated by Nim Compiler v1.6.12 */ +#define NIM_INTBITS 64 + +#include "nimbase.h" +#include <string.h> +#undef LANGUAGE_C +#undef MIPSEB +#undef MIPSEL +#undef PPC +#undef R3000 +#undef R4000 +#undef i386 +#undef linux +#undef mips +#undef near +#undef far +#undef powerpc +#undef unix +#define nimfr_(x, y) +#define nimln_(x, y) +typedef struct tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg; +typedef struct NimStringDesc NimStringDesc; +typedef struct TGenericSeq TGenericSeq; +typedef struct TNimType TNimType; +typedef struct TNimNode TNimNode; +typedef struct tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw; +typedef struct tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA; +typedef struct tyObject_GcHeap__iDiTSZpQ7px0t5vNrxVbUA tyObject_GcHeap__iDiTSZpQ7px0t5vNrxVbUA; +typedef struct tyObject_GcStack__UCyPjkT5JTcDkiVmdF9b1Hg tyObject_GcStack__UCyPjkT5JTcDkiVmdF9b1Hg; +typedef struct tyObject_MemRegion__Gp1H3ulLE0JSwys9chSegUQ tyObject_MemRegion__Gp1H3ulLE0JSwys9chSegUQ; +typedef struct tyObject_SmallChunk__IlnS2SZ9b9a9aa7geF7H7WlTQ tyObject_SmallChunk__IlnS2SZ9b9a9aa7geF7H7WlTQ; +typedef struct tyObject_BigChunk__w1NV79cuBqFbXit4Tp17eOg tyObject_BigChunk__w1NV79cuBqFbXit4Tp17eOg; +typedef struct tyObject_LLChunk__SQF3x9cXavsoHTw29byqkDLw tyObject_LLChunk__SQF3x9cXavsoHTw29byqkDLw; +typedef struct tyObject_IntSet__2jdqyVr8TdkdzxtDR9cMNeA tyObject_IntSet__2jdqyVr8TdkdzxtDR9cMNeA; +typedef struct tyObject_Trunk__49cO1kD2eWrtb8yk3xFe3Mg tyObject_Trunk__49cO1kD2eWrtb8yk3xFe3Mg; +typedef struct tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw; +typedef struct tyObject_HeapLinks__F5ahjOdOdTkYY2d0Q2Gl8A tyObject_HeapLinks__F5ahjOdOdTkYY2d0Q2Gl8A; +typedef struct tyTuple__KO8Ebr67mzOYgVGVXIV5PQ tyTuple__KO8Ebr67mzOYgVGVXIV5PQ; +typedef struct tyObject_GcStat__VaNnSVm7WoX0lNTqTCv50w tyObject_GcStat__VaNnSVm7WoX0lNTqTCv50w; +typedef struct tyObject_CellSet__1gT1qjnSW9cWCbrErC2YjgA tyObject_CellSet__1gT1qjnSW9cWCbrErC2YjgA; +typedef struct tyObject_PageDesc__2k4DJQa4eGP2jIhQQvG7aQ tyObject_PageDesc__2k4DJQa4eGP2jIhQQvG7aQ; +struct TGenericSeq { +NI len; +NI reserved; +}; +struct NimStringDesc { + TGenericSeq Sup; +NIM_CHAR data[SEQ_DECL_SIZE]; +}; +struct tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg { +NimStringDesc* name; +NI age; +}; +typedef tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg tyArray__3ZLM5yW0QMKoSQQYqBR4sQ[2]; +typedef NU8 tyEnum_TNimKind__dRYPikfx8C6QeI2ANiRwTw; +typedef NU8 tySet_tyEnum_TNimTypeFlag__L6XiVPmbiz6rQWqIFXIsjg; +typedef N_NIMCALL_PTR(void, tyProc__ojoeKfW4VYIm36I9cpDTQIg) (void* p, NI op); +typedef N_NIMCALL_PTR(void*, tyProc__WSm2xU5ARYv9aAR4l0z9c9auQ) (void* p); +struct TNimType { +NI size; +NI align; +tyEnum_TNimKind__dRYPikfx8C6QeI2ANiRwTw kind; +tySet_tyEnum_TNimTypeFlag__L6XiVPmbiz6rQWqIFXIsjg flags; +TNimType* base; +TNimNode* node; +void* finalizer; +tyProc__ojoeKfW4VYIm36I9cpDTQIg marker; +tyProc__WSm2xU5ARYv9aAR4l0z9c9auQ deepcopy; +}; +typedef NU8 tyEnum_TNimNodeKind__zmvn9aqxMUIOpaIc6RYBPNg; +struct TNimNode { +tyEnum_TNimNodeKind__zmvn9aqxMUIOpaIc6RYBPNg kind; +NI offset; +TNimType* typ; +NCSTRING name; +NI len; +TNimNode** sons; +}; +typedef N_NIMCALL_PTR(void, tyProc__T4eqaYlFJYZUv9aG9b1TV0bQ) (void); +struct tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw { +NI refcount; +TNimType* typ; +}; +struct tyObject_GcStack__UCyPjkT5JTcDkiVmdF9b1Hg { +void* bottom; +}; +struct tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA { +NI len; +NI cap; +tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw** d; +}; +typedef tyObject_SmallChunk__IlnS2SZ9b9a9aa7geF7H7WlTQ* tyArray__M5QRq6N4svLoIwlZOmQxHQ[256]; +typedef NU32 tyArray__BHbOSqU1t9b3Gt7K2c6fQig[24]; +typedef tyObject_BigChunk__w1NV79cuBqFbXit4Tp17eOg* tyArray__ncS3w2BYKGi9bXT5b1e3WWA[32]; +typedef tyArray__ncS3w2BYKGi9bXT5b1e3WWA tyArray__O9b1hn09cFfHywfOftglH4MQ[24]; +typedef tyObject_Trunk__49cO1kD2eWrtb8yk3xFe3Mg* tyArray__K9awrF1N4sTg9c39conY9aozxw[256]; +struct tyObject_IntSet__2jdqyVr8TdkdzxtDR9cMNeA { +tyArray__K9awrF1N4sTg9c39conY9aozxw data; +}; +typedef tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw* tyArray__Jee6tsSzFCBDKArKW15qfA[2]; +struct tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw { +tyArray__Jee6tsSzFCBDKArKW15qfA link; +NI key; +NI upperBound; +NI level; +}; +struct tyTuple__KO8Ebr67mzOYgVGVXIV5PQ { +tyObject_BigChunk__w1NV79cuBqFbXit4Tp17eOg* Field0; +NI Field1; +}; +typedef tyTuple__KO8Ebr67mzOYgVGVXIV5PQ tyArray__FxF33lwaa0ndwuf7R7TmBw[30]; +struct tyObject_HeapLinks__F5ahjOdOdTkYY2d0Q2Gl8A { +NI len; +tyArray__FxF33lwaa0ndwuf7R7TmBw chunks; +tyObject_HeapLinks__F5ahjOdOdTkYY2d0Q2Gl8A* next; +}; +struct tyObject_MemRegion__Gp1H3ulLE0JSwys9chSegUQ { +NI minLargeObj; +NI maxLargeObj; +tyArray__M5QRq6N4svLoIwlZOmQxHQ freeSmallChunks; +NU32 flBitmap; +tyArray__BHbOSqU1t9b3Gt7K2c6fQig slBitmap; +tyArray__O9b1hn09cFfHywfOftglH4MQ matrix; +tyObject_LLChunk__SQF3x9cXavsoHTw29byqkDLw* llmem; +NI currMem; +NI maxMem; +NI freeMem; +NI occ; +NI lastSize; +tyObject_IntSet__2jdqyVr8TdkdzxtDR9cMNeA chunkStarts; +tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw* root; +tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw* deleted; +tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw* last; +tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw* freeAvlNodes; +NIM_BOOL locked; +NIM_BOOL blockChunkSizeIncrease; +NI nextChunkSize; +tyObject_AvlNode__IYoO7WMK5SrBWxv8MOtVcw bottomData; +tyObject_HeapLinks__F5ahjOdOdTkYY2d0Q2Gl8A heapLinks; +}; +struct tyObject_GcStat__VaNnSVm7WoX0lNTqTCv50w { +NI stackScans; +NI cycleCollections; +NI maxThreshold; +NI maxStackSize; +NI maxStackCells; +NI cycleTableSize; +NI64 maxPause; +}; +struct tyObject_CellSet__1gT1qjnSW9cWCbrErC2YjgA { +NI counter; +NI max; +tyObject_PageDesc__2k4DJQa4eGP2jIhQQvG7aQ* head; +tyObject_PageDesc__2k4DJQa4eGP2jIhQQvG7aQ** data; +}; +struct tyObject_GcHeap__iDiTSZpQ7px0t5vNrxVbUA { +tyObject_GcStack__UCyPjkT5JTcDkiVmdF9b1Hg stack; +NI cycleThreshold; +NI zctThreshold; +tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA zct; +tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA decStack; +tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA tempStack; +NI recGcLock; +tyObject_MemRegion__Gp1H3ulLE0JSwys9chSegUQ region; +tyObject_GcStat__VaNnSVm7WoX0lNTqTCv50w stat; +tyObject_CellSet__1gT1qjnSW9cWCbrErC2YjgA marked; +tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA additionalRoots; +NI gcThreadId; +}; +typedef NimStringDesc* tyArray__nHXaesL0DJZHyVS07ARPRA[1]; +typedef NI tyArray__oXFh4MvEDAk4hEbFQSH7yQ[6]; +typedef NimStringDesc* tyArray__sMpvt1sOxOJ3LFGulnbeMQ[4]; +N_LIB_PRIVATE N_NIMCALL(void, nimGCvisit)(void* d, NI op); +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_3)(void); +N_LIB_PRIVATE N_NIMCALL(void, nimRegisterGlobalMarker)(tyProc__T4eqaYlFJYZUv9aG9b1TV0bQ markerProc); +N_LIB_PRIVATE N_NIMCALL(void, genericAssign)(void* dest, void* src, TNimType* mt); +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_7)(void); +N_LIB_PRIVATE N_NIMCALL(NimStringDesc*, copyStringRC1)(NimStringDesc* src); +static N_INLINE(void, nimGCunrefNoCycle)(void* p); +static N_INLINE(void, decRef__system_5310)(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* c); +static N_INLINE(NI, minuspercent___system_716)(NI x, NI y); +static N_INLINE(NIM_BOOL, ltpercent___system_1005)(NI x, NI y); +static N_INLINE(void, rtlAddZCT__system_5308)(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* c); +N_LIB_PRIVATE N_NOINLINE(void, addZCT__system_5259)(tyObject_CellSeq__6qQxmDUC9aUb88gPyztChFA* s, tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* c); +static N_INLINE(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw*, usrToCell__system_5265)(void* usr); +static N_INLINE(void, nimZeroMem)(void* p, NI size); +static N_INLINE(void, nimSetMem__systemZmemory_7)(void* a, int v, NI size); +static N_INLINE(void, asgnRef)(void** dest, void* src); +static N_INLINE(void, incRef__system_5303)(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* c); +static N_INLINE(NI, pluspercent___system_696)(NI x, NI y); +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_8)(void); +N_NIMCALL(NimStringDesc*, rawNewString)(NI cap); +N_LIB_PRIVATE N_NIMCALL(void, formatValue__pureZstrformat_162)(NimStringDesc** result, NimStringDesc* value, NimStringDesc* specifier); +static N_INLINE(void, appendString)(NimStringDesc* dest, NimStringDesc* src); +static N_INLINE(void, copyMem__system_1727)(void* dest, void* source, NI size); +static N_INLINE(void, nimCopyMem)(void* dest, void* source, NI size); +N_LIB_PRIVATE N_NIMCALL(NimStringDesc*, resizeString)(NimStringDesc* dest, NI addlen); +N_LIB_PRIVATE N_NIMCALL(void, formatValue__example_46)(NimStringDesc** result, NI value, NimStringDesc* specifier); +N_LIB_PRIVATE N_NIMCALL(NimStringDesc*, copyString)(NimStringDesc* src); +N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringDesc** args, NI argsLen_0); +N_LIB_PRIVATE N_NOINLINE(void, raiseOverflow)(void); +N_LIB_PRIVATE N_NIMCALL(NimStringDesc*, dollar___systemZdollars_3)(NI x); +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_14)(void); +static N_INLINE(void, initStackBottomWith)(void* locals); +N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom); +N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_DatInit000)(void); +N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_Init000)(void); +N_LIB_PRIVATE N_NIMCALL(void, atmexampledotnim_DatInit000)(void); +N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); +N_LIB_PRIVATE TNimType NTIperson__NF2Erj5R8mAkjQbMRdkMjg_; +extern TNimType NTIstring__77mFvmsOLKik79ci2hXkHEg_; +extern TNimType NTIint__hLlQjbV9bLNq5PFxYcqacsA_; +N_LIB_PRIVATE TNimType NTIarrayL48OO49_personT__3ZLM5yW0QMKoSQQYqBR4sQ_; +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_5, "John", 4); +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_6, "Kate", 4); +static NIM_CONST tyArray__3ZLM5yW0QMKoSQQYqBR4sQ TM__DfQaFFoJOv5Rj9bYYIj8A9cg_4 = {{((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_5), ((NI) 45)} +, +{((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_6), ((NI) 30)} +} +; +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_9, " is ", 4); +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_10, " years old", 10); +static NIM_CONST tyArray__oXFh4MvEDAk4hEbFQSH7yQ TM__DfQaFFoJOv5Rj9bYYIj8A9cg_12 = {((NI) 3), +((NI) 6), +((NI) 9), +((NI) 12), +((NI) 15), +((NI) 18)} +; +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_15, "mov", 3); +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_16, "btc", 3); +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_17, "cli", 3); +STRING_LITERAL(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_18, "xor", 3); +N_LIB_PRIVATE NIM_CONST tyArray__sMpvt1sOxOJ3LFGulnbeMQ opcodes__example_187 = {((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_15), +((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_16), +((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_17), +((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_18)} +; +N_LIB_PRIVATE tyArray__3ZLM5yW0QMKoSQQYqBR4sQ people__example_5; +N_LIB_PRIVATE tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg person__example_31; +extern tyObject_GcHeap__iDiTSZpQ7px0t5vNrxVbUA gch__system_5212; +N_LIB_PRIVATE NimStringDesc* fmtRes__example_40; +N_LIB_PRIVATE NI odd__example_154; +N_LIB_PRIVATE NimStringDesc* o__example_213; +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_3)(void) { + NI T1_; + T1_ = (NI)0; + for (T1_ = 0; T1_ < 2; T1_++) { + nimGCvisit((void*)people__example_5[T1_].name, 0); + } +} +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_7)(void) { + nimGCvisit((void*)person__example_31.name, 0); +} +static N_INLINE(NI, minuspercent___system_716)(NI x, NI y) { + NI result; + result = (NI)0; + result = ((NI) ((NU)((NU64)(((NU) (x))) - (NU64)(((NU) (y)))))); + return result; +} +static N_INLINE(NIM_BOOL, ltpercent___system_1005)(NI x, NI y) { + NIM_BOOL result; + result = (NIM_BOOL)0; + result = ((NU64)(((NU) (x))) < (NU64)(((NU) (y)))); + return result; +} +static N_INLINE(void, rtlAddZCT__system_5308)(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* c) { + addZCT__system_5259((&gch__system_5212.zct), c); +} +static N_INLINE(void, decRef__system_5310)(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* c) { + (*c).refcount = minuspercent___system_716((*c).refcount, ((NI) 8)); + { + NIM_BOOL T3_; + T3_ = (NIM_BOOL)0; + T3_ = ltpercent___system_1005((*c).refcount, ((NI) 8)); + if (!T3_) goto LA4_; + rtlAddZCT__system_5308(c); + } + LA4_: ; +} +static N_INLINE(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw*, usrToCell__system_5265)(void* usr) { + tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* result; + NI T1_; + result = (tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw*)0; + T1_ = (NI)0; + T1_ = minuspercent___system_716(((NI) (ptrdiff_t) (usr)), ((NI) 16)); + result = ((tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw*) (T1_)); + return result; +} +static N_INLINE(void, nimGCunrefNoCycle)(void* p) { + tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* T1_; + T1_ = (tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw*)0; + T1_ = usrToCell__system_5265(p); + decRef__system_5310(T1_); +} +static N_INLINE(void, nimSetMem__systemZmemory_7)(void* a, int v, NI size) { + void* T1_; + T1_ = (void*)0; + T1_ = memset(a, v, ((size_t) (size))); +} +static N_INLINE(void, nimZeroMem)(void* p, NI size) { + nimSetMem__systemZmemory_7(p, ((int) 0), size); +} +static N_INLINE(NI, pluspercent___system_696)(NI x, NI y) { + NI result; + result = (NI)0; + result = ((NI) ((NU)((NU64)(((NU) (x))) + (NU64)(((NU) (y)))))); + return result; +} +static N_INLINE(void, incRef__system_5303)(tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* c) { + (*c).refcount = pluspercent___system_696((*c).refcount, ((NI) 8)); +} +static N_INLINE(void, asgnRef)(void** dest, void* src) { + { + tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* T5_; + if (!!((src == NIM_NIL))) goto LA3_; + T5_ = (tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw*)0; + T5_ = usrToCell__system_5265(src); + incRef__system_5303(T5_); + } + LA3_: ; + { + tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw* T10_; + if (!!(((*dest) == NIM_NIL))) goto LA8_; + T10_ = (tyObject_Cell__bP7dB0nNeqVXKcR6F9axfyw*)0; + T10_ = usrToCell__system_5265((*dest)); + decRef__system_5310(T10_); + } + LA8_: ; + (*dest) = src; +} +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_8)(void) { + nimGCvisit((void*)fmtRes__example_40, 0); +} +static N_INLINE(void, nimCopyMem)(void* dest, void* source, NI size) { + void* T1_; + T1_ = (void*)0; + T1_ = memcpy(dest, source, ((size_t) (size))); +} +static N_INLINE(void, copyMem__system_1727)(void* dest, void* source, NI size) { + nimCopyMem(dest, source, size); +} +static N_INLINE(void, appendString)(NimStringDesc* dest, NimStringDesc* src) { + { + if (!!((src == ((NimStringDesc*) NIM_NIL)))) goto LA3_; + copyMem__system_1727(((void*) ((&(*dest).data[(*dest).Sup.len]))), ((void*) ((*src).data)), ((NI) ((NI)((*src).Sup.len + ((NI) 1))))); + (*dest).Sup.len += (*src).Sup.len; + } + LA3_: ; +} +static N_NIMCALL(void, TM__DfQaFFoJOv5Rj9bYYIj8A9cg_14)(void) { + nimGCvisit((void*)o__example_213, 0); +} +static N_INLINE(void, initStackBottomWith)(void* locals) { + nimGC_setStackBottom(locals); +} + +N_LIB_PRIVATE void PreMainInner(void) { +} + +N_LIB_PRIVATE int cmdCount; +N_LIB_PRIVATE char** cmdLine; +N_LIB_PRIVATE char** gEnv; +N_LIB_PRIVATE void PreMain(void) { + void (*volatile inner)(void); + inner = PreMainInner; + atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_DatInit000(); + initStackBottomWith((void *)&inner); + atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_Init000(); + atmexampledotnim_DatInit000(); + (*inner)(); +} + +N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { + NimMainModule(); +} + +N_CDECL(void, NimMain)(void) { + void (*volatile inner)(void); + PreMain(); + inner = NimMainInner; + initStackBottomWith((void *)&inner); + (*inner)(); +} + +int main(int argc, char** args, char** env) { + cmdLine = args; + cmdCount = argc; + gEnv = env; + NimMain(); + return nim_program_result; +} + +N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { +{ + TFrame FR_; FR_.len = 0; + + nimRegisterGlobalMarker(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_3); + + + nimRegisterGlobalMarker(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_7); + + + nimRegisterGlobalMarker(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_8); + + + nimRegisterGlobalMarker(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_14); + +}/* preInitProc end */ +{ + genericAssign((void*)people__example_5, (void*)TM__DfQaFFoJOv5Rj9bYYIj8A9cg_4, (&NTIarrayL48OO49_personT__3ZLM5yW0QMKoSQQYqBR4sQ_)); + { + NI i; + i = ((NI) 0); + { + while (1) { + NimStringDesc* T4_; + tyArray__nHXaesL0DJZHyVS07ARPRA T5_; + NI TM__DfQaFFoJOv5Rj9bYYIj8A9cg_11; + T4_ = NIM_NIL; + T4_ = person__example_31.name; person__example_31.name = copyStringRC1(people__example_5[(i)- 0].name); + if (T4_) nimGCunrefNoCycle(T4_); + person__example_31.age = people__example_5[(i)- 0].age; + nimZeroMem((void*)T5_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA)); + asgnRef((void**) (&fmtRes__example_40), NIM_NIL); + asgnRef((void**) (&fmtRes__example_40), rawNewString(((NI) 59))); + formatValue__pureZstrformat_162((&fmtRes__example_40), person__example_31.name, ((NimStringDesc*) NIM_NIL)); + asgnRef((void**) (&fmtRes__example_40), resizeString(fmtRes__example_40, 4)); +appendString(fmtRes__example_40, ((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_9)); + formatValue__example_46((&fmtRes__example_40), person__example_31.age, ((NimStringDesc*) NIM_NIL)); + asgnRef((void**) (&fmtRes__example_40), resizeString(fmtRes__example_40, 10)); +appendString(fmtRes__example_40, ((NimStringDesc*) &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_10)); + T5_[0] = copyString(fmtRes__example_40); + echoBinSafe(T5_, 1); + { + if (!(((NI) 1) <= ((NI) (i)))) goto LA8_; + goto LA2; + } + LA8_: ; + if (nimAddInt(i, ((NI) 1), &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_11)) { raiseOverflow(); }; + if (TM__DfQaFFoJOv5Rj9bYYIj8A9cg_11 < 0 || TM__DfQaFFoJOv5Rj9bYYIj8A9cg_11 > 1){ raiseOverflow(); } + i = (NI)(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_11); + } + } LA2: ; + } + { + { + NI x; + NI i_2; + x = (NI)0; + i_2 = ((NI) 0); + { + while (1) { + NI TM__DfQaFFoJOv5Rj9bYYIj8A9cg_13; + x = TM__DfQaFFoJOv5Rj9bYYIj8A9cg_12[(i_2)- 0]; + { + tyArray__nHXaesL0DJZHyVS07ARPRA T18_; + if (!((NI)(x % ((NI) 2)) == ((NI) 1))) goto LA16_; + odd__example_154 = x; + nimZeroMem((void*)T18_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA)); + T18_[0] = dollar___systemZdollars_3(odd__example_154); + echoBinSafe(T18_, 1); + } + LA16_: ; + { + if (!(((NI) 5) <= ((NI) (i_2)))) goto LA21_; + goto LA12; + } + LA21_: ; + if (nimAddInt(i_2, ((NI) 1), &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_13)) { raiseOverflow(); }; + if (TM__DfQaFFoJOv5Rj9bYYIj8A9cg_13 < 0 || TM__DfQaFFoJOv5Rj9bYYIj8A9cg_13 > 5){ raiseOverflow(); } + i_2 = (NI)(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_13); + } + } LA12: ; + } + } + { + NI i_3; + i_3 = ((NI) 0); + { + while (1) { + NimStringDesc* T26_; + tyArray__nHXaesL0DJZHyVS07ARPRA T27_; + NI TM__DfQaFFoJOv5Rj9bYYIj8A9cg_19; + T26_ = NIM_NIL; + T26_ = o__example_213; o__example_213 = copyStringRC1(opcodes__example_187[(i_3)- 0]); + if (T26_) nimGCunrefNoCycle(T26_); + nimZeroMem((void*)T27_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA)); + T27_[0] = copyString(o__example_213); + echoBinSafe(T27_, 1); + { + if (!(((NI) 3) <= ((NI) (i_3)))) goto LA30_; + goto LA24; + } + LA30_: ; + if (nimAddInt(i_3, ((NI) 1), &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_19)) { raiseOverflow(); }; + if (TM__DfQaFFoJOv5Rj9bYYIj8A9cg_19 < 0 || TM__DfQaFFoJOv5Rj9bYYIj8A9cg_19 > 3){ raiseOverflow(); } + i_3 = (NI)(TM__DfQaFFoJOv5Rj9bYYIj8A9cg_19); + } + } LA24: ; + } +} +} + +N_LIB_PRIVATE N_NIMCALL(void, atmexampledotnim_DatInit000)(void) { +static TNimNode* TM__DfQaFFoJOv5Rj9bYYIj8A9cg_2_2[2]; +static TNimNode TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[3]; +NTIperson__NF2Erj5R8mAkjQbMRdkMjg_.size = sizeof(tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg); +NTIperson__NF2Erj5R8mAkjQbMRdkMjg_.align = NIM_ALIGNOF(tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg); +NTIperson__NF2Erj5R8mAkjQbMRdkMjg_.kind = 18; +NTIperson__NF2Erj5R8mAkjQbMRdkMjg_.base = 0; +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_2_2[0] = &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[1]; +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[1].kind = 1; +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[1].offset = offsetof(tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg, name); +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[1].typ = (&NTIstring__77mFvmsOLKik79ci2hXkHEg_); +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[1].name = "name"; +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_2_2[1] = &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[2]; +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[2].kind = 1; +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[2].offset = offsetof(tyObject_Person__NF2Erj5R8mAkjQbMRdkMjg, age); +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[2].typ = (&NTIint__hLlQjbV9bLNq5PFxYcqacsA_); +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[2].name = "age"; +TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[0].len = 2; TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[0].kind = 2; TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[0].sons = &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_2_2[0]; +NTIperson__NF2Erj5R8mAkjQbMRdkMjg_.node = &TM__DfQaFFoJOv5Rj9bYYIj8A9cg_0[0]; +NTIarrayL48OO49_personT__3ZLM5yW0QMKoSQQYqBR4sQ_.size = sizeof(tyArray__3ZLM5yW0QMKoSQQYqBR4sQ); +NTIarrayL48OO49_personT__3ZLM5yW0QMKoSQQYqBR4sQ_.align = NIM_ALIGNOF(tyArray__3ZLM5yW0QMKoSQQYqBR4sQ); +NTIarrayL48OO49_personT__3ZLM5yW0QMKoSQQYqBR4sQ_.kind = 16; +NTIarrayL48OO49_personT__3ZLM5yW0QMKoSQQYqBR4sQ_.base = (&NTIperson__NF2Erj5R8mAkjQbMRdkMjg_); +} + diff --git a/prescheme-nim-local/nim/@msimd.nim.c b/prescheme-nim-local/nim/@msimd.nim.c new file mode 100644 index 0000000..99e738c --- /dev/null +++ b/prescheme-nim-local/nim/@msimd.nim.c @@ -0,0 +1,188 @@ +/* Generated by Nim Compiler v1.6.12 */ +/* Compiled for: Linux, amd64, gcc */ +/* Command for C compiler: + gcc -c -w -fmax-errors=3 -mavx -I/gnu/store/xqah57hhkjdyp880dvxmqpvn58g5j7mv-nim-1.6.12/lib -I/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim -o /home/wrk/.cache/nim/simd_d/@msimd.nim.c.o /home/wrk/.cache/nim/simd_d/@msimd.nim.c */ +#define NIM_INTBITS 64 + +#include "nimbase.h" +#include "xmmintrin.h" +#include <string.h> +#include "immintrin.h" +#undef LANGUAGE_C +#undef MIPSEB +#undef MIPSEL +#undef PPC +#undef R3000 +#undef R4000 +#undef i386 +#undef linux +#undef mips +#undef near +#undef far +#undef powerpc +#undef unix + # define nimfr_(proc, file) \ + TFrame FR_; \ + FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); + + # define nimfrs_(proc, file, slots, length) \ + struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR_; \ + FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); + + # define nimln_(n, file) \ + FR_.line = n; FR_.filename = file; + typedef struct NimStringDesc NimStringDesc; +typedef struct TGenericSeq TGenericSeq; +struct TGenericSeq { +NI len; +NI reserved; +}; +struct NimStringDesc { + TGenericSeq Sup; +NIM_CHAR data[SEQ_DECL_SIZE]; +}; +typedef NimStringDesc* tyArray__nHXaesL0DJZHyVS07ARPRA[1]; +typedef NF32 tyArray__9aTCwbdg1cSQimdVd0OEKVw[4]; +typedef NF tyArray__jOGfJgrdxgfAJsLC7WNNEw[4]; +N_LIB_PRIVATE N_NIMCALL(void, echoBinSafe)(NimStringDesc** args, NI argsLen_0); +static N_INLINE(void, nimZeroMem)(void* p, NI size); +static N_INLINE(void, nimSetMem__systemZmemory_7)(void* a, int v, NI size); +N_LIB_PRIVATE N_NIMCALL(NimStringDesc*, dollar___simd_70)(tyArray__9aTCwbdg1cSQimdVd0OEKVw x); +N_LIB_PRIVATE N_NIMCALL(NimStringDesc*, dollar___simd_192)(tyArray__jOGfJgrdxgfAJsLC7WNNEw x); +static N_INLINE(void, initStackBottomWith)(void* locals); +N_LIB_PRIVATE N_NOINLINE(void, nimGC_setStackBottom)(void* theStackBottom); +static N_INLINE(void, nimFrame)(TFrame* s); +N_LIB_PRIVATE N_NOINLINE(void, callDepthLimitReached__system_2997)(void); +static N_INLINE(void, popFrame)(void); +N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_DatInit000)(void); +N_LIB_PRIVATE N_NIMCALL(void, atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_Init000)(void); +N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void); +STRING_LITERAL(TM__NqVfYNeiCrBLDU2vGCYO9bA_3, "TESTING AVX", 11); +static NIM_CONST tyArray__nHXaesL0DJZHyVS07ARPRA TM__NqVfYNeiCrBLDU2vGCYO9bA_2 = {((NimStringDesc*) &TM__NqVfYNeiCrBLDU2vGCYO9bA_3)} +; +N_LIB_PRIVATE __m128 a__simd_2; +N_LIB_PRIVATE __m128 b__simd_3; +N_LIB_PRIVATE __m128 c__simd_4; +N_LIB_PRIVATE tyArray__jOGfJgrdxgfAJsLC7WNNEw l1__simd_122 = {1.0, +2.1, +3.2, +4.3} +; +N_LIB_PRIVATE tyArray__jOGfJgrdxgfAJsLC7WNNEw l2__simd_123 = {0.0, +1.1, +2.1, +3.3} +; +N_LIB_PRIVATE __m256d regs1__simd_124; +N_LIB_PRIVATE __m256d regs2__simd_125; +N_LIB_PRIVATE __m256d result__simd_126; +extern TFrame* framePtr__system_2564; +extern TFrame* framePtr__system_2564; +extern TFrame* framePtr__system_2564; +extern TFrame* framePtr__system_2564; +extern TFrame* framePtr__system_2564; +extern TFrame* framePtr__system_2564; +static N_INLINE(void, nimSetMem__systemZmemory_7)(void* a, int v, NI size) { + void* T1_; + T1_ = (void*)0; + T1_ = memset(a, v, ((size_t) (size))); +} +static N_INLINE(void, nimZeroMem)(void* p, NI size) { + nimSetMem__systemZmemory_7(p, ((int) 0), size); +} +static N_INLINE(void, initStackBottomWith)(void* locals) { + nimGC_setStackBottom(locals); +} +static N_INLINE(void, nimFrame)(TFrame* s) { + { + if (!(framePtr__system_2564 == ((TFrame*) NIM_NIL))) goto LA3_; + (*s).calldepth = ((NI16) 0); + } + goto LA1_; + LA3_: ; + { + (*s).calldepth = (NI16)((*framePtr__system_2564).calldepth + ((NI16) 1)); + } + LA1_: ; + (*s).prev = framePtr__system_2564; + framePtr__system_2564 = s; + { + if (!((*s).calldepth == ((NI16) 2000))) goto LA8_; + callDepthLimitReached__system_2997(); + } + LA8_: ; +} +static N_INLINE(void, popFrame)(void) { + framePtr__system_2564 = (*framePtr__system_2564).prev; +} + +N_LIB_PRIVATE void PreMainInner(void) { +} + +N_LIB_PRIVATE int cmdCount; +N_LIB_PRIVATE char** cmdLine; +N_LIB_PRIVATE char** gEnv; +N_LIB_PRIVATE void PreMain(void) { + void (*volatile inner)(void); + inner = PreMainInner; + atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_DatInit000(); + initStackBottomWith((void *)&inner); + atmdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsdotdotatsgnuatsstoreatsxqah57hhkjdyp880dvxmqpvn58g5j7mvminusnimminus1dot6dot12atslibatssystemdotnim_Init000(); + (*inner)(); +} + +N_LIB_PRIVATE N_CDECL(void, NimMainInner)(void) { + NimMainModule(); +} + +N_CDECL(void, NimMain)(void) { + void (*volatile inner)(void); + PreMain(); + inner = NimMainInner; + initStackBottomWith((void *)&inner); + (*inner)(); +} + +int main(int argc, char** args, char** env) { + cmdLine = args; + cmdCount = argc; + gEnv = env; + NimMain(); + return nim_program_result; +} + +N_LIB_PRIVATE N_NIMCALL(void, NimMainModule)(void) { +{ + tyArray__nHXaesL0DJZHyVS07ARPRA T1_; + union { __m128 source; tyArray__9aTCwbdg1cSQimdVd0OEKVw dest; } LOC2; + tyArray__nHXaesL0DJZHyVS07ARPRA T3_; + union { __m256d source; tyArray__jOGfJgrdxgfAJsLC7WNNEw dest; } LOC4; + nimfr_("simd", "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + nimln_(12, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + echoBinSafe(TM__NqVfYNeiCrBLDU2vGCYO9bA_2, 1); + nimln_(16, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + a__simd_2 = _mm_set1_ps(1.0f); + nimln_(17, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + b__simd_3 = _mm_set1_ps(2.0f); + nimln_(18, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + c__simd_4 = _mm_mul_ps(a__simd_2, b__simd_3); + nimln_(21, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + nimZeroMem((void*)T1_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA)); + LOC2.source = c__simd_4; + T1_[0] = dollar___simd_70(LOC2.dest); + echoBinSafe(T1_, 1); + nimln_(29, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + regs1__simd_124 = _mm256_loadu_pd(((void*) ((&l1__simd_122[(((NI) 0))- 0])))); + nimln_(30, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + regs2__simd_125 = _mm256_loadu_pd(((void*) ((&l2__simd_123[(((NI) 0))- 0])))); + nimln_(31, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + result__simd_126 = _mm256_sub_pd(regs1__simd_124, regs2__simd_125); + nimln_(32, "/export/local/home/wrk/iwrk/opensource/lisp/prescheme-explore/nim/simd.nim"); + nimZeroMem((void*)T3_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA)); + LOC4.source = result__simd_126; + T3_[0] = dollar___simd_192(LOC4.dest); + echoBinSafe(T3_, 1); + popFrame(); +} +} + diff --git a/prescheme-nim-local/nim/contrib/nimsimd b/prescheme-nim-local/nim/contrib/nimsimd new file mode 160000 +Subproject e485e9fdf604bd54bd5b2616a34979b7715ff8a diff --git a/prescheme-nim-local/nim/example.nim b/prescheme-nim-local/nim/example.nim new file mode 100644 index 0000000..6757120 --- /dev/null +++ b/prescheme-nim-local/nim/example.nim @@ -0,0 +1,51 @@ +# Example from nim front page. Compile with: +# +# nim -c -d:release c example && ./example + +import std/strformat + +type + Person = object + name: string + age: Natural # Ensures the age is positive + +let people = [ + Person(name: "John", age: 45), + Person(name: "Kate", age: 30) +] + +for person in people: + # Type-safe string interpolation, + # evaluated at compile time. + echo(fmt"{person.name} is {person.age} years old") + + +# Thanks to Nim's 'iterator' and 'yield' constructs, +# iterators are as easy to write as ordinary +# functions. They are compiled to inline loops. +iterator oddNumbers[Idx, T](a: array[Idx, T]): T = + for x in a: + if x mod 2 == 1: + yield x + +for odd in oddNumbers([3, 6, 9, 12, 15, 18]): + echo odd + + +# Use Nim's macro system to transform a dense +# data-centric description of x86 instructions +# into lookup tables that are used by +# assemblers and JITs. +import macros, strutils + +macro toLookupTable(data: static[string]): untyped = + result = newTree(nnkBracket) + for w in data.split(';'): + result.add newLit(w) + +const + data = "mov;btc;cli;xor" + opcodes = toLookupTable(data) + +for o in opcodes: + echo o diff --git a/prescheme-nim-local/nim/readme.md b/prescheme-nim-local/nim/readme.md new file mode 100644 index 0000000..556eb5d --- /dev/null +++ b/prescheme-nim-local/nim/readme.md @@ -0,0 +1,65 @@ +# NIM + +Compiles to C with + + nim -c -d:release c example + +See ~/.cache/nim/example_r/\@mexample.nim.c + +# Using simde + +https://github.com/guzba/nimsimd/tree/master + +```nim +# SIMD floating point multiplication +let + a = mm_set1_ps(1.0) # Vector of 4 float32 each with value 1.0 + b = mm_set1_ps(2.0) # Vector of 4 float32 each with value 2.0 + c = mm_mul_ps(a, b) # SIMD vector multiplication operator +# Cast the vector to echo as separate float32 values +echo cast[array[4, float32]](c) +``` + +Translates to C + +```C +tyArray__nHXaesL0DJZHyVS07ARPRA T1_; +union { __m128 source; tyArray__9aTCwbdg1cSQimdVd0OEKVw dest; } LOC2; + +echoBinSafe(TM__NqVfYNeiCrBLDU2vGCYO9bA_2, 1); +a__simd_2 = _mm_set1_ps(1.0f); +b__simd_3 = _mm_set1_ps(2.0f); +c__simd_4 = _mm_mul_ps(a__simd_2, b__simd_3); +nimZeroMem((void*)T1_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA)); +LOC2.source = c__simd_4; +T1_[0] = dollar___simd_70(LOC2.dest); +echoBinSafe(T1_, 1); +``` + +```nim +var l1 = [1.0, 2.1, 3.2, 4.3] +var l2 = [0.0, 1.1, 2.1, 3.3] + +var regs1 = mm256_loadu_pd(l1[0].addr) +var regs2 = mm256_loadu_pd(l2[0].addr) +var result = mm256_sub_pd(regs1,regs2) +echo cast[array[4, float64]](result) +``` + +```C +regs1__simd_124 = _mm256_loadu_pd(((void*) ((&l1__simd_122[(((NI) 0))- 0])))); +regs2__simd_125 = _mm256_loadu_pd(((void*) ((&l2__simd_123[(((NI) 0))- 0])))); +result__simd_126 = _mm256_sub_pd(regs1__simd_124, regs2__simd_125); +nimZeroMem((void*)T3_, sizeof(tyArray__nHXaesL0DJZHyVS07ARPRA)); +LOC4.source = result__simd_126; +T3_[0] = dollar___simd_192(LOC4.dest); +echoBinSafe(T3_, 1); +``` + +Output: + +``` +TESTING AVX +[2.0, 2.0, 2.0, 2.0] +[1.0, 1.0, 1.1, 1.0] +``` diff --git a/prescheme-nim-local/nim/simd.nim b/prescheme-nim-local/nim/simd.nim new file mode 100644 index 0000000..4c1e93b --- /dev/null +++ b/prescheme-nim-local/nim/simd.nim @@ -0,0 +1,29 @@ +# Trying simd stuff. Compile with: +# +# nim --path:contrib/nimsimd/src c simd && ./simd +# nim --path:contrib/nimsimd/src -c -d:release c simd && ./simd + +when defined(gcc) or defined(clang): + {.localPassc: "-mavx".} + + +import nimsimd/avx2 + +echo "TESTING AVX" + +# SIMD floating point multiplication +let + a = mm_set1_ps(1.0) # Vector of 4 float32 each with value 1.0 + b = mm_set1_ps(2.0) # Vector of 4 float32 each with value 2.0 + c = mm_mul_ps(a, b) # SIMD vector multiplication operator + +# Cast the vector to echo as separate float32 values +echo cast[array[4, float32]](c) + +var l1 = [1.0, 2.1, 3.2, 4.3] +var l2 = [0.0, 1.1, 2.1, 3.3] + +var regs1 = mm256_loadu_pd(l1[0].addr) +var regs2 = mm256_loadu_pd(l2[0].addr) +var result = mm256_sub_pd(regs1,regs2) +echo cast[array[4, float64]](result) diff --git a/prescheme-nim-local/notes.md b/prescheme-nim-local/notes.md new file mode 100644 index 0000000..62b64e2 --- /dev/null +++ b/prescheme-nim-local/notes.md @@ -0,0 +1,94 @@ +# Thinks that tripped me up + +# Underscores + +Using _ for Lisp names. + +# typedef struct + +```C +typedef struct +{ + size_t size; + size_t stride; + double * data; + gsl_block * block; + int owner; +} gsl_vector; +``` + +prescheme generated this syntax for + +```lisp +(define-wrapper-type gsl-vector) +``` + +```C +struct gsl_vector { +}; + +struct gsl_vector *vector_3X; +``` + +resulting in + +``` +expected 'gsl_vector *' but argument is of type 'struct gsl_vector *' + 82 | void gsl_vector_free (gsl_vector * v); +``` + +how to map one to the other? If you take out the struct it works. So, somehow, I need to create an opaque data structure. + +``` +(define (gsl-create-vector size) ; gsl_vector_alloc (3); + ((external "gsl_vector_alloc" (=> (integer) (^ unit))) + size)) + +(define (gsl-destroy-vector vector) + ((external "gsl_vector_free" (=> (address) unit)) + vector)) +``` + +as unit translate to void that works - but there is no type safety. Well, at least not at the prescheme level. + +ps-compiler/prescheme/type.scm +make-pointer-type + +For now I solved it by having sed edit out the 'struct' from the C code. + +# Floating point + +Initializing with 1.0 (leading zero) works. But 1.1 does not. The c-code becomes an empty space. + +``` +openblas.c:36:108: error: expected expression before ')' token + 36 | else {gsl_vector_set(vector_2X, 0, 0.0);gsl_vector_set(vector_2X, 1, 1.0);gsl_vector_set(vector_2X, 2, );gsl_vector_set(vector_2X, 3, 4.0);gsl_vector_set(vector_2X, 4, 5.0); +``` + +This was fixed by Andrew Whatson for me! + +# Loading a module + +Requires restarting prescheme? Note that file prescheme/memory.scm is loaded with ps-memory. + +``` +(define-structure openblas (export main) + (open prescheme) + ;; (open ps-receive) + (open ps-memory) + ;; (open prescheme interface) + (open ps-utils) + (open ps-string) + (open ps-vector) + ;; (open prescheme interfaces) + (files openblas)) +``` + +# SIMDE + +Let's try to multiply a vector with a scalar. + +``` +const __m128 scalar = _mm_set1_ps(s); +__m128 result = _mm_mul_ps(vector, scalar); +``` diff --git a/prescheme-nim-local/openblas.scm b/prescheme-nim-local/openblas.scm new file mode 100644 index 0000000..c171906 --- /dev/null +++ b/prescheme-nim-local/openblas.scm @@ -0,0 +1,108 @@ +;; openblas+gsl example (WIP) + +(define %vec-a (vector-unfold (lambda (i) + (* i i)) + 5)) + +;; take vec-a's length at compile-time +(define %len-a (vector-length %vec-a)) + + +(define foox + (external "computefoox" (=> (integer integer) integer) + (lambda (x y) + (display (+ x y))))) + +(define (handle-error message) + (define out (current-error-port)) + (error message)) + +(define-wrapper-type gsl-vector) + +(define (gsl-create-vector size) ; gsl_vector_alloc (3); + ((external "gsl_vector_alloc" (=> (integer) gsl-vector)) + size)) + +(define (gsl-destroy-vector vector) + ((external "gsl_vector_free" (=> (gsl-vector) unit ) ) + vector)) + +(define (with-vector vector proc) + (if (null-pointer? vector) + (handle-error "Could not create vector") + (let ((result (proc vector))) + (gsl-destroy-vector vector) + result))) + +;; void gsl_vector_set(gsl_vector *v, const size_t i, double x) +(define (gsl-vector-set! v i x) + ((external "gsl_vector_set" (=> (gsl-vector integer float) unit ) ) + v i x)) + +;; double gsl_vector_get(const gsl_vector *v, const size_t i) +(define (gsl-vector-get v i) + ((external "gsl_vector_get" (=> (gsl-vector integer) float ) ) + v i)) + +;; gcvt (float value, int ndigits, char * buf); +(define (gcvt v ndigits buf) + ((external "gcvt" (=> (float integer (^ char)) unit ) ) + v ndigits buf)) + + +;;(define-c-generator make-string #t +;; (lambda (call port indent) +;; ; calloc is used as a hack to get a zero at the end +;; (format port "(char *)calloc( 1, 1 + ") +;; (c-value (call-arg call 0) port) +;; (format port ")"))) + +(define (main) + (define out (current-output-port)) + + (write-string "Prescheme vector: print vec-a with vector-for-each:\n" out) + ; (make-pointer gsl-vector) + + (vector-for-each (lambda (i val) + (write-string " vec-a[" out) + (write-integer i out) + (write-string "] = " out) + (write-integer val out) + (write-string ", " out) + ) + %vec-a %len-a) + (newline out) + (write-string "OpenBLAS: print vec-a with vector-for-each:\n" out) + (with-vector + (gsl-create-vector 5) + (lambda (one-vec) + ;; (gsl-vector-for-each (lambda (i val) + ;; gsl-set-vector(one-vec,i,val); + ;; ) + ;; one-vec) + (let ((x 1.1)) + (gsl-vector-set! one-vec 0 (fl* x 0.0)) + (gsl-vector-set! one-vec 1 (fl* x x)) + (gsl-vector-set! one-vec 2 (fl* x 2.1)) + (gsl-vector-set! one-vec 3 4.0) + (gsl-vector-set! one-vec 4 5.0) + ;; (gsl-vector-set one-vec 5 6.0) + ) + (vector-for-each (lambda (i val) + (write-string " vec-b[" out) + (write-integer i out) + (write-string "] = " out) + ;; (write-number (gsl-vector-get one-vec i) out) + (let ((target (make-string 20))) + ;; (write-integer (gsl-vector-get one-vec i) out) + ;; (gcvt (gsl-vector-get one-vec i) target) + (gcvt (gsl-vector-get one-vec i) 4 target) + (write-string target out) + ) + (write-string ", " out) + ) + %vec-a %len-a) + )) + (newline out) + 0 +) diff --git a/prescheme-nim-local/prescheme-compile.scm b/prescheme-nim-local/prescheme-compile.scm new file mode 100644 index 0000000..87a460d --- /dev/null +++ b/prescheme-nim-local/prescheme-compile.scm @@ -0,0 +1,20 @@ +;; (prescheme-compiler 'hello '("packages.scm") 'hello-init "hello.c") +;(prescheme-compiler 'vec '("packages.scm") +; 'ps-init "vec.c" +; '(header "#include \"ps-init.h\"") +; ) +(prescheme-compiler 'openblas '("packages.scm") + 'ps-init "openblas.c" + '(header "#include \"ps-init.h\"" + "#include \"gsl/gsl_vector.h\"" + ;; "int computefoox(int x, int y);" + ) + ) +(prescheme-compiler 'simde '("packages.scm") + 'ps-init "simde.c" + '(header "#include \"ps-init.h\"" + "#include <simde/x86/avx512.h>" + ;; "int computefoox(int x, int y);" + ) + ) +,exit diff --git a/prescheme-nim-local/ps-init.h b/prescheme-nim-local/ps-init.h new file mode 100644 index 0000000..e6f56d2 --- /dev/null +++ b/prescheme-nim-local/ps-init.h @@ -0,0 +1,11 @@ +/* + * Call Pre-Scheme static initialization before main. + */ +__attribute__((constructor)) +void ps_init(void); + +/* + * Missing definition for open-input-file. Probably an oversight, it's + * defined in scheme48.h but should be in prescheme.h. + */ +#define NO_ERRORS 0 diff --git a/prescheme-nim-local/simde.c b/prescheme-nim-local/simde.c new file mode 100644 index 0000000..e34f7c7 --- /dev/null +++ b/prescheme-nim-local/simde.c @@ -0,0 +1,85 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "prescheme.h" +#include "ps-init.h" +#include <simde/x86/avx512.h> + + + +long main(void); +static long *Qvec_a; + +long main(void) +{ + long arg0K0; + long i_9X; + long val_8X; + simde__m256d avx_7X; + simde__m256d odds_6X; + simde__m256d evens_5X; + double *b_4X; + double *a_3X; + char *target_2X; + long i_1X; + FILE * out_0X; + { out_0X = stdout; + ps_write_string("SIMDE: Print vec-a with vector-for-each:\n", out_0X); + arg0K0 = 0; + goto L208;} + L208: { + i_1X = arg0K0; + if ((5 == i_1X)) { + { long ignoreXX; + PS_WRITE_CHAR(10, out_0X, ignoreXX) } + target_2X = (char *)calloc( 1, 1 + 20); + a_3X = (double*)malloc(sizeof(double) * 10); + b_4X = (double*)malloc(sizeof(double) * 10); + gcvt(1.2, 4, target_2X); + ps_write_string(target_2X, out_0X); + { long ignoreXX; + PS_WRITE_CHAR(10, out_0X, ignoreXX) } + *(a_3X + 0) = 2.2; + *(a_3X + 1) = 2.2; + *(a_3X + 2) = 4.2; + *(a_3X + 3) = 5.2; + *(b_4X + 0) = 1.1; + *(b_4X + 1) = 2.1; + *(b_4X + 2) = 3.1; + *(b_4X + 3) = 4.1; + evens_5X = simde_mm256_loadu_pd(a_3X); + odds_6X = simde_mm256_loadu_pd(b_4X); + avx_7X = simde_mm256_sub_pd(evens_5X, odds_6X);simde_mm256_storeu_pd(a_3X, avx_7X); + arg0K0 = 0; + goto L253;} + else { + val_8X = *(Qvec_a + i_1X); + ps_write_string(" vec-a[", out_0X); + ps_write_integer(i_1X, out_0X); + ps_write_string("] = ", out_0X); + ps_write_integer(val_8X, out_0X); + ps_write_string(", ", out_0X); + arg0K0 = (1 + i_1X); + goto L208;}} + L253: { + i_9X = arg0K0; + if ((4 == i_9X)) { + { long ignoreXX; + PS_WRITE_CHAR(10, out_0X, ignoreXX) } + return 0;} + else {gcvt((*(a_3X + i_9X)), 4, target_2X); + ps_write_string(target_2X, out_0X); + { long ignoreXX; + PS_WRITE_CHAR(10, out_0X, ignoreXX) } + arg0K0 = (1 + i_9X); + goto L253;}} +}void +ps_init(void) +{ +Qvec_a = malloc(5 * sizeof(long)); +Qvec_a[0] = 0; +Qvec_a[1] = 1; +Qvec_a[2] = 4; +Qvec_a[3] = 9; +Qvec_a[4] = 16; +} diff --git a/prescheme-nim-local/simde.scm b/prescheme-nim-local/simde.scm new file mode 100644 index 0000000..06e6fb6 --- /dev/null +++ b/prescheme-nim-local/simde.scm @@ -0,0 +1,97 @@ +;; simde example (WIP) + +(define %vec-a (vector-unfold (lambda (i) + (* i i)) + 5)) + +;; take vec-a's length at compile-time +(define %len-a (vector-length %vec-a)) + + +(define foox + (external "computefoox" (=> (integer integer) integer) + (lambda (x y) + (display (+ x y))))) + +(define (handle-error message) + (define out (current-error-port)) + (error message)) + +;;(define-c-generator make-string #t +;; (lambda (call port indent) +;; ; calloc is used as a hack to get a zero at the end +;; (format port "(char *)calloc( 1, 1 + ") +;; (c-value (call-arg call 0) port) +;; (format port ")"))) + +;; gcvt (float value, int ndigits, char * buf); +(define (gcvt v ndigits buf) + ((external "gcvt" (=> (float integer (^ char)) unit ) ) + v ndigits buf)) + +(define-wrapper-type m256d) + +;; (define (fmaddf a b c) +;; ((external "simde_mm256_fmadd_pd" (=> ((^ float) (^ float) (^ float)) (^ float) ) ) +;; a b c)) + +;; simde__m256d evens4 = simde_mm256_loadu_pd(l1); +(define (simde-loadu ds) + ((external "simde_mm256_loadu_pd" (=> ((^ float)) m256d)) + ds )) + +(define (simde-storeu ds avx) + ((external "simde_mm256_storeu_pd" (=> ((^ float) m256d) (^ float))) + ds avx) + ds ) + +(define (simde-sub-pd ds1 ds2) + ((external "simde_mm256_sub_pd" (=> (m256d m256d) m256d)) + ds1 ds2)) + +(define (main) + (define out (current-output-port)) + + (write-string "SIMDE: Print vec-a with vector-for-each:\n" out) + + (vector-for-each (lambda (i val) + (write-string " vec-a[" out) + (write-integer i out) + (write-string "] = " out) + (write-integer val out) + (write-string ", " out) + ) + %vec-a %len-a) + (newline out) + (let ((target (make-string 20)) + (f 1.2) + (a (make-vector 10 1.1)) + (b (make-vector 10 1.1)) + (c (make-vector 10 1.1)) + ) + (gcvt f 4 target) + (write-string target out) + (newline out) + (vector-set! a 0 2.2) + (vector-set! a 1 2.2) + (vector-set! a 2 4.2) + (vector-set! a 3 5.2) + (vector-set! b 0 1.1) + (vector-set! b 1 2.1) + (vector-set! b 2 3.1) + (vector-set! b 3 4.1) + (let* ((evens (simde-loadu a)) + (odds (simde-loadu b)) + (result (simde-storeu a (simde-sub-pd evens odds)))) + (vector-for-each (lambda (i val) + ;; (flonum-set! val i) + (gcvt val 4 target) + (write-string target out) + (newline out) + ) + result 4) + ) + ) + (newline out) + 0 +) diff --git a/prescheme-nim-local/vec.c b/prescheme-nim-local/vec.c new file mode 100644 index 0000000..b8e369f --- /dev/null +++ b/prescheme-nim-local/vec.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "prescheme.h" +#include "ps-init.h" + +long main(void); +static long *Qvec_a; + +long main(void) +{ + long arg0K0; + long val_2X; + long i_1X; + FILE * out_0X; + { out_0X = stdout; + ps_write_string("Print vec-a with vector-for-each:\n", out_0X); + ps_write_integer(5, out_0X); + arg0K0 = 0; + goto L119;} + L119: { + i_1X = arg0K0; + if ((5 == i_1X)) { + return 0;} + else { + val_2X = *(Qvec_a + i_1X); + ps_write_string(" vec-a[", out_0X); + ps_write_integer(i_1X, out_0X); + ps_write_string("] = ", out_0X); + ps_write_integer(val_2X, out_0X); + { long ignoreXX; + PS_WRITE_CHAR(10, out_0X, ignoreXX) } + arg0K0 = (1 + i_1X); + goto L119;}} +}void +ps_init(void) +{ +Qvec_a = malloc(5 * sizeof(long)); +Qvec_a[0] = 0; +Qvec_a[1] = 1; +Qvec_a[2] = 4; +Qvec_a[3] = 9; +Qvec_a[4] = 16; +} diff --git a/prescheme-nim-local/vec.scm b/prescheme-nim-local/vec.scm new file mode 100644 index 0000000..7fc4740 --- /dev/null +++ b/prescheme-nim-local/vec.scm @@ -0,0 +1,21 @@ +;; vec-a is computed at compile-time +(define %vec-a (vector-unfold (lambda (i) + (* i i)) + 5)) + +;; take vec-a's length at compile-time +(define %len-a (vector-length %vec-a)) + +(define (main) + (define out (current-output-port)) + (write-string "Print vec-a with vector-for-each:\n" out) + (write-integer %len-a out) + (vector-for-each (lambda (i val) + (write-string " vec-a[" out) + (write-integer i out) + (write-string "] = " out) + (write-integer val out) + (newline out)) + %vec-a %len-a) + 0 +) |