Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Ruby

on: [push, pull_request]

jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
ruby: [2.3, 2.4, 2.6, 2.7, '3.0', 3.1, 3.2, 3.3, 3.4, '4.0']
exclude:
- os: windows-latest
ruby: 2.3
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v6
- name: before_setup
shell: bash
run: |
case ${{ matrix.os }} in
ubuntu-latest)
sudo apt-get update && sudo apt-get install -yq libfftw3-dev
;;
windows-latest)
vcpkg install fftw3 --triplet=x64-mingw-static
# find $(cygpath -u "$VCPKG_INSTALLATION_ROOT")/packages -name "*fftw3*"
echo "BUNDLE_BUILD__NUMO___FFTW=\"--with-fftw-dir=$(cygpath -m ${VCPKG_INSTALLATION_ROOT})/packages/fftw3_x64-mingw-static\"" >> $GITHUB_ENV
;;
esac
- name: Set up Ruby
uses: ruby/setup-ruby@v1
id: ruby-inst
env:
BUNDLE_BUILD__NUMO___NARRAY: --with-cflags=-std=c17
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Run the default task
run: |
bundle exec rake compile -- ${{ env.BUNDLE_BUILD__NUMO___FFTW }}
bundle exec rake spec
- name: Upload artifact for error reproduction when failure
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: gem-build-logs.${{ matrix.os }}_${{ matrix.ruby }}
path: |
${{ github.workspace }}/vendor/bundle/ruby/**/gems/
${{ github.workspace }}/vendor/bundle/ruby/**/mkmf.log
3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--format documentation
--color
--require spec_helper
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

source "https://rubygems.org"

# Specify your gem's dependencies in gps_pvt.gemspec
gemspec
24 changes: 16 additions & 8 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
require "bundler/gem_tasks"

task :doc do
dir = "ext/numo/fftw"
src = %w[fftw.c]
path = src.map{|s| File.join(dir,s)}
sh "cd #{dir}; ruby extconf.rb; make #{src.join(' ')}"
sh "rm -rf yard .yardoc; yard doc -o yard -m markdown -r README.md #{path.join(' ')}"
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec)

require "rake/extensiontask"
Rake::ExtensionTask.new("numo/fftw") do |ext|
ext.lib_dir = "lib/numo"
end

task :cleandoc do
rm_rf %w[yard .yardoc]
require "yard"
YARD::Rake::YardocTask.new do |t|
t.before = proc{
Rake::Task["compile:numo/fftw"].invoke
}
t.files = Dir['**/numo/fftw/**/fftw.c', __dir__]
t.options = ['--embed-mixins']
#t.stats_options = ['--list-undoc']
end

task :default => [:compile, :spec]
11 changes: 1 addition & 10 deletions ext/numo/fftw/depend
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,4 @@ CLEANOBJS = *.o */*.o *.bak *~
ERB = erb -T-

fftw.c: fftw.erb.c
$(ERB) fftw.erb.c > fftw.c

doc : fftw.c
yard doc -o yard -m markdown $<

clean: cleansrc cleandoc
cleansrc:
-$(Q)$(RM) fftw.c
cleandoc:
-$(Q)$(RM_RF) yard .yardoc
$(ERB) $^ > $@
6 changes: 3 additions & 3 deletions ext/numo/fftw/fftw.erb.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ numo_fftw_<%=func%>(VALUE mod, VALUE vna, VALUE vsign)
void
Init_fftw()
{
VALUE mNumo,mFFTW;
VALUE /*mNumo,*/ mFFTW; // CAUTION: mNumo is already defined in narray.h

rb_require("numo/narray");
mNumo = rb_define_module("Numo");
//rb_require("numo/narray"); // move to fftw.rb because numo/narray.so should be loaded before Init_fftw()
//mNumo = rb_define_module("Numo");
mFFTW = rb_define_module_under(mNumo,"FFTW");

<% $funcs.each do |f| %>
Expand Down
2 changes: 2 additions & 0 deletions lib/numo/fftw.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "numo/narray"
require "numo/fftw.#{RbConfig::CONFIG['DLEXT']}"
7 changes: 5 additions & 2 deletions numo-fftw.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ Gem::Specification.new do |spec|
spec.require_paths = ["lib"]
spec.extensions = ["ext/numo/fftw/extconf.rb"]

spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake", "~> 0"
spec.add_development_dependency "bundler", ">= 1.3"
spec.add_development_dependency "rake"
spec.add_development_dependency "rake-compiler"
spec.add_development_dependency "rspec"
spec.add_development_dependency "yard"
spec.add_runtime_dependency "numo-narray", ">= 0.9.0.8"
end
76 changes: 76 additions & 0 deletions spec/complexFFT_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# frozen_string_literal: true
# port from numru-fftw3/test/complexFFT.rb

require 'rspec'

require "numo/fftw"

module Numo::FFTW
FORWARD = -1
BACKWARD = 1
singleton_methods.each{|func|
slice = (/(\d)d/ =~ func.to_s) ? $1.to_i : 0
{:fw => FORWARD, :bk => BACKWARD}.each{|dir, sign|
define_singleton_method("#{func}_#{dir}".to_sym){|na|
res = send(func, na, sign)
(dir == :bk) ? (res / res.shape[-slice..-1].inject(:*)) : res
}
}
}
end

RSpec::describe Numo::FFTW do
let(:fftw){described_class}
let(:eps){1e-10}
let(:seps){1e-6}

it 'can perform forward and backward FFT' do # test_fft_fw_bk
na = Numo::DFloat::new(8,4).fill(1) # will be corced to complex
na[1,1]=5
fc = fftw.dft_fw(na)
nb = fftw.dft_bk(fc).real
expect((na-nb).abs.max).to be < eps

fc = fftw.dft_1d_fw(na)
nb = fftw.dft_1d_bk(fc).real
expect((na-nb).abs.max).to be < eps
end

it 'can perform real forward FFT' do # test_real_all_dims
na = Numo::DFloat::new(8,4).fill(1) # will be corced to complex
na[1,1]=5
fc = fftw.dft(na, fftw::FORWARD)/na.length
nb = fftw.dft(fc, fftw::BACKWARD).real
expect((na-nb).abs.max).to be < eps
end

it 'can perform complex forward FFT' do # test_complex_all_dims
na = Numo::DComplex::new(8,4).fill(1) * Complex::I
na[1,1]=5
fc = fftw.dft(na, fftw::FORWARD)/na.length
nb = fftw.dft(fc, fftw::BACKWARD)
expect((na-nb).abs.max).to be < eps
end

it 'can perform single precision forward FFT' do # test_single_float
# single float (treated as single if lib fftw3f exits).
# see http://www.fftw.org/fftw3_doc/Precision.html for more info
na = Numo::SFloat::new(8,4).indgen
fc = fftw.dft(na, fftw::FORWARD)/na.length
nb = fftw.dft(fc, fftw::BACKWARD).real
expect((na-nb).abs.max).to be < eps
end
end

__END__
# TODO:
class FFTW3Test < Test::Unit::TestCase
def test_dim_selection
na = NArray.float(8,4).indgen!
fc = FFTW3.fft(na, FFTW3::FORWARD, 0)
fc = FFTW3.fft(fc, FFTW3::FORWARD, 1)
fc2 = FFTW3.fft(na, FFTW3::FORWARD)
assert( (fc-fc2).abs.max < @eps )
end
end

13 changes: 13 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = ".rspec_status"

# Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching!

config.expect_with :rspec do |c|
c.syntax = :expect
end
end