หมวดหมู่: เวลาคอมไพล์: การจัดแนวการเข้าถึงหน่วยความจำที่ยังไม่ได้รับการพิสูจน์ของ Mosaic
ข้อผิดพลาดนี้เกิดขึ้นเมื่อคอมไพเลอร์วิเคราะห์การดำเนินการเข้าถึงหน่วยความจำ (เช่น vector.load, vector.store, tpu.load หรือ tpu.store) และไม่สามารถพิสูจน์แบบคงที่ว่าดัชนีแบบไดนามิกที่ใช้สำหรับมิติข้อมูลที่เฉพาะเจาะจงเป็นตัวคูณของขนาดการแบ่งไทล์ที่จำเป็น
ตัวอย่างข้อความแสดงข้อผิดพลาด:
INTERNAL: Mosaic failed to compile TPU kernel: cannot statically prove that index in dimension 1 is a multiple of 128
at location: ...
The MLIR operation involved:
%14372 = "vector.load"(%14371, %93, %14363) : (memref<4x256xf32, #tpu.memory_space<vmem>>, index, index) -> vector<1x32xf32>
แบ็กเอนด์ XLA: TPU
ภาพรวม
เมื่อเคอร์เนลโหลดหรือจัดเก็บเวกเตอร์ ที่อยู่หน่วยความจำ
(คำนวณจากตัวชี้ฐานบวกดัชนีแบบไดนามิก) ต้องสอดคล้องกับขนาดการแบ่งไทล์ของเวกเตอร์ในฮาร์ดแวร์ เช่น หากมิติข้อมูลเรียงต่อกันเป็น 128 องค์ประกอบ ดัชนีแบบไดนามิกที่ใช้ในการเข้าถึงจะต้องเป็น 0, 128, 256 ฯลฯ โปรดทราบว่าการดำเนินการหลายอย่าง (เช่น การโหลดและการจัดเก็บเวกเตอร์) ไม่มีข้อกำหนดดังกล่าวสำหรับดัชนีแบบคงที่
คอมไพเลอร์จะบังคับใช้ข้อกำหนดนี้โดยใช้การวิเคราะห์แบบคงที่ โดยจะติดตาม ประวัติของตัวแปรดัชนีย้อนกลับไปตามการดำเนินการทางคณิตศาสตร์ที่ สร้างตัวแปรนั้น (เช่น การคูณ การบวก) หากคอมไพเลอร์ไม่สามารถรับประกัน (ในเวลาคอมไพล์) ว่าค่าผลลัพธ์จะหารด้วยขนาดการจัดเรียงได้เสมอ ระบบจะแสดงข้อผิดพลาดนี้
คอมไพเลอร์จะถือว่า "การจัดแนวที่ไม่ถูกต้องที่พิสูจน์แล้ว" และ "การจัดแนวที่ไม่รู้จัก" เหมือนกัน
ดังนั้นหากคุณใช้ดัชนีที่รับประกันได้ในทางคณิตศาสตร์ว่าไม่สอดคล้องกัน (เช่น
i * 128 + 32) คอมไพเลอร์จะแสดงข้อผิดพลาดเดียวกัน
ดังนั้นข้อผิดพลาดนี้อาจเกิดขึ้นในกรณีต่อไปนี้
- คุณใช้ตัวแปรขณะรันไทม์ (ดัชนีแบบไดนามิก) เพื่อเข้าถึงหน่วยความจำ
- ตรรกะการคำนวณดัชนีซับซ้อนเกินกว่าที่คอมไพเลอร์จะวิเคราะห์ได้
- ดัชนีถูกต้องตามหลักคณิตศาสตร์ แต่ไม่มีการพิสูจน์อย่างชัดเจนในโค้ด
- การวิเคราะห์แบบคงที่จะระบุ "การไม่สอดคล้องที่พิสูจน์แล้ว"
การแก้ไขข้อบกพร่อง
หากต้องการแก้ไขข้อผิดพลาดนี้ คุณมีตัวเลือกต่อไปนี้
1. ยืนยันการจัดแนวอย่างชัดเจน
หากคุณทราบว่าดัชนีถูกต้อง แต่คอมไพเลอร์พิสูจน์ไม่ได้ ให้ใช้tpu.assume_multipleการดำเนินการ ซึ่งทำหน้าที่เป็นสัญญาต่อคอมไพเลอร์ว่า
ค่าจะหารด้วยตัวประกอบที่เฉพาะเจาะจงได้
2. ใช้การโหลดที่จัดแนวและหมุน
ในกรณีที่การไม่ตรงกันเป็นไปโดยเจตนา แทนที่จะโหลดส่วนเวกเตอร์ขนาดเล็กที่ไม่ได้จัดแนว ให้ทำดังนี้
- โหลดไทล์ที่ใหญ่ขึ้นและจัดแนวอย่างสมบูรณ์ จากนั้นหมุนค่าตาม จำนวนแบบไดนามิกเพื่อเลื่อนข้อมูลที่ต้องการไปยังตำแหน่ง (เนื่องจากระบบไม่รองรับ เวกเตอร์สไลซ์ที่มีดัชนีเริ่มต้นแบบไดนามิก) หรือ
- ปรับรูปร่างหรือเพิ่มค่าให้กับเทนเซอร์เพื่อให้ข้อมูลเริ่มต้นที่ดัชนี 0 และระยะก้า
วระหว่างการเข้าถึงตรงกับการจัดแนวฮาร์ดแวร์
- ตัวอย่าง: หากคุณทำซ้ำในกลุ่มขนาด 32 โดยเริ่มที่ออฟเซ็ต 1 ออฟเซ็ตจะเป็น 1, 33, 65... (ไม่อยู่ในแนวเดียวกัน)
- แก้ไข: แพ็กข้อมูลใหม่เป็นเทนเซอร์ใหม่โดยให้ก้อนแรกอยู่ที่ 0 และเพิ่มมิติข้อมูลเป็น 128 ออฟเซ็ตจะกลายเป็น 0, 128, 256,... ซึ่งเป็นไปตามข้อกำหนดการจัดแนว
วิธีการเหล่านี้ใช้หน่วยความจำมากกว่า แต่โดยทั่วไปจะช่วยลดความซับซ้อนของตรรกะเคอร์เนลและไม่จำเป็นต้องมีการยืนยันการจัดแนวด้วยตนเอง