Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

ydah/fftw3-ruby

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FFTW3-Ruby

Ruby FFI bindings for FFTW3 (Fastest Fourier Transform in the West).

The gem exposes the FFTW planning and execution APIs for complex DFT, real-to-complex and complex-to-real transforms, real-to-real transforms, the advanced "many" interface, guru and guru64 planners, wisdom import/export, thread control, and runtime metadata.

Requirements

  • Ruby 3.1+
  • FFTW 3.3.x shared libraries installed on the system

Installing FFTW3

Ubuntu / Debian:

sudo apt-get install libfftw3-dev

macOS (Homebrew):

brew install fftw

Installation

Add the gem to your Gemfile:

gem "fftw3-ruby"

Then install dependencies:

bundle install

Precision Support

Runtime precision support depends on which FFTW libraries are installed.

require "fftw3"

FFTW3.available_precisions
FFTW3.double_available?
FFTW3.float_available?
FFTW3.long_double_available?
FFTW3.quad_available?

Notes:

  • Plan creation is available for any precision whose FFTW library can be loaded.
  • FFTW3::AlignedMemory#read and #write currently support :double, :float, and :long_double.
  • :quad library availability can be detected with FFTW3.quad_available?, but high-level buffer read/write helpers are not currently provided for quad buffers.

Core Types

FFTW3::AlignedMemory

Aligned buffers allocated with FFTW's allocator.

require "fftw3"

input = FFTW3::AlignedMemory.new(8, type: :complex, precision: :double)
input.write(Array.new(8) { |i| Complex(i, -i) })

input.pointer
input.read
input.free!

Options:

  • type: accepts :complex or :real
  • precision: accepts :double, :float, :long_double, or :quad

FFTW3::Plan

Factory methods return FFTW3::Plan instances. A plan can be executed in-place with the buffers it was created with, or with compatible alternate buffers via the new-array execute helpers.

FFTW3::Threads

Wrapper around FFTW thread initialization, planner thread count, optional planner locking, and the runtime thread callback hook.

FFTW3::Wisdom

Import and export FFTW wisdom through strings, files, and IO callbacks.

FFTW3::Utils

Small wrappers for FFTW global utility functions such as cleanup, set_timelimit, and alignment_of.

Quick Start

Basic 1D Complex DFT

require "fftw3"

n = 8
input = FFTW3::AlignedMemory.new(n, type: :complex, precision: :double)
output = FFTW3::AlignedMemory.new(n, type: :complex, precision: :double)

data = (0...n).map { |i| Complex(Math.sin(2 * Math::PI * i / n), 0.0) }
input.write(data)

plan = FFTW3::Plan.dft_1d(
  n,
  input,
  output,
  direction: :forward,
  flags: [:estimate]
)

plan.execute
result = output.read

puts result.map { |c| "(%.4f, %.4f)" % [c.real, c.imaginary] }

plan.destroy!
input.free!
output.free!

Real-to-Complex

require "fftw3"

n = 16
input = FFTW3::AlignedMemory.new(n, type: :real)
output = FFTW3::AlignedMemory.new((n / 2) + 1, type: :complex)

input.write(n.times.map { |i| Math.sin(2 * Math::PI * i / n) })

plan = FFTW3::Plan.dft_r2c_1d(n, input, output)
plan.execute

result = output.read

New-array Execute

require "fftw3"

n = 8
input_a = FFTW3::AlignedMemory.new(n, type: :complex)
output_a = FFTW3::AlignedMemory.new(n, type: :complex)
input_b = FFTW3::AlignedMemory.new(n, type: :complex)
output_b = FFTW3::AlignedMemory.new(n, type: :complex)

input_a.write(Array.new(n) { |i| Complex(i, 0.0) })
input_b.write(Array.new(n) { |i| Complex(0.0, i) })

plan = FFTW3::Plan.dft_1d(n, input_a, output_a, direction: :forward)

# Reuse the same plan with different buffers of the same shape.
plan.execute_dft(input_b, output_b)

plan.destroy!
input_a.free!
output_a.free!
input_b.free!
output_b.free!

Threading

Planner Thread Count

require "fftw3"

n = 1024
input = FFTW3::AlignedMemory.new(n, type: :complex)
output = FFTW3::AlignedMemory.new(n, type: :complex)

FFTW3::Threads.init
FFTW3::Threads.plan_with_nthreads(4)

plan = FFTW3::Plan.dft_1d(n, input, output, direction: :forward, flags: [:measure])
plan.execute

FFTW3::Threads.planner_nthreads
plan.destroy!
input.free!
output.free!
FFTW3::Threads.cleanup

Planner Locking

require "fftw3"

FFTW3::Threads.init
FFTW3::Threads.make_planner_thread_safe
FFTW3::Threads.cleanup

make_planner_thread_safe returns nil when the linked FFTW build does not expose that function.

Custom Thread Backend Callback

threads_set_callback is optional in FFTW. Check support before using it, and set it before creating plans.

require "fftw3"

if FFTW3::Threads.set_callback_supported?
  marker = FFI::MemoryPointer.new(:int)
  marker.write_int(7)

  FFTW3::Threads.set_callback(data: marker) do |work, jobdata, elsize, njobs, data_ptr|
    njobs.times do |index|
      work.call(jobdata + (elsize * index))
    end
  end

  # Reset to the default FFTW backend.
  FFTW3::Threads.set_callback(nil)
end

Wisdom

String and File APIs

require "fftw3"

wisdom = FFTW3::Wisdom.export_to_string
FFTW3::Wisdom.import_from_string(wisdom)

FFTW3::Wisdom.export_to_file("wisdom.fftw")
FFTW3::Wisdom.import_from_file("wisdom.fftw")

IO Callback APIs

require "fftw3"
require "stringio"

io = StringIO.new
FFTW3::Wisdom.export_to_io(io)
FFTW3::Wisdom.import_from_io(StringIO.new(io.string))

System Wisdom

require "fftw3"

FFTW3::Wisdom.import_system
FFTW3::Wisdom.forget!

Runtime Metadata and Utilities

require "fftw3"

input = FFTW3::AlignedMemory.new(8, type: :complex)

FFTW3.version
FFTW3.compiler
FFTW3.codelet_optimizations

FFTW3::Utils.set_timelimit(0.25)
FFTW3::Utils.alignment_of(input.pointer)
FFTW3::Utils.cleanup
input.free!

API Reference

Top-level FFTW3

Method Description
available_precisions Returns the precisions whose FFTW libraries can be loaded
double_available? / float_available? / long_double_available? / quad_available? Per-precision availability checks
version Linked FFTW version string
compiler Linked FFTW compiler string
codelet_optimizations Linked FFTW codelet optimization string

FFTW3::Plan Factory Methods

Method group Methods
Complex DFT dft_1d, dft_2d, dft_3d, dft
Real-to-complex dft_r2c_1d, dft_r2c_2d, dft_r2c_3d, dft_r2c
Complex-to-real dft_c2r_1d, dft_c2r_2d, dft_c2r_3d, dft_c2r
Real-to-real r2r_1d, r2r_2d, r2r_3d, r2r
Advanced / batched many_dft, many_dft_r2c, many_dft_c2r, many_r2r
Guru guru_dft, guru_split_dft, guru_dft_r2c, guru_split_dft_r2c, guru_dft_c2r, guru_split_dft_c2r, guru_r2r
Guru64 guru64_dft, guru64_split_dft, guru64_dft_r2c, guru64_split_dft_r2c, guru64_dft_c2r, guru64_split_dft_c2r, guru64_r2r

Notes:

  • dft_* and many_dft use direction:.
  • guru_dft and guru64_dft use sign:.
  • Guru and guru64 dimension arrays use hashes shaped like { n:, is:, os: }.

FFTW3::Plan Instance Methods

Method Description
execute Execute with the buffers used to create the plan
execute_dft New-array execute for complex DFT
execute_dft_r2c New-array execute for real-to-complex DFT
execute_dft_c2r New-array execute for complex-to-real DFT
execute_r2r New-array execute for real-to-real transforms
execute_split_dft New-array execute for split-complex guru DFT
execute_split_dft_r2c New-array execute for split real-to-complex guru DFT
execute_split_dft_c2r New-array execute for split complex-to-real guru DFT
flops Returns { add:, mul:, fma: }
cost FFTW plan cost
estimate_cost FFTW estimated plan cost
to_s / description String representation of the plan
print(io = $stdout) Write the plan description to an IO object
destroy! Destroy the underlying FFTW plan

FFTW3::Threads

Method Description
init Initialize FFTW thread support
plan_with_nthreads(n) Set planner and execution thread count
cleanup Release FFTW thread state
planner_nthreads Read configured thread count when supported
make_planner_thread_safe Enable FFTW's optional planner lock when supported
set_callback_supported? Check whether threads_set_callback is available
set_callback(callback = nil, data: nil, &block) Install or clear FFTW's runtime threading callback

FFTW3::Wisdom

Method Description
export_to_string / import_from_string Wisdom through Ruby strings
export_to_file / import_from_file Wisdom through filesystem paths
export_to_io / import_from_io Wisdom through Ruby IO callbacks
import_system Best-effort import from the system wisdom store
forget! Clear loaded wisdom

FFTW3::Utils

Method Description
cleanup Call FFTW global cleanup
set_timelimit(seconds) Set the FFTW planner time limit
alignment_of(pointer) Query FFTW's alignment classification for a pointer

Constants

Planner flags:

  • FFTW3::ESTIMATE
  • FFTW3::MEASURE
  • FFTW3::PATIENT
  • FFTW3::EXHAUSTIVE
  • FFTW3::PRESERVE_INPUT
  • FFTW3::DESTROY_INPUT
  • FFTW3::WISDOM_ONLY
  • Additional exported flags such as FFTW3::ESTIMATE_PATIENT, FFTW3::ALLOW_PRUNING, and FFTW3::NO_SIMD

Direction constants:

  • FFTW3::FORWARD
  • FFTW3::BACKWARD
  • :forward and :backward are also accepted where direction symbols are supported

R2R kinds:

  • FFTW3::R2HC
  • FFTW3::HC2R
  • FFTW3::DHT
  • FFTW3::REDFT00, REDFT01, REDFT10, REDFT11
  • FFTW3::RODFT00, RODFT01, RODFT10, RODFT11

Development

bundle install
bundle exec rake spec

License

The gem is available as open source under the terms of the MIT License.

FFTW3 itself is licensed under GPLv2+. Using this gem requires an installed FFTW3 library.

About

Ruby FFI bindings for FFTW3 (Fastest Fourier Transform in the West).

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.