อัลกอริทึมสำหรับการคำนวณ FFT ในแบบคู่ขนาน


12

ฉันพยายามทำให้การคำนวณ FFT เป็นคู่ขนานกับไฟล์สัญญาณขนาดเทราไบต์ ตอนนี้ FFT ที่ใช้ไลบรารีโอเพ่นซอร์สนั้นใช้เวลาหลายชั่วโมงแม้แต่วิ่งผ่าน CUDA บน GPU ที่เร็วที่สุดที่ฉันมี กรอบที่ฉันพยายามปรับให้เข้ากับกระบวนการนี้คือ Hadoop ในแง่พื้นฐานมาก Hadoop กระจายปัญหาบนโหนดเซิร์ฟเวอร์จำนวนเท่าใดก็ได้ในลักษณะดังต่อไปนี้:

•คุณแบ่งไฟล์อินพุตของคุณเป็นคู่ (คีย์, ค่า)
•คู่เหล่านี้จะถูกป้อนเข้าสู่อัลกอริทึม“ แผนที่” ซึ่งจะแปลงคู่ (คีย์, ค่า) ของคุณให้เป็นคู่อื่น ๆ (คีย์, ค่า) ตามสิ่งที่คุณใส่ไว้ในแผนที่
•จากนั้นเฟรมเวิร์กจะรวบรวมเอาท์พุต (คีย์, ค่า) ทั้งหมดจากแผนที่และเรียงลำดับตามคีย์รวมถึงการรวมค่าด้วยคีย์เดียวกันให้กับคู่เดียวดังนั้นคุณจึงจบลงด้วย (คีย์รายการ (ค่า 1, ค่า 2, .. )) คู่
• คู่เหล่านี้จะถูกป้อนเข้าสู่อัลกอริธึม "ลด" ซึ่งจะส่งผลให้คู่ (คีย์, ค่า) คู่เป็นผลลัพธ์สุดท้ายของคุณ (เขียนลงไฟล์)

มีแอพพลิเคชั่นมากมายสำหรับโมเดลนี้ในทางปฏิบัติเช่นการประมวลผลบันทึกเซิร์ฟเวอร์ แต่ฉันมีเวลายากที่จะใช้เฟรมเวิร์กเพื่อตัดค่า FFT ให้เป็น "แผนที่" และ "ลด" งานโดยเฉพาะอย่างยิ่งเนื่องจากฉันไม่คุ้นเคยกับ DSP จริงๆ

ฉันจะไม่รบกวนคุณในการเขียนโปรแกรมจัมโบ้จัมโบ้เพราะนี่คือ DSP Q&A อย่างไรก็ตามฉันสับสนในอัลกอริธึมที่มีอยู่สำหรับการคำนวณ FFTs แบบขนาน จัดทำแผนที่และลดภาระงาน (ทางเทคนิค) ไม่สามารถพูดคุยกันได้ดังนั้น FFT จะต้องแบ่งออกเป็นปัญหาอิสระซึ่งผลลัพธ์จะสามารถรวมกันอีกครั้งในตอนท้าย

ฉันได้ตั้งโปรแกรมการใช้งานง่าย ๆ ของ Cooley-Tukey Radix 2 DIT ที่ใช้กับตัวอย่างเล็ก ๆ แต่ใช้สำหรับการคำนวณดัชนี DFTs แบบคี่ / คู่แบบซ้ำ ๆ สำหรับพันล้านไบต์จะไม่ทำงาน ฉันใช้เวลาสองสามสัปดาห์ในการอ่านเอกสารจำนวนมากรวมถึงหนึ่งในอัลกอริทึม MapReduce FFT (เขียนโดย Tsz-Wo Sze เป็นส่วนหนึ่งของบทความของเขาเกี่ยวกับการคูณ SSA ฉันไม่สามารถเชื่อมโยงไฮเปอร์ลิงก์มากกว่า 2 รายการ) และ "สี่ขั้นตอน FFT" ( ที่นี่และที่นี่) ซึ่งดูเหมือนกันและเป็นสิ่งที่ฉันพยายามทำให้สำเร็จ อย่างไรก็ตามฉันใช้คณิตศาสตร์อย่างสิ้นหวังและใช้วิธีการเหล่านั้นกับชุดง่ายๆของ {1,2, 3, 4, 5, 6, 7, 8} (ด้วยจินตภาพทั้งหมดเป็น 0) ฉันผลลัพธ์ที่ไม่ถูกต้องอย่างดุเดือด ทุกคนสามารถอธิบายอัลกอริทึม FFT ขนานที่มีประสิทธิภาพให้ฉันเป็นภาษาอังกฤษธรรมดา (ที่ฉันเชื่อมโยงหรืออื่น ๆ ) เพื่อที่ฉันจะได้ลองและตั้งโปรแกรมได้หรือไม่?

แก้ไข: Jim Clay และใครก็ตามที่อาจสับสนกับคำอธิบายของฉันฉันพยายามทำไฟล์ FFT เดียวของเทราไบต์ แต่ฉันต้องการที่จะทำมันพร้อมกันในเซิร์ฟเวอร์หลายเครื่องเพื่อเพิ่มความเร็วในกระบวนการ


1
คุณพยายามทำอะไรให้สำเร็จ คุณต้องการทำไฟล์สัญญาณ FFT เดียวของเทราไบต์หรือไฟล์ FFT ขนาดเล็กหลายไฟล์ของแต่ละไฟล์หรือไม่?
Jim Clay

คำตอบ:


13

ฉันคิดว่าปัญหาหลักของคุณไม่ใช่วิธีขนานอัลกอริทึม (ซึ่งสามารถทำได้จริง) แต่มันเป็นความแม่นยำเชิงตัวเลข FFT ที่มีขนาดใหญ่นั้นค่อนข้างมีตัวเลขค่อนข้างยุ่งยาก ค่าสัมประสิทธิ์ FFT เป็นรูปแบบ และถ้า N มีขนาดใหญ่มากการคำนวณสัมประสิทธิ์จะมีเสียงดัง ให้บอกว่าคุณมีและคุณใช้เลขคณิตความเที่ยงสองเท่า 64 บิต 1,000 สัมประสิทธิ์แรกมีส่วนจริงที่เป็นเอกภาพอย่างแน่นอน (แม้ว่ามันจะไม่เป็นอย่างนั้น) ดังนั้นคุณจะต้องใช้คณิตศาสตร์ที่มีความแม่นยำสูงขึ้นซึ่งไม่มีประสิทธิภาพและยุ่งยากในการใช้ N=240ej2πkNN=240

นอกจากนี้คุณยังจะได้รับข้อผิดพลาดในการปัดเศษและการปัดเศษจำนวนมากเนื่องจากจำนวนของการดำเนินการที่เป็นจำนวนเอาต์พุตเดียวมีขนาดใหญ่มากเช่นกัน เนื่องจากลักษณะ "ทุกเอาต์พุตขึ้นอยู่กับอินพุตทุกตัว" ของ FFT การกระจายข้อผิดพลาดจึงอาละวาด

ฉันไม่ทราบวิธีง่ายๆในการแก้ไข คำขอของคุณเป็นสิ่งผิดปกติ แอปพลิเคชันส่วนใหญ่ที่ทำการวิเคราะห์สเปกตรัมของชุดข้อมูลขนาดใหญ่ทำการวิเคราะห์ที่รันอยู่ซึ่งคุณไม่มีปัญหานั้น บางทีถ้าคุณสามารถอธิบายแอปพลิเคชันของคุณและมันมีข้อ จำกัด อยู่บ้าง แต่เราสามารถชี้ให้คุณเห็นวิธีแก้ปัญหาที่เหมาะสมกว่า


ค่อนข้างเป็นจุดที่ถูกต้อง .. ฉันจะต้องคิดเพิ่มเติมเกี่ยวกับเรื่องนี้ บางทีฉันอาจหันไปใช้ "การวิเคราะห์ที่กำลังดำเนินอยู่" ในท้ายที่สุดอย่างที่คุณพูด
Philipp

ฉันรู้ว่าฉันมาสายจริงๆ แต่คุณมีโอกาสที่จะทำสิ่งใดได้บ้างเนื่องจากคุณกล่าวว่าสามารถทำได้
Claudio Brasser

4

แทนที่จะพยายามอีกครั้งเขียน FFT ที่คุณอาจลองใช้การดำเนินการ FFT ที่มีอยู่ (เช่นFFTWตัวอย่าง) และใช้มันซ้ำไปตามความยาวของสัญญาณของคุณ (ว่าใหญ่มันไม่) ผ่านทั้งที่ทับซ้อนกันเพิ่มหรือoverlap- บันทึกวิธีการ สิ่งนี้เป็นไปได้โดยการแสดง FFT ว่าเป็นการโน้มน้าวใจ

FFT ที่มีความยาวสั้นกว่านี้ไม่จำเป็นต้องสื่อสารกันและโครงร่างทั้งหมดตรงกับขั้นตอนลดแผนที่

โดยทั่วไปสิ่งที่คุณตั้งใจจะทำคือให้สัญญาณ X ของคุณแบ่งออกเป็นส่วนย่อย ๆ ที่อาจทับซ้อนกัน (เช่น X [0:10], X [5:15], X [10:20] ... .) ดำเนินการ FFT ในส่วนเล็ก ๆ เหล่านี้และรวมเข้าด้วยกันอีกครั้งในที่สุดเพื่อผลิตสุดท้าย สิ่งนี้เข้ากันได้ดีกับตัวดำเนินการลดแผนที่

ในช่วง "map" คุณสามารถสร้างคู่ (คีย์, ค่า) กับ "คีย์" เป็น ID ตามลำดับของแต่ละเซ็กเมนต์ (0,1,2,3,4,5, .... ) และ "ค่า" เป็น INDEX (หรือตำแหน่งไฟล์) ของค่าแรกของกลุ่มในไฟล์สัญญาณของคุณ ตัวอย่างเช่นหากไฟล์ของคุณเต็มด้วย INT32 ดัชนีของกลุ่มที่สอง (ด้านบน) จะอยู่ที่ 5 * ขนาดของ (INT32) (หรือถ้าอยู่ในรูปแบบอื่นคุณอาจมี lib สำหรับมัน)

ตอนนี้ผู้ปฏิบัติงานแต่ละคนได้รับ (คีย์ค่า) เปิดไฟล์ค้นหาไปยังจุดที่ถูกต้องอ่านตัวอย่าง M จากมัน (ที่ M คือ 10 ข้างบน) ดำเนินการ FFT และบันทึกเป็นไฟล์ที่มีชื่อบางตัวอย่างเช่น " RES_ [INKEY] .dat "และส่งคืนคู่ (คีย์ค่า) ในกรณีนี้ "คีย์" จะเป็น INDEX ("ค่า" ของ tuple ขาเข้า (คีย์, ค่า)) และ "ค่า" จะเป็นชื่อของไฟล์ที่มีผลลัพธ์ FFT (เราจะกลับไปที่สิ่งนี้)

ภายใน "ลด" คุณสามารถใช้งานเหลื่อมกันเพิ่มหรือทับซ้อนบันทึกโดยการยอมรับ (คีย์ค่า) จากขั้นตอน "แผนที่" เปิดไฟล์นั้นโหลดผลลัพธ์ FFT ทำ oa หรือระบบปฏิบัติการแล้วบันทึกไป INDEX ที่ถูกต้องในไฟล์เอาต์พุตของคุณ (ดูรหัสเทียมในขั้นตอนนี้ (หรือสิ่งนี้ ) ขั้นตอน "แผนที่" จะจัดการกับ "yt = ... " ในแบบคู่ขนานและขั้นตอน "ลด" จะจัดการส่วน "y (i, k) = ... ")

อาจจำเป็นต้องเล่นไฟล์บางไฟล์ที่นี่เพื่อลดทราฟฟิกบนเครือข่ายหรือโหลดเซิร์ฟเวอร์ที่อาจมีไฟล์ข้อมูลจริงของคุณ


1
ฉันไม่แน่ใจเกี่ยวกับความถูกต้องของการทับซ้อน - เพิ่มและการทับซ้อน - บันทึกเพื่อรวมชิ้นย่อยที่เล็กลงเพื่อดึง FFT ที่ใหญ่กว่า - เท่าที่ฉันรู้ว่ามี FFT ที่สองที่จำเป็นในการทำเช่นนั้น (DFT ของขนาด N = AB สามารถแบ่งออกเป็น A DFTs ขนาด B, แอปพลิเคชัน twiddle factor, และ B DFTs ขนาด A) มันอาจทำงานได้ถ้าเราต้องการความละเอียดเอาต์พุตที่ต่ำกว่า ...
pichenettes

สวัสดี picenettes ขอบคุณสำหรับสิ่งที่ฉันมีอยู่ในใจของฉันคือ ( engineeringproductivitytools.com/stuff/T0001/PT11.HTM ) ซึ่งฉันจะรวมไว้ในคำตอบ
A_A

2

ให้เราคิดว่าขนาดข้อมูลของคุณ N แผ่นกับศูนย์มิฉะนั้น ในกรณีของคุณเนื่องจากคุณพูดถึงขนาด "เทราไบต์ - สเกล" เราจะใช้ N = 402N

เนื่องจากมีขนาดใหญ่ - แต่สมเหตุสมผลอย่างยิ่งสำหรับเครื่องเดียว - ขนาด FFT ฉันขอแนะนำให้คุณทำซ้ำ Cooley-Tukey ของ radixเพียงครั้งเดียวแล้วปล่อยไลบรารี FFT ที่เหมาะสม (เช่น FFTW) ทำผลงานในแต่ละเครื่องสำหรับขนาดที่เล็กกว่า2}2N/2N/22N/2

เพื่อให้ชัดเจนยิ่งขึ้นไม่จำเป็นต้องใช้ MR ตลอดการเรียกซ้ำทั้งหมดซึ่งจะไม่มีประสิทธิภาพอย่างแน่นอน ปัญหาของคุณสามารถแบ่งออกเป็นล้าน FFTs ภายในและภายนอกขนาดเมกะไบต์และ FFT เมกะไบต์เหล่านั้นสามารถคำนวณได้อย่างสมบูรณ์แบบโดยใช้ FFTW หรือที่คล้ายกัน MR จะรับผิดชอบในการดูแลการสับและการรวมข้อมูลใหม่ไม่ใช่การคำนวณ FFT จริง ...

ความคิดแรกของฉันคือต่อไปนี้ แต่ฉันคิดว่าสิ่งนี้สามารถทำได้ใน MR เดียวที่มีการแสดงข้อมูลอย่างชาญฉลาด

Letเป็นสัญญาณอินพุตของคุณsR=2N/2

MR คนแรก: FFT ด้านใน

แผนที่: ดำเนินการทำลายล้างในเวลากลุ่มตัวอย่างเป็นบล็อกสำหรับ FFT ด้านใน

อินพุต:โดยที่คือดัชนีตัวอย่างใน ; ค่าที่ถ่ายโดย(k,v)k0..2N1vs[k]

ปล่อย: - โดยที่% แสดงถึงการแบ่งโมดูโลและ / จำนวนเต็ม(k%R,(k/R,v))

ลด: คำนวณ FFT ภายใน

อินพุต:โดยที่คือดัชนีบล็อก และเป็นรายการของคู่(k,vs)kvs(i,v)

เติมเวกเตอร์ขนาดดังกล่าวว่าสำหรับค่าทั้งหมดในรายการinRin[i]=v

ดำเนินการขนาด FFT บนที่จะได้รับเวกเตอร์ขนาดRinoutR

สำหรับใน , ปล่อยi0..R1(k,(i,out[i]))

MR คนที่สอง: FFT ด้านนอก

แผนที่: กลุ่มตัวอย่างสำหรับ fft ด้านนอกและใช้ปัจจัย twiddle

อินพุต:โดยที่คือดัชนีบล็อกตัวอย่างของ FFT ภายในสำหรับบล็อกนี้(k,(i,v))k(i,v)

ปล่อย(i,(k,v×exp2πjik2N))

ลด: ดำเนินการ FFT ภายนอก

อินพุต:โดยที่คือดัชนีบล็อก และเป็นรายการของคู่(k,vs)kvs(i,v)

เติมเวกเตอร์ขนาดดังกล่าวว่าสำหรับค่าทั้งหมดในรายการinRin[i]=v

ดำเนินการขนาด FFT บนที่จะได้รับเวกเตอร์ขนาดRinoutR

สำหรับในปล่อย0 . R - 1 ( i × R + k , o คุณt [ i ] ) )i0..R1(i×R+k,out[i]))

หลักฐานของรหัสไพ ธ อนแนวคิดที่นี่

อย่างที่คุณเห็น Mappers เป็นเพียงสับเปลี่ยนลำดับของข้อมูลดังนั้นภายใต้สมมติฐานต่อไปนี้:

  • การลดทอนเวลา (Mapper 1) สามารถทำได้ในขั้นตอนก่อนหน้า (ตัวอย่างเช่นโดยโปรแกรมที่แปลงข้อมูลเป็นรูปแบบอินพุตที่ถูกต้อง)
  • เฟรมเวิร์ก MR ของคุณรองรับ Reducers ที่เขียนไปยังคีย์ที่แตกต่างจากคีย์อินพุตของพวกเขา (ในเครื่องมือลดการใช้งานของ Google สามารถส่งออกข้อมูลไปยังคีย์เดียวกับที่ได้รับมาฉันคิดว่าเป็นเพราะ SSTable ถูกใช้เป็นรูปแบบเอาต์พุต)

ทั้งหมดนี้สามารถทำได้ในหนึ่ง MR เดียว, FFT ด้านในใน mapper, FFT ด้านนอกในตัวลด หลักฐานของแนวคิดที่นี่


ดูเหมือนว่าการติดตั้งของคุณน่าจะเป็นไปได้และฉันกำลังดำเนินการอยู่ในตอนนี้ แต่ในตัวลด FFT ด้านในคุณเขียน "แสดงขนาด 2 ^ R FFT เพื่อให้ได้เวกเตอร์ที่มีขนาด 2 ^ R" ถ้า R คือ 2 ^ (N / 2) FFT นี้จะไม่เป็นขนาด 2 ^ (2 ^ N / 2) และไม่ถูกต้องใช่ไหม คุณหมายถึง FFT of size R หรือเปล่า
Philipp

ใช่ดูเหมือนว่าฉันผสมและในบางแห่ง ... แก้ไข โปรดทราบว่าความคิดเห็นของฮิลมาร์นำไปใช้กับแนวทางของฉัน - คุณจะต้องใช้ความแม่นยำสูงกว่าสองเท่ามิฉะนั้นปัจจัยทวีคูณบางอย่าง ( ) จะมีส่วนจริง ของ 1 ในขณะที่พวกเขาไม่ควร - นำไปสู่ความไม่ถูกต้องเป็นตัวเลข 2 R exp - 2 π j i kR2Rexp2πjik2N
pichenettes

0

หากสัญญาณของคุณมีหลายมิติการทำ FFT ให้ขนานกันนั้นสามารถทำได้อย่างง่ายดาย ให้มิติหนึ่งอยู่ติดกันในกระบวนการ MPI ดำเนินการ FFT และย้าย (altoall) เพื่อทำงานในมิติถัดไป FFTW ทำเช่นนี้

หากข้อมูลเป็น 1D แสดงว่าปัญหานั้นยากกว่ามาก ตัวอย่างเช่น FFTW ไม่ได้เขียน 1D FFT โดยใช้ MPI ถ้ามีใครใช้ Radix-2 decimation-in-frequency algorithm ดังนั้นขั้นตอนแรก ๆ สามารถทำได้ในรูปแบบไร้เดียงสา DFT ทำให้ผู้ใช้สามารถใช้ 2 หรือ 4 โหนดโดยไม่สูญเสียความแม่นยำ (นี่เป็นเพราะรากของความเป็นเอกภาพ ด่านแรกเป็น -1 หรือ i ซึ่งดีต่อการใช้งาน)

อนึ่งคุณวางแผนจะทำอะไรกับข้อมูลเมื่อคุณแปลงข้อมูลแล้ว? มันอาจจะทำอะไรบางอย่างถ้าใครรู้ว่าเกิดอะไรขึ้นกับเอาท์พุท

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.