รหัสข้อผิดพลาด: E2003

หมวดหมู่: เวลาคอมไพล์: การจัดแนวการเข้าถึงหน่วยความจำที่ยังไม่ได้รับการพิสูจน์ของ 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. คุณใช้ตัวแปรขณะรันไทม์ (ดัชนีแบบไดนามิก) เพื่อเข้าถึงหน่วยความจำ
  2. ตรรกะการคำนวณดัชนีซับซ้อนเกินกว่าที่คอมไพเลอร์จะวิเคราะห์ได้
  3. ดัชนีถูกต้องตามหลักคณิตศาสตร์ แต่ไม่มีการพิสูจน์อย่างชัดเจนในโค้ด
  4. การวิเคราะห์แบบคงที่จะระบุ "การไม่สอดคล้องที่พิสูจน์แล้ว"

การแก้ไขข้อบกพร่อง

หากต้องการแก้ไขข้อผิดพลาดนี้ คุณมีตัวเลือกต่อไปนี้

1. ยืนยันการจัดแนวอย่างชัดเจน

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

2. ใช้การโหลดที่จัดแนวและหมุน

ในกรณีที่การไม่ตรงกันเป็นไปโดยเจตนา แทนที่จะโหลดส่วนเวกเตอร์ขนาดเล็กที่ไม่ได้จัดแนว ให้ทำดังนี้

  • โหลดไทล์ที่ใหญ่ขึ้นและจัดแนวอย่างสมบูรณ์ จากนั้นหมุนค่าตาม จำนวนแบบไดนามิกเพื่อเลื่อนข้อมูลที่ต้องการไปยังตำแหน่ง (เนื่องจากระบบไม่รองรับ เวกเตอร์สไลซ์ที่มีดัชนีเริ่มต้นแบบไดนามิก) หรือ
  • ปรับรูปร่างหรือเพิ่มค่าให้กับเทนเซอร์เพื่อให้ข้อมูลเริ่มต้นที่ดัชนี 0 และระยะก้า วระหว่างการเข้าถึงตรงกับการจัดแนวฮาร์ดแวร์
    • ตัวอย่าง: หากคุณทำซ้ำในกลุ่มขนาด 32 โดยเริ่มที่ออฟเซ็ต 1 ออฟเซ็ตจะเป็น 1, 33, 65... (ไม่อยู่ในแนวเดียวกัน)
    • แก้ไข: แพ็กข้อมูลใหม่เป็นเทนเซอร์ใหม่โดยให้ก้อนแรกอยู่ที่ 0 และเพิ่มมิติข้อมูลเป็น 128 ออฟเซ็ตจะกลายเป็น 0, 128, 256,... ซึ่งเป็นไปตามข้อกำหนดการจัดแนว

วิธีการเหล่านี้ใช้หน่วยความจำมากกว่า แต่โดยทั่วไปจะช่วยลดความซับซ้อนของตรรกะเคอร์เนลและไม่จำเป็นต้องมีการยืนยันการจัดแนวด้วยตนเอง