Paralel FFT hesaplamak için algoritmalar


12

Terabayt büyüklüğündeki sinyal dosyaları üzerinde bir FFT hesaplamasını paralelleştirmeye çalışıyorum. Şu anda açık kaynak kodlu bir kitaplık kullanan böyle bir FFT, CUDA üzerinden bile sahip olduğum en hızlı GPU'da bile saatler sürüyor. Bu sürece uyum sağlamaya çalıştığım çerçeve Hadoop. Çok temel bir ifadeyle, Hadoop bir sorunu herhangi bir sayıdaki sunucu düğümü üzerinde aşağıdaki şekilde dağıtır:

• Giriş dosyanızı (anahtar, değer) çiftlerine böldünüz.
• Bu çiftler, (anahtar, değer) çiftlerinizi Haritanın içine koyduğunuza göre diğer (anahtar, değer) çiftlerine dönüştüren bir “Harita” algoritmasına beslenir.
• Daha sonra çerçeve, Haritalar'daki tüm (anahtar, değer) çıktılarını toplar ve bunları anahtarla sıralar ve aynı anahtarla değerleri tek bir çiftte toplar, böylece (anahtar, liste (değer1, değer2, ..)) çiftleri
• Bu çiftler daha sonra bir sonuç olarak (bir dosyaya yazılır) daha fazla (anahtar, değer) çifti çıktısı veren bir "Azalt" algoritmasına beslenir.

Sunucu günlüklerini işlemek gibi pratik şeylerde bu model için birçok uygulama var, ancak özellikle DSP'ye gerçekten aşina olmadığımdan, bir FFT'yi “harita” ve “azaltmak” için parçalamak için çerçeve uygulamakta zorlanıyorum.

Programlama mumbo jumbo ile sizi rahatsız etmeyeceğim, çünkü bu bir DSP Q&A. Bununla birlikte, FFT'leri paralel olarak hesaplamak için hangi algoritmaların mevcut olduğu konusunda kafam karıştı; Harita ve Küçült görevleri birbiriyle (teknik olarak) konuşamaz, bu nedenle FFT sonuçların bir şekilde yeniden birleştirilebileceği bağımsız sorunlara bölünmelidir.

Cooley-Tukey Radix 2 DIT'in küçük örnekler üzerinde çalışan basit bir uygulamasını programladım, ancak bir milyar bayt için tek / çift dizin DFT'lerini tekrar tekrar hesaplamak için kullanmayın. Bir MapReduce FFT algoritması (Tsz-Wo Sze tarafından SSA çarpımı hakkındaki yazısının bir parçası olarak yazılmıştır, 2'den fazla köprü bağlayamıyorum) ve “dört adımlı FFT” de dahil olmak üzere birçok makale okumak için birkaç hafta geçirdim. ( burada ve burada), birbirimize ve yapmaya çalıştığım şeye benziyor. Bununla birlikte, matematikte umutsuzca kötüyüm ve bu yöntemlerden herhangi birini elle (1,2, 3, 4, 5, 6, 7, 8} (tüm hayali bileşenler 0 olan) verir. beni çılgınca yanlış sonuçlar. Herkes bana verimli bir paralel FFT algoritması açık İngilizce (ben bağladım ya da başka bir) açıklayabilir böylece denemek ve programlamak için?

Edit: Jim Clay ve benim açıklama ile şaşkın olabilir herkes, terabayt dosya tek bir FFT yapmaya çalışıyorum. Ancak süreci hızlandırmak için aynı anda birden fazla sunucuda yapmak istiyorum.


1
Tam olarak neyi başarmak istiyorsun? Terabayt sinyal dosyasının tek bir FFT'sini veya her dosyanın birden çok daha küçük FFT'sini yapmak ister misiniz?
Jim Clay

Yanıtlar:


13

Ben senin asıl sorun algoritması (aslında yapılabilir) paralel nasıl olduğunu düşünüyorum ama bu sayısal hassasiyet. Büyük boyutlu FFT'ler sayısal olarak oldukça zordur. FFT katsayıları ve N çok büyükse katsayı hesaplaması gürültülü olur. Diyelim ki ve 64 bit çift kesinlikli aritmetik kullanıyorsunuz. İlk 1000 katsayının tam olarak birliği olan gerçek bir parçası vardır (bu şekilde olmamasına rağmen), bu yüzden kullanmak için çok verimsiz ve hantal olan daha yüksek hassasiyetli matematiğe ihtiyacınız olacaktır.ej2πkNN=240

Ayrıca, tek bir çıktı sayısına giren çok sayıda işlem de çok büyük olduğundan, çok sayıda yuvarlama ve kesme hatası toplayacaksınız. FFT'nin "her çıktı her girdiye bağlı" doğası nedeniyle, hata yayılımı yaygındır.

Bu sorunu çözmenin kolay bir yolunun farkında değilim. İsteğiniz alışılmadık bir istek. Büyük veri kümelerinin spektral analizini yapan uygulamaların çoğu, o problemin olmadığı durumlarda çalışan bir analiz yapar. Belki de uygulamanızı ve kısıtlamalarını ancak daha fazlasını açıklayabilirseniz, sizi daha uygun bir çözüme yönlendirebiliriz.


Oldukça geçerli bir nokta .. Bunun hakkında daha fazla düşünmem gerekecek. Belki de dediğin gibi, sonunda "çalışan bir analize" başvuracağım.
Philipp

Gerçekten geç kaldığımı biliyorum, ama herhangi bir şansla, nasıl yapılabileceğine dair bir kaynağınız var mı, çünkü bunun yapılabileceğini söylediniz mi?
Claudio Brasser

4

Bunun yerine çalışmakla (gibi varolan FFT uygulaması kullanarak deneyebilirsiniz FFT yeniden yazma FFTW örneğin) ve ya aracılığıyla sinyalin uzunluğuna (ne kadar büyük olursa olsun) boyunca tekrar tekrar uygulamak örtüşme-ekleme veya binen kaydetme yöntemleri. Bu, FFT'yi bir evrişim olarak ifade etmekle mümkündür .

Bu daha kısa uzunluktaki FFT'lerin birbirleriyle iletişim kurmasına gerek yoktur ve tüm şema harita azaltma adımlarıyla eşleşir.

Genel olarak, yapmayı amaçladığınız şey X sinyalinizi üst üste binebilecek daha küçük bölümlere ayırmaktır (örneğin X [0:10], X [5:15], X [10:20] ... .). Bu küçük segmentler üzerinde FFT yapın ve sonuncusu üretmek için sonunda yeniden birleştirin. Bu, harita azaltma operatörlerine çok iyi uyuyor.

"Harita" sırasında (anahtar, değer) çiftleri oluşturabilirsiniz, "anahtar" her segmentin bir sıralı kimliği (0,1,2,3,4,5, ....) ve INDEX (veya dosya konumu), sinyal dosyanızdaki bir segmentin ilk değerinin. Örneğin, dosyanız INT32'lerle doluysa, ikinci segmentin dizini (yukarıda) 5 * sizeof (INT32) değerindedir. (Ya da başka bir formatta ise bunun için bir kütüphaneniz olabilir)

Şimdi, her çalışan bir (anahtar, değer) alır, bir dosyayı açar, doğru noktayı arar, M örneklerini okur (burada M 10 yukarıdadır), FFT'yi gerçekleştirir ve dosyayı bir adla bir dosyaya kaydeder, örneğin " RES_ [INKEY] .dat "ile bir (anahtar, değer) çifti döndürür. Bu durumda, "anahtar" INDEX (gelen (anahtar, değer) demetinin "değer") ve "değer", FFT sonuçlarını içeren dosyanın adı olacaktır. (buna geri döneceğiz)

"Azalt" içinde artık "harita" adımından bir (anahtar, değer) kabul ederek, bu dosyayı açarak, FFT sonuçlarını yükleyerek, oa veya os yaparak ve daha sonra kaydederek örtüşme-ekleme veya örtüşme-kaydetme uygulayabilirsiniz. çıktı dosyanızda doğru INDEX. (Bkz pseudocode bunda (veya bu ), "map" adım kolları paralel olarak "yt = ..." ve "azaltmak" adım kolları "y (i, k) = ..." kısmı.)

Burada, ağdaki trafiği veya gerçek veri dosyanızı içerebilecek bir sunucunun yükünü azaltmak için bazı dosya dönüşümü gerekebilir.


1
Daha büyük boyutlu FFT'yi almak için daha küçük parçaları birleştirmek için örtüşme ve ekleme işleminin geçerliliğinden emin değilim - bildiğim kadarıyla bunu yapmak için ikinci bir FFT geçişi var (N boyutunda bir DFT = AB, B boyutu A DFT'lere, twiddle faktörü uygulamasına, sonra A boyutu B DFT'lerine ayrılabilir. Yine de daha düşük bir çözünürlük çıkışı istersek işe yarayabilir ...
pichenettes

Merhaba picenettes, bunun için teşekkürler, aklımda olan şey ( cevabına dahil edeceğim bu ( engineeringproductivitytools.com/stuff/T0001/PT11.HTM ) idi.
A_A

2

Veri boyutunuzun olduğunu varsayalım . Aksi takdirde sıfırlarla doldurun. Sizin durumunuzda, "Terabayt ölçeği" boyutlarından bahsettiğiniz için N = 40 alacağız.2N

Yana tek makine için ama kesinlikle makul - - Bir büyük FFT boyutu, ben sadece yapmaya önermek radix biri tek Cooley-Tukey yinelemeyi , ve sonra düzgün FFT kitaplığı izin (FFTW gibi) her makinede boyutu için işi yapın .2N/2N/22N/2

Daha açık olmak gerekirse, MR'ı tüm özyineleme boyunca kullanmaya gerek yoktur, bu gerçekten oldukça verimsiz olacaktır. Sorununuz bir milyon megabayt boyutunda iç ve dış FFT'lere bölünebilir ve bu megabayt FFT'ler FFTW veya benzeri kullanılarak mükemmel bir şekilde hesaplanabilir. MR, gerçek FFT hesaplamasını değil, veri karıştırma ve rekombinasyonu denetlemekten sorumlu olacak ...

İlk fikrim şu olurdu, ancak bunun daha akıllı veri gösterimi ile tek bir MR'da yapılabileceğinden şüpheleniyorum.

Let olması bunu giriş sinyali,sR=2N/2

İlk MR: iç FFT

Harita: zamanında decimation gerçekleştirin, iç FFT için bloklar halinde örnekleri gruplandırın

girdi: burada , örnek indekstir ; tarafından alınan değer(k,v)k0..2N1vs[k]

emit: - burada% modulo ve / tamsayı bölümünü temsil eder.(k%R,(k/R,v))

Azalt: iç FFT'yi hesapla

girdi: burada blok dizindir; ve çiftlerinin bir listesidir(k,vs)kvs(i,v)

bir vektör doldurmak boyutu öyle ki listedeki tüm değerleri için.inRin[i]=v

bir boyut yerine ilgili FFT bir vektör elde etmek için büyüklüğüRinoutR

için içinde , yayarlari0..R1(k,(i,out[i]))

İkinci MR: dış FFT

Harita: dış fft için grup örnekleri ve twiddle faktörlerini uygulama

girdi: burada bir blok endeksidir, bu blok için iç FFT'nin bir örneği.(k,(i,v))k(i,v)

emit(i,(k,v×exp2πjik2N))

Azalt: dış FFT gerçekleştir

girdi: burada blok dizindir; ve çiftlerinin bir listesidir(k,vs)kvs(i,v)

bir vektör doldurmak boyutu öyle ki listedeki tüm değerleri için.inRin[i]=v

bir boyut yerine ilgili FFT bir vektör elde etmek için büyüklüğüRinoutR

için içinde , yayarlar0 . . R - 1 ( i × R + k , o u t [ i ] ) )i0..R1(i×R+k,out[i]))

Burada kavram python kodu kanıtı.

Gördüğünüz gibi, Haritacılar yalnızca veri sırasını karıştırıyor, bu nedenle aşağıdaki varsayımlar altında:

  • zamanla decimation (Mapper 1) önceki bir adımda yapılabilir (örneğin, verileri doğru giriş formatına dönüştüren program tarafından).
  • MR çerçeveniz, redüktörleri giriş anahtarlarından farklı bir anahtara yazmayı destekler (Google'ın uygulama redüktörlerinde yalnızca aldıkları ile aynı anahtara veri gönderebilir, bunun SSTable'ın bir çıkış biçimi olarak kullanılmasından kaynaklandığını düşünüyorum).

Bütün bunlar tek bir MR, eşleştiricideki iç FFT, redüktördeki dış FFT'de yapılabilir. Burada kavram kanıtı .


Uygulamanız ümit verici görünüyor ve şu anda bunun içinden geçiyorum, ancak iç FFT redüktöründe, "2 ^ R boyutundan bir vektör almak için 2 ^ R FFT boyutunda bir performans gerçekleştirin" yazıyorsunuz. R 2 ^ (N / 2) ise, bu FFT boyutu 2 ^ (2 ^ N / 2) ve dolayısıyla yanlış olmaz mı? Şunu mu demek istedin R size FFT boyutunda?
Philipp

R2Rexp2πjik2N

0

Sinyaliniz çok boyutlu ise, FFT'yi paralel hale getirmek oldukça kolay bir şekilde gerçekleştirilebilir; MPI işleminde bir boyutu bitişik tutun, FFT'yi gerçekleştirin ve bir sonraki boyut üzerinde çalışmak için (hepsi de) aktarın. FFTW bunu yapıyor.

Veriler 1D ise, sorun çok daha zordur. Örneğin FFTW, MPI kullanarak 1D FFT yazmadı. Eğer bir kişi bir yarıçap-frekans frekansı belirleme algoritması kullanıyorsa, ilk birkaç aşama saf bir DFT olarak gerçekleştirilebilir, böylece herhangi bir hassasiyet kaybı olmadan 2 veya 4 düğüm kullanılmasına izin verilir (bunun nedeni, İlk aşamalar -1 veya i'dir, bu da çalışmak için güzeldir).

Bu arada, verileri dönüştürdükten sonra verilerle ne yapmayı planlıyorsunuz? Çıktının başına ne geldiğini biliyorsanız (örn. Evrişim, alçak geçiren filtre, vb.) Bir şey yapılabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.