-mpmd-absorb-inferred-fragments
قطعات ریشه قطعات استنباط شده را جذب می کنند.
باعث می شود قطعات ریشه قطعات استنباط شده را جذب کنند، به عنوان مثال، با ادغام قطعات تولید کننده/مصرف استنباط شده در قطعات ریشه، که در آن قطعه ریشه هر قطعه ای است که:
- یک قطعه کاربر، یا
- توسط هیچ قطعه دیگری استفاده نمی شود (مثلاً قطعه ای که توسط عملیات بازگشت یا فقط یک انتقال استفاده می شود) یا
- کاربر یک مقدار تولید شده توسط هر قطعه دیگری (به عنوان مثال، کاربر آرگومان های بلوک یا انتقال) نیست.
برای انجام این کار، پاس الگوهای زیر را اعمال می کند تا زمانی که به یک نقطه ثابت برسد:
(1) با توجه به یک قطعه ریشه rf ، اگر یک قطعه استنباط شده ipf وجود داشته باشد به طوری که ipf تولیدکننده rf باشد و rf نزدیکترین مصرف کننده ipf باشد، ipf در rf ادغام می شود.
و دوگانه:
(2) با توجه به یک قطعه ریشه rf ، اگر یک مصرف کننده icf استنباط شده باشد به طوری که icf مصرف کننده rf باشد و rf نزدیک ترین تولید کننده icf باشد، آنگاه icf در rf ادغام می شود.
این بدان معناست که ما ساختار/شکل برنامه را همانطور که توسط کاربر تعریف شده است، از طریق محاسبات نامگذاری شده و تخصیص مرحله/مش حفظ می کنیم.
توجه داشته باشید که این پاس در ادغام قطعات استنتاج شده کاملاً تهاجمی است و به ویژه می تواند تفاوت های کوچکی را در مراحل مختلف ایجاد کند که می تواند تعداد قطعات منحصر به فرد را برای کامپایل افزایش دهد.
این پاس به ما هشدار می دهد اگر توابع غیر نقطه ورود نهایی همچنان شامل قطعات استنباط شده باشند، زیرا ممکن است باعث مشکلات عملکرد شود (به عنوان مثال، انباشت گرادیان اشتباه شده است).
گزینه ها
-absorb-on-entry-point-function : Whether to absorb inferred fragments into user-defined fragments on entry-point functions, in addition to targets of mpmd.calls.
-mpmd-call-inline
تمام عملیات mpmd.call را وارد می کند.
عملیات mpmd.call درون خطی، کپی کردن ویژگیهای آنها در هر عملیات درونخطی.
-mpmd-copy-constants
ثابت های تولید شده در یک قطعه را برای مصرف کنندگان خود کپی می کند.
احتمالاً از طریق انتقال، ثابتها را از قطعات تولیدکننده به قطعات مصرفکننده کپی میکند.
مثال:
%f = fragment () () {
return constant
}
%t = transfer %f
fragment (%t) (%arg) {
op(... %arg ...)
...
}
~~>
%f = fragment () () {
return constant
}
%t = transfer %f
fragment (%t) (%arg) {
%c = constant
op(... %c ...)
...
}
این می تواند برای عملکرد زمان اجرا مفید باشد: بهینه سازی های بالقوه را با کنار هم قرار دادن ثابت با کاربرانش امکان پذیر می کند و از انتقال ثابت ها جلوگیری می کند. علاوه بر این، استفاده از حافظه را بهبود می بخشد: ما فضای مورد نیاز برای پارامترهای محاسبات را کاهش می دهیم.
-mpmd-erase-unused-callee-block-arguments
هر آرگومان بلوک mpmd callee را که توسط محاسبات (hlo) استفاده نمی شود، پاک می کند.
آرگومان های بلوک استفاده نشده را از توابع فراخوانی شده توسط mpmd.calls پاک می کند. اگر آرگومان بلوکی استفاده نشده باشد یا فقط توسط پایاندهنده تابع استفاده شود، یعنی اگر توسط هیچ محاسباتی hlo استفاده نشده باشد، بلااستفاده در نظر میگیریم.
-mpmd-fragment-dce
آرگومان ها/نتایج قطعه استفاده نشده را حذف می کند و مناطق قطعه را ساده می کند.
آرگومان ها و نتایج قطعه استفاده نشده را حذف می کند، در حالی که مناطق قطعه را ساده می کند، و اساسا کد MPMD مرده را حذف می کند.
-mpmd-fragment-dedup
هر عملوند تکراری را حذف می کند و منجر به قطعه می شود.
هر آرگومان تکراری استفاده شده را حذف میکند و به قطعات تبدیل میشود. با این کار آرگومان ها و نتایج تکراری استفاده نمی شوند. برای حذف آرگومان ها و نتایج استفاده نشده باید پاس های دیگر اجرا شوند.
-mpmd-from-unroll-to-call-counter
شمارشگر unroll attr یک call op را به یک call counter attr تبدیل می کند.
هر زمان که یک call op ویژگی unroll_counter داشته باشد، این پاس آن را با ویژگی call_counter جایگزین میکند. این برای مواردی مورد نیاز است که در آن دنباله ای از فراخوان ها از باز کردن حلقه در MLIR (مثلاً از طریق -mpmd-unroll-for-loops ) به جای باز کردن حلقه در سطح پایتون حاصل می شود.
-mpmd-merge-forward-with-backward
قطعات جلو را با قطعات عقب ادغام کنید.
یک قطعه رو به جلو تولید کننده را با یک قطعه عقب مصرف کننده ادغام کنید، اگر اولی بلافاصله قبل از دومی باشد. این فقط برای آخرین مرحله در برنامه 1F1B صادق است، بنابراین هیچ قطعه ای را در مراحل قبلی ادغام نمی کند، که رفتار مورد نظر است.
-mpmd-merge-inferred-fragments
قطعات استنباط شده را با قطعات تعریف شده توسط کاربر ادغام می کند.
ادغام های استنباط شده با قطعات تعریف شده توسط کاربر یا سایر قطعات استنباط شده. این پاس برای پاکسازی/ساده کردن ماژول مفید است و می تواند پس از عبور سایر کامپایلرها که قطعات استنتاج شده را معرفی می کنند مفید باشد، در حالی که -mpmd-transfer-aware-merge در بالا تهاجمی تر است و باید فقط برای اهداف بهینه سازی استفاده شود.
وقتی clone_inferred_fragments=true ، پس این پاس ادغام اجازه می دهد تا قطعات خاصی شبیه سازی شوند. به طور خاص، اگر با یک جفت قطعه f1 و f2 مواجه شویم که:
- f2 از f1 و
- f1 استنباط شده، خالص و به اندازه کافی ساده است (تک عملیات بدون بازگشت و نتیجه واحد)، سپس یک کلون از f1 را در f2 ادغام می کنیم، یعنی خود f1 (و سایر کاربران) مستقل از f2 باقی می مانند. ممکن است ادغام قطعات تولیدکننده استنباط شده بدون شبیهسازی نامطلوب باشد، زیرا میتواند وابستگیهای غیرضروری بین قطعات ایجاد کند. به عنوان مثال،
%inferred = frag m1 { return stablehlo.const … }
%frag1 = frag m1 (%inferred, …)
%frag2 = frag m1 (%inferred, …)
~>
%inferred_frag1 = frag m1 (…) { … return const_m1, … }
%frag2 = frag m2 (inferred_frag1, …)
بنابراین frag2 اکنون به inferred_frag1 بستگی دارد و ما یک وابستگی ایجاد می کنیم.
با این حال، گاهی اوقات ما می خواهیم در جای خود ادغام شویم، به عنوان مثال، زمانی که قطعه استنباط شده دارای مجموعه هایی در داخل است.
گزینه ها
-clone-inferred-fragments : Whether to clone inferred fragments. Chains of clonable fragments are merged one-by-one into their consumers and recursively.
-merge-any-consumer : Whether to merge with any consumer or only the closest consumer.
-merge-sideways : Whether to merge with the next fragment in the same mesh (neighbor), even if not a consumer.
-mpmd-merge-transfers
مجموعهای از انتقالها را ادغام میکند که قطعات تولیدکننده و مصرفکننده مشابهی دارند.
مجموعهای از انتقالها از نوع محموله یکسانی را که قطعات تولیدکننده و مصرفکننده مشابهی دارند ادغام میکند. مقادیر محموله این انتقال ها دارای عناصر کمتری نسبت به یک آستانه معین هستند، خرد نشده و در pinned_host زندگی نمی کنند.
ادغام مجموعه ای از انتقال ها به این معنی است: به هم پیوستن مقادیر انتقال یافته در سایت تولید کننده و تقسیم آنها در سایت مصرف کننده.
-mpmd-merge-user-fragments-into-scheduling-units
ادغام قطعات مبتنی بر کاربر قبل از زمانبندی خط لوله.
جفت قطعات تعریف شده توسط کاربر را ادغام می کند تا با پاس های زمان بندی خط لوله استفاده شوند.
-mpmd-move-transfers-to-producer
نقل و انتقالات را در کنار تولیدکنندگان خود منتقل می کند.
انتقالها را در کنار سازندههایشان جابهجا میکند: اگر عملوند آرگومان بلوکی است، انتقال را به ابتدای بلوک منتقل کنید، در غیر این صورت آن را بعد از عملیات تعریفکننده منتقل کنید.
-mpmd-remove-transfer-cycles
چرخه های انتقال فقط دستگاه را از برنامه حذف می کند و از انتقال های غیر ضروری جلوگیری می کند.
چرخه های انتقال را حذف می کند.
به عنوان مثال در نمادها:
x1 = انتقال (x0) : m0 -> m1 x2 = انتقال (x1) : m1 -> m2 x3 = انتقال (x2) : m2 -> m3 x0_1 = انتقال (x3): m3 -> m0 x1_1 = انتقال (x0_1) : m0 -> m1
~~>
x1 = انتقال (x0) : m0 -> m1 x2 = انتقال (x1): m1 -> m2 x3 = انتقال (x2): m2 -> m3 x0_1 = x0 x1_1 = x1
یعنی سپس با استفاده از مقادیر موجود چرخه را می شکنیم و انتقال های غیر ضروری را حذف می کنیم.
توجه داشته باشید که این میتواند سربار حافظه را افزایش دهد، زیرا انتقال دادهها به دور و دوباره به این معنی است که دورهای وجود دارد که دادهها روی دستگاه نیست. بنابراین، ما این کار را فقط در صورتی انجام می دهیم که چرخه فقط شامل انتقال دستگاه به دستگاه باشد، به عنوان مثال، از آنجایی که چرخه device -> host -> device می تواند برای اهداف حافظه باشد.
این از Canonicalizer MLIR استفاده نمیکند، زیرا تضمین نمیکند که همه چیز متعارف باشد، و همچنین استفاده از آن گرانتر است.
-mpmd-rule-based-merge
قطعات را بر اساس قوانین تعریف شده توسط کاربر ادغام می کند.
قطعات را بر اساس فهرست مشخصی از قوانین ادغام می کند، هر کدام فهرستی از قطعه منبع را برای ادغام (براساس اطلاعات قطعه آنها) و اطلاعات هدف را برای برچسب گذاری قطعه ادغام شده مشخص می کند.
گزینه ها
-rules : A list of fragment merge rules, each with a list of source fragment infos and a target fragment info.
-remove-control-dependencies : Whether to remove control dependencies at the end of the pass.
-mpmd-scheduling-units-verifier
بررسی می کند که آیا برنامه دارای واحدهای زمان بندی مورد نیاز است یا خیر.
-mpmd-sink-negligible-ops-into-call-op
عملیات ناچیز را به فراخوانی (یعنی تابع فراخوانی شده) تبدیل می کند.
عملیات (ناچیز) را در توابع فراخوانی میکند: اگر یک op با عملوند صفر و یک نتیجه واحد وجود داشته باشد که به عنوان یک عملوند خاص از همه فراخوانیهای یک تابع استفاده میشود، آنگاه آن را در آن فراخوانی ops قرار میدهیم، یعنی آن را در تابع فراخوانی کلون میکنیم و تمام کاربردهای آرگومان مربوطه را با کلون جایگزین میکنیم. عملیات غرق شده از تابع فراخوان حذف می شود و آرگومان های استفاده نشده فراخواننده (و عملوندهای عملیات فراخوانی مربوطه) حذف می شوند. توجه داشته باشید که در هنگام استفاده از فراخوانی برای میکروبچینگ، این به طور بالقوه می تواند محاسبات را در بسیاری از میکروبچ ها تکرار کند. اگرچه، این محاسبه به احتمال زیاد ناچیز است زیرا هیچ عملوندی ندارد.
-mpmd-split-and-prioritize-transfer-independent-computations
بر اساس نتایج منتقل شده، قطعات را به عقب تقسیم می کند.
یک قطعه را به دو بخش تقسیم می کند تا بتوانیم محاسبات را زودتر شروع کنیم. یعنی قطعه را به دو قطعه A -> B تقسیم می کنیم، جایی که A به هیچ نتیجه انتقالی متکی نیست و حداکثر بزرگ است و B به نتایج انتقال متکی است.
-mpmd-split-bwd-fragments
بر اساس نتایج منتقل شده، قطعات را به عقب تقسیم می کند.
قطعات را به عقب تقسیم می کند به طوری که هر محاسباتی که در نتایج منتقل شده جریان نداشته باشد به یک قطعه از خود تبدیل می شود. قطعه اصلی مقداری باقیمانده را برمی گرداند که به عنوان عملوند اضافی به قطعات تقسیم شده ارسال می شوند.
این تقسیم به ما امکان می دهد نتایج را زودتر به مش های دیگر منتقل کنیم. یکی از کاربردهای متعارف این بهینه سازی، تقسیم محاسبات گرادیان فعال سازی در پس انتشار از محاسبه گرادیان پارامتر خواهد بود. همچنین توجه داشته باشید که به دلیل نیاز به عبور بالقوه از طریق برخی مقادیر باقیمانده در قطعات جدید، فشار حافظه افزایش می یابد.
-mpmd-uniquify-function-inputs-outputs
هر مقداری که چندین بار برگردانده شده است یا هر آرگومان بلوکی که مستقیماً توسط تابع برگردانده شده است را یکسان می کند.
اگر یک تابع چندین بار یک مقدار را برمی گرداند، با ایجاد یک قطعه اختصاص داده شده به مش آن مقدار که چندین بار مقدار را برمی گرداند، چندین نسخه برای آن مقدار ایجاد می کند. پس از این عبور، هر عملوند بازگشتی منحصر به فرد است. این مهم برای اطمینان از تخصیص نتایج مربوطه در بافرهای مختلف است، مانند مثال jax.jit زیر:
def f(x):
y = x + x
return y, y
z1, z2 = f(5)
z1 += 1
print(z1) ~~> 6
print(z2) ~~> 5
به طور مشابه، اگر یک تابع یک آرگومان بلوکی را برگرداند، این پاس یک قطعه هویت برای آن آرگومان بلوک ایجاد میکند و تضمین میکند که مقادیر با مقدار به تابع ارسال میشوند، نه با مرجع.
گزینه ها
-use-transfer-instead-of-fragment : Whether to use mpmd.transfer or mpmd.fragment for uniquification
-mpmd-unroll-for-loops
حلقههای mpmd.for را بهطور کامل باز میکند.
پاسی ایجاد میکند که mpmd.for ops را کاملاً باز میکند، در حالی که یک ویژگی unroll_counter را به هر عملیات unroll شده متصل میکند.
نیاز دارد: ضریب unroll برابر با تعداد تکرارها باشد.
-mpmd-verify-stage-merging
تأیید می کند که ادغام قطعات اختصاص داده شده به مراحل موفقیت آمیز بوده است.
بررسی می کند که قطعات با انتساب مرحله به درستی ادغام شده اند. این به این معنی است که امکان وجود دو فرگمنت معادل از نظر تخصیص و شمارنده در ماژول وجود ندارد.
دو قطعه از نظر انتساب و شمارنده اگر a معادل هستند. آنها به یک مش اختصاص داده شده اند، ب. آنها به همان مرحله منصوب می شوند، ج. آنها تعداد انتقال یکسانی دارند و d. یا هر دو یک شمارنده تماس دارند یا یکی از آنها شمارنده تماس تعریف نشده است (یعنی یک شمارنده تماس تعریف نشده با هر شمارنده تماس مطابقت دارد).
این برای تضمین به کاربر این است که هر محاسبات اختصاص داده شده به همان مرحله به طور پیوسته اجرا می شود.