يوضِّح ما يلي دلالات العمليات المحدّدة في واجهة
XlaBuilder
. يتم عادةً ربط هذه العمليات بشكلٍ مباشر بالعمليات المحدّدة في
واجهة RPC في
xla_data.proto
.
ملاحظة حول التسمية: نوع البيانات العام الذي تتعامل معه XLA هو آرامٍ بأبعاد N تحتوي على عناصر من نوع موحّد (مثل 32 بت عائمة). في جميع المستندات، يُستخدَم صفيف للإشارة إلى صفيف بأبعاد عشوائية. لتسهيل الأمر، تحمل الحالات الخاصة أسماء أكثر تحديدًا وشيوعًا، على سبيل المثال، المتجه هو صفيف أحادي الأبعاد و المصفوفة هي صفيف ثنائي الأبعاد.
AfterAll
يمكنك الاطّلاع أيضًا على
XlaBuilder::AfterAll
.
يأخذ AfterAll عددًا متغيرًا من الرموز المميّزة وينشئ رمزًا مميّزًا واحدًا. الرموز المميّزة هي أنواع أساسية يمكن ربطها بين العمليات التي تؤدي إلى تأثيرات جانبية لفرض الترتيب. يمكن استخدام AfterAll
كعملية دمج للرموز لترتيب
عملية بعد مجموعة من العمليات.
AfterAll(operands)
الوسيطات | النوع | الدلالات |
---|---|---|
operands |
XlaOp |
عدد متغيّر من الرموز المميّزة |
AllGather
يمكنك الاطّلاع أيضًا على
XlaBuilder::AllGather
.
تُجري عملية الربط على مستوى النُسخ المكرّرة.
AllGather(operand, all_gather_dim, shard_count, replica_group_ids,
channel_id)
الوسيطات | النوع | الدلالات |
---|---|---|
operand
|
XlaOp
|
صفيف لتسلسل العناصر في كل النسخ |
all_gather_dim |
int64 |
سمة الربط |
replica_groups
|
متّجه المتّجهات
int64 |
المجموعات التي يتم بينها تسلسل |
channel_id
|
اختياري int64
|
معرّف قناة اختياري للتواصل بين الوحدات |
replica_groups
هي قائمة بمجموعات النُسخ المكرّرة التي يتم بينها تنفيذ التسلسل (يمكن استرداد معرّف النسخة المكرّرة الحالية باستخدامReplicaId
). يحدّد ترتيب النُسخ المكرّرة في كل مجموعة الترتيب الذي يتم فيه العثور على مدخلاتها في النتيجة. يجب أن يكونreplica_groups
فارغًا (وفي هذه الحالة تنتمي جميع النُسخ المكرّرة إلى مجموعة واحدة، مرتّبة من0
إلىN - 1
)، أو أن يحتوي على عدد العناصر نفسه المُدرَج في عدد النُسخ المكرّرة. على سبيل المثال، يُجريreplica_groups = {0, 2}, {1, 3}
دمجًا بين النُسخ المكرّرة0
و2
و1
و3
.shard_count
هو حجم كل مجموعة نُسخ. نحتاج إلى ذلك في الحالات التي تكون فيها قيمة الحقلreplica_groups
فارغة.- يتم استخدام
channel_id
للتواصل بين الوحدات: لا يمكن إلاall-gather
للعمليات التي تستخدمchannel_id
نفسه التواصل مع بعضها.
شكل الإخراج هو شكل الإدخال مع all_gather_dim
الذي تم shard_count
مضاعفته. على سبيل المثال، إذا كانت هناك نسختان طبق الأصل وكان الم Operand يملك
القيمة [1.0, 2.5]
و[3.0, 5.25]
على التوالي في كلتا النُسختَين، ستكون قيمة
الإخراج من هذا الإجراء حيث يكون all_gather_dim
هو 0
هي [1.0, 2.5, 3.0,
5.25]
في كلتا النُسختَين.
AllReduce
يمكنك الاطّلاع أيضًا على
XlaBuilder::AllReduce
.
تُجري عملية حسابية مخصّصة على النُسخ المكرّرة.
AllReduce(operand, computation, replica_group_ids, channel_id)
الوسيطات | النوع | الدلالات |
---|---|---|
operand
|
XlaOp
|
صفيف أو مجموعة غير فارغة من صفائف لتقليلها في النُسخ المكرّرة |
computation |
XlaComputation |
احتساب التخفيض |
replica_groups
|
متّجه المتّجهات
int64 |
المجموعات التي يتم إجراء التخفيضات بينها |
channel_id
|
اختياري int64
|
معرّف قناة اختياري للتواصل بين الوحدات |
- عندما تكون
operand
مصفوفة من الصفائف، يتم تنفيذ دالة all-reduce على كل عنصر من المصفوفة. replica_groups
هي قائمة بمجموعات النُسخ المكرّرة التي يتم التخفيض بينها (يمكن استرداد معرّف النسخة المكرّرة الحالية باستخدامReplicaId
). يجب أن تكونreplica_groups
فارغة (في هذه الحالة تنتمي كل النُسخ المكرّرة إلى مجموعة واحدة)، أو أن تحتوي على العدد نفسه من العناصر مثل عدد النُسخ المكرّرة. على سبيل المثال، يُجريreplica_groups = {0, 2}, {1, 3}
عملية تقليل بين النُسخ المكرّرة0
و2
و1
و3
.- يتم استخدام
channel_id
للتواصل بين الوحدات: لا يمكن إلاall-reduce
للعمليات التي تستخدمchannel_id
نفسه التواصل مع بعضها.
يكون شكل الإخراج هو نفسه شكل الإدخال. على سبيل المثال، إذا كانت هناك نسختان
مكرّرة وكان المعامل يملك القيمة [1.0, 2.5]
و[3.0, 5.25]
على التوالي في النسختَين المكرّرتين، ستكون قيمة الإخراج من عملية التشغيل هذه وحساب
المجموع هي [4.0, 7.75]
في كلتا النسختَين المكرّرتين. إذا كان الإدخال هو
مجموعة، يكون الناتج هو مجموعة أيضًا.
تتطلّب احتساب نتيجة AllReduce
توفُّر إدخال واحد من كل نسخة،
وإذا نفَّذت نسخة واحدة عقدة AllReduce
مرّات أكثر من نسخة أخرى،
ستنتظر النسخة السابقة إلى الأبد. بما أنّ النُسخ المكرّرة جميعها تعمل على تنفيذ
البرنامج نفسه، لا تتوفّر طرق كثيرة لحدوث ذلك، ولكنّه من الممكن أن يحدث ذلك عندما
يعتمد شرط حلقة while على بيانات من الخلاصة، وتسبب البيانات التي يتمّ إدخالها
في تكرار حلقة while عدّة مرات في نسخة مكرّرة مقارنةً بأخرى.
AllToAll
يمكنك الاطّلاع أيضًا على
XlaBuilder::AllToAll
.
AllToAll هي عملية جماعية تُرسِل البيانات من جميع النوى إلى جميع النوى. وتتضمّن مرحلتين:
- مرحلة الانتشار في كل نواة، يتم تقسيم المعامل إلى
split_count
عدد من الكتل على طولsplit_dimensions
، ويتم توزيع الكتل على جميع النوى، على سبيل المثال، يتم إرسال الكتلة رقم i إلى النواة رقم i. - مرحلة الالتقاط يربط كلّ نواة الكتل المستلَمة على طول
concat_dimension
.
يمكن ضبط النوى المشارِكة من خلال:
replica_groups
: تحتوي كل مجموعة نُسخ مطابقة على قائمة بأرقام تعريف النُسخ المطابقة المشارِكة في عملية الحساب (يمكن retrieving retrieving رقم تعريف النسخة المطابقة الحالية باستخدامReplicaId
). سيتم تطبيق AllToAll داخل المجموعات الفرعية بالترتيب المحدّد. على سبيل المثال، تعنيreplica_groups = { {1,2,3}, {4,5,0} }
أنّه سيتم تطبيق AllToAll ضمن النُسخ المكرّرة{1, 2, 3}
، وفي مرحلة التجميع، سيتم تسلسل الوحدات المستلَمة بالترتيب نفسه 1 و2 و3. بعد ذلك، سيتم تطبيق AllToAll آخر ضمن النُسخ 4 و5 و0، وسيكون ترتيب التسلسل هو 4 و5 و0 أيضًا. إذا كانتreplica_groups
فارغة، تنتمي جميع النُسخ المطابقة إلى مجموعة واحدة، وذلك بترتيب التسلسل الذي تظهر به.
المتطلبات الأساسية:
- حجم سمة الم Operand في
split_dimension
قابل للقسمة علىsplit_count
. - شكل الم Operand ليس صفيفًا.
AllToAll(operand, split_dimension, concat_dimension, split_count,
replica_groups)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة إدخال من n سمة |
split_dimension
|
int64
|
قيمة في الفاصل [0,
n) تُحدِّد السمة التي يتم تقسيم الم Operand
على أساسها |
concat_dimension
|
int64
|
قيمة في الفاصل [0,
n) تُحدِّد السمة
التي يتم تجميع المربّعات المُقسّمة
بطولها |
split_count
|
int64
|
عدد النوى التي
تشارك في هذه العملية. إذا كان الحقل
replica_groups فارغًا، يجب أن يكون
هذا العدد هو عدد
النُسخ، وإلا يجب أن يكون
هذا العدد مساويًا لعدد
النُسخ في كل مجموعة. |
replica_groups
|
ReplicaGroup متّجه
|
تحتوي كل مجموعة على قائمة بأرقام تعريف النُسخ المكرّرة. |
في ما يلي مثال على Alltoall.
XlaBuilder b("alltoall");
auto x = Parameter(&b, 0, ShapeUtil::MakeShape(F32, {4, 16}), "x");
AllToAll(x, /*split_dimension=*/1, /*concat_dimension=*/0, /*split_count=*/4);
في هذا المثال، هناك 4 نوى تشارك في Alltoall. في كل نواة، يتم تقسيم المُشغِّل إلى 4 أجزاء على طول السمة 1، لذا يكون لكل جزء الشكل f32[4,4]. يتم توزيع الأجزاء الأربعة على جميع النوى. بعد ذلك، يربط كلّ نواة الأجزاء المستلَمة على طول السمة 0، بترتيب النواة 0-4. وبالتالي، يكون شكل الإخراج على كل نواة هو f32[16,4].
BatchNormGrad
اطّلِع أيضًا على
XlaBuilder::BatchNormGrad
والبحث الأصلي عن تقنية تسويّة اللقطات
للحصول على وصف مفصّل للخوارزمية.
تُحسِب هذه الدالة مشتقات معيار الدالة.
BatchNormGrad(operand, scale, mean, variance, grad_output, epsilon,
feature_index)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة ثنائية الأبعاد المطلوب توحيدها (x) |
scale |
XlaOp |
صفيف أحادي الأبعاد (\(\gamma\)) |
mean |
XlaOp |
صفيف أحادي الأبعاد (\(\mu\)) |
variance |
XlaOp |
صفيف أحادي الأبعاد (\(\sigma^2\)) |
grad_output |
XlaOp |
تم تمرير التدرجات إلى BatchNormTraining (\(\nabla y\)) |
epsilon |
float |
قيمة Epsilon (\(\epsilon\)) |
feature_index |
int64 |
فهرس سمة الميزة في operand |
لكلّ سمة في سمة العنصر (feature_index
هو فهرس سمة العنصر في operand
)، تحتسِب العملية التدرّجات المتعلّقةoperand
وoffset
وscale
في جميع السمات الأخرى. يجب أن يكون
feature_index
فهرسًا صالحًا لسمة العنصر في operand
.
يتم تعريف التدرجات الثلاثة باستخدام الصيغ التالية (على افتراض أنّه
يتم استخدام صفيف من 4 أبعاد على النحو operand
مع فهرس سمة السمة l
وحجم
الدفعة m
والأحجام المكانية w
وh
):
\[ \begin{split} c_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sigma^2_l+\epsilon} \right) \\\\ d_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \\\\ \nabla x_{ijkl} &= \frac{\gamma_{l} }{\sqrt{\sigma^2_{l}+\epsilon} } \left( \nabla y_{ijkl} - d_l - c_l (x_{ijkl} - \mu_{l}) \right) \\\\ \nabla \gamma_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sqrt{\sigma^2_{l}+\epsilon} } \right) \\\\\ \nabla \beta_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \end{split} \]
تمثل المدخلات mean
وvariance
قيم اللحظات على مستوى السمتَين
المجمّعة والمكانية.
نوع الإخراج هو مجموعة من ثلاثة أسماء معرِّفة:
النواتج | النوع | الدلالات |
---|---|---|
grad_operand
|
XlaOp
|
التدرّج بالنسبة إلى الإدخال operand ($\nabla
x$) |
grad_scale
|
XlaOp
|
التدرّج بالنسبة إلى الإدخال scale ($\nabla
\gamma$) |
grad_offset
|
XlaOp
|
التدرّج بالنسبة إلى المدخل offset ($\nabla
\beta$) |
BatchNormInference
اطّلِع أيضًا على
XlaBuilder::BatchNormInference
والبحث الأصلي عن تقنية تسويّة اللقطات
للحصول على وصف مفصّل للخوارزمية.
تسويف صفيف على مستوى السمات المكانية والدفعة
BatchNormInference(operand, scale, offset, mean, variance, epsilon,
feature_index)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من n سمة ليتم تسويته |
scale |
XlaOp |
صفيف أحادي الأبعاد |
offset |
XlaOp |
صفيف أحادي الأبعاد |
mean |
XlaOp |
صفيف أحادي الأبعاد |
variance |
XlaOp |
صفيف أحادي الأبعاد |
epsilon |
float |
قيمة Epsilon |
feature_index |
int64 |
فهرس سمة الميزة في operand |
لكلّ ميزة في سمة الميزة (feature_index
هو فهرس سمة الميزة في operand
)، تحتسِب العملية المتوسط والتباين
على مستوى جميع السمات الأخرى، وتستخدِم المتوسط والتباين لتسويه كلّ
عنصر في operand
. يجب أن يكون feature_index
فهرسًا صالحًا لسمة
السمة في operand
.
BatchNormInference
مكافئة لاستدعاء BatchNormTraining
بدون حساب mean
وvariance
لكل دفعة. ويستخدم الإدخال mean
و
variance
بدلاً من ذلك كقيم مقدَّرة. يهدف هذا الإجراء إلى تقليل
وقت الاستجابة في الاستنتاج، ومن هنا جاء اسم BatchNormInference
.
الناتج هو صفيف منتظم ذي n سمة بالشكل نفسه للصفيف المُدخل
operand
.
BatchNormTraining
يمكنك أيضًا الاطّلاع على
XlaBuilder::BatchNormTraining
وthe original batch normalization paper
للاطّلاع على وصف تفصيلي للخوارزمية.
تسويف صفيف على مستوى السمات المكانية والدفعة
BatchNormTraining(operand, scale, offset, epsilon, feature_index)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة ثنائية الأبعاد المطلوب توحيدها (x) |
scale |
XlaOp |
صفيف أحادي الأبعاد (\(\gamma\)) |
offset |
XlaOp |
صفيف أحادي الأبعاد (\(\beta\)) |
epsilon |
float |
قيمة Epsilon (\(\epsilon\)) |
feature_index |
int64 |
فهرس سمة الميزة في operand |
لكلّ ميزة في سمة الميزة (feature_index
هو فهرس سمة الميزة في operand
)، تحتسِب العملية المتوسط والتباين
على مستوى جميع السمات الأخرى، وتستخدِم المتوسط والتباين لتسويه كلّ
عنصر في operand
. يجب أن يكون feature_index
فهرسًا صالحًا لسمة
السمة في operand
.
تُنفَّذ الخوارزمية على النحو التالي لكل دفعة في operand
\(x\) التي تحتوي على m
عناصر مع w
وh
كحجم للأبعاد المكانية (على افتراض أنّ operand
هي صفيف من 4 أبعاد):
تُحتسب قيمة متوسط المجموعة \(\mu_l\) لكلّ سمة
l
في سمة السمة: \(\mu_l=\frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h x_{ijkl}\)احتساب التباين في المجموعة \(\sigma^2_l\): $\sigma^2l=\frac{1}{mwh}\sum{i=1}^m\sum{j=1}^w\sum{k=1}^h (x_{ijkl} - \mu_l)^2$
تسويتها وتحويلها إلى مقاييس وتغييرها: \(y_{ijkl}=\frac{\gamma_l(x_{ijkl}-\mu_l)}{\sqrt[2]{\sigma^2_l+\epsilon} }+\beta_l\)
تتم إضافة قيمة epsilon، وهي عادةً رقم صغير، لتجنُّب أخطاء القسمة على صفر.
نوع الإخراج هو مجموعة من ثلاثة XlaOp
:
النواتج | النوع | الدلالات |
---|---|---|
output
|
XlaOp
|
مصفوفة من n سمة بالشكل نفسه للإدخال
operand (y) |
batch_mean |
XlaOp |
صفيف أحادي الأبعاد (\(\mu\)) |
batch_var |
XlaOp |
صفيف أحادي الأبعاد (\(\sigma^2\)) |
batch_mean
وbatch_var
هما لحظتان يتم احتسابهما على مستوى السمتَين "الدفعة" و
"المسافة" باستخدام الصيغ أعلاه.
BitcastConvertType
يمكنك الاطّلاع أيضًا على
XlaBuilder::BitcastConvertType
.
على غرار tf.bitcast
في TensorFlow، تُنفِّذ عملية تحويل ثنائي برمجيًا
على مستوى العنصر من شكل بيانات إلى شكل مستهدَف. يجب أن يكون حجم الإدخال والإخراج متطابقًا: على سبيل المثال، تصبح عناصر s32
عناصر f32
من خلال إجراء تحويل الوحدات، وسيصبح عنصر
s32
واحدًا أربعة عناصر s8
. يتم تنفيذ Bitcast كتحويل
أدنى مستوى، لذا فإنّ الأجهزة التي تستخدم طرقًا مختلفة لتمثيل الأرقام الكسورية ستقدّم بدورها نتائج مختلفة.
BitcastConvertType(operand, new_element_type)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من النوع T مع سمات D |
new_element_type |
PrimitiveType |
النوع U |
يجب أن تتطابق أبعاد الم Operand والشكل المستهدَف، باستثناء السمة الأخيرة التي ستتغيّر حسب نسبة الحجم الأساسي قبل وبعد التحويل.
يجب ألا تكون أنواع عناصر المصدر والوجهة مجموعات ثنائية.
تحويل Bitcast إلى نوع بدائي بعرض مختلف
BitcastConvert
تتيح تعليمات HLO الحالة التي لا يكون فيها حجم نوع T'
العنصر الناتج مساويًا لحجم عنصر الإدخال T
. بما أنّ العملية
الكاملة هي عملية بث بتات من الناحية النظرية ولا تغيّر وحدات البت الأساسية، يجب تغيير شكل عنصر الإخراج. بالنسبة إلى B = sizeof(T), B' =
sizeof(T')
، هناك حالتان محتملتان.
أولاً، عندما يكون B > B'
، يحصل شكل الإخراج على أصغر بعد جديد بحجم
B/B'
. على سبيل المثال:
f16[10,2]{1,0} %output = f16[10,2]{1,0} bitcast-convert(f32[10]{0} %input)
تظلّ القاعدة كما هي بالنسبة إلى القيم الكلية الفعّالة:
f16[2]{0} %output = f16[2]{0} bitcast-convert(f32[] %input)
بدلاً من ذلك، بالنسبة إلى B' > B
، يتطلب الإجراء أن تكون السمة المنطقية الأخيرة
لشكل الإدخال مساوية لـ B'/B
، ويتم حذف هذه السمة أثناء
التحويل:
f32[10]{0} %output = f32[10]{0} bitcast-convert(f16[10,2]{1,0} %input)
يُرجى العلم أنّ عمليات التحويل بين عروض البت المختلفة لا تتم على مستوى العنصر.
البث
يمكنك الاطّلاع أيضًا على
XlaBuilder::Broadcast
.
تضيف السمات إلى صفيف من خلال تكرار البيانات في الصفيف.
Broadcast(operand, broadcast_sizes)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
الصفيف المطلوب تكراره |
broadcast_sizes |
ArraySlice<int64> |
أحجام السمات الجديدة |
يتم إدراج السمات الجديدة على يمين العنصر، أي إذا كان broadcast_sizes
يحتوي على
قيم {a0, ..., aN}
وكان شكل المعامل يحتوي على سمات {b0, ..., bM}
، عندئذٍ
يحتوي شكل الإخراج على سمات {a0, ..., aN, b0, ..., bM}
.
فهرس السمات الجديدة في نُسخ من الم Operand، أي
output[i0, ..., iN, j0, ..., jM] = operand[j0, ..., jM]
على سبيل المثال، إذا كان operand
عددًا قياسيًا f32
بقيمة 2.0f
، وكان
broadcast_sizes
هو {2, 3}
، ستكون النتيجة صفيفًا بالتنسيق
f32[2, 3]
وستكون كل القيم في النتيجة هي 2.0f
.
BroadcastInDim
يمكنك الاطّلاع أيضًا على
XlaBuilder::BroadcastInDim
.
تُوسّع هذه الدالة حجم الصفيف وعدد أبعاده عن طريق تكرار البيانات في الصفيف.
BroadcastInDim(operand, out_dim_size, broadcast_dimensions)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
الصفيف المطلوب تكراره |
out_dim_size |
ArraySlice<int64> |
أحجام أبعاد الشكل المستهدَف |
broadcast_dimensions |
ArraySlice<int64> |
السمة في الشكل المستهدَف التي تتطابق مع كل سمة من سمات شكل الم Operand |
يشبه "البث"، ولكنه يسمح بإضافة سمات في أي مكان وتوسيع السمات الحالية التي يبلغ حجمها 1.
يتم بث operand
إلى الشكل الموضّح في out_dim_size
.
تُعرِض broadcast_dimensions
سمات operand
إلى سمات
الشكل المستهدَف، أي أنّه يتم ربط السمة i من الم Operand بالسمة
broadcast_dimension[i] من شكل الإخراج. يجب أن تكون سمات
operand
بحجم 1 أو أن تكون بالحجم نفسه للسمة في شكل المخرج
الذي تتمّ ربطها به. يتم ملء السمات المتبقية بسمات
بحجم 1. بعد ذلك، يتمّ بثّ السمات المتدهورة على طول هذه السمات
المتدهورة للوصول إلى شكل الإخراج. يتم وصف الدلالات بالتفصيل في
صفحة البث.
الاتصال
يمكنك الاطّلاع أيضًا على
XlaBuilder::Call
.
تستدعي عملية حسابية باستخدام الوسيطات المحدّدة.
Call(computation, args...)
الوسيطات | النوع | الدلالات |
---|---|---|
computation |
XlaComputation |
حساب من النوع T_0, T_1, ..., T_{N-1} -> S مع N مَعلمة من نوع عشوائي |
args |
تسلسل N XlaOp |
عدد N من الوسيطات من النوع العشوائي |
يجب أن تتطابق عدد مَعلمات args
وأنواعها مع مَعلمات
computation
. يُسمح بعدم توفّر args
.
CompositeCall
يمكنك الاطّلاع أيضًا على
XlaBuilder::CompositeCall
.
تُغلِّف عملية مكوّنة من عمليات StableHLO أخرى، ويأخذ العنصر مدخلات وcomposite_attributes وينتج نتائج. يتم تنفيذ دلالات العملية من خلال سمة التحليل. يمكن استبدال العملية المركبة بتحليلها بدون تغيير دلالات البرنامج. في الحالات التي لا يوفّر فيها تضمين عملية التقسيم دلالات العملية نفسها، يُفضّل استخدام custom_call.
يُستخدَم حقل الإصدار (القيمة التلقائية هي 0) للإشارة إلى الحالات التي تتغيّر فيها دلالات العنصر المركب.
يتم تنفيذ هذه العملية على أنّها kCall
مع السمة is_composite=true
. يتم تحديد الحقل
decomposition
باستخدام السمة computation
. تخزِّن سمات واجهة المستخدم
السمات المتبقية التي تبدأ بالبادئة composite.
.
مثال على عملية CompositeCall:
f32[] call(f32[] %cst), to_apply=%computation, is_composite=true,
frontend_attributes = {
composite.name="foo.bar",
composite.attributes={n = 1 : i32, tensor = dense<1> : tensor<i32>},
composite.version="1"
}
Call(computation, args..., name, composite_attributes, version)
الوسيطات | النوع | الدلالات |
---|---|---|
inputs |
XlaOp |
عدد متغيّر من القيم |
name |
string |
اسم المكوّن المُركّب |
composite_attributes |
اختياري string |
معجم اختياري لسمات منسقة في سلسلة |
decomposition |
XlaComputation |
حساب من النوع T_0, T_1, ..., T_{N-1} -> S مع N مَعلمة من نوع عشوائي |
version |
int64 . |
تحديثات من رقم إلى إصدار لدلالات العملية المركبة |
Cholesky
يمكنك الاطّلاع أيضًا على
XlaBuilder::Cholesky
.
تُحتسب تحليلة كولشيك لمجموعة من المصفوفات الإيجابية التحديد المتماثلة (هيرميتية).
Cholesky(a, lower)
الوسيطات | النوع | الدلالات |
---|---|---|
a |
XlaOp |
مصفوفة من النوع المركب أو النوع الكسري العشري مع أكثر من بُعدَين |
lower |
bool |
ما إذا كنت تريد استخدام المثلث العلوي أو السفلي من a |
إذا كان lower
هو true
، يتم احتساب المصفوفات الثلاثية السفلية l
بحيث يكون a = l .
l^T$. إذا كان lower
هو false
، يتم احتساب المصفوفات الثلاثية العلوية u
بحيث
\(a = u^T . u\).
لا تتم قراءة بيانات الإدخال إلا من المثلث السفلي/العلوي من a
، استنادًا إلى
قيمة lower
. ويتم تجاهل القيم من المثلث الآخر. يتم عرض بيانات الإخراج
في المثلث نفسه، أما القيم في المثلث الآخر فتكون
محددة من خلال التنفيذ ويمكن أن تكون أيّ شيء.
إذا كان a
يتضمّن أكثر من سمتَين، يتم التعامل مع a
على أنّه مجموعة من المصفوفات،
حيث تكون جميع السمتَين الثانويتَين باستثناء السمتَين الرئيسيتَين هما سمتَا المجموعة.
إذا لم تكن المصفوفة a
متماثلة (هيرميتية) موجبة محددة، تكون النتيجة
محددة من التنفيذ.
عقدة تقييد القيم
يمكنك الاطّلاع أيضًا على
XlaBuilder::Clamp
.
تحصر عاملًا ضمن النطاق بين الحد الأدنى والحد الأقصى.
Clamp(min, operand, max)
الوسيطات | النوع | الدلالات |
---|---|---|
min |
XlaOp |
صفيف من النوع T |
operand |
XlaOp |
صفيف من النوع T |
max |
XlaOp |
صفيف من النوع T |
تُعطى الدالة معاملًا والحد الأدنى والحد الأقصى، وتُعرِض المعامل إذا كان في
النطاق بين الحد الأدنى والحد الأقصى، أو تعرِض الحد الأدنى إذا كان
المعامل أقل من هذا النطاق أو الحد الأقصى إذا كان المعامل أعلى من
هذا النطاق. أي clamp(a, x, b) = min(max(a, x), b)
.
يجب أن تكون جميع المصفوفات الثلاث بالشكل نفسه. بدلاً من ذلك، يمكن أن يكون min
و/أو max
متغيّرًا متسلسلًا من النوع T
، وذلك لأنّه شكل محظور من
البث.
مثال على الكميتين min
وmax
:
let operand: s32[3] = {-1, 5, 9};
let min: s32 = 0;
let max: s32 = 6;
==>
Clamp(min, operand, max) = s32[3]{0, 5, 6};
تصغير
راجِع أيضًا
XlaBuilder::Collapse
وعملية tf.reshape
.
تُدمج أبعاد الصفيف في سمة واحدة.
Collapse(operand, dimensions)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من النوع T |
dimensions |
int64 متّجه |
مجموعة فرعية متسلسلة بترتيب معيّن من سمات T |
تستبدِل دالة "التجميع" المجموعة الفرعية المحدّدة من سمات الم Operand بسمة واحدة. وسيطات الإدخال هي صفيف عشوائي من النوع T وأحد
المتجهات الثابتة في وقت الترجمة لفهارس السمات. يجب أن تكون فهارس السمات
مجموعة فرعية متسلسلة من سمات T
بترتيب تصاعدي (من الأرقام الأقل إلى الأرقام الأعلى للسمات). وبالتالي، فإنّ {0, 1, 2} أو {0, 1} أو {1, 2} هي مجموعات سمات صالحة، ولكن
{1, 0} أو {0, 2} ليست كذلك. ويتم استبدالها بسمة جديدة واحدة في
الموضع نفسه في تسلسل السمات الذي تحلّ محلّه، مع حجم السمة
الجديدة يساوي حاصل ضرب أحجام السمات الأصلية. إنّ الرقم الأصغر
للسمة في dimensions
هو السمة التي تتغيّر ببطء أكبر (الأكثر أهمية)
في تداخل الحلقات الذي يدمج هذه السمات، والرقم الأعلى
للسمة هو السمة التي تتغيّر بسرعة أكبر (الأكثر ثانوية). اطّلِع على عامل التشغيل tf.reshape
إذا كنت بحاجة إلى مزيد من
ترتيب التجميع العام.
على سبيل المثال، لنفترض أنّ v هي مصفوفة من 24 عنصرًا:
let v = f32[4x2x3] { { {10, 11, 12}, {15, 16, 17} },
{ {20, 21, 22}, {25, 26, 27} },
{ {30, 31, 32}, {35, 36, 37} },
{ {40, 41, 42}, {45, 46, 47} } };
// Collapse to a single dimension, leaving one dimension.
let v012 = Collapse(v, {0,1,2});
then v012 == f32[24] {10, 11, 12, 15, 16, 17,
20, 21, 22, 25, 26, 27,
30, 31, 32, 35, 36, 37,
40, 41, 42, 45, 46, 47};
// Collapse the two lower dimensions, leaving two dimensions.
let v01 = Collapse(v, {0,1});
then v01 == f32[4x6] { {10, 11, 12, 15, 16, 17},
{20, 21, 22, 25, 26, 27},
{30, 31, 32, 35, 36, 37},
{40, 41, 42, 45, 46, 47} };
// Collapse the two higher dimensions, leaving two dimensions.
let v12 = Collapse(v, {1,2});
then v12 == f32[8x3] { {10, 11, 12},
{15, 16, 17},
{20, 21, 22},
{25, 26, 27},
{30, 31, 32},
{35, 36, 37},
{40, 41, 42},
{45, 46, 47} };
CollectivePermute
يمكنك الاطّلاع أيضًا على
XlaBuilder::CollectivePermute
.
CollectivePermute هي عملية جماعية تُرسِل البيانات وتتلقّاها على مستوى النُسخ.
CollectivePermute(operand, source_target_pairs)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة إدخال من n سمة |
source_target_pairs |
<int64, int64> متّجه |
قائمة بأزواج (source_replica_id, target_replica_id) بالنسبة إلى كل زوج، يتم إرسال المُعامِل من النسخة المكرّرة للمصدر إلى النسخة المكرّرة للهدف. |
يُرجى العلم أنّ هناك القيود التالية على source_target_pair
:
- يجب ألا يتضمّن أي زوجَين معرّف النسخة المستهدفة نفسه، ويجب ألا يتضمّنَا معرّف النسخة المصدر نفسه.
- إذا لم يكن معرّف النسخة المتماثلة هدفًا في أيّ زوج، يكون الناتج في تلك النسخة المتماثلة هو مصفوفة تتكون من أصفار بالشكل نفسه للدخل.
دمج
يمكنك الاطّلاع أيضًا على
XlaBuilder::ConcatInDim
.
يُنشئ Concatenate صفيفًا من عوامل صفيف متعددة. تحتوي المصفوفة على العدد نفسه من السمات مثل كل من عناصر مصفوفة الإدخال (التي يجب أن تحتوي على العدد نفسه من السمات مثل بعضها) وتحتوي على الوسيطات في الترتيب الذي تم تحديده.
Concatenate(operands..., dimension)
الوسيطات | النوع | الدلالات |
---|---|---|
operands |
تسلسل N XlaOp |
صفائف N من النوع T ذات الأبعاد [L0, L1, ...]. يجب أن تكون N >= 1. |
dimension |
int64 |
قيمة في النطاق [0, N) تُحدِّد اسم السمة التي سيتم تسلسلها بين operands |
باستثناء dimension
، يجب أن تكون جميع السمات متطابقة. ويعود سبب ذلك
إلى أنّ XLA لا تتيح استخدام صفائف "مجزّأة". يُرجى العلم أيضًا أنّه لا يمكن تسلسل قيم 0 سمة (لأنّه من المستحيل تسمية السمة التي يتم التسلسل على طولها).
مثال أحادي الأبعاد:
Concat({ {2, 3}, {4, 5}, {6, 7} }, 0)
>>> {2, 3, 4, 5, 6, 7}
مثال على القياس ثنائي الأبعاد:
let a = {
{1, 2},
{3, 4},
{5, 6},
};
let b = {
{7, 8},
};
Concat({a, b}, 0)
>>> {
{1, 2},
{3, 4},
{5, 6},
{7, 8},
}
المخطّط:
الجملة الشرطية
يمكنك الاطّلاع أيضًا على
XlaBuilder::Conditional
.
Conditional(pred, true_operand, true_computation, false_operand,
false_computation)
الوسيطات | النوع | الدلالات |
---|---|---|
pred |
XlaOp |
عدد صحيح من النوع PRED |
true_operand |
XlaOp |
وسيطة من النوع \(T_0\) |
true_computation |
XlaComputation |
XlaComputation من النوع \(T_0 \to S\) |
false_operand |
XlaOp |
وسيطة من النوع \(T_1\) |
false_computation |
XlaComputation |
XlaComputation من النوع \(T_1 \to S\) |
تُنفِّذ true_computation
إذا كانت pred
هي true
، وfalse_computation
إذا كانت pred
هي false
، وتعرض النتيجة.
يجب أن تأخذ الدالة true_computation
وسيطة واحدة من النوع \(T_0\) ، وسيتم
استدعاؤها باستخدام true_operand
الذي يجب أن يكون من النوع نفسه. يجب أن تأخذ الدالة
false_computation
وسيطة واحدة من النوع \(T_1\) ، وسيتم
استدعاؤها باستخدام false_operand
الذي يجب أن يكون من النوع نفسه. يجب أن يكون نوع
القيمة المعروضة لكل من true_computation
وfalse_computation
متطابقًا.
يُرجى العِلم أنّه سيتم تنفيذ أحد الإجراءَين true_computation
وfalse_computation
فقط
استنادًا إلى قيمة pred
.
Conditional(branch_index, branch_computations, branch_operands)
الوسيطات | النوع | الدلالات |
---|---|---|
branch_index |
XlaOp |
عدد صحيح من النوع S32 |
branch_computations |
تسلسل N XlaComputation |
XlaComputations من النوع \(T_0 \to S , T_1 \to S , ..., T_{N-1} \to S\) |
branch_operands |
تسلسل N XlaOp |
الوسيطات من النوع \(T_0 , T_1 , ..., T_{N-1}\) |
تنفيذ branch_computations[branch_index]
وعرض النتيجة إذا كان
branch_index
هو S32
أصغر من 0 أو أكبر من أو يساوي N، يتم تنفيذbranch_computations[N-1]
كالفرع التلقائي.
يجب أن يقبل كل branch_computations[b]
وسيطة واحدة من النوع \(T_b\) ، و
سيتم استدعاؤه باستخدام branch_operands[b]
الذي يجب أن يكون من النوع نفسه. يجب أن يكون
نوع القيمة المعروضة لكل branch_computations[b]
متطابقًا.
يُرجى العِلم أنّه سيتم تنفيذ إجراء واحد فقط من branch_computations
استنادًا إلى
قيمة branch_index
.
Conv (التفاف)
يمكنك الاطّلاع أيضًا على
XlaBuilder::Conv
.
مثل ConvWithGeneralPadding، ولكن يتم تحديد الحشو بطريقة مختصرة على النحو التالي:
سواء كان SAME أو VALID. تعمل إضافة SAME على إضافة أصفار إلى الإدخال (lhs
) لكي يكون شكل الإخراج مماثلاً لشكل الإدخال في حال عدم مراعاة الخطوات. يعني وضع الحشو الصالح ببساطة عدم وضع حشو.
ConvWithGeneralPadding (التفاف)
يمكنك الاطّلاع أيضًا على
XlaBuilder::ConvWithGeneralPadding
.
تُحسِّب عملية تلافيف من النوع المستخدَم في الشبكات العصبية. في ما يلي، يمكن اعتبار عملية التفاف كنافذة متعددة الأبعاد تتحرك عبر منطقة قاعدة متعددة الأبعاد ويتم إجراء عملية حسابية لكل موضع ممكن للنافذة.
الوسيطات | النوع | الدلالات |
---|---|---|
lhs |
XlaOp |
صفيف من الإدخالات ببعد (n+2) |
rhs |
XlaOp |
صفيف من الأبعاد (n+2) لأوزان النواة |
window_strides |
ArraySlice<int64> |
مصفوفة ثنائية الأبعاد لخطوات النواة |
padding |
ArraySlice< pair<int64,int64>> |
صفيف n-d من الحشو (low, high) |
lhs_dilation |
ArraySlice<int64> |
صفيف عامل تمدد lhs ذي الأبعاد n |
rhs_dilation |
ArraySlice<int64> |
صفيف عامل تمدد يسار الجملة ببعد n |
feature_group_count |
int64 | عدد مجموعات الميزات |
batch_group_count |
int64 | عدد مجموعات الدفعات |
لنفترض أنّ n هو عدد السمات المكانية. وسيطة lhs
هي صفيف
ببعد (n+2) يصف المنطقة الأساسية. يُعرف هذا باسم الإدخال،
على الرغم من أنّ الجانب الأيمن هو إدخال أيضًا. في الشبكة العصبية، هذه هي
عمليات تنشيط الإدخال. في ما يلي السمات n+2 بالترتيب التالي:
batch
: يمثّل كل إحداثي في هذه السمة إدخالًا مستقلاً يتم إجراء عملية التفاف عليه.z/depth/features
: يرتبط بكل موضع (y,x) في المنطقة الأساسية متجه ، والذي يدخل في هذه السمة.-
spatial_dims
: تصف السمات المكانيةn
التي تحدّد المنطقة الأساسية التي تتحرّك فيها النافذة.
الوسيطة rhs
هي صفيف من (n+2) سمة يصف ملف التمويه/النواة/النافذة. وتكون السمات على النحو التالي:
-
output-z
: سمةz
للناتج input-z
: يجب أن يساوي حجم هذه السمة مضروبًا فيfeature_group_count
حجم سمةz
في lhs.spatial_dims
: تصف السمةn
الأبعاد المكانية التي تحدّد النافذة n-d التي تتحرّك في جميع أنحاء المنطقة الأساسية.
تحدِّد الوسيطة window_strides
خطوة نافذة الالتفاف
في السمات المكانية. على سبيل المثال، إذا كانت الخطوة في السمة المكانية الأولى هي 3، لا يمكن وضع النافذة إلا عند الإحداثيات التي يكون فيها الفهرس المكاني الأول قابلاً للقسمة على 3.
تحدِّد الوسيطة padding
مقدار الحشو بالصفر الذي سيتم تطبيقه على
المساحة الأساسية. يمكن أن تكون قيمة الحشو سالبة، وتشير القيمة المطلقة للحشو السالب إلى عدد العناصر التي يجب إزالتها من السمة المحدّدة قبل إجراء عملية التفاف. padding[0]
تحدّد الحشو لسمة y
وpadding[1]
تحدّد الحشو لسمة x
. يتضمّن كل
زوج الحشو المنخفض كأول عنصر والحشو العالي كثاني
عنصر. يتم تطبيق الحشو المنخفض في اتجاه الفواصل الدنيا بينما يتم تطبيق الحشو المُرتفع في اتجاه الفواصل الأعلى. على سبيل المثال، إذا كان
padding[1]
يساوي (2,3)
، سيتمّ إضافة صفرَين على يمين العنصر و
ثلاثة أصفار على يساره في السمة المكانية الثانية. إنّ استخدام الحشو هو
معادل لإدخال قيم الصفر نفسها في الإدخال (lhs
) قبل
إجراء عملية التفاف.
تحدّد وسيطتا lhs_dilation
وrhs_dilation
عامل التمدد الذي
يتم تطبيقه على lhs وrhs على التوالي في كلّ سمة مكانية. إذا كان عامل التمدد في سمة مكانية هو d، يتم تلقائيًا وضع d-1 من الفتحات بين كل إدخال في تلك السمة، ما يؤدي إلى زيادة حجم الصفيف. يتم ملء الفراغات بقيمة لا تؤدي إلى أيّ إجراء، ويعني ذلك بالنسبة إلى تصفية المُركّب
الأصفار.
يُعرف تمدد الجانب الأيمن من المعادلة أيضًا باسم "التفاف atrous". لمزيد من التفاصيل، يُرجى الاطّلاع على tf.nn.atrous_conv2d
. ويُعرف تمدد الجانب الأيسر من المعادلة أيضًا باسم
التفاف المُعاد. لمزيد من التفاصيل، يُرجى الاطّلاع على tf.nn.conv2d_transpose
.
يمكن استخدام الوسيطة feature_group_count
(القيمة التلقائية 1) للعمليات المتعلّقة بالالتفاف المُجمَّع. يجب أن يكون feature_group_count
مقسومًا لكل من سمة الإدخال
وسمة الإخراج. إذا كانت قيمة feature_group_count
أكبر من 1،
يعني ذلك أنّه من الناحية المفهومية، يتم تقسيم سمة المدخلات والسمات الناتجة rhs
وسمة الناتجة بالتساوي إلى العديد من feature_group_count
المجموعات، وتتألف كل مجموعة من تسلسل فرعي متتالي من السمات. يجب أن تكون سمة
سمة ميزة الإدخال rhs
مساوية لسمة
سمة ميزة الإدخال lhs
مقسومة على feature_group_count
(كي يكون لها حجم
مجموعة من ميزات الإدخال). تُستخدَم المجموعات i معًا لاحتساب
feature_group_count
للعديد من عمليات التفاف الصور المنفصلة. يتم تسلسل نتائج
عمليات الدمج هذه معًا في سمة ميزة الإخراج.
بالنسبة إلى الالتفاف المتعمّق، سيتم ضبط الوسيطة feature_group_count
على
سمة ميزة الإدخال، وسيتم إعادة تشكيل الفلتر من
[filter_height, filter_width, in_channels, channel_multiplier]
إلى
[filter_height, filter_width, 1, in_channels * channel_multiplier]
. لمزيد من
التفاصيل، يُرجى الاطّلاع على tf.nn.depthwise_conv2d
.
يمكن استخدام الوسيطة batch_group_count
(القيمة التلقائية 1) للفلاتر
المجمّعة أثناء الانتشار العكسي. يجب أن يكون batch_group_count
مقسومًا لقياس
حجم سمة الحزمة lhs
(الإدخال). إذا كانت قيمة batch_group_count
أكبر
من 1، يعني ذلك أنّ سمة مجموعة الأركان الأساسية للإخراج يجب أن تكون بحجم input batch
/ batch_group_count
. يجب أن يكون batch_group_count
مقسومًا لحجم
العنصر الناتج.
يتضمّن شكل الإخراج السمات التالية بالترتيب التالي:
batch
: يجب أن يساوي حجم هذه السمة مضروبًا فيbatch_group_count
حجم سمةbatch
في lhs.z
: الحجم نفسه لسمةoutput-z
في النواة (rhs
).spatial_dims
: قيمة واحدة لكل موضع صالح للنافذة التدرّجية.
يوضّح الشكل أعلاه طريقة عمل الحقل batch_group_count
. في الواقع، ننقسم
كل دفعة من lhs إلى batch_group_count
مجموعة، وننفّذ الإجراء نفسه ل
ميزات الإخراج. بعد ذلك، نُجري عمليات تصفية ثنائية لكلّ من هذه المجموعات ونقوم
بدمجها معًا على طول سمة الإخراج. تظلّ الدلالات
التشغيلية لجميع السمات الأخرى (السمات المتعلّقة بالسمات والمكان) كما هي.
يتم تحديد مواضع النافذة التجميعية الصالحة من خلال الخطوات وحجم المنطقة الأساسية بعد الحشو.
لوصف ما تفعله عملية التفاف، نأخذ عملية التفاف ثنائية الأبعاد ونختار بعض
إحداثيات batch
وz
وy
وx
ثابتة في الإخراج. و(y,x)
هو
موضع أحد أركان النافذة ضمن منطقة القاعدة (مثلاً، (y,x)
هو
العلوي الأيمن، استنادًا إلى كيفية تفسيرك للأبعاد المكانية). لدينا الآن نافذة
ثنائية الأبعاد، تم أخذها من منطقة القاعدة، حيث تكون كل نقطة ثنائية الأبعاد مرتبطة بأحد vektors
الأحادي الأبعاد، وبالتالي نحصل على مربّع ثلاثي الأبعاد. من نواة الالتفاف، بما أنّنا ثبّتنا
إحداثي الإخراج z
، لدينا أيضًا مربّع ثلاثي الأبعاد. يتضمّن المربّعَان
السمات نفسها، لذا يمكننا الحصول على مجموع حاصل ضرب كل عنصر في المربّعَين (على غرار حاصل الضرب النقطي). هذه هي قيمة الإخراج.
يُرجى العلم أنّه إذا كان output-z
هو مثلاً، 5، ثمّ ينتج كل موضع من النافذة 5
قيم في الناتج في سمة z
من الناتج. تختلف هذه القيم
حسب الجزء المستخدَم من نواة التفاف - هناك مربّع ثلاثي الأبعاد من
القيم المستخدَمة لكل إحداثي output-z
. وبالتالي، يمكنك اعتبارها 5
عمليات تلافيف منفصلة باستخدام فلتر مختلف لكل منها.
في ما يلي رمز زائف لدمج ثنائي الأبعاد مع الحشو والخطوات:
for (b, oz, oy, ox) { // output coordinates
value = 0;
for (iz, ky, kx) { // kernel coordinates and input z
iy = oy*stride_y + ky - pad_low_y;
ix = ox*stride_x + kx - pad_low_x;
if ((iy, ix) inside the base area considered without padding) {
value += input(b, iz, iy, ix) * kernel(oz, iz, ky, kx);
}
}
output(b, oz, oy, ox) = value;
}
ConvertElementType
يمكنك الاطّلاع أيضًا على
XlaBuilder::ConvertElementType
.
على غرار static_cast
على مستوى العنصر في C++، تُجري عملية تحويل على مستوى العنصر
من شكل بيانات إلى شكل مستهدَف. يجب أن تتم مطابقة السمات، ويكون التحويل على مستوى العنصر، على سبيل المثال، تصبح عناصر s32
عناصر f32
من خلال إجراء تحويل s32
إلى f32
.
ConvertElementType(operand, new_element_type)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من النوع T مع سمات D |
new_element_type |
PrimitiveType |
النوع U |
يجب أن تتطابق أبعاد الم Operand وشكل الهدف. يجب ألا تكون أنواع عنصرَي المصدر والوجهة مجموعات ثنائية.
سيؤدي تحويل مثل T=s32
إلى U=f32
إلى تنفيذ روتين تحويل عدد صحيح إلى عدد عشري
عادي، مثل التقريب إلى أقرب عدد صحيح زوجي.
let a: s32[3] = {0, 1, 2};
let b: f32[3] = convert(a, f32);
then b == f32[3]{0.0, 1.0, 2.0}
CrossReplicaSum
تُجري AllReduce
عملية حسابية للجمع.
CustomCall
يمكنك الاطّلاع أيضًا على
XlaBuilder::CustomCall
.
استدعاء دالة يقدّمها المستخدم ضمن عملية حسابية
CustomCall(target_name, args..., shape)
الوسيطات | النوع | الدلالات |
---|---|---|
target_name |
string |
اسم الدالة سيتمّ إصدار تعليمات اتصال تستهدف اسم الرمز هذا. |
args |
تسلسل N XlaOp |
وسيطات N من النوع العشوائي، والتي سيتم تمريرها إلى الدالة |
shape |
Shape |
شكل ناتج الدالة |
يكون توقيع الدالة هو نفسه، بغض النظر عن عدد المَعلمات أو نوعها:
extern "C" void target_name(void* out, void** in);
على سبيل المثال، إذا تم استخدام CustomCall على النحو التالي:
let x = f32[2] {1,2};
let y = f32[2x3] { {10, 20, 30}, {40, 50, 60} };
CustomCall("myfunc", {x, y}, f32[3x3])
في ما يلي مثال على تنفيذ myfunc
:
extern "C" void myfunc(void* out, void** in) {
float (&x)[2] = *static_cast<float(*)[2]>(in[0]);
float (&y)[2][3] = *static_cast<float(*)[2][3]>(in[1]);
EXPECT_EQ(1, x[0]);
EXPECT_EQ(2, x[1]);
EXPECT_EQ(10, y[0][0]);
EXPECT_EQ(20, y[0][1]);
EXPECT_EQ(30, y[0][2]);
EXPECT_EQ(40, y[1][0]);
EXPECT_EQ(50, y[1][1]);
EXPECT_EQ(60, y[1][2]);
float (&z)[3][3] = *static_cast<float(*)[3][3]>(out);
z[0][0] = x[1] + y[1][0];
// ...
}
يجب ألا يكون للدالة المقدَّمة من المستخدِم أيّ تأثيرات جانبية، ويجب أن يكون تنفيذها معادلًا.
نقطة
يمكنك الاطّلاع أيضًا على
XlaBuilder::Dot
.
Dot(lhs, rhs)
الوسيطات | النوع | الدلالات |
---|---|---|
lhs |
XlaOp |
صفيف من النوع T |
rhs |
XlaOp |
صفيف من النوع T |
تعتمد الدلالات الدقيقة لهذه العملية على ترتيبات المَعلمات:
الإدخال | الناتج | الدلالات |
---|---|---|
المتّجه [n] dot المتّجه [n] |
الكمية القياسية | حاصل ضرب المتّجهَين |
مصفوفة [m x k] dot متجه [k] |
المتّجه [م] | ضرب المصفوفة في المتجه |
المصفوفة [m x k] dot المصفوفة [k x n] |
مصفوفة [m x n] | ضرب مصفوفة في مصفوفة |
تُجري العملية مجموع المنتجات على السمة الثانية من lhs
(أو
السمة الأولى إذا كانت تحتوي على سمة واحدة) والسمة الأولى من rhs
. هذه هي السمات
"المتعاقد عليها". يجب أن تكون الأبعاد المتعاقد عليها لكل من lhs
وrhs
بالحجم نفسه. في الممارسة العملية، يمكن استخدامه لإجراء ضربات نقطية بين
المتجهات أو عمليات ضرب المتجهات/المصفوفات أو عمليات ضرب المصفوفات/المصفوفات.
DotGeneral
يمكنك الاطّلاع أيضًا على
XlaBuilder::DotGeneral
.
DotGeneral(lhs, rhs, dimension_numbers)
الوسيطات | النوع | الدلالات |
---|---|---|
lhs |
XlaOp |
صفيف من النوع T |
rhs |
XlaOp |
صفيف من النوع T |
dimension_numbers |
DotDimensionNumbers |
أرقام سمات العقد والدفعات |
تشبه Dot، ولكنها تسمح بتحديد أرقام سمات التعاقد والمجموعة
لكل من lhs
وrhs
.
حقول DotDimensionNumbers | النوع | الدلالات |
---|---|---|
lhs_contracting_dimensions
|
int64 متكرّر | lhs سمة التعاقد
الأرقام |
rhs_contracting_dimensions
|
int64 متكرّر | rhs سمة التعاقد
الأرقام |
lhs_batch_dimensions
|
int64 متكرّر | lhs سمة المجموعة
الأرقام |
rhs_batch_dimensions
|
int64 متكرّر | rhs سمة المجموعة
الأرقام |
تُجري دالة DotGeneral مجموع المنتجات على السمات المتعاقدة المحدّدة في
dimension_numbers
.
لا يلزم أن تكون أرقام سمات العقد المرتبطة من lhs
وrhs
متطابقة، ولكن يجب أن تكون لها أحجام السمات نفسها.
مثال على أرقام السمات المتعاقدة:
lhs = { {1.0, 2.0, 3.0},
{4.0, 5.0, 6.0} }
rhs = { {1.0, 1.0, 1.0},
{2.0, 2.0, 2.0} }
DotDimensionNumbers dnums;
dnums.add_lhs_contracting_dimensions(1);
dnums.add_rhs_contracting_dimensions(1);
DotGeneral(lhs, rhs, dnums) -> { {6.0, 12.0},
{15.0, 30.0} }
يجب أن تكون أحجام سمات الدفعات المرتبطة من lhs
وrhs
متطابقة.
مثال على أرقام سمات الحِزم (حجم الحزمة 2، مصفوفات 2×2):
lhs = { { {1.0, 2.0},
{3.0, 4.0} },
{ {5.0, 6.0},
{7.0, 8.0} } }
rhs = { { {1.0, 0.0},
{0.0, 1.0} },
{ {1.0, 0.0},
{0.0, 1.0} } }
DotDimensionNumbers dnums;
dnums.add_lhs_contracting_dimensions(2);
dnums.add_rhs_contracting_dimensions(1);
dnums.add_lhs_batch_dimensions(0);
dnums.add_rhs_batch_dimensions(0);
DotGeneral(lhs, rhs, dnums) -> { { {1.0, 2.0},
{3.0, 4.0} },
{ {5.0, 6.0},
{7.0, 8.0} } }
الإدخال | الناتج | الدلالات |
---|---|---|
[b0, m, k] dot [b0, k, n] |
[b0, m, n] | عمليات الضرب الحسابي للمصفوفات في حِزم |
[b0, b1, m, k] dot [b0, b1, k, n] |
[b0, b1, m, n] | عمليات الضرب الحسابي للمصفوفات في حِزم |
ويترتب على ذلك أنّ رقم السمة الناتج يبدأ بسمة المجموعة، ثمّ سمة lhs
غير المتعاقدة/غير المخصّصة للمجموعات، ثمّ سمة rhs
غير المتعاقدة/غير المخصّصة للمجموعات.
DynamicSlice
يمكنك الاطّلاع أيضًا على
XlaBuilder::DynamicSlice
.
تستخرج دالة DynamicSlice مصفوفة فرعية من مصفوفة الإدخال في العنصر الديناميكي
start_indices
. يتم تمرير حجم الشريحة في كل سمة في size_indices
، التي تحدّد نقطة نهاية فواصل الشرائح الحصرية في كل سمة: [start, start + size). يجب أن يكون شكل start_indices
أحادي الأبعاد، وأن يكون حجم السمة مساويًا لعدد سمات
operand
.
DynamicSlice(operand, start_indices, size_indices)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من N سمة من النوع T |
start_indices |
تسلسل N XlaOp |
قائمة بـ N عدد صحيح سكالري يحتوي على الفواصل الزمنية لبداية الشريحة لكل سمة يجب أن تكون القيمة أكبر من أو تساوي صفرًا. |
size_indices |
ArraySlice<int64> |
قائمة بـ N عدد من الأعداد الصحيحة تحتوي على حجم الشريحة لكل سمة يجب أن تكون كل قيمة أكبر من الصفر بوضوح، ويجب أن يكون البدء + الحجم أقل من أو يساوي حجم السمة لتجنُّب التفاف القيمة على باقي حجم السمة. |
يتم احتساب فهارس الشريحة الفعّالة من خلال تطبيق التحويل التالي
على كل فهرس i
في [1, N)
قبل إجراء الشريحة:
start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - size_indices[i])
يضمن ذلك أن تكون الشريحة المستخرَجة دائمًا ضمن الحدود بالنسبة إلى صفيف المعامل. إذا كانت الشريحة ضمن الحدود قبل تطبيق التحويل، لن يكون للتحويل أي تأثير.
مثال أحادي الأبعاد:
let a = {0.0, 1.0, 2.0, 3.0, 4.0}
let s = {2}
DynamicSlice(a, s, {2}) produces:
{2.0, 3.0}
مثال على القياس ثنائي الأبعاد:
let b =
{ {0.0, 1.0, 2.0},
{3.0, 4.0, 5.0},
{6.0, 7.0, 8.0},
{9.0, 10.0, 11.0} }
let s = {2, 1}
DynamicSlice(b, s, {2, 2}) produces:
{ { 7.0, 8.0},
{10.0, 11.0} }
DynamicUpdateSlice
يمكنك الاطّلاع أيضًا على
XlaBuilder::DynamicUpdateSlice
.
تُنشئ دالة DynamicUpdateSlice نتيجةً هي قيمة صفيف الإدخال
operand
، مع استبدال شريحة update
في start_indices
.
يحدِّد شكل update
شكل الصفيف الفرعي للنتيجة التي
يتم تعديلها.
يجب أن يكون شكل start_indices
أحادي الأبعاد، وأن يكون حجم السمة مساويًا
لعدد سمات operand
.
DynamicUpdateSlice(operand, update, start_indices)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من N سمة من النوع T |
update |
XlaOp |
صفيف من N سمة من النوع T يحتوي على تعديل الشريحة يجب أن تكون كل سمة من سمات شكل التعديل أكبر من الصفر بدقة، ويجب أن تكون القيمة "البداية" + القيمة "التعديل" أقل من أو تساوي حجم الم Operand لكل سمة لتجنُّب إنشاء فهارس تعديل خارج الحدود. |
start_indices |
تسلسل N XlaOp |
قائمة بـ N عدد صحيح سكالري يحتوي على الفواصل الزمنية لبداية الشريحة لكل سمة يجب أن تكون القيمة أكبر من أو تساوي صفرًا. |
يتم احتساب فهارس الشريحة الفعّالة من خلال تطبيق التحويل التالي
على كل فهرس i
في [1, N)
قبل إجراء الشريحة:
start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - update.dimension_size[i])
يضمن ذلك أنّ الشريحة المعدَّلة تكون دائمًا ضمن الحدود بالنسبة إلى صفيف المعامل. إذا كانت الشريحة ضمن الحدود قبل تطبيق التحويل، لن يكون للتحويل أي تأثير.
مثال أحادي الأبعاد:
let a = {0.0, 1.0, 2.0, 3.0, 4.0}
let u = {5.0, 6.0}
let s = {2}
DynamicUpdateSlice(a, u, s) produces:
{0.0, 1.0, 5.0, 6.0, 4.0}
مثال على القياس ثنائي الأبعاد:
let b =
{ {0.0, 1.0, 2.0},
{3.0, 4.0, 5.0},
{6.0, 7.0, 8.0},
{9.0, 10.0, 11.0} }
let u =
{ {12.0, 13.0},
{14.0, 15.0},
{16.0, 17.0} }
let s = {1, 1}
DynamicUpdateSlice(b, u, s) produces:
{ {0.0, 1.0, 2.0},
{3.0, 12.0, 13.0},
{6.0, 14.0, 15.0},
{9.0, 16.0, 17.0} }
العمليات الحسابية الثنائية على مستوى العنصر
يمكنك الاطّلاع أيضًا على
XlaBuilder::Add
.
تتوفّر مجموعة من العمليات الحسابية الثنائية على مستوى العنصر.
Op(lhs, rhs)
حيث يكون Op
أحد الدوالّ التالية: Add
(الجمع)، أو Sub
(الطرح)، أو Mul
(العملية الحسابية الضرب)، أو Div
(العملية الحسابية القسمة)، أو Pow
(العملية الحسابية الأس)، أو Rem
(الباقي)، أو Max
(الحد الأقصى)، أو Min
(الحد الأدنى)، أو And
(الدالة المنطقية "و")، أو Or
(الدالة المنطقية
"أو")، أو Xor
(الدالة المنطقية "خيار أو")، أو ShiftLeft
(الدالة الحسابية "الترقيم الثنائي لليمين")،
أو ShiftRightArithmetic
(الدالة الحسابية "الترقيم الثنائي لليسار")، أو ShiftRightLogical
(الدالة المنطقية
"الترقيم الثنائي لليسار")، أو Atan2
(الدالة "الظل القاطع" التي تستخدِم مَعلمتَين)، أو Complex
(الدالة التي تجمع الأجزاء الحقيقية
والخيالية في عدد مركب)
الوسيطات | النوع | الدلالات |
---|---|---|
lhs |
XlaOp |
المعامل على يمين العلامة: صفيف من النوع T |
rhs |
XlaOp |
المعامل على يسار العلامة: صفيف من النوع T |
يجب أن تكون أشكال الوسائط متشابهة أو متوافقة. اطّلِع على مستندات البث لمعرفة معنى توافق الأشكال. تكون نتيجة العملية ذات شكل ينتج عن بث صفيفَي الإدخال. في هذا الصيغة، لا تتوفّر عمليات بين صفائف رتب مختلفة، ما لم يكن أحد الم Operand هو عددًا قياسيًا.
عندما يكون Op
هو Rem
، يتم أخذ علامة النتيجة من المقسوم، وتكون قيمة النتيجة المطلقة دائمًا أقل من القيمة المطلقة للمقسوم عليه.
يؤدي تعذُّر قسمة الأعداد الصحيحة (قسمة/باقي القسمة/باقي القسمة بعلامة/بدون علامة على الصفر أو باقي القسمة/باقي القسمة بعلامةINT_SMIN
مع -1
) إلى إنشاء قيمة
يتم تحديدها أثناء التنفيذ.
يتوفّر خيار بديل يتيح البث بتنسيقات مختلفة لهذه العمليات:
Op(lhs, rhs, broadcast_dimensions)
حيث يكون Op
هو نفسه كما هو موضّح أعلاه. يجب استخدام هذا الصيغة من العملية
للعمليات الحسابية بين صفائف من الرتب المختلفة (مثل إضافةermatix
إلى متجه).
عامل التشغيل broadcast_dimensions
الإضافي هو شريحة من الأعداد الصحيحة المستخدَمة في
توسيع عدد سمات عامل التشغيل ذي الأبعاد الأقل إلى
عدد سمات عامل التشغيل ذي الأبعاد الأعلى. broadcast_dimensions
تُعرِض سمات الشكل ذي الأبعاد الأقل على سمات
الشكل ذي الأبعاد الأعلى. يتم ملء الأبعاد غير المُحدَّدة للشكل الموسَّع
بأبعاد بحجم واحد. بعد ذلك، تُرسِل ميزة "بث السمات المتدهورة"
الأشكال على طول هذه السمات المتدهورة لمساواة
أشكال كلا المعاملَين. يتم وصف الدلالات بالتفصيل في
صفحة البث.
عمليات المقارنة على مستوى العنصر
يمكنك الاطّلاع أيضًا على
XlaBuilder::Eq
.
تتوفّر مجموعة من عمليات المقارنة الثنائية العادية لكل عنصر. يُرجى العلم أنّ قواعد مقارنة الأعداد الكسورية IEEE 754 العادية تنطبق عند مقارنة أنواع الأعداد الكسورية.
Op(lhs, rhs)
حيث يكون Op
أحد القيم Eq
(يساوي)، أو Ne
(لا يساوي)، أو Ge
(أكبر من أو يساوي)، أو Gt
(أكبر من)، أو Le
(أصغر من أو يساوي)، أو Lt
(أصغر من). توفّر مجموعة أخرى من عوامل التشغيل، وهي EqTotalOrder وNeTotalOrder وGeTotalOrder
وGtTotalOrder وLeTotalOrder وLtTotalOrder، الوظائف نفسها،
باستثناء أنّها تتيح أيضًا ترتيبًا إجماليًا على الأرقام المتغيرة النقطة، من خلال فرض -NaN < -Inf < -Finite < -0 < +0 < +Finite < +Inf < +NaN.
الوسيطات | النوع | الدلالات |
---|---|---|
lhs |
XlaOp |
المعامل على يمين العلامة: صفيف من النوع T |
rhs |
XlaOp |
المعامل على يسار العلامة: صفيف من النوع T |
يجب أن تكون أشكال الوسائط متشابهة أو متوافقة. اطّلِع على مستندات
البث لمعرفة معنى توافق الأشكال. تكون نتيجة العملية على شكل نتيجة
بث صفيفَي الإدخال بنوع العنصر PRED
. في هذا الصيغة،لا تتوفّر العمليات بين الصفائف ذات الرتب المختلفة، ما لم يكن أحد
المَعلمتَين عددًا قياسيًا.
يتوفّر خيار بديل يتيح البث بتنسيقات مختلفة لهذه العمليات:
Op(lhs, rhs, broadcast_dimensions)
حيث يكون Op
هو نفسه كما هو موضّح أعلاه. يجب استخدام هذا الصيغة من العملية
لعمليات المقارنة بين صفائف من الرتب المختلفة (مثل إضافةermat إلى متجه).
عامل التشغيل broadcast_dimensions
الإضافي هو شريحة من الأعداد الصحيحة التي تحدِّد
السمات التي سيتم استخدامها لبث عوامل التشغيل. يتم وصف الدلالات بالتفصيل في صفحة البث.
الدوالّ الأحادية لكل عنصر
يتيح XlaBuilder الدوالّ الأحادية العنصر التالية:
Abs(operand)
القيمة المطلقة لكل عنصر x -> |x|
.
Cbrt(operand)
عملية الجذر التكعيبي لكل عنصر x -> cbrt(x)
.
Ceil(operand)
دالة ceil على مستوى العنصر x -> ⌈x⌉
.
Clz(operand)
احتساب الأصفار البادئة لكل عنصر على حدة
Cos(operand)
دالة الجيب الزائدي لكل عنصر x -> cos(x)
Erf(operand)
دالة الخطأ لكل عنصر x -> erf(x)
حيث
\(\text{erf}(x) = \frac{2}{\sqrt{\pi} }\int_0^x e^{-t^2} \, dt\).
Exp(operand)
دالة أسية طبيعية على مستوى العنصر x -> e^x
.
Expm1(operand)
الأسّ الطبيعي لكل عنصر مطروحًا منه واحد
x -> e^x - 1
Floor(operand)
الحد الأدنى لكل عنصر x -> ⌊x⌋
.
Imag(operand)
الجزء التخيلي لكل عنصر من عناصر شكل معقد (أو حقيقي).
x -> imag(x)
. إذا كان الم Operand من النوع الكسري العائم، يتم عرض القيمة 0.
IsFinite(operand)
يختبر ما إذا كان كل عنصر من operand
محدودًا،
أي ليس موجب أو سالب ما لا نهاية، وليس NaN
. تعرِض صفيفًا
من قيم PRED
بالشكل نفسه للإدخال، حيث يكون كل عنصر true
إذا كان عنصر الإدخال المقابل محدودًا فقط.
Log(operand)
اللوغاريتم الطبيعي لكل عنصر x -> ln(x)
Log1p(operand)
اللوغاريتم الطبيعي المتغيّر على مستوى العنصر x -> ln(1+x)
.
Logistic(operand)
حساب الدالة اللوجستية على مستوى العنصر x ->
logistic(x)
.
Neg(operand)
النفي على مستوى العنصر x -> -x
.
Not(operand)
رمز المعامل المنطقي not (ليس) على مستوى العنصر x -> !(x)
تحسب دالة PopulationCount(operand)
عدد الوحدات بت التي تم ضبطها في كل
عنصر من operand
.
Real(operand)
الجزء الحقيقي لكل عنصر من شكل مركّب (أو حقيقي).
x -> real(x)
. إذا كان المعامل من النوع الكسري، يتم عرض القيمة نفسها.
Round(operand)
التقريب حسب العنصر، مع الابتعاد عن الصفر
RoundNearestEven(operand)
التقريب حسب العنصر، يتم ربطه بأقرب عدد زوجي.
Rsqrt(operand)
مقلوب عملية الجذر التربيعي لكل عنصر
x -> 1.0 / sqrt(x)
.
Sign(operand)
عملية التوقيع على كل عنصر x -> sgn(x)
حيث
\[\text{sgn}(x) = \begin{cases} -1 & x < 0\\ -0 & x = -0\\ NaN & x = NaN\\ +0 & x = +0\\ 1 & x > 0 \end{cases}\]
باستخدام عامل تشغيل المقارنة لنوع العنصر operand
.
Sin(operand)
دالة الجيبّ المنتظم على مستوى العنصر x -> sin(x)
.
Sqrt(operand)
عملية الجذر التربيعي لكل عنصر x -> sqrt(x)
.
Tan(operand)
دالة ظلّية على مستوى العنصر x -> tan(x)
.
Tanh(operand)
دالة الظل الزائدي لكل عنصر x -> tanh(x)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
المعامل للدالة |
يتم تطبيق الدالة على كل عنصر في الصفيف operand
، ما يؤدي إلى الحصول على صفيف
بالشكل نفسه. يُسمح بأن يكون operand
عددًا متّجهًا
(ببعد 0).
Fft
تُنفِّذ عملية XLA FFT تحويلات فورييه المباشرة والعكسية ل المدخلات/المخرجات الحقيقية والمركّبة. يمكن استخدام تحويلات فورييه المتعدّدة الأبعاد على ما يصل إلى 3 محاور.
يمكنك الاطّلاع أيضًا على
XlaBuilder::Fft
.
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
الصفيف الذي نجري عليه تحويل فورييه |
fft_type |
FftType |
اطّلِع على الجدول أدناه. |
fft_length |
ArraySlice<int64> |
أطوال النطاق الزمني للأعمدة التي يتم تحويلها. ويلزم ذلك على وجه الخصوص لاستخدام IRFFT لضبط الحجم المناسب للمحور الداخلي، لأنّ RFFT(fft_length=[16]) له شكل الإخراج نفسه مثل RFFT(fft_length=[17]) . |
FftType |
الدلالات |
---|---|
FFT |
تحويل فورييه المباشر للإشارة المركّبة إلى إشارة مركّبة الشكل لم يتغيّر. |
IFFT |
تحويل فورييه العكسي من المعقد إلى المعقد الشكل لم يتغيّر. |
RFFT |
تحويل فورييه المباشر للأرقام الحقيقية إلى مركبة يتم تقليل شكل المحور الداخلي إلى fft_length[-1] // 2 + 1 إذا كانت fft_length[-1] قيمة غير صفرية، مع حذف الجزء المزدوج العكسي للإشارة المحوَّلة بعد تردد Nyquist. |
IRFFT |
تحويل فورييه العكسي للأرقام الحقيقية إلى مركبة (أي يأخذ أرقامًا مركبة ويعرض أرقامًا حقيقية). يتم توسيع شكل المحور الداخلي إلى fft_length[-1] إذا كانت fft_length[-1] قيمة غير صفرية، ما يشير إلى جزء الإشارة المحوَّلة خارج تردد Nyquist من العنصر المرافق العكسي لإدخالات 1 إلى fft_length[-1] // 2 + 1 . |
تحويل فورييه المتعدّد الأبعاد
عند تقديم أكثر من fft_length
واحد، يكون ذلك معادلاً لتطبيق
تسلسل من عمليات تحويل فورييه السريع على كل محور من المحاور الداخلية. يُرجى العلم أنّه في الحالتَين
الحقيقية إلى المعقدة والمعقدة إلى الحقيقية، يتم أولاً (بشكل فعّال) تحويل محور التحويل الداخلي (RFFT) ثم تحويل IRFFT، ولهذا السبب، فإنّ محور التحويل الداخلي هو الذي يغيّر الحجم. ستكون عمليات تحويل المحاور الأخرى بعد ذلك
معقدة->معقدة.
تفاصيل التنفيذ
تستند تحويلة فورييه لرقائق وحدة المعالجة المركزية إلى TensorFFT من Eigen. تستخدم تحويلة فورييه باستخدام وحدة معالجة الرسومات cuFFT.
Gather
تعمل عملية التجميع في XLA على تجميع عدة شرائح (كل شريحة في موضع تشغيل مختلف محتمل) من صفيف الإدخال.
الدلالات العامة
يمكنك الاطّلاع أيضًا على
XlaBuilder::Gather
.
للحصول على وصف أكثر وضوحًا، يُرجى الاطّلاع على قسم "الوصف غير الرسمي" أدناه.
gather(operand, start_indices, offset_dims, collapsed_slice_dims,
slice_sizes, start_index_map)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
الصفيف الذي نجمعه منه |
start_indices |
XlaOp |
صفيف يحتوي على الفهارس البادئة للشرائح التي نجمعها |
index_vector_dim |
int64 |
السمة في start_indices التي "تحتوي" على الفهارس البادئة. يُرجى الاطّلاع أدناه على وصف مفصّل. |
offset_dims |
ArraySlice<int64> |
مجموعة السمات في شكل الإخراج التي يتمّ إزاحتها إلى صفيف تمّ تقطيعه من الم Operand |
slice_sizes |
ArraySlice<int64> |
slice_sizes[i] هي حدود الشريحة للسمة i . |
collapsed_slice_dims |
ArraySlice<int64> |
مجموعة السمات في كل شريحة تم تصغيرها يجب أن يكون حجم هذه السمات هو 1. |
start_index_map |
ArraySlice<int64> |
خريطة تصف كيفية ربط الفواصل في start_indices بالفواصل القانونية في الم Operand |
indices_are_sorted |
bool |
ما إذا كان من المؤكد أن يتم ترتيب الفهارس حسب المُتصل |
لتسهيل الأمر، نضع علامة batch_dims
على السمات في صفيف الإخراج وليس في offset_dims
.
الناتج هو صفيف يتضمّن batch_dims.size
+ offset_dims.size
سمة.
يجب أن يساوي operand.rank
مجموع offset_dims.size
و
collapsed_slice_dims.size
. يجب أيضًا أن تكون slice_sizes.size
مساوية
operand.rank
.
إذا كان index_vector_dim
يساوي start_indices.rank
، نعتبر ضمنيًا أنّه
لعنصر start_indices
سمة 1
متأخرة (أي إذا كان start_indices
من
شكل [6,7]
وكان index_vector_dim
يساوي 2
، نعتبر ضمنيًا أنّ
شكل start_indices
هو [6,7,1]
).
يتم احتساب حدود صفيف الإخراج على طول السمة i
على النحو التالي:
إذا كانت
i
متوفّرة فيbatch_dims
(أي تساويbatch_dims[k]
ل بعضk
)، نختار حدود السمة المقابلة منstart_indices.shape
، مع تخطّيindex_vector_dim
(أي اختيارstart_indices.shape.dims
[k
] إذا كانk
<index_vector_dim
وstart_indices.shape.dims
[k
+1
] في غير ذلك).إذا كان
i
متوفّرًا فيoffset_dims
(أي يساويoffset_dims
[k
] ل بعضk
)، نختار الحدّ المقابل منslice_sizes
بعد الأخذ في الاعتبارcollapsed_slice_dims
(أي نختارadjusted_slice_sizes
[k
] حيث يكونadjusted_slice_sizes
هوslice_sizes
مع إزالة الحدود في الفهارسcollapsed_slice_dims
).
من الناحية الرسمية، يتم حساب فهرس الم OperandIn
المرتبط بفهرس ناتج معيّنOut
على النحو التالي:
لنفترض أنّ
G
= {Out
[k
] لـk
فيbatch_dims
}. استخدِمG
لقطعS
عمود كهذا بحيث يكونS
[i
] =start_indices
[Combine(G
,i
)] حيث يُدخِل دالة Combine(A, b) العنصر b في الموضعindex_vector_dim
في A. يُرجى العلم أنّه تم تحديد هذا الإجراء بشكل جيد حتى إذا كانتG
فارغة: إذا كانتG
فارغة، تكونS
=start_indices
.أنشئ فهرسًا أوليًا،
S
in
، فيoperand
باستخدامS
من خلال نشرS
باستخدامstart_index_map
. وبشكل أدق:S
in
[start_index_map
[k
]] =S
[k
] إذا كانk
<start_index_map.size
.S
in
[_
] =0
بخلاف ذلك.
أنشئ مؤشرًا
O
in
فيoperand
من خلال توزيع المؤشرات في سمات البادئة فيOut
وفقًا لمجموعةcollapsed_slice_dims
. وبشكل أدق:O
in
[remapped_offset_dims
(k
)] =Out
[offset_dims
[k
]] إذا كانk
<offset_dims.size
(يتم تعريفremapped_offset_dims
أدناه).O
in
[_
] =0
بخلاف ذلك.
In
هوO
in
+S
in
حيث يشير الرمز + إلى عملية جمع العناصر.
دالة remapped_offset_dims
هي دالة أحادية الاتجاه ونطاقها هو [0
،
offset_dims.size
) ونطاقها هو [0
، operand.rank
) \ collapsed_slice_dims
. على سبيل المثال،
offset_dims.size
هو 4
، وoperand.rank
هو 6
،
collapsed_slice_dims
هو {0
، 2
}، ثم remapped_offset_dims
هو {0
→1
،
1
→3
، 2
→4
، 3
→5
}.
إذا تم ضبط indices_are_sorted
على true، يمكن أن تفترض XLA أنّه تم ترتيب start_indices
(بترتيب تصاعدي، بعد بعثرة قيمها وفقًا لجدول start_index_map
) من قِبل المستخدم. وإذا لم يكن الأمر كذلك، تكون الدلالات
محددة التنفيذ.
وصف غير رسمي وأمثلة
بشكل غير رسمي، يتطابق كل فهرس Out
في صفيف الإخراج مع عنصر E
في صفيف الم Operand، ويتم احتسابه على النحو التالي:
نستخدم سمات الحِزم في
Out
للبحث عن فهرس بداية منstart_indices
.نستخدم
start_index_map
لربط الفهرس الأوّلي (الذي قد يكون حجمه أقل من operand.rank) بفهرس أوّلي "كامل" فيoperand
.نقطع شريحة ديناميكية بحجم
slice_sizes
باستخدام فهرس البدء الكامل.نعيد تشكيل الشريحة من خلال تصغير سمات
collapsed_slice_dims
. وبما أنّه يجب أن يكون حدّ جميع سمات الشريحة المُدمجة هو 1، فإنّ عملية إعادة التنسيق هذه تكون قانونية دائمًا.نستخدم سمات البدء في
Out
للفهرسة في هذا المقطع للحصول على عنصر الإدخال،E
، المقابل لفهرس الإخراجOut
.
تم ضبط index_vector_dim
على start_indices.rank
- 1
في جميع الأمثلة التالية. لا تؤدي القيم الأكثر إثارة للاهتمام لـ index_vector_dim
إلى تغيير
العملية بشكل أساسي، ولكنّها تجعل العرض المرئي أكثر تعقيدًا.
للحصول على فكرة عن كيفية ملاءمة كل ما سبق معًا، لنلقِ نظرة على مثال
يجمع 5 شرائح من الشكل [8,6]
من صفيف [16,11]
. يمكن تمثيل
موضع شريحة في مصفوفة [16,11]
على أنّه فهرس
متجه على شكل S64[2]
، وبالتالي يمكن تمثيل مجموعة المواضع الخمسة على أنّها
مصفوفة S64[5,2]
.
يمكن بعد ذلك تصوير سلوك عملية التجميع على أنّه تحويل فهرس
يأخذ [G
,O
0
,O
1
]، وهو فهرس في
شكل الإخراج، ويربطه بعنصر في صفيف الإدخال بالطريقة التالية:
نختار أولاً متجهًا (X
,Y
) من مصفوفة فهرس التجميع باستخدام G
.
العنصر في مصفوفة الإخراج عند الفهرس
[G
,O
0
,O
1
] هو العنصر في مصفوفة
الإدخال عند الفهرس [X
+O
0
,Y
+O
1
].
slice_sizes
هي [8,6]
، وهي تحدّد نطاق O0
و
O1
، وهذا بدوره يحدّد حدود الشريحة.
تعمل عملية التجميع هذه كشريحة ديناميكية للمجموعة مع G
بصفتها سمة
المجموعة.
قد تكون مؤشرات التجميع متعددة الأبعاد. على سبيل المثال، سأعرض إليك
نسخة أكثر عمومية من المثال أعلاه باستخدام صفيف "جمع الفهارس" بالشكل [4,5,2]
، وسأترجم الفهارس على النحو التالي:
مرة أخرى، يعمل هذا كشريحة ديناميكية للمجموعة G
0
و
G
1
كسمات المجموعة. لا يزال حجم الشريحة [8,6]
.
تعمل عملية التجميع في XLA على تعميم الدلالات غير الرسمية الموضّحة أعلاه بالطرق التالية:
يمكننا ضبط السمات التي تشكّل سمات offset في شكل الإخراج (السمات التي تحتوي على
O
0
وO
1
في المثال السابق). يتمّ تعريف سمات حِزم الإخراج (السمات التي تحتوي علىG
0
وG
1
في المثال الأخير) على أنّها سمات الإخراج التي ليست سمات تمكين.قد يكون عدد سمات الإزاحة الناتجة الظاهرة بشكل صريح في شكل المخرج أصغر من عدد السمات في الإدخال. يجب أن يكون حجم القطعة المتعلّقة بهذه الأبعاد "المفقودة"
collapsed_slice_dims
، والتي تم إدراجها صراحةً على أنّهاcollapsed_slice_dims
.1
وبما أنّ حجم الشريحة هو1
، فإنّ الفهرس الوحيد الصالح لها هو0
، ولا يؤدي حذفها إلى حدوث التباس.قد تحتوي الشريحة المستخرَجة من صفيف "جمع الفهارس" ((
X
,Y
) في المثال المتأخر) على عناصر أقل من عدد السمات في صفيف الإدخال، ويحدِّد الربط الصريح كيفية توسيع الفهرس للحصول على العدد نفسه من السمات مثل الإدخال.
في المثال الأخير، نستخدم (2) و (3) لتنفيذ tf.gather_nd
:
يتم استخدام G
0
وG
1
لقطع فهرس بدء
من صفيف فهارس التجميع كالمعتاد، باستثناء أنّ الفهرس البدءي يحتوي على عنصر واحد فقط، وهو X
. وبالمثل، هناك فهرس واحد فقط لموضع الإزاحة في الإخراج بالقيمة
O
0
. ومع ذلك، قبل استخدامها كفهارس في صفيف الإدخال، تتم توسيعها وفقًا لعملية "ربط فهرس التجميع" (start_index_map
في الوصف الرسمي) وعملية "ربط البادئة" (remapped_offset_dims
في الوصف الرسمي) إلى [X
،0
] و[0
،O
0
] على التوالي، مما يؤدي إلى [X
،O
0
]. بعبارة أخرى، يتم ربط فهرس الإخراج
[G
0
،G
1
،O
0
] بفهرس الإدخال
[GatherIndices
[G
0
،G
1
،0
]،O
0
]
الذي يمنحنا الدلالات الخاصة بـ tf.gather_nd
.
رقم slice_sizes
لهذا الطلب هو [1,11]
. يعني هذا بشكلٍ بديهي أنّ كل X
فهرس في صفيف فهارس التجميع يختار صفًا كاملاً، والنتيجة هي التسلسل التلقائي لكل هذه الصفوف.
GetDimensionSize
يمكنك الاطّلاع أيضًا على
XlaBuilder::GetDimensionSize
.
لعرض حجم السمة المحدّدة للمَعلمة. يجب أن يكون المُعامل على شكل صفيف.
GetDimensionSize(operand, dimension)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة إدخال من n سمة |
dimension |
int64 |
قيمة في الفاصل [0, n) تحدّد السمة |
SetDimensionSize
يمكنك الاطّلاع أيضًا على
XlaBuilder::SetDimensionSize
.
تُستخدَم لضبط الحجم الديناميكي لسمة XlaOp المحدّدة. يجب أن يكون المُعامل على شكل صفيف.
SetDimensionSize(operand, size, dimension)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف إدخال من n سمة |
size |
XlaOp |
int32 يمثّل الحجم الديناميكي أثناء التشغيل |
dimension |
int64 |
قيمة في النطاق [0, n) تحدّد السمة |
تمرير الم Operand كنتيجة، مع السمة الديناميكية التي يتتبّعها compilador
سيتم تجاهل القيم المُضافة من خلال عمليات التخفيض في مرحلة ما بعد المعالجة.
let v: f32[10] = f32[10]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
let five: s32 = 5;
let six: s32 = 6;
// Setting dynamic dimension size doesn't change the upper bound of the static
// shape.
let padded_v_five: f32[10] = set_dimension_size(v, five, /*dimension=*/0);
let padded_v_six: f32[10] = set_dimension_size(v, six, /*dimension=*/0);
// sum == 1 + 2 + 3 + 4 + 5
let sum:f32[] = reduce_sum(padded_v_five);
// product == 1 * 2 * 3 * 4 * 5
let product:f32[] = reduce_product(padded_v_five);
// Changing padding size will yield different result.
// sum == 1 + 2 + 3 + 4 + 5 + 6
let sum:f32[] = reduce_sum(padded_v_six);
GetTupleElement
يمكنك الاطّلاع أيضًا على
XlaBuilder::GetTupleElement
.
الفهرس في مجموعة تحتوي على قيمة ثابتة في وقت الترجمة
يجب أن تكون القيمة ثابتة في وقت الترجمة حتى تتمكّن عملية استنتاج الشكل من تحديد نوع القيمة الناتجة.
وهذا مشابه لـ std::get<int N>(t)
في C++. من الناحية النظرية:
let v: f32[10] = f32[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
let s: s32 = 5;
let t: (f32[10], s32) = tuple(v, s);
let element_1: s32 = gettupleelement(t, 1); // Inferred shape matches s32.
يمكنك أيضًا الاطّلاع على tf.tuple
.
الخلاصة
يمكنك الاطّلاع أيضًا على
XlaBuilder::Infeed
.
Infeed(shape)
الوسيطة | النوع | الدلالات |
---|---|---|
shape |
Shape |
شكل البيانات المقروءة من واجهة الخلاصة يجب ضبط حقل تنسيق الشكل ليطابق تنسيق البيانات المُرسَلة إلى الجهاز، وإلا سيكون سلوكه غير محدّد. |
تقرأ عنصر بيانات واحدًا من واجهة البث التلقائي للإعلانات في الخلاصة في
الجهاز، وتُفسر البيانات على أنّها الشكل المحدّد وتنسيقه، وتُعرِض
XlaOp
للبيانات. يُسمح بعمليات "إدخال الخلاصة" المتعدّدة في عملية حسابية، ولكن يجب أن يكون هناك ترتيب إجمالي بين عمليات "إدخال الخلاصة". على سبيل المثال، يتضمّن اثنان من خلاصتَي الأخبار في الرمز البرمجي أدناه طلبًا إجماليًا لأنّ هناك تبعية بين حلقات while.
result1 = while (condition, init = init_value) {
Infeed(shape)
}
result2 = while (condition, init = result1) {
Infeed(shape)
}
لا تتوفّر أشكال المجموعات المُدمَجة. بالنسبة إلى شكل مجموعة ثنائية فارغة، تكون عملية "الخلاصة" غير مجدية بشكلٍ فعال وتستمر بدون قراءة أي بيانات من الخلاصة للجهاز.
أمواج هادئة قصيرة
يمكنك الاطّلاع أيضًا على
XlaBuilder::Iota
.
Iota(shape, iota_dimension)
ينشئ قيمة ثابتة على الجهاز بدلاً من نقل مضيف
كبير محتمل. تنشئ صفيفًا له شكل محدّد ويحتوي على قيم تبدأ من
صفر وتزيد بمقدار واحد على طول السمة المحدّدة. بالنسبة إلى
أنواع الأرقام العشرية، يكون الصفيف الناتج مساويًا لـ ConvertElementType(Iota(...))
حيث
يكون Iota
من النوع الصحيح ويتم التحويل إلى النوع العشري.
الوسيطات | النوع | الدلالات |
---|---|---|
shape |
Shape |
شكل الصفيف الذي أنشأه Iota() |
iota_dimension |
int64 |
السمة المطلوب زيادتها. |
على سبيل المثال، يعرض Iota(s32[4, 8], 0)
[[0, 0, 0, 0, 0, 0, 0, 0 ],
[1, 1, 1, 1, 1, 1, 1, 1 ],
[2, 2, 2, 2, 2, 2, 2, 2 ],
[3, 3, 3, 3, 3, 3, 3, 3 ]]
يمكن إرجاع المشتريات مقابل Iota(s32[4, 8], 1)
.
[[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ]]
خريطة
يمكنك الاطّلاع أيضًا على
XlaBuilder::Map
.
Map(operands..., computation)
الوسيطات | النوع | الدلالات |
---|---|---|
operands |
تسلسل N XlaOp |
مصفوفات N من الأنواع T0..T{N-1} |
computation |
XlaComputation |
حساب من النوع T_0, T_1, .., T_{N + M -1} -> S مع N مَعلمة من النوع T وM من نوع عشوائي |
dimensions |
صفيف int64 |
صفيف لسمات الخريطة |
تطبِّق دالة عددية على صفائف operands
المحدّدة، ما ينتج عنه صفيف
بالأبعاد نفسها حيث يكون كل عنصر هو نتيجة الدالة المُحدَّدة
المطبَّقة على العناصر المقابلة في صفائف الإدخال.
الدالة المُعرَّفة هي عملية حسابية عشوائية مع القيود التي تفرضها
N مدخلات من النوع السقلي T
وإخراج واحد من النوع S
. يحتوي الناتج على
السمات نفسها التي تحتوي عليها المعاملات باستثناء أنّه يتم استبدال نوع العنصر T
بـ S.
على سبيل المثال: تربط Map(op1, op2, op3, computation, par1)
elem_out <-
computation(elem1, elem2, elem3, par1)
في كل فهرس (متعدّد الأبعاد) في
صفائف الإدخال لإنشاء صفيف الإخراج.
OptimizationBarrier
يمنع أي عملية تحسين من نقل العمليات الحسابية عبر الحاجز.
يضمن تقييم جميع المدخلات قبل أيّ عوامل تشغيل تعتمد على مخرجات الحاجز.
وسادة
يمكنك الاطّلاع أيضًا على
XlaBuilder::Pad
.
Pad(operand, padding_value, padding_config)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة من النوع T |
padding_value |
XlaOp |
عدد صحيح من النوع T لملء الحشو المُضاف |
padding_config |
PaddingConfig |
مقدار المساحة الفارغة على كلا الحافتَين (منخفض أو مرتفع) وبين عناصر كل سمة |
يوسع صفيف operand
المحدَّد عن طريق إضافة مسافة حول الصفيف وكذلك بين
عناصر الصفيف باستخدام padding_value
المحدَّد. padding_config
تُحدِّد مقدار الحشو على الحواف والحشو الداخلي لكل
سمة.
PaddingConfig
هو حقل متكرّر من PaddingConfigDimension
، يحتوي على
ثلاثة حقول لكل سمة: edge_padding_low
وedge_padding_high
و
interior_padding
.
تحدِّد edge_padding_low
وedge_padding_high
مقدار الحشو المُضاف
في الطرف الأدنى (بجانب الفهرس 0) والطرف الأعلى (بجانب أعلى فهرس)
لكل سمة على التوالي. يمكن أن تكون قيمة الحشو على الحواف سالبة، ويشير
القيمة المطلقة للحشو السالب إلى عدد العناصر التي يجب إزالتها
من السمة المحدّدة.
تحدِّد interior_padding
مقدار المساحة المتروكة التي تتم إضافتها بين أي عنصرين
في كل سمة، ولا يجوز أن تكون سالبة. تحدث عملية الحشو الداخلي
بشكل منطقي قبل عملية الحشو على الحواف، لذا في حال الحشو السلبي على الحواف، تتم إزالة العناصر
من المُشغِّل الذي تمّت إضافة حشو داخلي إليه.
لا تؤدي هذه العملية إلى أيّ تغيير إذا كانت جميع أزواج الحشو على الحواف هي (0، 0) وكانت قيم الحشو الداخلي هي 0. يعرض الشكل أدناه أمثلة على قيم
edge_padding
وinterior_padding
المختلفة لصفيف ثنائي الأبعاد.
Recv
يمكنك الاطّلاع أيضًا على
XlaBuilder::Recv
.
Recv(shape, channel_handle)
الوسيطات | النوع | الدلالات |
---|---|---|
shape |
Shape |
شكل البيانات المطلوب استلامها |
channel_handle |
ChannelHandle |
معرّف فريد لكل زوج من الإرسال/الاستلام |
تتلقّى بيانات بالشكل المحدّد من تعليمات Send
في عملية حسابية أخرى تشترك في الاسم المعرِّف نفسه للقناة. تعرِض هذه الدالة رمز معالجة
XlaOp للبيانات المستلَمة.
تمثّل واجهة برمجة التطبيقات للعميل في عملية Recv
الاتّصال المتزامن.
ومع ذلك، يتم تجزئة التعليمات داخليًا إلى تعليمات HLO (Recv
وRecvDone
) لتفعيل عمليات نقل البيانات غير المتزامنة. يمكنك أيضًا الاطّلاع على
HloInstruction::CreateRecv
وHloInstruction::CreateRecvDone
.
Recv(const Shape& shape, int64 channel_id)
تخصيص الموارد المطلوبة لتلقّي البيانات من تعليمات Send
التي تحتوي على
معرّف القناة نفسه تُعيد هذه الدالة سياقًا للموارد المخصّصة، والتي يتم استخدامها
من خلال تعليمات RecvDone
التالية للانتظار إلى أن تكتمل عملية نقل data. السياق هو مجموعة من {receive buffer (shape), request identifier
(U32)} ولا يمكن استخدامه إلا من خلال تعليمات RecvDone
.
RecvDone(HloInstruction context)
استنادًا إلى سياق تم إنشاؤه بواسطة تعليمات Recv
، ينتظر اكتمال نقل البيانات ويعرض البيانات التي تم استلامها.
تقليل
يمكنك الاطّلاع أيضًا على
XlaBuilder::Reduce
.
تُطبِّق دالة تقليل على صفيف واحد أو أكثر بشكل موازٍ.
Reduce(operands..., init_values..., computation, dimensions)
الوسيطات | النوع | الدلالات |
---|---|---|
operands |
تسلسل N XlaOp |
مصفوفات N من أنواع T_0, ..., T_{N-1} |
init_values |
تسلسل N XlaOp |
عدد N من القيم السلاسل من أنواع T_0, ..., T_{N-1} . |
computation |
XlaComputation |
عملية حسابية من النوع T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}) |
dimensions |
صفيف int64 |
صفيف غير مرتب للسمات المطلوب تقليلها |
المكان:
- يجب أن تكون قيمة N أكبر من أو تساوي 1.
- يجب أن يكون الحساب "تقريبًا" ترابطيًا (راجِع المعلومات أدناه).
- يجب أن تتطابق أبعاد جميع صفائف الإدخال.
- يجب أن تشكل جميع القيم الأولية هوية ضمن
computation
. - إذا كان
N = 1
،Collate(T)
هوT
. - إذا كان
N > 1
،Collate(T_0, ..., T_{N-1})
عبارة عن مجموعة من عناصرN
من النوعT
.
تقلِّل هذه العملية سمة واحدة أو أكثر من كل صفيف إدخال إلى مقاييس.
عدد سمات كل صفيف معروض هو
number_of_dimensions(operand) - len(dimensions)
. ناتج العملية هو
Collate(Q_0, ..., Q_N)
حيث Q_i
صفيف من النوع T_i
،
وتكون أبعاده موضّحة أدناه.
يُسمح لأنظمة التشغيل الأساسية المختلفة بإعادة ربط عملية احتساب التقليل. وقد يؤدي ذلك إلى حدوث اختلافات رقمية، لأنّ بعض دوالّ التخفيض، مثل الإضافة، ليست مترافقة مع الأعداد الكسورية. ومع ذلك، إذا كان نطاق البيانات محدودًا، تكون عملية الإضافة باستخدام الأرقام العائمة قريبة بالقدر الكافي من الارتباط لمعظم الاستخدامات العملية.
أمثلة
عند التقليل على مستوى سمة واحدة في صفيف واحد من صف واحد يحتوي على القيم [10, 11,
12, 13]
، باستخدام دالة التقليل f
(وهي computation
)، يمكن حساب ذلك
على النحو التالي:
f(10, f(11, f(12, f(init_value, 13)))
ولكن هناك أيضًا العديد من الاحتمالات الأخرى، مثل:
f(init_value, f(f(10, f(init_value, 11)), f(f(init_value, 12), f(init_value, 13))))
في ما يلي مثال تقريبي على الرمز البرمجي الاصطناعي لكيفية تنفيذ التخفيض، باستخدام عملية الجمع كعملية حساب التخفيض مع قيمة أولية هي 0.
result_shape <- remove all dims in dimensions from operand_shape
# Iterate over all elements in result_shape. The number of r's here is equal
# to the number of dimensions of the result.
for r0 in range(result_shape[0]), r1 in range(result_shape[1]), ...:
# Initialize this result element
result[r0, r1...] <- 0
# Iterate over all the reduction dimensions
for d0 in range(dimensions[0]), d1 in range(dimensions[1]), ...:
# Increment the result element with the value of the operand's element.
# The index of the operand's element is constructed from all ri's and di's
# in the right order (by construction ri's and di's together index over the
# whole operand shape).
result[r0, r1...] += operand[ri... di]
في ما يلي مثال على تقليل صفيف ثنائي الأبعاد (مصفوفة). يحتوي الشكل على بُعدَين، البُعد 0 بحجم 2 والبُعد 1 بحجم 3:
نتائج تقليل السمتَين 0 أو 1 باستخدام دالة "إضافة":
يُرجى العلم أنّ كلتا نتيجتَي الاختزال هما صفيفَان أحاديَا الأبعاد. يعرض المخطّط البياني أحدهما كعمود والآخر كصف فقط لتسهيل الرؤية.
للحصول على مثال أكثر تعقيدًا، إليك صفيف ثلاثي الأبعاد. عدد أبعادها هو 3، ويتمثل البُعد 0 في الحجم 4، والبُعد 1 في الحجم 2، والبُعد 2 في الحجم 3. للتبسيط، تتمّ تكرار القيم من 1 إلى 6 في السمة 0.
على غرار المثال ثنائي الأبعاد، يمكننا تقليل سمة واحدة فقط. إذا قلّلنا السمة 0، على سبيل المثال، نحصل على صفيف ثنائي الأبعاد تم تجميع جميع القيم في السمة 0 في قيمة عددية:
| 4 8 12 |
| 16 20 24 |
إذا قلّلنا السمة 2، نحصل أيضًا على صفيف ثنائي الأبعاد تم تجميع كل القيم في السمة 2 في قيمة عددية:
| 6 15 |
| 6 15 |
| 6 15 |
| 6 15 |
يُرجى العِلم أنّه يتم الحفاظ على الترتيب النسبي بين السمات المتبقية في الإدخال في الإخراج، ولكن قد يتم تخصيص أرقام جديدة لبعض السمات (لأنّه يتغيّر عدد السمات).
يمكننا أيضًا تقليل الأبعاد المتعددة. تؤدي إضافة السمتَين 0 و1 إلى تقليل القيمة، ما ينتج عنه
صفيف 1D [20, 28, 36]
.
يؤدي تقليل الصفيف الثلاثي الأبعاد على جميع أبعاده إلى إنشاء المقياس 84
.
دالة Reduce المتعدّدة المَعلمات
عندما يكون N > 1
، يكون تطبيق دالة reduce أكثر تعقيدًا قليلاً، لأنّه يتم
تطبيقه في الوقت نفسه على جميع المدخلات. يتم تقديم المَعلمات إلى عملية ال حساب بالترتيب التالي:
- تنفيذ قيمة مخفضة للمعامل الأول
- ...
- تشغيل قيمة مخفضة للمعامل N
- إدخال قيمة للم Operand الأول
- ...
- إدخال قيمة للمَعلمة N
على سبيل المثال، نأخذ في الاعتبار دالة الاختزال التالية التي يمكن استخدامها للقيام بحساب الحد الأقصى وargmax لصفيف أحادي الأبعاد بشكل موازٍ:
f: (Float, Int, Float, Int) -> Float, Int
f(max, argmax, value, index):
if value >= max:
return (value, index)
else:
return (max, argmax)
بالنسبة إلى صفائف الإدخال V = Float[N], K = Int[N]
ذي الأبعاد الواحدة وقيم البدء
I_V = Float, I_K = Int
، فإنّ النتيجة f_(N-1)
الناتجة عن التقليل على مستوى سمة الإدخال الوحيدة هي ما يعادل التطبيق المتكرّر التالي:
f_0 = f(I_V, I_K, V_0, K_0)
f_1 = f(f_0.first, f_0.second, V_1, K_1)
...
f_(N-1) = f(f_(N-2).first, f_(N-2).second, V_(N-1), K_(N-1))
سيؤدي تطبيق هذا التخفيض على صفيف من القيم وصفيف من المؤشرات التسلسلية (أي iota) إلى التكرار المشترَك على الصفيفات، وعرض مجموعة تربعية تحتوي على القيمة القصوى والمؤشر المطابق.
ReducePrecision
يمكنك الاطّلاع أيضًا على
XlaBuilder::ReducePrecision
.
يحدِّد تأثير تحويل قيم النقطة العائمة إلى تنسيق بدقة أقل (مثل IEEE-FP16) والعودة إلى التنسيق الأصلي. يمكن تحديد عدد وبتَي القاعدة والأس في التنسيق الأقل دقة بشكلٍ عشوائي، على الرغم من أنّه قد لا تكون جميع أحجام البتات متوافقة مع جميع عمليات تنفيذ الأجهزة.
ReducePrecision(operand, mantissa_bits, exponent_bits)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة من النوع النقطة العائمة T |
exponent_bits |
int32 |
عدد بتات الأس في تنسيق بدقة أقل |
mantissa_bits |
int32 |
عدد بتات الكسور العشرية بتنسيق دقة أقل |
والنتيجة هي صفيف من النوع T
. يتم تقريب قيم الإدخال إلى أقرب
قيمة يمكن تمثيلها باستخدام العدد المحدّد من بتات الكسور العشرية (باستخدام الدلالات "الربط بالعدد الصحيح"
)، ويتم ضبط أي قيم تتجاوز النطاق المحدّد بعدد ملفّات ومقاييس القيمة المطلقة على ما لا نهاية موجبًا أو سالبًا. يتم
الاحتفاظ بقيم NaN
، على الرغم من أنّه قد يتم تحويلها إلى قيم NaN
عادية.
يجب أن يتضمّن التنسيق الأقل دقة رمزًا واحدًا على الأقل للقوة (لتمييز قيمة الصفر عن القيمة اللانهائية، لأنّ كلاهما يتضمّن مانتيساً تساوي صفرًا)، ويجب أن يتضمّن عددًا غير سالب من وحدات المانتيسا. قد يتجاوز عدد بتات الأس أو
الجزء العشري القيمة المقابلة للنوع T
، ويكون الجزء
المناظر من عملية التحويل مجرد عملية لا تؤدي إلى أيّ نتيجة.
ReduceScatter
يمكنك الاطّلاع أيضًا على
XlaBuilder::ReduceScatter
.
ReduceScatter هي عملية جماعية تُجري بشكل فعّال عملية AllReduce ثم تُوزّع النتيجة من خلال تقسيمها إلى shard_count
كتل على طول
scatter_dimension
وتتلقّى النسخة المكرّرة i
في مجموعة النُسخ المكرّرة شريحة ith
.
ReduceScatter(operand, computation, scatter_dim, shard_count,
replica_group_ids, channel_id)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف أو مجموعة غير فارغة من الصفائف لتقليلها على مستوى النُسخ المكرّرة |
computation |
XlaComputation |
احتساب التخفيض |
scatter_dimension |
int64 |
السمة المطلوب بعثرها |
shard_count |
int64 |
عدد المجموعات المطلوب تقسيمها scatter_dimension |
replica_groups |
متّجه المتّجهات int64 |
المجموعات التي يتم إجراء التخفيضات بينها |
channel_id |
اختياري int64 |
معرّف قناة اختياري للتواصل بين الوحدات |
- عندما تكون
operand
صفيفًا من الصفائف، يتم تنفيذ عملية التجميع-التوزيع على كل عنصر من الصفيف. replica_groups
هي قائمة بمجموعات النُسخ التي يتم التقليل بينها (يمكن استرداد معرّف النسخة الحالية باستخدامReplicaId
). يحدّد ترتيب النُسخ في كل مجموعة الترتيب الذي سيتم فيه توزيع نتيجة التقليل الشامل. يجب أن يكون الحقلreplica_groups
فارغًا (وفي هذه الحالة تنتمي جميع النُسخ المكرّرة إلى مجموعة واحدة)، أو أن يحتوي على عدد العناصر نفسه لعدد النُسخ المكرّرة. عندما يكون هناك أكثر من مجموعة نُسخ طبق الأصل واحدة، يجب أن تكون جميعها بالحجم نفسه. على سبيل المثال، يُجريreplica_groups = {0, 2}, {1, 3}
عملية تقليل بين النسخ المكرّرة0
و2
و1
و3
، ثم ينشر النتيجة.shard_count
هو حجم كل مجموعة نُسخ. نحتاج إلى ذلك في الحالات التي تكون فيها قيمة الحقلreplica_groups
فارغة. إذا لم تكنreplica_groups
فارغة، يجب أن تساويshard_count
حجم كل مجموعة نُسخ طبق الأصل.- يتم استخدام
channel_id
للتواصل بين الوحدات: لا يمكن إلاreduce-scatter
للعمليات التي تحملchannel_id
نفسه التواصل مع بعضها.
شكل الإخراج هو شكل الإدخال الذي تم جعله أصغر scatter_dimension
shard_count
مرة. على سبيل المثال، إذا كانت هناك نسختان طبق الأصل وكان الم Operand يحمل القيمة [1.0, 2.25]
و[3.0, 5.25]
على التوالي في نسختَي النسخ، ستكون قيمة الإخراج من هذا الإجراء الذي يكون فيه scatter_dim
هو 0
هي
[4.0]
للنسخة الأولى و[7.5]
للنسخة الثانية.
ReduceWindow
يمكنك الاطّلاع أيضًا على
XlaBuilder::ReduceWindow
.
تطبِّق دالة تقليل على جميع العناصر في كل نافذة من تسلسل N
مصفوفات متعددة الأبعاد، ما يؤدي إلى إنشاء صفيف واحد أو مجموعة من N
مصفوفات متعددة الأبعاد كإخراج. تحتوي كل صفيف إخراج على عدد العناصر نفسه المُمثّل
لعدد المواضع الصالحة للنافذة. يمكن التعبير عن طبقة التجميع على النحو التالي:
ReduceWindow
. على غرار Reduce
، يتم دائمًا تطبيق computation
بعد init_values
على يمين الصفحة.
ReduceWindow(operands..., init_values..., computation, window_dimensions,
window_strides, padding)
الوسيطات | النوع | الدلالات |
---|---|---|
operands |
N XlaOps |
تسلسل من صفائف متعددة الأبعاد من النوع T_0,..., T_{N-1} بعدد N، يمثّل كلّ منها المنطقة الأساسية التي يتمّ وضع النافذة عليها |
init_values |
N XlaOps |
القيم البادئة N للاختزال، واحدة لكل مَعلمة من المَعلمات N راجِع تقليل لمعرفة التفاصيل. |
computation |
XlaComputation |
دالة تقليل من النوع T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}) ، لتطبيقها على العناصر في كل نافذة من جميع عناصر الإدخال |
window_dimensions |
ArraySlice<int64> |
صفيف من الأعداد الصحيحة لقيم سمة الفترة |
window_strides |
ArraySlice<int64> |
صفيف من الأعداد الصحيحة لقيم خطوة النافذة |
base_dilations |
ArraySlice<int64> |
صفيف من الأعداد الصحيحة لقيم التمدد الأساسية |
window_dilations |
ArraySlice<int64> |
صفيف من الأعداد الصحيحة لقيم تمديد النافذة |
padding |
Padding |
نوع الحشو للنافذة (Padding::kSame، الذي يضيف الحشو للحصول على شكل الإخراج نفسه مثل الإدخال إذا كانت الخطوة 1، أو Padding::kValid، الذي لا يستخدم أيّ حشو و "يوقف" النافذة بعد أن تصبح غير مناسبة) |
المكان:
- يجب أن تكون قيمة N أكبر من أو تساوي 1.
- يجب أن تتطابق أبعاد جميع صفائف الإدخال.
- إذا كان
N = 1
،Collate(T)
هوT
. - إذا كان
N > 1
،Collate(T_0, ..., T_{N-1})
عبارة عن مجموعة من عناصرN
من النوع(T0,...T{N-1})
.
يوضّح الرمز والشكل أدناه مثالاً على استخدام ReduceWindow
. الإدخال هو
مصفوفة بحجم [4x6] وكل من سمات window_dimensions وwindow_stride_dimensions هي
[2x3].
// Create a computation for the reduction (maximum).
XlaComputation max;
{
XlaBuilder builder(client_, "max");
auto y = builder.Parameter(0, ShapeUtil::MakeShape(F32, {}), "y");
auto x = builder.Parameter(1, ShapeUtil::MakeShape(F32, {}), "x");
builder.Max(y, x);
max = builder.Build().value();
}
// Create a ReduceWindow computation with the max reduction computation.
XlaBuilder builder(client_, "reduce_window_2x3");
auto shape = ShapeUtil::MakeShape(F32, {4, 6});
auto input = builder.Parameter(0, shape, "input");
builder.ReduceWindow(
input,
/*init_val=*/builder.ConstantLiteral(LiteralUtil::MinValue(F32)),
*max,
/*window_dimensions=*/{2, 3},
/*window_stride_dimensions=*/{2, 3},
Padding::kValid);
تشير الخطوة التي تساوي 1 في سمة إلى أنّ موضع النافذة في سمة يبعد عنصرًا واحدًا عن النافذة المجاورة. لتحديد أنّه لا تتداخل أيّ نوافذ مع بعضها، يجب أن تكون سمات window_stride_dimensions مساوية لسمات window_dimensions. يوضّح الشكل أدناه استخدام قيم مختلفتَين لسمة الخطوة. يتم تطبيق الحشو على كل سمة من سمات الإدخال، وتكون العمليات الحسابية متماثلة كما لو أنّ الإدخال قد تم إدخاله بالسمات التي يحتوي عليها بعد الحشو.
للحصول على مثال على الحشو غير البسيط، ننصحك بحساب الحد الأدنى لإطار التقليل
(القيمة الأولية هي MAX_FLOAT
) باستخدام السمة 3
وخطوة التقدّم 2
على مصفوفة الإدخال
[10000, 1000, 100, 10, 1]
. تعمل دالة الحشو kValid
على احتساب الحد الأدنى على مدار فترتين
صالحتَين: [10000, 1000, 100]
و[100, 10, 1]
، ما يؤدي إلى
الناتج [100, 1]
. تعمل دالة الحشو kSame
أولاً على إضافة عناصر إلى الصفيف لكي يكون الشكل بعد
نافذة الاختزال مماثلًا للإدخال في الخطوة الأولى من خلال إضافة عناصر
أولية على كلا الجانبين، ما يؤدي إلى الحصول على [MAX_VALUE, 10000, 1000, 100, 10, 1,
MAX_VALUE]
. يؤدي تشغيل دالة reduce-window على الصفيف المُضاف إليه محتوى إلى العمل على ثلاث
نوافذ [MAX_VALUE, 10000, 1000]
و[1000, 100, 10]
و[10, 1, MAX_VALUE]
، ويؤدي إلى توليد[1000, 10, 1]
.
إنّ ترتيب تقييم دالة الاختزال عشوائي وقد يكون
غير حاسم. لذلك، يجب ألا تكون دالة التخفيض حساسة بشكل مفرط
لإعادة الربط. اطّلِع على المناقشة حول الارتباط في
سياق Reduce
للحصول على مزيد من التفاصيل.
ReplicaId
يمكنك الاطّلاع أيضًا على
XlaBuilder::ReplicaId
.
تُعيد هذه الدالة المعرّف الفريد (عدد صحيح 32 بت) للنسخة.
ReplicaId()
المعرّف الفريد لكل نسخة هو عدد صحيح غير موقَّع في النطاق [0, N)
،
حيث يكون N
هو عدد النُسخ. بما أنّ جميع النُسخ المكرّرة تعمل بالبرنامج نفسه، سيؤدي استدعاء ReplicaId()
في البرنامج إلى عرض قيمة مختلفة في
كل نسخة مكرّرة.
إعادة التشكيل
راجِع أيضًا
XlaBuilder::Reshape
وعملية Collapse
.
تعيد تشكيل سمات صفيف إلى تكوين جديد.
Reshape(operand, dimensions)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من النوع T |
dimensions |
int64 متّجه |
متجه أحجام السمات الجديدة |
من الناحية النظرية، تعمل دالة reshape أولاً على تسطيح صفيف إلى متجه أحادي الأبعاد من
قيم البيانات، ثمّ تنقّي هذا المتجه إلى شكل جديد. تشكل وسيطات الإدخال
مصفوفة عشوائية من النوع T، وناقلاً ثابتًا في وقت الترجمة لعناصر فهرس السمات، وناقلاً ثابتًا في وقت الترجمة لحجم السمات للنتيجة.
يحدِّد متجه dimensions
حجم مصفوفة الإخراج. القيمة في
الفهرس 0 في dimensions
هي حجم السمة 0، والقيمة في الفهرس 1 هي
حجم السمة 1، وهكذا. يجب أن يساوي حاصل ضرب سمات dimensions
حاصل ضرب أحجام سمات الم Operand. عند تحسين المصفوفة المُدمَجة
إلى المصفوفة متعددة الأبعاد التي تحدّدها dimensions
، يتم ترتيب السمات في
dimensions
من الأكثر اختلافًا ببطء (الأكثر أهمية) إلى الأكثر اختلافًا بسرعه (الأكثر ثانوية).
على سبيل المثال، لنفترض أنّ v هي مصفوفة من 24 عنصرًا:
let v = f32[4x2x3] { { {10, 11, 12}, {15, 16, 17} },
{ {20, 21, 22}, {25, 26, 27} },
{ {30, 31, 32}, {35, 36, 37} },
{ {40, 41, 42}, {45, 46, 47} } };
let v012_24 = Reshape(v, {24});
then v012_24 == f32[24] {10, 11, 12, 15, 16, 17, 20, 21, 22, 25, 26, 27,
30, 31, 32, 35, 36, 37, 40, 41, 42, 45, 46, 47};
let v012_83 = Reshape(v, {8,3});
then v012_83 == f32[8x3] { {10, 11, 12}, {15, 16, 17},
{20, 21, 22}, {25, 26, 27},
{30, 31, 32}, {35, 36, 37},
{40, 41, 42}, {45, 46, 47} };
كحالة خاصة، يمكن أن تحوِّل الدالة reshape صفيفًا يتألّف من عنصر واحد إلى عدد سكالري، والعكس صحيح. على سبيل المثال:
Reshape(f32[1x1] { {5} }, {}) == 5;
Reshape(5, {1,1}) == f32[1x1] { {5} };
Rev (عكس)
يمكنك الاطّلاع أيضًا على
XlaBuilder::Rev
.
Rev(operand, dimensions)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من النوع T |
dimensions |
ArraySlice<int64> |
السمات المطلوب عكسها |
تعكس ترتيب العناصر في صفيف operand
على طول
dimensions
المحدّد، ما يؤدي إلى إنشاء صفيف ناتج بالشكل نفسه. يتم تخزين كل عنصر من ملف
صفيف المعاملات في فهرس متعدد الأبعاد في صفيف الإخراج في ملف
فهرس محوَّل. يتم تحويل المؤشر المتعدّد الأبعاد عن طريق عكس
المؤشر في كلّ سمة تريد عكسها (أي إذا كانت سمة بحجم N هي إحدى
السمات التي تريد عكسها، يتم تحويل مؤشرها i إلى N - 1 - i).
من بين استخدامات عملية Rev
عكس صفيف أوزان التفاف على طول
سمتَي النافذة أثناء احتساب التدرّج في الشبكات العصبية.
RngNormal
يمكنك الاطّلاع أيضًا على
XlaBuilder::RngNormal
.
تُنشئ دالة RANDALL ناتجًا بشكل معيّن باستخدام أرقام عشوائية يتم إنشاؤها وفقًا للتوزيع \(N(\mu, \sigma)\) العادي. يجب أن يكون للمَعلمتَين \(\mu\) و \(\sigma\)و شكل الإخراج نوع عنصر فاصلة عائمة. بالإضافة إلى ذلك، يجب أن تكون المَعلمات ذات قيمة عددية.
RngNormal(mu, sigma, shape)
الوسيطات | النوع | الدلالات |
---|---|---|
mu |
XlaOp |
عدد скалري من النوع T يحدِّد متوسّط الأرقام التي تم إنشاؤها |
sigma |
XlaOp |
عدد скалري من النوع T يحدِّد الانحراف المعياري للقيمة التي تم إنشاؤها |
shape |
Shape |
شكل الإخراج من النوع T |
RngUniform
يمكنك الاطّلاع أيضًا على
XlaBuilder::RngUniform
.
تُنشئ هذه الدالة ناتجًا لشكل معيّن باستخدام أرقام عشوائية يتم إنشاؤها باتّباع التوزيع الموحّد على النطاق \([a,b)\). يجب أن تكون المَعلمات ونوع عنصر المخرجات من النوع المنطقي أو النوع الصحيح أو النوع المتغير النقطة العائمة، ويجب أن تكون الأنواع متسقة. لا تتوافق الخلفيات لوحدة المعالجة المركزية ووحدة معالجة الرسومات حاليًا سوى مع F64 وF32 وF16 وBF16 وS64 وU64 وS32 وU32. بالإضافة إلى ذلك، يجب أن تكون المَعلمات ذات قيمة عددية. إذا \(b <= a\) كانت النتيجة محددة من خلال التنفيذ
RngUniform(a, b, shape)
الوسيطات | النوع | الدلالات |
---|---|---|
a |
XlaOp |
عدد скалري من النوع T يحدِّد الحدّ الأدنى للفاصل |
b |
XlaOp |
عدد скалري من النوع T يحدِّد الحدّ الأقصى للفاصل |
shape |
Shape |
شكل الإخراج من النوع T |
RngBitGenerator
تُنشئ هذه الدالة إخراجًا بشكل معيّن مملوء بوحدات بت عشوائية موحّدة باستخدام الخوارزمية المحدّدة (أو الإعداد التلقائي للخلفية) وتُرجع حالة معدَّلة (بالشكل نفسه للحالة الأولية) والبيانات العشوائية التي تم إنشاؤها.
الحالة المبدئية هي الحالة المبدئية لإنشاء الأرقام العشوائية الحالية. ويعتمد الشكل المطلوب والقيم الصالحة على الخوارزمية المستخدَمة.
نضمن أنّ الإخراج هو دالة حتمية للحالة الأولية، ولكنلا نضمن أنّه حتمِي بين الخلفيات وإصدارات compilers المختلفة.
RngBitGenerator(algorithm, key, shape)
الوسيطات | النوع | الدلالات |
---|---|---|
algorithm |
RandomAlgorithm |
خوارزمية PRNG التي سيتم استخدامها |
initial_state |
XlaOp |
الحالة الأولية لخوارزمية PRNG |
shape |
Shape |
شكل الإخراج للبيانات التي تم إنشاؤها |
القيم المتاحة لسمة algorithm
:
rng_default
: خوارزمية خاصة بالخلفية مع متطلبات شكل خاصة بالخلفيةrng_three_fry
: خوارزمية PRNG المستندة إلى العداد ThreeFry شكلinitial_state
هوu64[2]
مع قيم عشوائية. Salmon et al. SC 2011. أرقام عشوائية متوازية: خطوات سهلة وبسيطةrng_philox
: خوارزمية Philox لإنشاء أرقام عشوائية بشكل موازٍ شكلinitial_state
هوu64[3]
بقيم عشوائية. Salmon et al. SC 2011. أرقام عشوائية متوازية: خطوات سهلة وبسيطة
رسم بياني للنقاط المبعثرة
تُنشئ عملية التوزيع في XLA تسلسلًا من النتائج التي هي قيم
صفيف الإدخال operands
، مع عدّة شرائح (في الفهارس المحدّدة باستخدام
scatter_indices
) تم تعديلها باستخدام تسلسل القيم في updates
باستخدام
update_computation
.
يمكنك الاطّلاع أيضًا على
XlaBuilder::Scatter
.
scatter(operands..., scatter_indices, updates..., update_computation,
index_vector_dim, update_window_dims, inserted_window_dims,
scatter_dims_to_operand_dims)
الوسيطات | النوع | الدلالات |
---|---|---|
operands |
تسلسل N XlaOp |
مصفوفات N من الأنواع T_0, ..., T_N التي سيتم توزيعها عليها |
scatter_indices |
XlaOp |
صفيف يحتوي على الفواصل الزمنية لبداية الشرائح التي يجب توزيعها عليها |
updates |
تسلسل N XlaOp |
مصفوفات N من أنواع T_0, ..., T_N يحتوي updates[i] على القيم التي يجب استخدامها لدالة التشتت operands[i] . |
update_computation |
XlaComputation |
عملية الحساب التي سيتم استخدامها لدمج القيم الحالية في صفيف الإدخال والتعديلات أثناء التوزيع يجب أن تكون هذه العملية الحسابية من النوع T_0, ..., T_N, T_0, ..., T_N -> Collate(T_0, ..., T_N) . |
index_vector_dim |
int64 |
السمة في scatter_indices التي تحتوي على الفهارس الافتتاحية. |
update_window_dims |
ArraySlice<int64> |
مجموعة الأبعاد في شكل updates التي تشكّل أبعاد النافذة |
inserted_window_dims |
ArraySlice<int64> |
مجموعة أبعاد النافذة التي يجب إدراجها في شكل updates |
scatter_dims_to_operand_dims |
ArraySlice<int64> |
خريطة سمات من مؤشرات الانتشار إلى مساحة فهرس الم Operand يتم تفسير هذا الصفيف على أنّه يربط i بـ scatter_dims_to_operand_dims[i] . يجب أن يكون العدد فرديًا وإجماليًا. |
indices_are_sorted |
bool |
ما إذا كان من المؤكد أن يتم ترتيب الفهارس حسب المُتصل |
unique_indices |
bool |
ما إذا كان المتصل يضمن أنّ الفهارس فريدة |
المكان:
- يجب أن تكون قيمة N أكبر من أو تساوي 1.
- يجب أن تتضمّن كلّ من
operands
[0
] و... وoperands
[N-1
] السمات نفسها. - يجب أن تتضمّن كلّ من
updates
[0
] و... وupdates
[N-1
] السمات نفسها. - إذا كان
N = 1
،Collate(T)
هوT
. - إذا كان
N > 1
،Collate(T_0, ..., T_N)
عبارة عن مجموعة من عناصرN
من النوعT
.
إذا كانت index_vector_dim
تساوي scatter_indices.rank
، نفترض ضمنيًا أنّه
scatter_indices
تحتوي على سمة 1
متأخرة.
نحدِّد update_scatter_dims
من النوع ArraySlice<int64>
على أنّه مجموعة
السمات في شكل updates
التي لا تنتمي إلى update_window_dims
، بترتيب صعودي.
يجب أن تلتزم وسيطات التوزيع بالقيود التالية:
يجب أن تحتوي كل مصفوفة
updates
علىupdate_window_dims.size + scatter_indices.rank - 1
سمة.يجب أن تتوافق حدود السمة
i
في كل صفيفupdates
مع النقاط التالية:- إذا كانت
i
متوفّرة فيupdate_window_dims
(أي تساويupdate_window_dims
[k
] لبعضk
)، يجب ألا يتجاوز حدّ السمةi
فيupdates
الحدّ المقابل لoperand
بعد تضمينinserted_window_dims
(أيadjusted_window_bounds
[k
]، حيث يحتويadjusted_window_bounds
على حدودoperand
مع إزالة الحدود في الفهرسinserted_window_dims
). - إذا كانت قيمة
i
متوفّرة فيupdate_scatter_dims
(أي تساويupdate_scatter_dims
[k
] لبعض القيمk
)، يجب أن يكون حدّ السمةi
فيupdates
مساويًا للحدّ المقابل لscatter_indices
، مع تخطّيindex_vector_dim
(أيscatter_indices.shape.dims
[k
]، إذا كانتk
<index_vector_dim
وscatter_indices.shape.dims
[k+1
] في الحالات الأخرى).
- إذا كانت
يجب أن يكون
update_window_dims
بترتيب تصاعدي، وألا يتضمّن أي أرقام سمات متكرّرة، وأن يكون ضمن النطاق[0, updates.rank)
.يجب أن يكون
inserted_window_dims
بترتيب تصاعدي، وألا يتضمّن أي أرقام سمات متكرّرة، وأن يكون ضمن النطاق[0, operand.rank)
.يجب أن يساوي
operand.rank
مجموعupdate_window_dims.size
وinserted_window_dims.size
.يجب أن تكون
scatter_dims_to_operand_dims.size
مساويةscatter_indices.shape.dims
[index_vector_dim
]، ويجب أن تكون قيمها في النطاق[0, operand.rank)
.
بالنسبة إلى فهرس معيّن U
في كل صفيف updates
، يتم احتساب الفهرس المقابل I
في
صفيف operands
المقابل الذي يجب تطبيق هذا التعديل عليه
على النحو التالي:
- لنفترض أنّ
G
= {U
[k
] لـk
فيupdate_scatter_dims
}. استخدِمG
للبحث عن متجه الفهرسS
في صفيفscatter_indices
بحيث يكونS
[i
] =scatter_indices
[Combine(G
,i
)] حيث تُدرج دالة Combine(A, b) العنصر b في المواضعindex_vector_dim
في A. - أنشئ فهرسًا
S
in
فيoperand
باستخدامS
من خلال نثرS
باستخدام خريطةscatter_dims_to_operand_dims
. أسلوب أكثر رسمية:S
in
[scatter_dims_to_operand_dims
[k
]] =S
[k
] إذا كانk
<scatter_dims_to_operand_dims.size
.S
in
[_
] =0
بخلاف ذلك.
- أنشئ فهرسًا
W
in
في كل صفيفoperands
من خلال نثر الفهارس فيupdate_window_dims
فيU
وفقًا لinserted_window_dims
. أسلوب أكثر رسمية:W
in
[window_dims_to_operand_dims
(k
)] =U
[k
] إذا كانk
فيupdate_window_dims
، حيثwindow_dims_to_operand_dims
هي الوظيفة الأحادية الاتجاه التي لها النطاق [0
،update_window_dims.size
) والنطاق [0
،operand.rank
) \inserted_window_dims
. (على سبيل المثال، إذا كانupdate_window_dims.size
هو4
وoperand.rank
هو6
وinserted_window_dims
هو {0
،2
}، يكونwindow_dims_to_operand_dims
هو {0
→1
،1
→3
،2
→4
،3
→5
}).W
in
[_
] =0
بخلاف ذلك.
I
هوW
in
+S
in
حيث يشير الرمز + إلى عملية جمع العناصر.
باختصار، يمكن تعريف عملية التشتت على النحو التالي.
- اضبط
output
علىoperands
، أي لجميع الفهارسJ
، لجميع الفهارسO
في المصفوفةoperands
[J
]:
output
[J
][O
] =operands
[J
][O
] - لكل فهرس
U
في الصفيفupdates
[J
] والفهرس المقابلO
في الصفيفoperand
[J
]، إذا كانO
فهرسًا صالحًا لسمةoutput
:
(output
[0
][O
]، ...،output
[N-1
][O
]) =update_computation
(output
[0
][O
]، ...، ،output
[N-1
][O
]،updates
[0
][U
]، ...،updates
[N-1
][U
])
إنّ ترتيب تطبيق التعديلات غير محدّد. وبالتالي، عندما تشير عدة فهرسات في updates
إلى الفهرس نفسه في operands
، ستكون القيمة المقابلة في output
غير محدّدة.
تجدر الإشارة إلى أنّ المَعلمة الأولى التي يتم تمريرها إلى update_computation
ستكون
دائمًا القيمة الحالية من صفيف output
، وستكون المَعلمة الثانية
دائمًا القيمة من صفيف updates
. وهذا مهم
بشكل خاص في الحالات التي تكون فيها update_computation
غير تبديلية.
في حال ضبط indices_are_sorted
على "صحيح"، يمكن أن تفترض XLA أنّه تم ترتيب
scatter_indices
(بترتيب تصاعدي، بعد توزيع قيمه
وفقًا لـ scatter_dims_to_operand_dims
) من قِبل المستخدم. وإذا لم يكن الأمر كذلك، يتم تحديد المعاني من خلال التنفيذ.
إذا تم ضبط unique_indices
على true، يمكن أن تفترض XLA أنّ جميع العناصر
المُشتَتة هي فريدة. وبالتالي، يمكن أن تستخدم XLA عمليات غير ذرية. إذا تم ضبط قيمة
unique_indices
على "صحيح" وكانت الفهارس التي يتم توزيعها عليها ليست
فريدة، تكون الدلالات محدّدة من التنفيذ.
بشكل غير رسمي، يمكن اعتبار عملية التشتيت عكس عملية التجميع، أي أنّه تُعدّل عملية التشتيت العناصر في الإدخال التي يتم استخراجها من قِبل عملية التجميع المقابلة.
للحصول على وصف غير رسمي مفصّل وأمثلة، يُرجى الرجوع إلى القسم
"الوصف غير الرسمي" ضمن Gather
.
اختيار
يمكنك الاطّلاع أيضًا على
XlaBuilder::Select
.
تُنشئ صفيفًا للإخراج من عناصر صفيفَي إدخال استنادًا إلى قيم صفيف العبارة.
Select(pred, on_true, on_false)
الوسيطات | النوع | الدلالات |
---|---|---|
pred |
XlaOp |
مصفوفة من النوع PRED |
on_true |
XlaOp |
صفيف من النوع T |
on_false |
XlaOp |
صفيف من النوع T |
يجب أن تكون المصفوتان on_true
وon_false
بالشكل نفسه. وهذا هو أيضًا
شكل صفيف الإخراج. يجب أن تكون السمات في المصفوفة pred
مماثلة لسمات
on_true
وon_false
، مع نوع العنصر PRED
.
بالنسبة إلى كل عنصر P
من pred
، يتم أخذ العنصر المقابل في صفيف الإخراج
من on_true
إذا كانت قيمة P
هي true
، ومن on_false
إذا كانت
قيمة P
هي false
. بما أنّه شكل محظور من البث، يمكن أن يكون
pred
عددًا متسلسلاً من النوع PRED
. في هذه الحالة، يتم أخذ صفيف الإخراج
بالكامل من on_true
إذا كانت pred
هي true
، ومن on_false
إذا كانت pred
هي
false
.
مثال على pred
غير متّجه:
let pred: PRED[4] = {true, false, false, true};
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 200, 300, 4};
مثال على دالة قياسية pred
:
let pred: PRED = true;
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 2, 3, 4};
تتوفّر خيارات بين القوائم. تُعتبر القوائم المتعدّدة أنواعًا scalar
لهذا الغرض. إذا كان on_true
وon_false
مجموعتَين من القيم (يجب أن يكون لهما
الشكل نفسه)، يجب أن يكون pred
عددًا متسلسلًا من النوع PRED
.
SelectAndScatter
يمكنك الاطّلاع أيضًا على
XlaBuilder::SelectAndScatter
.
يمكن اعتبار هذه العملية عملية مركبة تحسب أولاً
ReduceWindow
على صفيف operand
لاختيار عنصر من كل نافذة، ثم تبعثِر صفيف source
على فهارس العناصر المحدّدة لمحاولة
إنشاء صفيف ناتج بالشكل نفسه لصفيف الم Operand. تُستخدَم الدالة الثنائية
select
لاختيار عنصر من كل نافذة من خلال تطبيقها
على كل نافذة، ويتمّ استدعاؤها مع السمة التي تجعل متجه فهرس المَعلمة الأولى أقلّ ترتيبًا أبجديًا من متجه فهرس المَعلمة الثانية. تعرِض الدالة select
القيمة true
إذا تم اختيار المَعلمة الأولى، وتعرِض القيمة false
إذا تم اختيار المَعلمة الثانية، ويجب أن تحافظ الدالة على التسلسل (أي إذا كان select(a, b)
وselect(b, c)
true
، يكون select(a, c)
هو true
أيضًا) لكي لا يعتمد العنصر المحدّد على ترتيب العناصر التي يتم التنقّل فيها خلال فترة زمنية معيّنة.
يتم تطبيق الدالة scatter
على كل فهرس محدّد في صفيف الإخراج. ويقبل دالة الوسيط المتغير سمتَين قياسيتين:
- القيمة الحالية في الفهرس المحدّد في صفيف النتائج
- قيمة النقاط المتبعثرة من
source
التي تنطبق على الفهرس المحدّد
يجمع هذا الدالة بين المَعلمتَين ويعرض قيمة عددية تستخدم لتعديل
القيمة في الفهرس المحدّد في صفيف الإخراج. في البداية، يتم ضبط جميع فهارس
صفيف الإخراج على init_value
.
يكون شكل مصفوفة الإخراج هو نفسه شكل مصفوفة operand
، ويجب أن يكون شكل مصفوفة source
هو نفسه شكل نتيجة تطبيق عملية ReduceWindow
على مصفوفة operand
. يمكن استخدام SelectAndScatter
ل
الانتشار العكسي لقيم التدرّج لطبقة تجميع في شبكة عصبية.
SelectAndScatter(operand, select, window_dimensions, window_strides,
padding, source, init_value, scatter)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من النوع T تنزلق النوافذ فوقه |
select |
XlaComputation |
عملية حسابية ثنائية من النوع T, T -> PRED ، لتطبيقها على جميع العناصر في كل نافذة، تعرِض true في حال اختيار المَعلمة الأولى وتعرِض false في حال اختيار المَعلمة الثانية |
window_dimensions |
ArraySlice<int64> |
صفيف من الأعداد الصحيحة لقيم سمة الفترة |
window_strides |
ArraySlice<int64> |
صفيف من الأعداد الصحيحة لقيم خطوة النافذة |
padding |
Padding |
نوع الحشو للنافذة (Padding::kSame أو Padding::kValid) |
source |
XlaOp |
مصفوفة من النوع T تحتوي على القيم المطلوب بعثرها |
init_value |
XlaOp |
قيمة عددية من النوع T للقيمة الأولية لصفيف الإخراج |
scatter |
XlaComputation |
حساب ثنائي من النوع T, T -> T لتطبيق كل عنصر مصدر خطوط متقطعة مع عنصر الوجهة |
يعرض الشكل أدناه أمثلة على استخدام SelectAndScatter
، مع احتساب الدالة select
للقيمة القصوى بين مَعلماتها. يُرجى العِلم أنّه عندما تتراكب
النوافذ، كما هو موضّح في الشكل (2) أدناه، قد يتم
اختيار فهرس مصفوفة operand
عدة مرات من خلال نوافذ مختلفة. في الشكل، يتم اختيار العنصر الذي يمثّل القيمة 9 من خلال كلتا النافذتَين العلويتَين (الأزرق والأحمر)، وتُنشئ دالة الإضافة الثنائية scatter
عنصر الإخراج الذي يمثّل القيمة 8 (2 + 6).
ترتيب تقييم الدالة scatter
عشوائي وقد يكون
غير محدّد. لذلك، يجب ألا تكون دالة scatter
حساسة بشكل مفرط
لإعادة الربط. اطّلِع على المناقشة حول الارتباط في
سياق Reduce
للحصول على مزيد من التفاصيل.
إرسال
يمكنك الاطّلاع أيضًا على
XlaBuilder::Send
.
Send(operand, channel_handle)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
البيانات المطلوب إرسالها (صفيف من النوع T) |
channel_handle |
ChannelHandle |
معرّف فريد لكل زوج من الإرسال/الاستلام |
تُرسِل بيانات الم Operand المحدَّدة إلى Recv
في عملية حسابية أخرى
تشترك في معرّف القناة نفسه. لا تعرض أي بيانات.
على غرار عملية Recv
، تمثّل واجهة برمجة التطبيقات للعميل لعملية Send
التواصل غير المتزامن، ويتم تقسيمها داخليًا إلى تعليمات HLO بدورتين
(Send
وSendDone
) لتفعيل عمليات نقل البيانات غير المتزامنة. يمكنك أيضًا الاطّلاع على
HloInstruction::CreateSend
وHloInstruction::CreateSendDone
.
Send(HloInstruction operand, int64 channel_id)
تبدأ عملية نقل غير متزامنة للمَعلمة إلى الموارد التي تم تخصيصها باستخدام Recv
مع معرّف القناة نفسه. تُعرِض سياقًا يتم استخدامه في SendDone
التالي للانتظار إلى أن تكتمل عملية نقل البيانات. السياق هو مجموعة من {operand (shape), request identifier
(U32)} ولا يمكن استخدامه إلا من خلال تعليمات SendDone
.
SendDone(HloInstruction context)
استنادًا إلى سياق تم إنشاؤه بواسطة تعليمات Send
، ينتظر اكتمال نقل البيانات. لا تعرض التعليمات أي بيانات.
تحديد موعد إرسال تعليمات القناة
في ما يلي ترتيب تنفيذ التعليمات الأربعة لكل قناة (Recv
وRecvDone
Send
وSendDone
).
- يحدث
Recv
قبلSend
- يحدث
Send
قبلRecvDone
- يحدث
Recv
قبلRecvDone
- يحدث
Send
قبلSendDone
عندما تنشئ برامج التحويل البرمجي في الخلفية جدولاً زمنيًا خطيًا لكل عملية حسابية تتم من خلال تعليمات القناة، يجب ألا تكون هناك دورات في العمليات الحسابية. على سبيل المثال، تؤدي الجداول الزمنية أدناه إلى حدوث حالات "توقّف عمليات متعددة في انتظار بعضها".
يُرجى العلم أنّ القيود المفروضة على التعليمات لا تنطبق إلا على وحدات TPU أثناء التشغيل. على GPU، سيحظر send
وrecv
أي بيانات فعلية ولن يرسلاها إلا بعد إتمام عملية
مصافحة بين الجهازَين المصدر والوجهة.
شريحة
يمكنك الاطّلاع أيضًا على
XlaBuilder::Slice
.
تستخرج ميزة "القطع" صفيفًا فرعيًا من صفيف الإدخال. تحتوي المصفوفة الفرعية على عدد السمات نفسه الذي تحتوي عليه المصفوفة الأساسية، كما تحتوي على القيم داخل مربّع حدودي ضمن مصفوفة الإدخال حيث يتم تحديد سمات مربّع الحدود ومقاييسه كوسيطات لعملية القطع.
Slice(operand, start_indices, limit_indices, strides)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
صفيف من N سمة من النوع T |
start_indices |
ArraySlice<int64> |
قائمة بـ N عدد صحيح يحتوي على الفواصل الزمنية لبداية الشريحة لكل سمة يجب أن تكون القيم أكبر من أو تساوي صفرًا. |
limit_indices |
ArraySlice<int64> |
قائمة بـ N عدد صحيح يحتوي على الفواصل النهائية (الحصرية) للقسم لكل سمة يجب أن تكون كل قيمة أكبر من أو تساوي قيمة start_indices الخاصة بالسمة وأقل من أو تساوي حجم السمة. |
strides |
ArraySlice<int64> |
قائمة بـ N عدد صحيح يحدّد خطوة الإدخال للقسم تختار الشريحة كل strides[d] عنصر في السمة d . |
مثال أحادي الأبعاد:
let a = {0.0, 1.0, 2.0, 3.0, 4.0}
Slice(a, {2}, {4}) produces:
{2.0, 3.0}
مثال على القياس ثنائي الأبعاد:
let b =
{ {0.0, 1.0, 2.0},
{3.0, 4.0, 5.0},
{6.0, 7.0, 8.0},
{9.0, 10.0, 11.0} }
Slice(b, {2, 1}, {4, 3}) produces:
{ { 7.0, 8.0},
{10.0, 11.0} }
ترتيب
يمكنك الاطّلاع أيضًا على
XlaBuilder::Sort
.
Sort(operands, comparator, dimension, is_stable)
الوسيطات | النوع | الدلالات |
---|---|---|
operands |
ArraySlice<XlaOp> |
عناصر التشغيل المطلوب ترتيبها |
comparator |
XlaComputation |
عملية حسابية المقارن لاستخدامها |
dimension |
int64 |
السمة التي يتم الترتيب حسبها. |
is_stable |
bool |
ما إذا كان يجب استخدام الترتيب الثابت |
في حال تقديم عامل واحد فقط:
إذا كان الم Operand هو مصفوفة لاتّجاه واحد (صفيف)، تكون النتيجة صفيفًا مرتبًا. إذا كنت تريد ترتيب الصفيف بترتيب تصاعدي، يجب أن يُجري المقارن مقارنةً أقل من. بشكل رسمي، بعد ترتيب الصفيف، ينطبق ذلك على جميع مواضع الفهرس
i, j
معi < j
التي إماcomparator(value[i], value[j]) = comparator(value[j], value[i]) = false
أوcomparator(value[i], value[j]) = true
.إذا كان المعامل يتضمّن عددًا أكبر من السمات، يتم ترتيب المعامل على طول السمة المقدَّمة. على سبيل المثال، بالنسبة إلى مصفوفة ثنائية الأبعاد (مكثّف)، ستحدّد قيمة السمة
0
ترتيب كل عمود بشكل مستقل، وستحدّد قيمة السمة1
ترتيب كل صف بشكل مستقل. إذا لم يتم تحديد رقم سمة، يتم اختيار السمة الأخيرة تلقائيًا. بالنسبة إلى السمة التي يتمّ ترتيبها، ينطبق ترتيب الترتيب نفسه كما هو الحال في الحالة ذات السمة الواحدة.
في حال تقديم n > 1
عامل حسابي:
يجب أن تكون جميع عناصر
n
هي مصفوفات ذات الأبعاد نفسها. قد تختلف أنواع العناصر في مصفوفات السلاسل المتسلسلة.يتم ترتيب جميع المعاملات معًا، وليس بشكل فردي. من الناحية المفهومية، تتم معاملة المَعلمات كمجموعة. عند التحقّق مما إذا كان يجب تبديل عناصر كلّ معامل في موضعَي الفهرس
i
وj
، يتمّ استدعاء المقارن باستخدام2 * n
مَعلمة قياسية، حيث تتطابق المَعلمة2 * k
مع القيمة في الموضعi
من المعاملk-th
، وتتطابق المَعلمة2 * k + 1
مع القيمة في الموضعj
من المعاملk-th
. وعادةً ما يقارن المقارن2 * k
بين المَعلمتَين2 * k
و2 * k + 1
ويقارن ربما بين أزواج مَعلمات أخرى لتحديد الفائز في حال تساوي النتيجة.والنتيجة هي مجموعة تتألف من المُعامِلات بترتيب مرتّب (بالاستناد إلى السمة المقدَّمة، كما هو موضّح أعلاه). يتوافق المعامل
i-th
للمجموعة مع المعاملi-th
لدالة Sort.
على سبيل المثال، إذا كانت هناك ثلاثة عناصر تشغيل هي operand0 = [3, 1]
وoperand1 = [42, 50]
وoperand2 = [-3.0, 1.1]
، وكان المقارن يقارن
قيم operand0
فقط باستخدام عامل التشغيل "أقل من"، تكون نتيجة الترتيب هي السلسلة الهرمية ([1, 3], [50, 42], [1.1, -3.0])
.
في حال ضبط is_stable
على true، يُضمن أنّ الترتيب ثابت، أي إذا كانت هناك عناصر يُعتبرها المقارن متساوية، يتم الاحتفاظ بالترتيب النسبي للقيم المتساوية. يكون العنصران e1
وe2
متساويين إذا كان comparator(e1, e2) = comparator(e2, e1) = false
فقط. يتم تلقائيًا ضبط is_stable
على false.
TopK
يمكنك الاطّلاع أيضًا على
XlaBuilder::TopK
.
تبحث دالة TopK
عن قيم ومؤشرات k
أكبر أو أصغر العناصر
للبعد الأخير من مصفوفة السلاسل المتعدّدة المحدّدة.
TopK(operand, k, largest)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
مصفوفة السلاسل المتسلسلة التي يتم استخراج أهم k عنصر منها يجب أن يكون للمصفّح قياس واحد أو أكثر. يجب أن يكون حجم السمة الأخيرة من مصفوفة السلاسل المتسلسلة أكبر من أو يساوي k . |
k |
int64 |
عدد العناصر المطلوب استخراجها. |
largest |
bool |
لتحديد ما إذا كنت تريد استخراج أكبر أو أصغر k عنصر. |
بالنسبة إلى مصفوفة إدخال أحادية البعد (صفيف)، يبحث عن k
أكبر أو أصغر
إدخالَين في الصفيف ويعرض مجموعة من صفيفَين (values, indices)
. وبالتالي،
values[j]
هو أكبر/أصغر إدخال في operand
في j
، فهرسه هو
indices[j]
.
بالنسبة إلى مصفوفة تنشيط الإدخال التي تحتوي على أكثر من سمة واحدة، يتم احتساب أهم k
إدخال
على طول السمة الأخيرة، مع الحفاظ على جميع السمات الأخرى (الصفوف) في الإخراج.
وبالتالي، بالنسبة إلى عامل تشغيل على شكل [A, B, ..., P, Q]
حيث Q >= k
، تكون النتيجة
مجموعة (values, indices)
حيث:
values.shape = indices.shape = [A, B, ..., P, k]
إذا كان عنصران في صف متساويان، يظهر العنصر الذي يملك الفهرس الأدنى أولاً.
تبديل
راجِع أيضًا عملية tf.reshape
.
Transpose(operand)
الوسيطات | النوع | الدلالات |
---|---|---|
operand |
XlaOp |
الم Operand الذي سيتم تبديله |
permutation |
ArraySlice<int64> |
كيفية تبديل السمات |
تبدِّل سمات الم Operand باستخدام الترتيب المحدَّد، أي
∀ i . 0 ≤ i < number of dimensions ⇒
input_dimensions[permutation[i]] = output_dimensions[i]
.
وهذا هو نفسه Reshape(operand, permutation, Permute(permutation, operand.shape.dimensions)).
TriangularSolve
يمكنك الاطّلاع أيضًا على
XlaBuilder::TriangularSolve
.
لحل أنظمة المعادلات الخطية ذات المصفوفات المثلثية السفلية أو العليا
عن طريق التعويض الأمامي أو العكسي. من خلال البث على طول سمات
الأولوية، تحلّ سلسلة الإجراءات هذه أحد أنظمة المصفوفات op(a) * x =
b
أو x * op(a) = b
للمتغيّر x
، مع الأخذ في الاعتبار a
وb
، حيث يكون op(a)
إما op(a) = a
أو op(a) = Transpose(a)
أو
op(a) = Conj(Transpose(a))
.
TriangularSolve(a, b, left_side, lower, unit_diagonal, transpose_a)
الوسيطات | النوع | الدلالات |
---|---|---|
a |
XlaOp |
صفيف أبعاده أكبر من اثنين من النوع المركّب أو النوع العشري الفارسي بالتنسيق [..., M, M] |
b |
XlaOp |
صفيف أبعاده أكبر من 2 من النوع نفسه بالتنسيق [..., M, K] إذا كانت left_side صحيحة، [..., K, M] في الحالات الأخرى |
left_side |
bool |
تشير إلى ما إذا كان يجب حلّ نظام من النوع op(a) * x = b (true ) أو x * op(a) = b (false ). |
lower |
bool |
ما إذا كنت تريد استخدام المثلث العلوي أو السفلي من a |
unit_diagonal |
bool |
إذا كانت true ، يُفترض أنّ العناصر القطرية في a هي 1 ولا يتم الوصول إليها. |
transpose_a |
Transpose |
ما إذا كان يجب استخدام a كما هي أو نقلها أو أخذ نقلها المزدوج |
لا تتم قراءة بيانات الإدخال إلا من المثلث السفلي/العلوي من a
، استنادًا إلى
قيمة lower
. ويتم تجاهل القيم من المثلث الآخر. يتم عرض بيانات الإخراج
في المثلث نفسه، أما القيم في المثلث الآخر فتكون
محددة من خلال التنفيذ ويمكن أن تكون أيّ شيء.
إذا كان عدد سمات a
وb
أكبر من 2، يتم التعامل معهما
كحِزم من المصفوفات، حيث تكون جميع السمات سوى السمتَين الثانويتَين هي سمات
الحِزم. يجب أن يكون لـ a
وb
سمات حِزم متساوية.
Tuple
يمكنك الاطّلاع أيضًا على
XlaBuilder::Tuple
.
مجموعة تحتوي على عدد متغيّر من عناصر بيانات، ولكل منها شكل خاص به
وهذا مشابه لـ std::tuple
في C++. من الناحية النظرية:
let v: f32[10] = f32[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
let s: s32 = 5;
let t: (f32[10], s32) = tuple(v, s);
يمكن تحليل المجموعات (الوصول إليها) من خلال عملية GetTupleElement
.
في حين
يمكنك الاطّلاع أيضًا على
XlaBuilder::While
.
While(condition, body, init)
الوسيطات | النوع | الدلالات |
---|---|---|
condition |
XlaComputation |
دالة XlaComputation من النوع T -> PRED التي تحدِّد شرط إنهاء الحلقة |
body |
XlaComputation |
دالة XlaComputation من النوع T -> T التي تحدِّد نص الحلقة |
init |
T |
القيمة الأولية للمَعلمتَين condition وbody |
تنفيذ body
بشكل تسلسلي إلى أن يتعذّر تنفيذ condition
يشبه هذا الإجراء
حلقة while النموذجية في العديد من اللغات الأخرى باستثناء الاختلافات والحدود المفروضة أدناه.
- تعرض عقدة
While
قيمة من النوعT
، وهي النتيجة من التنفيذ الأخير لـbody
. - يتم تحديد شكل النوع
T
بشكل ثابت ويجب أن يكون متطابقًا في جميع النُسخ.
يتمّ إعداد مَعلمات T للعمليات الحسابية باستخدام قيمة init
في
الخطوة الأولى، ويتمّ تعديلها تلقائيًا إلى النتيجة الجديدة من body
في كلّ خطوة لاحقة.
من حالات الاستخدام الرئيسية لعقدة While
هي تنفيذ التنفيذ المتكرّر ل
التدريب في الشبكات العصبية. يظهر أدناه رمز برمجي وهمي مبسّط مع رسم بياني
يمثّل العملية الحسابية. يمكن العثور على الرمز في
while_test.cc
.
النوع T
في هذا المثال هو Tuple
يتألّف من int32
لعدد
المرات وvector[10]
للمركم. على مدار 1000 تكرار، تستمر السلسلة المغلقة في إضافة متجه ثابت إلى المُجمِّع.
// Pseudocode for the computation.
init = {0, zero_vector[10]} // Tuple of int32 and float[10].
result = init;
while (result(0) < 1000) {
iteration = result(0) + 1;
new_vector = result(1) + constant_vector[10];
result = {iteration, new_vector};
}