Các thuật toán để tính toán FFT song song


12

Tôi đang cố gắng song song hóa tính toán của một FFT trên các tệp tín hiệu có kích thước terabyte. Ngay bây giờ một FFT như vậy sử dụng thư viện nguồn mở mất nhiều giờ, thậm chí chạy qua CUDA trên GPU nhanh nhất tôi có. Khuôn khổ mà tôi đang cố gắng thích nghi với quy trình này là Hadoop. Theo các thuật ngữ rất cơ bản, Hadoop phân phối một vấn đề đối với bất kỳ số lượng nút máy chủ nào theo cách sau:

• Bạn chia tệp đầu vào thành các cặp (khóa, giá trị).
• Các cặp này được đưa vào thuật toán Bản đồ của Nhật Bản, biến đổi các cặp (khóa, giá trị) của bạn thành một số cặp (khóa, giá trị) khác dựa trên những gì bạn đặt trong Bản đồ.
• Khung sau đó thu thập tất cả các đầu ra (khóa, giá trị) từ Bản đồ và sắp xếp chúng theo khóa, cũng như tổng hợp các giá trị với cùng một khóa cho một cặp, do đó, bạn kết thúc bằng (khóa, danh sách (value1, value2, ..)) các cặp
• Các cặp này sau đó được đưa vào thuật toán Giảm Giảm, lần lượt đưa ra nhiều cặp (khóa, giá trị) như kết quả cuối cùng của bạn (được ghi vào một tệp).

Có nhiều ứng dụng cho mô hình này trong các công cụ thực tế như xử lý nhật ký máy chủ, nhưng tôi gặp khó khăn khi áp dụng khung để cắt một FFT vào các bản đồ và các nhiệm vụ giảm bớt, đặc biệt là vì tôi không thực sự quen thuộc với DSP.

Tôi sẽ không làm phiền bạn với mumbo jumbo lập trình, vì đây là Q & A DSP. Tuy nhiên, tôi bối rối về những thuật toán tồn tại để tính toán các FFT song song; Ánh xạ và Giảm các nhiệm vụ không thể (về mặt kỹ thuật) nói chuyện với nhau, do đó FFT phải được chia thành các vấn đề độc lập mà từ đó kết quả có thể được kết hợp lại bằng cách nào đó vào cuối.

Tôi đã lập trình một triển khai đơn giản cho Cooley-Tukey Radix 2 DIT hoạt động trên các ví dụ nhỏ, nhưng sử dụng nó để tính toán đệ quy các DFT lẻ / chẵn cho một tỷ byte sẽ không hoạt động. Tôi đã dành vài tuần để đọc nhiều bài báo, bao gồm một bài viết về thuật toán FFT MapReduce (được viết bởi Tsz-Wo Sze như một phần của bài viết về phép nhân SSA, tôi không thể liên kết nhiều hơn 2 siêu liên kết) và FFT bốn bước ( ở đâyở đây), có vẻ giống nhau và với những gì tôi đang cố gắng thực hiện. Tuy nhiên, tôi vô cùng kém về toán học và áp dụng bất kỳ phương pháp nào trong số đó cho một tập hợp đơn giản như {1,2, 3, 4, 5, 6, 7, 8} (với tất cả các thành phần tưởng tượng là 0) mang lại Tôi cực kỳ không chính xác kết quả. Bất cứ ai cũng có thể giải thích một thuật toán FFT song song hiệu quả cho tôi bằng tiếng Anh đơn giản (một thuật toán mà tôi đã liên kết hoặc bất kỳ thuật toán nào khác) để tôi có thể thử và lập trình nó?

Chỉnh sửa: Jim Clay và bất kỳ ai khác có thể bị nhầm lẫn bởi lời giải thích của tôi, tôi đang cố gắng thực hiện một FFT duy nhất của tệp terabyte. Nhưng tôi muốn có thể làm điều đó đồng thời trên nhiều máy chủ để tăng tốc quá trình.


1
Chính xác thì bạn đang cố đạt được điều gì? Bạn có muốn thực hiện một FFT duy nhất của tệp tín hiệu terabyte hoặc nhiều FFT nhỏ hơn của mỗi tệp không?
Jim Clay

Câu trả lời:


13

Tôi nghĩ vấn đề chính của bạn không phải là làm thế nào để song song thuật toán (mà thực sự có thể thực hiện được) mà là độ chính xác về số. Các FFT có kích thước lớn khá khó khăn. Các hệ số FFT có dạng và nếu N rất lớn thì việc tính toán hệ số sẽ bị nhiễu. Hãy nói rằng bạn cóN=240và bạn sử dụng số học chính xác gấp đôi 64 bit. 1000 hệ số đầu tiên có một phần thực sự chính xác (mặc dù không phải như vậy), do đó bạn sẽ cần toán học có độ chính xác cao hơn, rất không hiệu quả và cồng kềnh khi sử dụng.ej2πkNN=240

Bạn cũng sẽ có rất nhiều lỗi làm tròn và cắt ngắn vì số lượng thao tác tuyệt đối đi vào một số đầu ra duy nhất cũng rất lớn. Do tính chất "mọi đầu ra phụ thuộc vào mọi đầu vào" của FFT, việc truyền lỗi xảy ra tràn lan.

Tôi không biết một cách dễ dàng để làm việc xung quanh đó. Yêu cầu của bạn là một bất thường. Hầu hết các ứng dụng phân tích quang phổ của các tập dữ liệu lớn thực hiện phân tích đang chạy mà bạn không gặp phải vấn đề đó. Có lẽ nếu bạn có thể mô tả ứng dụng của mình và nó hạn chế hơn, chúng tôi có thể chỉ cho bạn một giải pháp phù hợp hơn.


Khá là một điểm hợp lệ .. Tôi sẽ phải suy nghĩ thêm về điều này. Có lẽ tôi sẽ dùng đến một "phân tích chạy" cuối cùng, như bạn nói.
Phi

Tôi biết tôi thực sự đến muộn, nhưng trong bất kỳ trường hợp nào, bạn có một nguồn về cách nó có thể được thực hiện, vì bạn đã đề cập rằng nó có thể được thực hiện?
Claudio Brasser

4

Thay vì cố gắng viết lại FFT, bạn có thể thử sử dụng triển khai FFT hiện có (ví dụ như FFTW ) và áp dụng nó lặp đi lặp lại dọc theo chiều dài tín hiệu của bạn (cho dù nó lớn đến đâu) thông qua việc thêm chồng chéo hoặc chồng chéo- lưu phương pháp. Điều này có thể bằng cách biểu thị FFT như một tổ hợp .

Các FFT có độ dài ngắn hơn này không cần phải giao tiếp với nhau và toàn bộ sơ đồ khớp với các bước thu nhỏ bản đồ.

Nói chung, những gì bạn sẽ làm là để tín hiệu X của bạn được chia thành các phân đoạn nhỏ hơn cũng có thể bị chồng chéo (ví dụ X [0:10], X [5:15], X [10:20] ... .). Thực hiện FFT trên các phân đoạn nhỏ này và kết hợp lại chúng vào cuối để tạo ra phân đoạn cuối cùng. Điều này rất phù hợp với các toán tử giảm bản đồ.

Trong khi "ánh xạ", bạn có thể tạo các cặp (khóa, giá trị) với "khóa" là một số ID tuần tự của từng phân đoạn (0,1,2,3,4,5, ....) và "giá trị" là INDEX (hoặc vị trí tệp) của giá trị đầu tiên của một phân đoạn trong tệp tín hiệu của bạn. Vì vậy, ví dụ, nếu tệp của bạn chứa đầy INT32 thì chỉ mục của phân đoạn thứ hai (ở trên) ở mức 5 * sizeof (INT32). (Hoặc nếu nó ở bất kỳ định dạng nào khác, bạn có thể có một lib cho nó)

Bây giờ, mỗi công nhân nhận được một (khóa, giá trị) mở một tệp, tìm đúng điểm, đọc các mẫu M từ nó (trong đó M là 10 ở trên), thực hiện FFT và lưu nó vào một tệp có tên, ví dụ " RES_ [INKEY] .dat "và trả về một cặp (khóa, giá trị). Trong trường hợp này, "khóa" sẽ là INDEX ("giá trị" của bộ dữ liệu đến (khóa, giá trị)) và "giá trị" sẽ là tên của tệp chứa kết quả FFT. (chúng tôi sẽ quay lại vấn đề này)

Trong "giảm", giờ đây bạn có thể triển khai thêm chồng chéo hoặc lưu chồng lấp bằng cách chấp nhận (khóa, giá trị) từ bước "bản đồ", mở tệp đó, tải kết quả FFT, thực hiện oa hoặc os và sau đó lưu chúng vào INDEX đúng trong tệp đầu ra của bạn. (Xem mã giả trong phần này (hoặc cái này ), bước "bản đồ" xử lý song song "yt = ..." và bước "giảm" xử lý phần "y (i, k) = ...".)

Một số trò tung hứng tập tin có thể cần thiết ở đây để giảm lưu lượng trên mạng hoặc tải của máy chủ có thể chứa tệp dữ liệu thực tế của bạn.


1
Tôi không chắc về tính hợp lệ của việc thêm chồng chéo và lưu chồng lấp để kết hợp các khối nhỏ hơn để lấy FFT kích thước lớn hơn - theo như tôi biết có một FFT thứ hai cần thiết để làm điều đó (một DFT có kích thước N = AB có thể được chia thành A DFT có kích thước B, ứng dụng hệ số twiddle, sau đó B DFT có kích thước A). Nó có thể hoạt động nếu chúng ta muốn có đầu ra độ phân giải thấp hơn ...
pichenettes

Xin chào picenettes, nhờ việc này, những gì tôi đã có trong tâm trí của tôi là này ( engineeringproductivitytools.com/stuff/T0001/PT11.HTM ) mà tôi sẽ bao gồm trong câu trả lời.
A_A

2

2N

2N/2N/22N/2

Nói rõ hơn, không cần sử dụng MR dọc theo toàn bộ đệ quy, điều này thực sự sẽ không hiệu quả. Vấn đề của bạn có thể được chia thành một triệu FFT bên trong và bên ngoài, và các FFT megabyte đó hoàn toàn có thể được tính bằng cách sử dụng FFTW hoặc tương tự. MR sẽ chịu trách nhiệm giám sát việc xáo trộn dữ liệu và kết hợp lại, chứ không phải tính toán FFT thực tế ...

Ý tưởng đầu tiên của tôi sẽ là như sau, nhưng tôi nghi ngờ điều này có thể được thực hiện trong một MR với biểu diễn dữ liệu thông minh hơn.

sR=2N/2

MR đầu tiên: FFT bên trong

Bản đồ: thực hiện việc xác định thời gian, nhóm các mẫu trong các khối cho FFT bên trong

(k,v)k0..2N1vs[k]

(k%R,(k/R,v))

Giảm: tính FFT bên trong

(k,vs)kvs(i,v)

inRin[i]=v

RinoutR

i0..R1(k,(i,out[i]))

MR thứ hai: FFT bên ngoài

Bản đồ: mẫu nhóm cho fft bên ngoài và áp dụng các yếu tố twiddle

(k,(i,v))k(i,v)

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

Giảm: thực hiện FFT bên ngoài

(k,vs)kvs(i,v)

inRin[i]=v

RinoutR

i0..R1(i×R+k,out[i]))

Bằng chứng về mã python ở đây.

Như bạn có thể thấy, các Mappers chỉ xáo trộn thứ tự dữ liệu, do đó, theo các giả định sau:

  • decimation in time (Mapper 1) có thể được thực hiện ở bước trước (ví dụ: bằng chương trình chuyển đổi dữ liệu sang định dạng đầu vào bên phải).
  • Khung MR của bạn hỗ trợ Bộ giảm tốc ghi vào khóa khác với khóa đầu vào của chúng (Trong bộ giảm tốc triển khai của Google chỉ có thể xuất dữ liệu sang cùng khóa khi họ nhận được, tôi nghĩ rằng do SSTable được sử dụng làm định dạng đầu ra).

Tất cả điều này có thể được thực hiện trong một MR duy nhất, FFT bên trong trong trình ánh xạ, FFT bên ngoài trong bộ giảm tốc. Bằng chứng về khái niệm ở đây .


Việc triển khai của bạn có vẻ đầy hứa hẹn và tôi đang thực hiện ngay bây giờ, nhưng trong trình giảm FFT bên trong, bạn viết "thực hiện kích thước 2 ^ R FFT vào để có được một vectơ có kích thước 2 ^ R". Nếu R là 2 ^ (N / 2), thì FFT này sẽ có kích thước 2 ^ (2 ^ N / 2), và do đó không chính xác? Ý bạn là FFT có kích thước R?
Philipp

R2Rexp2πjik2N

0

Nếu tín hiệu của bạn là đa chiều, thì việc song song FFT có thể được thực hiện khá dễ dàng; giữ một chiều tiếp giáp trong quy trình MPI, thực hiện FFT và hoán vị (altoall) để hoạt động trên chiều tiếp theo. FFTW làm điều này.

Nếu dữ liệu là 1D, vấn đề khó khăn hơn nhiều. FFTW, ví dụ, đã không viết FFT 1D bằng MPI. Nếu người ta sử dụng thuật toán tần số thập phân radix-2, thì một vài giai đoạn đầu tiên có thể được thực hiện như một DFT ngây thơ, cho phép một người sử dụng 2 hoặc 4 nút mà không mất bất kỳ độ chính xác nào (điều này là do gốc rễ của sự thống nhất cho giai đoạn đầu tiên là -1 hoặc i, rất phù hợp để làm việc).

Ngẫu nhiên, bạn dự định làm gì với dữ liệu sau khi bạn đã chuyển đổi nó? Nó có thể làm một cái gì đó nếu người ta biết điều gì xảy ra với đầu ra (nghĩa là bộ tích chập, bộ lọc thông thấp, v.v.).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.