การกำหนดที่อยู่หน่วยความจำใน MPI_Gather C

ฉันกำลังพยายามส่งข้อมูลไปที่ MPI_Gather ฉันจัดสรรหน่วยความจำดังนี้:

float *phie, *phitemp;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

phitemp=(float *) malloc(20*sizeof(float));
if (rank==1) phie=(float *) malloc(itermax*20*size*sizeof(float));

แล้วให้กระบวนการทั้งหมดส่งข้อมูลไปอันดับ 1 โดยใช้ MPI_Gather() ดังนี้

for (iter=0;iter<itermax;iter++) {    
   MPI_Gather((float *) phitemp, 20, MPI_FLOAT, (float *) (phie+iter*20*size*sizeof(float)), 20, MPI_FLOAT, 1, MPI_COMM_WORLD);
   iter=0;

}

ฉันได้รับข้อความแสดงข้อผิดพลาดแจ้งว่าฉันไม่ได้จัดสรรหน่วยความจำอย่างเหมาะสม


person Marta    schedule 01.02.2017    source แหล่งที่มา
comment
เพิ่มคำถามของฉัน ฉันใช้ตัวแปร iter เพื่อย้ายที่อยู่ของบัฟเฟอร์การรับใน MPI_Gather() iter อาจมีค่าที่แตกต่างกันในโปรเซสเซอร์ที่แตกต่างกัน อันไหนที่ใช้ในฟังก์ชัน MPI_Gather อันหนึ่งสำหรับโปรเซสเซอร์ที่รับข้อมูล? หากเป็นเช่นนั้น ฉันจะแน่ใจได้อย่างไรว่าโปรเซสเซอร์ต่างๆ กำลังรออยู่   -  person Marta    schedule 01.02.2017
comment
โปรดเพิ่มถ้อยคำที่ตรงกับข้อความแสดงข้อผิดพลาดในคำถามของคุณ!   -  person Zulan    schedule 01.02.2017
comment
หากคุณเพิ่มคำถามเพิ่มเติม โปรดใช้ฟังก์ชันแก้ไขและใส่คำถามเพิ่มเติมไว้ในเนื้อหาของคำถาม   -  person Zulan    schedule 01.02.2017


คำตอบ (1)


เลขคณิตของตัวชี้จะกระทำตามขนาดของคำที่ตัวชี้ชี้ไป เนื่องจาก phie เป็น float * ดังนั้น sizeof(float) ใน phie+iter*20*size*sizeof(float) จึงซ้ำซ้อน และคุณกำลังอยู่นอกหน่วยความจำที่ถูกต้อง

ลบ sizeof(float) หรือเปลี่ยนเป็นการจัดทำดัชนีอาร์เรย์ที่ชัดเจนยิ่งขึ้น: &(phie[iter * 20 * size])

คุณควรลบพอยน์เตอร์แคสต์ออกทั้งหมด เนื่องจากซ้ำซ้อนและสามารถซ่อนปัญหาได้ คุณควรส่งเฉพาะเมื่อคุณรู้ว่าคุณต้องการมันเท่านั้น

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

person Zulan    schedule 01.02.2017
comment
ขอบคุณ ฉันได้แก้ไขแล้ว แต่ข้อผิดพลาดยังคงอยู่ - person Marta; 02.02.2017
comment
ถ้า MPI_Gather ไม่อนุญาตให้กระบวนการแซงกัน จะสามารถแทรกบรรทัดเอาต์พุตก่อนคำสั่ง MPI_Gather ได้อย่างไร printf(iter: %d, processor: %d before MPI_Gather.\n, iter, rank); ให้ผลลัพธ์นี้เหรอ? iter: 0, ตัวประมวลผล: 0 ก่อน MPI_Gather iter: 0, ตัวประมวลผล: 1 ก่อน MPI_Gather iter: 0, ตัวประมวลผล: 2 ก่อน MPI_Gather iter: 0, ตัวประมวลผล: 3 ก่อน MPI_Gather iter: 1, ตัวประมวลผล: 0 ก่อน MPI_Gather iter: 1, ตัวประมวลผล: 1 ก่อน MPI_Gather iter: 2, ตัวประมวลผล: 1 ก่อน MPI_Gather iter: 3, ตัวประมวลผล: 1 ก่อน MPI_Gather iter: 4, ตัวประมวลผล: 1 ก่อน MPI_Gathe - person Marta; 02.02.2017
comment
โปรดแก้ไขตัวอย่างที่ทำซ้ำได้น้อยที่สุด (อ่านหน้านั้นอย่างละเอียด) ในคำถามของคุณสำหรับความพยายามในการแก้ไขข้อบกพร่องเพิ่มเติม - person Zulan; 02.02.2017
comment
ปฏิบัติการไม่สามารถแซงหน้ากันได้ หมายความว่าจะจับคู่กันตามลำดับเท่านั้น แต่โฟลว์การควบคุมอันดับไม่จำเป็นต้องซิงค์กัน - MPI_Gather ไม่ได้หมายความถึงอุปสรรค นอกจากนี้ยังไม่มีการรับประกันใดๆ เกี่ยวกับวิธีการรวม stdout จากอันดับที่แตกต่างกัน - person Zulan; 02.02.2017
comment
นั่นเป็นข้อบกพร่องเล็กๆ น้อยๆ ที่ฉันได้แก้ไขแล้ว ขอขอบคุณสำหรับการชี้แจงก่อนหน้านี้: นั่นคือปัญหาหลักที่ฉันกำลังเผชิญอยู่ - person Marta; 02.02.2017