Efficient signal processing using Haskell and LLVM Henning - - PowerPoint PPT Presentation

efficient signal processing using haskell and llvm
SMART_READER_LITE
LIVE PREVIEW

Efficient signal processing using Haskell and LLVM Henning - - PowerPoint PPT Presentation

Efficient signal processingusing Haskell and LLVM Efficient signal processing using Haskell and LLVM Henning Thielemann 2016-09-15 Efficient signal processingusing Haskell and LLVM Features 1 Features 2 Discussion Efficient signal


slide-1
SLIDE 1

Efficient signal processingusing Haskell and LLVM

Efficient signal processing using Haskell and LLVM

Henning Thielemann 2016-09-15

slide-2
SLIDE 2

Efficient signal processingusing Haskell and LLVM Features

1 Features 2 Discussion

slide-3
SLIDE 3

Efficient signal processingusing Haskell and LLVM Features

Introduction

Warning: synthesizer-llvm – already fast and feature-rich, but still pretty low-level. Nonetheless no need for much LLVM hacking.

slide-4
SLIDE 4

Efficient signal processingusing Haskell and LLVM Features Signal producers and modifiers

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-5
SLIDE 5

Efficient signal processingusing Haskell and LLVM Features Signal producers and modifiers

Signal

module module module Synthesizer.LLVM.Simple.Signal signal simulated by signal generator compute and emit samples step by step (iterator) Value Float Float Float ∼ Float Float Float value in LLVM Signal.T a ∼ [a] producer:

  • sciSaw :: Float

Float Float

  • > Signal.T (Value Float

Float Float) modifier: amplify :: Float Float Float

  • >

Signal.T (Value Float Float Float) -> Signal.T (Value Float Float Float)

slide-6
SLIDE 6

Efficient signal processingusing Haskell and LLVM Features Signal producers and modifiers

Oscillator

supported waveforms: Csound: waves made from tables SuperCollider: specialized oscillator per waveform synthesizer-llvm: any function as waveform Synthesizer.LLVM.Wave band-limited oscillators: SuperCollider: available synthesizer-llvm: not available

slide-7
SLIDE 7

Efficient signal processingusing Haskell and LLVM Features Causal processes: sharing and feedback

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-8
SLIDE 8

Efficient signal processingusing Haskell and LLVM Features Causal processes: sharing and feedback

Causal processes

Problems: let let let x = Signal.osciSaw freq in in in x + x Signal x is computed twice. amplify :: Float Float Float

  • >

Signal.T (Value Float Float Float) -> Signal.T (Value Float Float Float) No warranty for usability of amplify in real-time processing.

slide-9
SLIDE 9

Efficient signal processingusing Haskell and LLVM Features Causal processes: sharing and feedback

Causal processes

Solution: module module module Synthesizer.LLVM.Causal.Process Process.T a b ∼ Signal.T a -> Signal.T b instance instance instance Arrow Process.T warrants causality: never accesses future input values e.g. reverse reverse reverse cannot be a Process.T tailored to real-time processing allows for sharing allows for feedback Example: amplify :: Float Float Float

  • >

Process.T (Value Float Float Float) (Value Float Float Float)

slide-10
SLIDE 10

Efficient signal processingusing Haskell and LLVM Features Parameterized code

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-11
SLIDE 11

Efficient signal processingusing Haskell and LLVM Features Parameterized code

Parameters

Problem: Test > play (osciSaw (hertz 440)) ... Test > play (osciSaw (hertz 550)) ... Code for osciSaw is compiled twice. Goal: compile osciSaw once add parameters to compiled code

slide-12
SLIDE 12

Efficient signal processingusing Haskell and LLVM Features Parameterized code

Parameters

Solution: module module module Synthesizer.LLVM.Parameter module module module Synthesizer.LLVM.Parameterized.* module module module Synthesizer.LLVM.CausalParameterized.* Example: amplify :: Param.T p Float Float Float

  • >

CausalP.T p (Value Float Float Float) (Value Float Float Float) p: record containing all parameters Param.T p Float Float Float: selector from record p arr fst fst fst :: Param.T (Float Float Float, Bool Bool Bool) Float Float Float 440 :: Param.T p Float Float Float:

constant 440 folded into code parameter omitted in low-level parameter structure

slide-13
SLIDE 13

Efficient signal processingusing Haskell and LLVM Features Parameterized code

Parameters

Example:

  • Causal. applyStorable

(Causal.amplify (arr id id id)) :: Float Float Float

  • > SV.Vector Float

Float Float

  • >

SV.Vector Float Float Float

slide-14
SLIDE 14

Efficient signal processingusing Haskell and LLVM Features Sample value types: Stereo sounds, binary logic signals

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-15
SLIDE 15

Efficient signal processingusing Haskell and LLVM Features Sample value types: Stereo sounds, binary logic signals

Rich sample value types

Csound, SuperCollider: Signals of Floats synthesizer-llvm:

various precisions: Float Float Float, Double Double Double integers (counts, linear congruence noise) Bool Bool Bool (trigger and gate signals) enumerations (comparison result) stereo pairs tuples (combined low-pass, band-pass, high-pass filter) complex numbers (Fourier coefficients) arrays (ring buffers, parallel processes) serial chunks (vectorization)

  • paque records (internal filter parameters)

functions (waveform)

slide-16
SLIDE 16

Efficient signal processingusing Haskell and LLVM Features Sample value types: Stereo sounds, binary logic signals

Stereo

module module module Synthesizer.LLVM.Frame.Stereo module module module Synthesizer.LLVM.Frame.StereoInterleaved amplifyStereo :: a -> Causal.T (Stereo.T (Value a)) (Stereo.T (Value a)) No need to resort to pairs of signals.

slide-17
SLIDE 17

Efficient signal processingusing Haskell and LLVM Features Sample value types: Stereo sounds, binary logic signals

Ugly: CausalP.takeWhile takeWhile takeWhile (LLVM.cmp LLVM.CmpGT) threshold Nice: CausalPV.takeWhile takeWhile takeWhile (%>) threshold module module module Synthesizer.LLVM.Simple.Value module module module Synthesizer.LLVM.Causal.ProcessValue module module module Synthesizer.LLVM.CausalParameterized.ProcessValue

slide-18
SLIDE 18

Efficient signal processingusing Haskell and LLVM Features Frequency filter parameters and different signal rates

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-19
SLIDE 19

Efficient signal processingusing Haskell and LLVM Features Frequency filter parameters and different signal rates

Frequency filter

Problem: Frequency filters controlled by frequency f , resonance Q Computing internal filter parameters from f , Q is expensive, but filter parameters may not change rapidly Applying filters is cheap, but must be performed at audio sample rate Solutions elsewhere: Csound, SuperCollider distinguish between:

high audio rate: e.g. 44100 Hz low control rate: e.g. 4410 Hz audio rate must be multiple of control rate

ChucK: Update parameters on demand

slide-20
SLIDE 20

Efficient signal processingusing Haskell and LLVM Features Frequency filter parameters and different signal rates

Coping with internal filter parameters

module module module Synthesizer.LLVM.Filter.* Separate filter parameter computation, rate adaption, filter application subsumes features of other frameworks filter parameters: explicit but opaque data type automatically select filter depending on filter parameter type: module module module Synthesizer.LLVM.Causal.Controlled dependency this way:

multiple ways to define filter

  • ne way to perform filter
slide-21
SLIDE 21

Efficient signal processingusing Haskell and LLVM Features Vectorization

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-22
SLIDE 22

Efficient signal processingusing Haskell and LLVM Features Vectorization

Vector computation

modern CPUs can perform multiple operations at once, AVX: 8 Float Float Float multiplications in one instruction certainly the main way to accelerate code in future processors utilize vector operations: LLVM optimizer: turn scalar into vector operations automatically custom synthesizer-llvm implementations LLVM: both generic and processor specific vector instructions supports non-native vector sizes LLVM optimizer: Pro: transparent to synthesizer-llvm API Con: not allowed to perform certain optimizations

slide-23
SLIDE 23

Efficient signal processingusing Haskell and LLVM Features Vectorization

Custom vector implementations

possible schemes: serial: chop signal in chunks of vector size parallel: compute several equal processes in lock-step mixed: e.g. serial chunks of stereo signals pipeline: chain of equal processes switch between vectorization schemes: expensive → stick to one scheme serial vectorization most flexible automatically scales to (future) longer vectors

slide-24
SLIDE 24

Efficient signal processingusing Haskell and LLVM Features Vectorization

Custom vector implementations

serial chunks: module module module Synthesizer.LLVM.Frame.SerialVector module module module Synthesizer.LLVM.Simple.SignalPacked module module module Synthesizer.LLVM.Parameterized.SignalPacked module module module Synthesizer.LLVM.Causal.ProcessPacked module module module Synthesizer.LLVM.Causal.ControlledPacked module module module Synthesizer.LLVM.CausalParameterized.ProcessPacked module module module Synthesizer.LLVM.CausalParameterized.ControlledPacked parallel: replace Value a by Value (Vector n a) mixed serial/parallel: module module module Synthesizer.LLVM.Frame.StereoInterleaved pipeline: Synthesizer.LLVM.Causal.Process.pipeline

slide-25
SLIDE 25

Efficient signal processingusing Haskell and LLVM Features Treat arrows like plain functions

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-26
SLIDE 26

Efficient signal processingusing Haskell and LLVM Features Treat arrows like plain functions

Arrows are cumbersome

Functional: \x -> let let let y = lowpass x in in in mix y (delay y) Temporary variables for shared results – Wanted! Arrow combinators: mix <<< id id id &&& delay <<< lowpass Too few temporary variables (no x) Arrow notation: proc x -> do do do y <- lowpass

  • < x

z <- delay

  • < y

mix -< (y,z) Too many temporary variables (unnecessary z).

slide-27
SLIDE 27

Efficient signal processingusing Haskell and LLVM Features Treat arrows like plain functions

Turn Arrows to functions

module module module Synthesizer.LLVM.CausalParameterized.Functional let let let x = Func.lift $ arr id id id y = lowpass $& x in in in mix $& y &|& (delay $& y) Func.withArgs $ \x -> let let let y = lowpass $& x in in in mix $& y &|& (delay $& y) Input selector instead of function parameter: x :: Func.T input (Value Float Float Float) Observed sharing y runs only once

slide-28
SLIDE 28

Efficient signal processingusing Haskell and LLVM Features Compose music from tones

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-29
SLIDE 29

Efficient signal processingusing Haskell and LLVM Features Compose music from tones

Compose tones

parameterizable signals render to StorableVector

  • verlapping mix of scheduled signals

Synthesizer.LLVM.Storable.Signal.arrange result: StorableVector accessible to further processing

slide-30
SLIDE 30

Efficient signal processingusing Haskell and LLVM Features MIDI control

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-31
SLIDE 31

Efficient signal processingusing Haskell and LLVM Features MIDI control

separate MIDI channels separate command types (note, controller, program change) separate controllers convert controller events to audio data

  • r opaque filter parameters

module module module Synthesizer.LLVM.MIDI module module module Synthesizer.LLVM.MIDI.BendModulation

slide-32
SLIDE 32

Efficient signal processingusing Haskell and LLVM Features Integration with ALSA and JACK

1 Features

Signal producers and modifiers Causal processes: sharing and feedback Parameterized code Sample value types: Stereo sounds, binary logic signals Frequency filter parameters and different signal rates Vectorization Treat arrows like plain functions Compose music from tones MIDI control Integration with ALSA and JACK

2 Discussion

slide-33
SLIDE 33

Efficient signal processingusing Haskell and LLVM Features Integration with ALSA and JACK

Integration with ALSA and JACK

ALSA: separate sub-systems for

Audio: ALSA PCM MIDI: ALSA sequencer

JACK: call-back design compatible with Causal.Process processes chunks of audio and MIDI data reactive audio programming Event+Behavior: MIDI events integration of Event+Behavior with audio

slide-34
SLIDE 34

Efficient signal processingusing Haskell and LLVM Features Integration with ALSA and JACK

Integration with ALSA and JACK

process data in chunks CausalParameterized.Process.processIO module module module Synthesizer.LLVM.Server.ALSA module module module Synthesizer.LLVM.Server.JACK

slide-35
SLIDE 35

Efficient signal processingusing Haskell and LLVM Discussion

1 Features 2 Discussion

slide-36
SLIDE 36

Efficient signal processingusing Haskell and LLVM Discussion

Signal processing EDSL in Haskell

An EDSL in Haskell as cumbersome and unsafe as C – any advantage over C? Advantages: automatic adaption to instruction set extensions (e.g. SSE, AVX, AVX2) put much processing in one loop

does not increase speed, but allows for short-time feedback

generation of efficient signal processing including short-time feedback at runtime, e.g. also at user-request. User may

enter custom process graphs, load example graphs from disk, send it via MIDI-SYSEX to your software synthesizer.

slide-37
SLIDE 37

Efficient signal processingusing Haskell and LLVM Discussion

Comparison with Csound, SuperCollider etc.

Advantages of established software synthesizers: lots of predefined effects and examples Disadvantage: Also need sophisticated Haskell interfaces. Advantages of Haskell EDSL: exchange audio data between LLVM synthesizer and other Haskell code in memory smaller, more basic building blocks, due to richer type system and short-time feedback thus, easier to extend

slide-38
SLIDE 38

Efficient signal processingusing Haskell and LLVM Discussion

Short-time feedback

Short-time feedback is a pretty invasive feature. The fine print is: short-time feedback makes processing unstable, hard to predict, may not be reproducible at different sampling rates conflicts with vectorization, machine vectors are the new processing chunks

slide-39
SLIDE 39

Efficient signal processingusing Haskell and LLVM Discussion

LLVM

Pros: JIT multiple processor back-ends vectorization

  • ptimizations

Cons: global variables (e.g. no connection between Module and Builder) destructive updates (e.g. in optimization) Phi-Nodes instead of Basic-Block-Arguments low responsibility:

frequent changes, hardly documented little reactions to questions bugs are quickly introduced but require years to be fixed (e.g. inttopointer, LLVMRunFunction)

slide-40
SLIDE 40

Efficient signal processingusing Haskell and LLVM Discussion

To Do

vectorization without vector in API types

vectorized Signal and Process type custom LLVM vectorization pass

storable-vector with typed chunk size signal with sample rate as type dimensional discrete time test mode for LLVM monad for virtual downgrade of the machine better integration with a reactive Haskell programming framework

slide-41
SLIDE 41

Efficient signal processingusing Haskell and LLVM Discussion

Remaining technical difficulties

Optimizations interfere badly with call-backs Call-backs are needed for

allocation and deallocation, reading from lazy data structures.

Crashes are hard to debug