فيما يلي وصف دلالات العمليات المحددة في واجهة XlaBuilder
. في العادة، تربط هذه العمليات واحدًا لواحد بالعمليات المحددة في واجهة RPC في xla_data.proto
.
ملاحظة بشأن التسمية: يتعامل نوع البيانات المعمم الذي يتعامل معه XLA هو عبارة عن مصفوفة أبعاد N تحتوي على عناصر من نوع موحد (مثل عدد عائم 32 بت). في جميع المستندات، يتم استخدام صفيف للدلالة على مصفوفة عشوائية من الأبعاد. للملاءمة، يكون للحالات الخاصة أسماء محددة ومألوفة أكثر؛ على سبيل المثال، يكون المتجه مصفوفة أحادية البُعد، أما المصفوفة فهي مصفوفة ثنائية الأبعاد.
AfterAll
يمكنك أيضًا الاطّلاع على
XlaBuilder::AfterAll
.
تأخذ العلامة بعد All عددًا متنوعًا من الرموز المميزة وتنتج رمزًا واحدًا. الرموز المميزة هي أنواع أولية يمكن تسلسلها بين عمليات التأثير الجانبي لفرض الطلب. يمكن استخدام 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
مرة. على سبيل المثال، إذا كان هناك نسختان مكررتان والمعامل يحتوي على
القيمة [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
صفًا من الصفائف، يتم تنفيذ الاختزال الكامل على كل عنصر في الصف. 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 في نسخة مطابقة أكثر من أخرى.
AllToAll
يمكنك أيضًا الاطّلاع على
XlaBuilder::AllToAll
.
AllToAll هي عملية جماعية ترسل البيانات من كل النوى إلى جميع النوى. وهي تشمل مرحلتين:
- مرحلة التبعثر. في كل نواة، ينقسم المعامل إلى
split_count
عدد من الكتل على طولsplit_dimensions
، وتنتشر الكتل إلى كل النوى، على سبيل المثال يتم إرسال الكتلة الأولى إلى النواة الأولى. - مرحلة جمع البيانات. يعمل كل نواة على تسلسل الوحدات التي تم استلامها على طول
concat_dimension
.
يمكن ضبط إعدادات النواة الأساسية المشارِكة من خلال:
replica_groups
: تحتوي كل ReplicaGroup على قائمة بأرقام التعريف المتماثلة المشار إليها في العملية الحسابية (يمكن استرداد معرف النسخة المطابقة الحالية باستخدام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
فارغة، تنتمي جميع النُسخ المتماثلة إلى مجموعة واحدة، بترتيب تسلسل ظهورها.
المتطلبات الأساسية:
- ويكون حجم بُعد المعامل في
split_dimension
قابلاً للقسمة علىsplit_count
. - شكل المعامل ليس صفًا.
AllToAll(operand, split_dimension, concat_dimension, split_count,
replica_groups)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
صفيف إدخال أبعادي n |
split_dimension
|
int64
|
قيمة في الفاصل الزمني [0,
n) تُسمي البُعد
الذي يتم تقسيم المُعامل
عليه |
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 أجزاء على طول البعد 0، بحيث يكون لكل جزء الشكل f32[4,4]. تتوزع الأجزاء الأربعة في كل النوى. بعد ذلك، يعمل كل نواة على تسلسل الأجزاء التي يتم استلامها على طول البعد 1، بترتيب النواة 0-4. لذا فإن الناتج على كل نواة يشكل f32[16,4].
BatchNormGrad
راجِع أيضًا
XlaBuilder::BatchNormGrad
وورقة التسوية الأصلية المجمّعة
للحصول على وصف تفصيلي للخوارزمية.
لحساب تدرجات قاعدة الدفعة.
BatchNormGrad(operand, scale, mean, variance, grad_output, epsilon, feature_index)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
صفيفة الأبعاد n المطلوب تسويتها (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
.
يتم تعريف التدرجات الثلاثة باستخدام الصيغ التالية (على افتراض مصفوفة رباعية الأبعاد مثل 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 ($\nabl
x$) |
grad_scale
|
XlaOp
|
التدرج بالنسبة إلى الإدخال scale ($\nabl
\gamma$) |
grad_offset
|
XlaOp
|
التدرج بالنسبة إلى الإدخال offset ($\nabl
\beta$) |
BatchNormInference
راجِع أيضًا
XlaBuilder::BatchNormInference
وورقة التسوية الأصلية المجمّعة
للحصول على وصف تفصيلي للخوارزمية.
تطبيع صفيف عبر الأبعاد المجمعة والأبعاد المكانية.
BatchNormInference(operand, scale, offset, mean, variance, epsilon, feature_index)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
الصفيفة البُعدية المطلوب تسويتها |
scale |
XlaOp |
مصفوفة بُعد واحدة |
offset |
XlaOp |
مصفوفة بُعد واحدة |
mean |
XlaOp |
مصفوفة بُعد واحدة |
variance |
XlaOp |
مصفوفة بُعد واحدة |
epsilon |
float |
قيمة إبسيلون |
feature_index |
int64 |
فهرس لسمة العنصر باللغة operand |
بالنسبة إلى كل ميزة في بُعد الميزة (يمثل feature_index
فهرس
بُعد الميزة في operand
)، تحسب العملية المتوسط والتباين بين جميع الأبعاد الأخرى وتستخدم المتوسط والتباين لتسوية كل عنصر في operand
. يجب أن تكون السمة feature_index
فهرسًا صالحًا لسمة الميزة في operand
.
تعادل BatchNormInference
استدعاء BatchNormTraining
بدون
احتساب mean
وvariance
لكل دفعة. وتستخدم المدخلات mean
وvariance
بدلاً من ذلك كقيم مقدَّرة. والغرض من هذه العملية هو تقليل وقت الاستجابة في الاستنتاج، وبالتالي اسم BatchNormInference
.
والمُخرج هو صفيف ذو أبعاد نيّة له شكل الإدخال operand
نفسه.
BatchNormTraining
راجِع أيضًا
XlaBuilder::BatchNormTraining
وthe original batch normalization paper
للحصول على وصف تفصيلي للخوارزمية.
تطبيع صفيف عبر الأبعاد المجمعة والأبعاد المكانية.
BatchNormTraining(operand, scale, offset, epsilon, feature_index)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
صفيفة الأبعاد n المطلوب تسويتها (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
عبارة عن مصفوفة رباعية الأبعاد):
تحسب متوسط الدفعة \(\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\)
تتم إضافة قيمة إبسيلون، التي عادة ما تكون عددًا صغيرًا، لتجنب أخطاء القسمة على صفر.
نوع الإخراج هو صف من ثلاث ثوانٍ من 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
من خلال سلسلة Bitcast، وسيتحوّل عنصر s32
واحد إلى أربعة عناصر s8
. يتم تنفيذ Bitcast كبث منخفض المستوى، لذا فإن الأجهزة ذات تمثيلات النقطة العائمة المختلفة تعطي نتائج مختلفة.
BitcastConvertType(operand, new_element_type)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
صفيفة من النوع T مع مفاتيح خافتة D |
new_element_type |
PrimitiveType |
النوع U |
يجب أن تتطابق أبعاد المعامل والشكل المستهدف، بصرف النظر عن البعد الأخير الذي سيتغير بنسبة الحجم الأساسي قبل التحويل وبعده.
يجب ألا يكون نوعا عنصر المصدر والوجهة صفوفًا.
تحويل البث الرقمي إلى نوع أساسي بعرض مختلف
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}
.
فهرس السمات الجديد إلى نُسخ من المعامل، أي
output[i0, ..., iN, j0, ..., jM] = operand[j0, ..., jM]
على سبيل المثال، إذا كان operand
مقياسًا رقميًا يتضمّن قيمة 2.0f
، وbroadcast_sizes
هو {2, 3}
، ستكون النتيجة صفيفًا على شكل f32[2, 3]
وستكون جميع القيم في النتيجة 2.0f
.f32
BroadcastInDim
يمكنك أيضًا الاطّلاع على
XlaBuilder::BroadcastInDim
.
لتوسيع حجم وترتيب صفيف من خلال تكرار البيانات في الصفيف.
BroadcastInDim(operand, out_dim_size, broadcast_dimensions)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
الصفيف المطلوب تكراره |
out_dim_size |
ArraySlice<int64> |
أحجام أبعاد الشكل المستهدف |
broadcast_dimensions |
ArraySlice<int64> |
أي البعد في الشكل المستهدف يتجاوب كل بُعد في شكل المعامل مع |
يشبه البثّ، ولكنّه يسمح بإضافة أبعاد في أي مكان وتوسيع الأبعاد الحالية بالحجم 1.
يتم بث operand
بالشكل الموضح في out_dim_size
.
تربط broadcast_dimensions
أبعاد operand
بأبعاد الشكل المستهدف، أي أنه يتم تعيين بُعد i للمعامل إلى بُعد 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 s |
N وسيطات من النوع عشوائي |
يجب أن تتطابق قيمة args
وأنواعها مع معلَمات computation
. ويُسمح بعدم إضافة args
.
تشوليسكي
يمكنك أيضًا الاطّلاع على
XlaBuilder::Cholesky
.
تحسب تحليل الكوليسكي لدفعة من المصفوفات الموجبة المتماثلة (الهرمية) المحدّدة.
Cholesky(a, lower)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
a |
XlaOp |
صفيف ترتيب أكبر من 2 لنوع معقد أو من نقطة عائمة. |
lower |
bool |
ما إذا كان سيتم استخدام المثلث العلوي أو السفلي لـ a . |
إذا كانت lower
هي true
، تحسب المصفوفات المثلثة السفلية l
بحيث تكون $a = l .
l^T$. إذا كانت قيمة lower
هي false
، ستحتسب المصفوفات المثلثية العليا u
بحيث
\(a = u^T . u\).
تتم قراءة بيانات الإدخال فقط من المثلث السفلي/العلوي لـ a
، بناءً على قيمة lower
. ويتم تجاهل القيم من المثلث الآخر. يتم إرجاع بيانات الناتج في نفس المثلث؛ القيم في المثلث الآخر محددة التنفيذ وقد تكون أي شيء.
إذا كان الترتيب a
أكبر من 2، يتم التعامل مع 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. |
يؤدّي التصغير إلى استبدال المجموعة الفرعية المحدّدة من أبعاد المعامل بسمة واحدة. وسيطات الإدخال هي صفيف عشوائي من النوع 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
:
- يجب ألا يكون لأي زوجين نفس معرف النسخة المطابقة المستهدفة، ويجب ألا يكون لهما نفس معرف النسخة المماثلة للمصدر.
- إذا لم يكن معرِّف النسخة المتماثلة هدفًا في أي زوج، يكون الناتج على تلك النسخة المتماثلة موقدًا يتكون من 0(أرقام) لها نفس شكل المُدخل.
تسلسل
يمكنك أيضًا الاطّلاع على
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 |
معالجة Xlaللنوع \(T_0 \to S\) |
false_operand |
XlaOp |
الوسيطة من النوع \(T_1\) |
false_computation |
XlaComputation |
معالجة Xlaللنوع \(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 |
العمليات الحسابية من النوع Xla \(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
.
الإحالات الناجحة (الالتفاف)
يمكنك أيضًا الاطّلاع على
XlaBuilder::Conv
.
كـ ConsWithGeneralPadding، ولكن يتم تحديد المساحة المتروكة بطريقة مختصرة على أنها SAME أو ACTIVE. تؤدي المساحة المتروكة نفسها إلى توفير مساحة الإدخال (lhs
) بالأصفار حتى يكون للمخرجات نفس شكل الإدخال عند عدم الانتقال إلى الحساب. المساحة المتروكة "صالحة" تعني ببساطة عدم وجود مساحة متروكة.
conversionWithGeneralPadding (الالتفاف)
يمكنك أيضًا الاطّلاع على
XlaBuilder::ConvWithGeneralPadding
.
تحسب التفافًا من النوع المستخدم في الشبكات العصبية. وهنا، يمكن اعتبار الالتفاف على أنه نافذة ذات أبعاد ن تتحرك عبر مساحة قاعدة ذات أبعاد ن ويتم إجراء عملية حسابية لكل موضع محتمل للنافذة.
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
lhs |
XlaOp |
ترتيب صفيفة المدخلات n+2 |
rhs |
XlaOp |
ترتيب صفيفة النواة بقيمة n+2 |
window_strides |
ArraySlice<int64> |
صفيفة n-d لخطوات النواة |
padding |
ArraySlice< pair<int64,int64>> |
مصفوفة n-d من المساحة المتروكة (منخفضة، عالية) |
lhs_dilation |
ArraySlice<int64> |
مصفوفة عامل التوسعة n-d lh |
rhs_dilation |
ArraySlice<int64> |
مصفوفة عامل التوسع n-d rhs |
feature_group_count |
int64 | عدد مجموعات الخصائص |
batch_group_count |
int64 | عدد مجموعات الدفعات |
لنفترض أن n هو عدد الأبعاد المكانية. الوسيطة lhs
هي مصفوفة من الترتيب n+2 تصف مساحة القاعدة. وهذا ما يسمى المدخل، على الرغم من أن
الإدخال بالطبع هو أيضًا مدخل. في الشبكة العصبية، هذه هي عمليات تنشيط الإدخال.
تكون الأبعاد n+2 بالترتيب التالي:
batch
: يمثل كل إحداثي في هذا البُعد مدخلاً مستقلاً يتم من أجله إجراء الالتفاف.z/depth/features
: لكل موضع (ص,س) في مساحة القاعدة خط متجه مرتبط به، ويدخل في هذا البُعد.spatial_dims
: يصف الأبعاد المكانيةn
التي تحدد مساحة القاعدة التي تتحرك عبرها النافذة.
الوسيطة rhs
هي مصفوفة ترتيب n+2 تصف الفلتر/النواة/النافذة الالتفافية. تكون الأبعاد بهذا الترتيب:
output-z
: السمةz
للناتج.input-z
: يجب أن يساوي حجم هذا البُعد مضروبًا فيfeature_group_count
حجم البُعدz
بالأرقام lh.spatial_dims
: يصف الأبعاد المكانيةn
التي تحدد النافذة n-d التي تتحرك في جميع مساحة القاعدة.
تحدد الوسيطة window_strides
مقدار تحرك النافذة الالتفافية في الأبعاد المكانية. على سبيل المثال، إذا كانت قيمة الخطوة في البعد المكاني الأول هي 3، فلا يمكن وضع النافذة إلا في الإحداثيات التي يكون فيها الفهرس المكاني الأول قابلاً للقسمة على 3.
تحدِّد الوسيطة padding
مقدار المساحة المتروكة الصفرية التي سيتم تطبيقها على منطقة القاعدة. يمكن أن تكون مقدار المساحة المتروكة سالبة -- تشير القيمة المطلقة للمساحة المتروكة السالبة إلى عدد العناصر المطلوب إزالتها من البُعد المحدد قبل إجراء الالتفاف. تحدّد padding[0]
المساحة المتروكة للبُعد y
وتحدد padding[1]
المساحة المتروكة للبُعد x
. كل زوج يحتوي على مساحة متروكة منخفضة كعنصر أول والمساحة المتروكة العالية كعنصر ثاني. يتمّ تطبيق المساحة المتروكة المنخفضة في اتجاه الفهارس السفلية بينما يتمّ تطبيق المساحة المتروكة العالية في اتجاه الفهارس الأعلى. على سبيل المثال، إذا كانت قيمة padding[1]
هي (2,3)
، ستكون هناك مساحة متروكة بمقدار صفرَين على اليسار و3 أصفار على اليمين في البعد المكاني الثاني. يعادل استخدام المساحة المتروكة إدخال تلك القيم الصفرية نفسها في الإدخال (lhs
) قبل إجراء الالتفاف.
تحدد الوسيطات lhs_dilation
وrhs_dilation
عامل الاتساع الذي سيتم تطبيقه على قيم hs وrhs على التوالي، في كل بُعد مكاني. إذا كان عامل الاتساع في بُعد مكاني هو d، فسيتم وضع ثقوب d-1 ضمنيًا بين كل إدخال من الإدخالات في هذا البعد، مما يزيد من حجم المصفوفة. الثقوب مليئة بقيمة بيئة مستقلة، والتي تعني الالتفاف صفر.
يسمى اتساع Rhs أيضًا التواء الحاد. ولمزيد من التفاصيل، يمكنك الاطّلاع على tf.nn.atrous_conv2d
. يُطلق على اتساع نظام خط تشبيك (Hs) أيضًا اسم الالتفاف المنقول. لمزيد من التفاصيل، يُرجى الاطّلاع على 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-th معًا لحساب 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
بالأرقام lh.z
: الحجم نفسه مثلoutput-z
على النواة (rhs
).spatial_dims
: قيمة واحدة لكل موضع صالح للنافذة الالتفافية.
يوضّح الشكل أعلاه طريقة عمل الحقل batch_group_count
. على نحو فعّال، نقسّم كل حزمة lh إلى batch_group_count
مجموعة، ونفعل الشيء نفسه مع ميزات المخرجات. بعد ذلك، بالنسبة إلى كل مجموعة من هذه المجموعات، نقوم بإجراء التفاف زوجي
وننشئ تسلسلاً للناتج على طول بُعد ميزة الإخراج. وتظل الدلالات التشغيلية
لجميع الأبعاد الأخرى (الميزة والمكانية) كما هي.
يتم تحديد المواضع الصالحة للنافذة الالتفافية من خلال الخطوات وحجم منطقة القاعدة بعد المساحة المتروكة.
لوصف ما يفعله الالتفاف، ضع في الاعتبار الالتفاف الثنائي الأبعاد واختر بعض إحداثيات batch
وz
وy
وx
الثابتة في الإخراج. وعندئذٍ، تمثّل (y,x)
موضعًا من زاوية النافذة ضمن مساحة القاعدة (مثل الزاوية العلوية اليسرى، حسب طريقة تفسيرك للأبعاد المكانية). لدينا الآن نافذة ثنائية الأبعاد، مأخوذة من مساحة القاعدة، حيث ترتبط كل نقطة ثنائية الأبعاد بمتجه أحادي الأبعاد، ولذلك نحصل على مربع ثلاثي الأبعاد. من النواة الالتفافية، بما أننا أصلحنا إحداثي
الإخراج 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 |
يجب أن تتطابق أبعاد المعامل والشكل المستهدف. يجب ألا يكون نوعا عنصر المصدر والوجهة صفوفًا.
ستؤدي عملية إحالة ناجحة مثل 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 s |
وسيطات 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] |
الكمية القياسية | حاصل ضرب نقطي على شكل متّجه |
مصفوفة [م x ك] dot متجه [k] |
المتّجهات [m] | ضرب متجه المصفوفة |
مصفوفة [م x ك] dot مصفوفة [ك x n] |
مصفوفة [م × n] | ضرب مصفوفة المصفوفة |
تنفِّذ العملية مجموع المنتجات على البُعد الثاني لـ lhs
(أو
الأول إذا كان له الترتيب 1) والبعد الأول لـ 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
الترتيب ==
1، وأن يكون حجم البعد مساويًا لترتيب operand
.
DynamicSlice(operand, start_indices, size_indices)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
صفيف الأبعاد N من النوع T |
start_indices |
تسلسل N XlaOp |
قائمة بعدد صحيح عددي يحتوي على مؤشرات بدء الشريحة لكل بُعد. يجب أن تكون القيمة أكبر من صفر أو تساويه. |
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
الترتيب == 1، وأن يكون حجم البعد مساويًا لترتيب operand
.
DynamicUpdateSlice(operand, update, start_indices)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
صفيف الأبعاد N من النوع T |
update |
XlaOp |
مصفوفة أبعاد N من النوع T تحتوي على تعديل الشريحة. يجب أن يكون كل بُعد لشكل التحديث أكبر من الصفر تمامًا، ويجب أن تكون بداية + التحديث أقل من أو تساوي حجم المعامل لكل بُعد لتجنب إنشاء فهارس تحديث خارج الحدود. |
start_indices |
تسلسل N XlaOp |
قائمة بعدد صحيح عددي يحتوي على مؤشرات بدء الشريحة لكل بُعد. يجب أن تكون القيمة أكبر من صفر أو تساويه. |
يتم حساب فهارس الشرائح الفعالة من خلال تطبيق التحويل التالي لكل فهرس 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
(القسمة) أو Rem
(المتبقي) أو Max
(الحد الأقصى) أو Min
(الحد الأدنى) أو LogicalAnd
(المنطقي AND) أو LogicalOr
(منطقية OR).
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
lhs |
XlaOp |
معامل الجانب الأيسر: صفيف من النوع T |
rhs |
XlaOp |
معامل الجانب الأيمن: صفيف من النوع T |
يجب أن تكون أشكال الوسيطات إما متشابهة أو متوافقة. راجِع مستندات البث حول معنى أن تكون الأشكال متوافقة. نتيجة العملية لها شكل ناتج عن بث صفيفَي الإدخال. في هذا المتغير، لا تتوفر العمليات بين الصفائف ذات الترتيبات المختلفة، ما لم يكن أحد المعاملات رقمًا قياسيًا.
عندما تكون Op
Rem
، تكون علامة النتيجة مأخوذة من الموزع، وتكون القيمة المطلقة للنتيجة دائمًا أقل من القيمة المطلقة للقاسم.
ينتج عن تجاوز قسمة العدد الصحيح (القسمة/المتبقية الموقَّعة/غير الموقعة/المتبقية بصفر أو بالقسمة/البقيّة الموقعة INT_SMIN
مع -1
) قيمة محددة للتنفيذ.
هناك صيغة بديلة تتيح بثًا صوتيًا من ترتيب مختلف للعمليات التالية:
Op(lhs, rhs, broadcast_dimensions)
تكون السمة Op
هي نفسها المذكورة أعلاه. يجب استخدام هذا المتغير من العملية في العمليات الحسابية بين صفائف الترتيب المختلفة (مثل إضافة مصفوفة إلى متجه).
المعامل 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 N +Infinite <+0 N +Finite<.
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
lhs |
XlaOp |
معامل الجانب الأيسر: صفيف من النوع T |
rhs |
XlaOp |
معامل الجانب الأيمن: صفيف من النوع T |
يجب أن تكون أشكال الوسيطات إما متشابهة أو متوافقة. راجِع مستندات البث حول معنى أن تكون الأشكال متوافقة. تحتوي نتيجة العملية على شكل ناتج عن بث صفيفَي الإدخال باستخدام نوع العنصر PRED
. في هذا المتغير، لا تتوفر العمليات بين المصفوفات ذات الترتيبات المختلفة ما لم يكن أحد المعاملين مقياسًا.
هناك صيغة بديلة تتيح بثًا صوتيًا من ترتيب مختلف للعمليات التالية:
Op(lhs, rhs, broadcast_dimensions)
تكون السمة Op
هي نفسها المذكورة أعلاه. يجب استخدام هذا المتغير من العملية في عمليات المقارنة بين الصفائف ذات الترتيبات المختلفة (مثل إضافة مصفوفة إلى متجه).
المعامل broadcast_dimensions
الإضافي هو شريحة من الأعداد الصحيحة تحدد الأبعاد التي يجب استخدامها في بث المعاملات. وتم توضيح المعاني الدلالية بالتفصيل
في صفحة البث.
الدوال الأحادية من حيث العناصر
يدعم XlaBuilder الدوال الموحدة التالية من حيث العناصر:
Abs(operand)
القيمة x -> |x|
في قيمة العناصر في كل العناصر
Ceil(operand)
عنصر القائمة على العناصر x -> ⌈x⌉
.
Cos(operand)
جيب التمام x -> cos(x)
في منظور العناصر
Exp(operand)
دالة x -> e^x
طبيعية في مستوى العناصر.
Floor(operand)
دور x -> ⌊x⌋
في مستوى العناصر.
Imag(operand)
جزء تخيلي من حيث العناصر من شكل معقد (أو حقيقي). x -> imag(x)
. إذا كان المعامل نوع نقطة عائمة، يتم عرض 0.
IsFinite(operand)
تختبر ما إذا كان كل عنصر من عناصر operand
محدودًا،
أي أنّ ليس قيمة لا نهاية لها موجبة أو سالبة، وليس قيمة NaN
. تعرض صفيفًا من قيم PRED
بنفس شكل المُدخل، حيث يكون كل عنصر true
إذا كان عنصر الإدخال المقابل محدودًا فقط.
Log(operand)
لوغاريتم طبيعي من منظور العناصر x -> ln(x)
LogicalNot(operand)
عنصر منطقي من حيث العناصر وليس x -> !(x)
.
Logistic(operand)
احتساب الدالة اللوجستية على مستوى العناصر x ->
logistic(x)
.
PopulationCount(operand)
تحسب عدد وحدات البت المحددة في كل عنصر من عناصر operand
.
Neg(operand)
رمز نفي من حيث العناصر x -> -x
.
Real(operand)
جزء حقيقي من حيث العناصر من شكل معقد (أو حقيقي).
x -> real(x)
. إذا كان المعامل من نوع النقطة العائمة، يتم عرض القيمة نفسها.
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
.
Sqrt(operand)
عملية جذر تربيعي على مستوى العناصر x -> sqrt(x)
.
Cbrt(operand)
عملية جذر تكعيبي على مستوى العناصر x -> cbrt(x)
.
Tanh(operand)
المماس الزائدي على مستوى العناصر x -> tanh(x)
.
Round(operand)
التقريب إلى قيمة العناصر في كل عنصر، وهو يؤدي إلى الانتقال من الصفر.
RoundNearestEven(operand)
تقريب العناصر على مستوى العناصر، يربط بالأقرب الزوجي
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
معامل الدالة |
يتم تطبيق الدالة على كل عنصر في المصفوفة operand
، ما يؤدي إلى إنشاء مصفوفة بالشكل نفسه. يُسمح للحقل operand
بأن يكون رقمًا قياسيًا (الترتيب 0).
Fft
تُنفذ عملية XLA FFT عمليات تحويل فورييه للأمام والعكس للمدخلات/المخرجات الحقيقية والمعقدة. يُسمح باستخدام بروتوكول FFT متعدد الأبعاد على ما يصل إلى 3 محاور.
يمكنك أيضًا الاطّلاع على
XlaBuilder::Fft
.
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
الصفيفة التي نحوّلها إلى "فورييه". |
fft_type |
FftType |
اطّلِع على الجدول التالي لمزيد من المعلومات. |
fft_length |
ArraySlice<int64> |
أطوال النطاق الزمني للمحاور التي يتم تحويلها. وهذا الإجراء مطلوب على وجه التحديد لنظام IRFFT لضبط حجم المحور الداخلي بشكل صحيح، لأنّ RFFT(fft_length=[16]) له شكل الإخراج نفسه مثل RFFT(fft_length=[17]) . |
FftType |
دلالات الألفاظ |
---|---|
FFT |
إعادة توجيه FFT من المعقد إلى المعقد. لم يتغير الشكل. |
IFFT |
دالة FFT العكسية المركّبة إلى المركّبة. لم يتغير الشكل. |
RFFT |
إعادة توجيه FFT فعلي إلى معقد. يتم تخفيض شكل المحور الداخلي إلى fft_length[-1] // 2 + 1 إذا كانت قيمة fft_length[-1] غير صفرية، ما يؤدّي إلى حذف الجزء المرافق المعكوس من الإشارة المحوّلة خارج تردد Nyquist. |
IRFFT |
معكوس عملية FFT من مركبين حقيقيين (أي يأخذ معقدًا، يُرجع حقيقة). يتم توسيع شكل المحور الداخلي إلى fft_length[-1] إذا كانت قيمة fft_length[-1] غير صفرية، ما يتم استنتاج جزء من الإشارة المحوّلة خارج نطاق تردد Nyquist من المرافق العكسية للإدخالات 1 إلى fft_length[-1] // 2 + 1 . |
ميزة "FFT" متعددة الأبعاد
عند توفير أكثر من fft_length
واحد، يعادل ذلك تطبيق سلسلة من عمليات النقل في الوقت الفعلي (FFT) على كل من المحاور الداخلية. لاحظ أنه بالنسبة للحالات الحقيقية
>المعقدة والمعقدة->يتم تحويل المحور الداخلي
(بشكل فعال) أولاً (RFFT; الأخير لـ IRFFT)، وهذا هو السبب في أن المحور
الداخلي هو الذي يتغير الحجم. ستكون حينئذٍ تحويلات المحاور
الأخرى معقدة->معقدة.
تفاصيل التنفيذ
تتوافق وحدة المعالجة المركزية FFT مع TensorFFT من Eigen. يستخدم GPU FFT CUFFT.
جمع
تجمع عملية 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> |
مجموعة الأبعاد في شكل الإخراج التي تتم إزاحتها في صفيف مُقسّمة من المعامل. |
slice_sizes |
ArraySlice<int64> |
slice_sizes[i] هي حدود الشريحة على البُعد i . |
collapsed_slice_dims |
ArraySlice<int64> |
مجموعة الأبعاد في كل شريحة يتم تصغيرها. يجب أن يكون لهذه الأبعاد المقاس 1. |
start_index_map |
ArraySlice<int64> |
خريطة توضّح كيفية ربط الفهارس في start_indices بالفهارس القانونية في المعامل. |
indices_are_sorted |
bool |
ما إذا كان بإمكان المتصل ترتيب الفهارس مضمونها أم لا. |
unique_indices |
bool |
ما إذا كان المتصل يضمن أن تكون المؤشرات فريدة. |
ولتسهيل الأمر، نصنّف السمات في مصفوفة الإخراج وليس في offset_dims
على أنّها batch_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
ضمنيًا أنّ شكل 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
(أي أنّ القيمةadjusted_slice_sizes
تساويoffset_dims
[k
] لبعض القيمk
)، نختار الحد المناظِر منslice_sizes
بعد احتسابcollapsed_slice_dims
(مثلاً، نختارadjusted_slice_sizes
[k
] حيث تكونadjusted_slice_sizes
هيslice_sizes
مع إزالة الحدود في الفهارسcollapsed_slice_dims
).
رسميًا، يتم حساب فهرس المعامل In
المقابل لفهرس الناتج Out
على النحو التالي:
اسمح
G
= {Out
[k
] لـk
فيbatch_dims
}. استخدِمG
لتقسيم الاتجاهS
بحيثS
[i
] =start_indices
[دمج(G
،i
)] حيث تؤدي الدمج(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
على "صحيح"، يمكن لخوارزمية XLA أن تفترض أنّ start_indices
تم ترتيبها (بترتيب start_index_map
تصاعديًا) حسب المستخدم. إذا لم تكن كذلك، فسيتم
تحديد دلالات التنفيذ.
إذا تم ضبط unique_indices
على "true"، يمكن لخوارزمية XLA أن تفترض أن جميع العناصر
المبعثرة على عناصر فريدة. إذًا، يمكن لخوارزمية XLA استخدام العمليات غير الذرية. إذا تم ضبط unique_indices
على "true" وكانت الفهارس المتفرقة غير فريدة، يتم تحديد دلالات التنفيذ.
وصف وأمثلة غير رسمية
بشكل غير رسمي، يتجاوب كل فهرس Out
في صفيف الإخراج مع العنصر E
في مصفوفة المعامل، ويتم احتسابه على النحو التالي:
نستخدم السمات المجمّعة في
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 دلالات غير رسمية الموضحة أعلاه بالطرق التالية:
يمكننا تحديد الأبعاد في شكل الإخراج التي تمثل أبعاد الإزاحة (السمات التي تحتوي على
O
0
وO
1
في المثال الأخير). يتم تعريف سمات الإخراج المجمّعة (السمات التي تحتوي علىG
0
وG
1
في المثال الأخير) على أنّها سمات الإخراج التي لا تتم إزاحتها.قد يكون عدد أبعاد إزاحة المخرجات الموجودة بوضوح في شكل المخرجات أصغر من ترتيب الإدخال. وهذه السمات "المفقودة" المدرَجة بشكل صريح على أنّها
collapsed_slice_dims
يجب أن تحتوي على حجم شريحة1
. وبما أنّ حجم الشريحة هو1
، فإنّ الفهرس الوحيد الصالح هو0
، لذا فإنّ إزالتها لا تؤدي إلى أيّ غموض.قد تحتوي الشريحة المستخرجة من مصفوفة "جمع المؤشرات" ((
X
،Y
) في المثال الأخير) على عناصر أقل من ترتيب صفيف الإدخال، وتشير عملية التعيين الواضحة إلى كيفية توسيع الفهرس للحصول على نفس ترتيب الإدخال.
كمثال أخير، نستخدم (2) و (3) لتنفيذ tf.gather_nd
:
يتم استخدام G
0
وG
1
لفصل فهرس البدء من مصفوفة الفهارس المجمَّعة كالمعتاد، باستثناء ما إذا كان فهرس البدء يحتوي على عنصر واحد فقط، وهو X
. وبالمثل، يتوفّر فهرس إزاحة ناتج واحد فقط بالقيمة
O
0
. ومع ذلك، قبل استخدام هذه المؤشرات كمؤشرات في صفيف الإدخال،
يتم توسيعها وفقًا لـ "تجميع بيانات الفهرس" (start_index_map
في
الوصف الرسمي) و "Offset Mapping" (remapped_offset_dims
في
الوصف الرسمي) إلى [X
و0
] و[0
وO
0
] على التوالي،
مع إضافة ما يصل إلى [X
,O
0
] إلى القيم0
0
0
0
0
O
O
G
G
G
G
1
1
GatherIndices
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) تحدّد السمة. |
المرور عبر المعامل نتيجةً لذلك، مع تتبع البُعد الديناميكي بواسطة برنامج التحويل.
وسيتم تجاهل القيم المحشوّة من خلال عمليات التقليل من انتقال البيانات.
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
من البيانات. يُسمح بإجراء عمليات متعددة للخلاصة في العملية الحسابية، ولكن يجب أن يكون هناك ترتيب إجمالي بين عمليات الخلاصة. على سبيل المثال، لاثنتين من خلاصات Infeed في التعليمات البرمجية أدناه ترتيب إجمالي نظرًا لوجود تبعية بين التكرارات الحلقية while.
result1 = while (condition, init = init_value) {
Infeed(shape)
}
result2 = while (condition, init = result1) {
Infeed(shape)
}
أشكال الصفوف المتداخلة غير متوافقة. بالنسبة إلى شكل الصف الفارغ، تكون عملية Infeed في الواقع عملية حظر وتستمر بدون قراءة أي بيانات من خلاصة الجهاز.
أمواج هادئة قصيرة
يمكنك أيضًا الاطّلاع على
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 s |
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
مختلفة لمصفوفة ثنائية الأبعاد.
الإشعارات
يمكنك أيضًا الاطّلاع على
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
باستخدام معرّف channel_id نفسه تعرض سياقًا للموارد المخصّصة، والذي يستخدمه
تعليمات RecvDone
التالية لانتظار اكتمال عملية نقل
البيانات. السياق هو صف من {Get buffer (shape), requestidentifier
(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
.
تقلل هذه العملية بُعدًا واحدًا أو أكثر من كل صفيف إدخال إلى عدد قياسي.
ترتيب كل صفيف يتم عرضه هو rank(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 rank 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]
في ما يلي مثال على تقليل صفيفة ثنائية الأبعاد (مصفوفة). رتبة الشكل 2، البعد 0 بالحجم 2 والبعد 1 بالحجم 3:
نتائج تقليل الأبعاد 0 أو 1 باستخدام دالة "add":
لاحظ أن نتيجتي الاختزال عبارة عن صفائف أحادي البُعد. يظهر المخطط واحدًا كعمود والآخر كصف فقط للراحة البصرية.
لمثال أكثر تعقيدًا، إليك صفيف ثلاثي الأبعاد. وترتيبه هو 3، والبعد 0 للحجم 4، والبعد 1 بالحجم 2 والبعد 2 بالحجم 3. للتبسيط، يتم نسخ القيم من 1 إلى 6 عبر البعد 0.
على غرار المثال الثنائي الأبعاد، يمكننا تقليل بُعد واحد فقط. إذا خفّضنا البُعد 0، على سبيل المثال، نحصل على مصفوفة الترتيب 2 حيث تم طي جميع القيم في البُعد 0 في عدد قياسي:
| 4 8 12 |
| 16 20 24 |
إذا اختزِلنا البعد 2، نحصل أيضًا على مصفوفة الترتيب 2 حيث تم طي جميع القيم على مستوى البُعد 2 في عدد قياسي:
| 6 15 |
| 6 15 |
| 6 15 |
| 6 15 |
تجدر الإشارة إلى أنّ الترتيب النسبي بين الأبعاد المتبقية في المُدخل يتم الاحتفاظ به في المُخرج، ولكن قد يتم تخصيص أرقام جديدة لبعض الأبعاد (بما أنّ ترتيبه يتغيّر).
يمكننا أيضًا تقليل الأبعاد المتعددة. ينتج عن جمع البعدين 0 و1 الصفيف أحادي البُعد [20, 28, 36]
.
يؤدي تخفيض الصفيف الثلاثي الأبعاد بجميع أبعاده إلى إنشاء القيمة العددية 84
.
فارياديك فري
عند استخدام N > 1
، يصبح تخفيض تطبيق الدالة أكثر تعقيدًا بعض الشيء، إذ يتم تطبيقه في الوقت نفسه على جميع المدخلات. يتم توفير المعاملات إلى العملية الحسابية بالترتيب التالي:
- جارٍ تنفيذ القيمة المخفَّضة للمعامل الأول
- ...
- جارٍ تشغيل القيمة المخفضة للمعامل N
- قيمة الإدخال للمعامل الأول
- ...
- قيمة الإدخال للمعامل "ن"
على سبيل المثال، بالنظر إلى دالة الاختزال التالية، التي يمكن استخدامها لحساب الحد الأقصى وargmax لصفيف 1-D بالتوازي:
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
. ويتم تقريب قيم الإدخال إلى أقرب قيمة يمكن تمثيلها بعدد معين من وحدات بت mantisa (باستخدام دلالات "الارتباطات الزوجية")، وأي قيم تتجاوز النطاق المحدد بعدد وحدات البت الأسية يتم تثبيتها على ما لا نهاية موجبة أو سالبة. يتم الاحتفاظ بقيم NaN
على الرغم من إمكانية تحويلها إلى قيم NaN
الأساسية.
يجب أن يحتوي التنسيق الأقل دقة على بت أس واحد على الأقل (من أجل تمييز القيمة الصفرية عن اللانهاية، نظرًا لأن كلاً منهما يحتوي على سرعة صفرية)، ويجب أن يحتوي على عدد غير سالب من بتات مانتسا. قد يتجاوز عدد وحدات بت الأس أو السرعة
القيمة المقابلة للنوع T
؛ في حين يكون الجزء المقابل من الإحالة الناجحة ببساطة قيمة بيئة مستقلة.
ReduceScatter
يمكنك أيضًا الاطّلاع على
XlaBuilder::ReduceScatter
.
DropScatter هي عملية جماعية تُجري عملية 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
مرة. على سبيل المثال، إذا كان هناك نسختان طبق الأصل وكان المعامل يتضمن القيمة [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 |
تسلسل من الصفائف متعددة الأبعاد N من الأنواع T_0,..., T_{N-1} ، ويمثل كل منها مساحة القاعدة التي يتم وضع النافذة عليها. |
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 |
نوع المساحة المتروكة للنافذة (المساحة المتروكة::kSame، والتي يتم وضعها بحيث يكون لها شكل الإخراج نفسه مثل المدخل إذا كانت الخطوة 1، أو المساحة المتروكة::kصالحة التي لا تستخدم مساحة متروكة و "توقف" النافذة عند عدم ملاءمتها) |
المكان:
- يجب أن تكون 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]
. يعمل تشغيل نافذة التقليل فوق المصفوفة المحشوة على ثلاثة
نوافذ [MAX_VALUE, 10000, 1000]
و[1000, 100, 10]
و[10, 1, MAX_VALUE]
،
ويتم إخراجها في [1000, 10, 1]
.
يكون ترتيب تقييم دالة الاختزال عشوائيًا وقد يكون
غير مؤكدًا. لذلك، ينبغي ألا تكون دالة الاختزال حساسة
بشكل مفرط لإعادة الاقتران. للحصول على مزيد من التفاصيل، يمكنك الاطّلاع على المناقشة حول الارتباط النفسي في
سياق Reduce
.
ReplicaId
يمكنك أيضًا الاطّلاع على
XlaBuilder::ReplicaId
.
لعرض المعرف الفريد (مقياس U32) للنسخة المطابقة.
ReplicaId()
المُعرف الفريد لكل نسخة طبق الأصل هو عدد صحيح غير مُوقَّع في الفاصل الزمني [0, N)
،
حيث يكون N
هو عدد النُسخ المتماثلة. ونظرًا لأن جميع النسخ المتماثلة تشغّل البرنامج نفسه،
سيعرض استدعاء ReplicaId()
في البرنامج قيمة مختلفة في كل نسخة طبق الأصل.
إعادة التشكيل
يمكنك الاطّلاع أيضًا على XlaBuilder::Reshape
وعملية Collapse
.
إعادة تشكيل أبعاد صفيف في تهيئة جديدة.
Reshape(operand, new_sizes)
Reshape(operand, dimensions, new_sizes)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
صفيفة من النوع T |
dimensions |
متجه int64 |
ترتيب تصغير السمات |
new_sizes |
متجه int64 |
الخط المتجه لأحجام الأبعاد الجديدة |
نظريًا، تقوم إعادة تشكيل الصفيف أولاً بتسطيح صفيف في متجه أحادي البعد لقيم البيانات، ثم تنقيح هذا المتجه في شكل جديد. وسيطات الإدخال هي صفيف عشوائي من النوع T، ومتجه ثابت في وقت التجميع لمؤشرات الأبعاد، ومتجه ثابت في وقت التجميع لأحجام الأبعاد للنتيجة.
يجب أن تكون القيم في الخط المتجه dimension
، إذا تم توفيرها، تبديلاً لجميع أبعاد حرف T، وتكون القيمة التلقائية عند عدم تقديمها هي {0, ..., rank - 1}
. ترتيب الأبعاد في dimensions
هو من البُعد الأبطأ تغيُّرًا (الأكثر أهمية) إلى
البعد الأسرع متغيرًا (الأصغر) في تداخل الحلقة التي تعمل على تصغير صفيف الإدخال
إلى بُعد واحد. يحدد الخط المتجه new_sizes
حجم صفيف الإخراج. القيمة في الفهرس 0 بـ new_sizes
هي حجم البُعد 0، والقيمة في الفهرس 1 هي حجم البُعد 1، وهكذا. يجب أن يكون ناتج الأبعاد new_size
مساويًا لمنتج أحجام أبعاد المعامل. عند تحسين الصفيف المصغّر إلى مصفوفة متعددة الأبعاد المحدّدة في new_sizes
، يتم ترتيب الأبعاد في new_sizes
من أبطأ تنوع (الأكثر أهمية) إلى أسرع متغير (الأكثر ثانوية).
على سبيل المثال، لنفترض أن 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} } };
In-order collapse:
let v012_24 = Reshape(v, {0,1,2}, {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, {0,1,2}, {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} };
Out-of-order collapse:
let v021_24 = Reshape(v, {1,2,0}, {24});
then v012_24 == f32[24] {10, 20, 30, 40, 11, 21, 31, 41, 12, 22, 32, 42,
15, 25, 35, 45, 16, 26, 36, 46, 17, 27, 37, 47};
let v021_83 = Reshape(v, {1,2,0}, {8,3});
then v021_83 == f32[8x3] { {10, 20, 30}, {40, 11, 21},
{31, 41, 12}, {22, 32, 42},
{15, 25, 35}, {45, 16, 26},
{36, 46, 17}, {27, 37, 47} };
let v021_262 = Reshape(v, {1,2,0}, {2,6,2});
then v021_262 == f32[2x6x2] { { {10, 20}, {30, 40},
{11, 21}, {31, 41},
{12, 22}, {32, 42} },
{ {15, 25}, {35, 45},
{16, 26}, {36, 46},
{17, 27}, {37, 47} } };
في حالة خاصة، يمكن لإعادة التشكيل تحويل صفيفة عنصر واحد إلى عددي والعكس صحيح. على سبيل المثال:
Reshape(f32[1x1] { {5} }, {0,1}, {}) == 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
.
تنشئ ناتجًا لشكل معيّن بأرقام عشوائية يتم إنشاؤها بعد التوزيع الطبيعي. \(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
تنشئ مخرجًا بشكل معين مملوءًا بوحدات بت عشوائية موحدة باستخدام الخوارزمية المحددة (أو الإعدادات الافتراضية للخلفية) وتعرض حالة محدثة (بنفس شكل الحالة الأولية) والبيانات العشوائية التي يتم إنشاؤها.
الحالة الأولية هي الحالة الأولية لإنشاء الأرقام العشوائية الحالية. ويعتمد الشكل المطلوب والقيم الصالحة على الخوارزمية المستخدمة.
ويضمن أن يكون الناتج دالة حتمية للحالة الأولية، ولكن لا يمكن ضمان أنّه حتمي بين الخلفيات وإصدارات برامج التجميع المختلفة.
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. الأرقام العشوائية المتوازية: سهلة مثل 1 و2 و3.rng_philox
: خوارزمية Philox لإنشاء أرقام عشوائية بالتوازي شكلinitial_state
هوu64[3]
ذو قيم عشوائية. Salmon et al. SC 2011. الأرقام العشوائية المتوازية: سهلة مثل 1 و2 و3.
رسم بياني للنقاط المبعثرة
تنشئ عملية التبعثر 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> |
خريطة أبعاد من مؤشرات التبعثر إلى مساحة فهرس المعامل. يتم تفسير هذه الصفيفة على أنّها تعيين i إلى scatter_dims_to_operand_dims[i] . ينبغي أن يكون فرديًا وإجماليًا. |
indices_are_sorted |
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
] fork
فيupdate_scatter_dims
}. استخدِمG
للبحث عن متجه فهرسS
في مصفوفةscatter_indices
بحيثS
[i
] =scatter_indices
[دمج(G
,i
)] حيث يؤدي الدمج(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 أن تفترض أنّ start_indices
تم ترتيبها (بترتيب start_index_map
تصاعديًا) حسب المستخدم. إذا لم تكن كذلك، فسيتم
تحديد دلالات التنفيذ.
بشكل غير رسمي، يمكن اعتبار عملية التبعثر معكوسة لعملية الجمع، بمعنى أنّ عملية التبعثر تحدّث العناصر في الإدخال التي يتم استخراجها من عملية جمع البيانات المقابلة.
وللحصول على وصف تفصيلي وأمثلة غير رسمية، يمكنك مراجعة
قسم "الوصف غير الرسمي" ضمن 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};
تتوفر إمكانية الاختيار بين الصفوف. تُعد الصفوف أنواعًا
عددية لهذا الغرض. إذا كان on_true
وon_false
صفين (يجب أن يكون لهما نفس الشكل!)، يجب أن يكون pred
مقياسًا من النوع PRED
.
SelectAndScatter
يمكنك أيضًا الاطّلاع على
XlaBuilder::SelectAndScatter
.
يمكن اعتبار هذه العملية عملية مركّبة تحسب أولاً ReduceWindow
في الصفيف operand
لاختيار عنصر من كل نافذة، ثم تبعثر بعد ذلك صفيف source
على فهارس العناصر المحدّدة
لإنشاء صفيف ناتج بنفس شكل مصفوفة المعامل. تُستخدَم الدالة 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 |
نوع المساحة المتروكة للنافذة (المساحة المتروكة::kSame أو الحشو::kصالح) |
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 |
معرّف فريد لكل زوج من الإرسال/الاستلام |
يرسل بيانات المعامل المحدّدة إلى تعليمات Recv
في عملية حاسوبية أخرى تتشارك الاسم المعرِّف نفسه للقناة. ولا يعرض أي بيانات.
على غرار عملية Recv
، تمثّل عملية واجهة برمجة التطبيقات الخاصة بالعميل في Send
اتصالاً متزامنًا، ويتم تقسيمها داخليًا إلى تعليمات HLO (Send
وSendDone
) لإتاحة عمليات النقل غير المتزامنة للبيانات. يمكنك أيضًا الاطّلاع على
HloInstruction::CreateSend
وHloInstruction::CreateSendDone
.
Send(HloInstruction operand, int64 channel_id)
تبدأ عملية نقل غير متزامنة للمعامل إلى الموارد المخصّصة من خلال
تعليمات Recv
باستخدام معرّف القناة نفسه. تعرض هذه الدالة سياقًا وتستخدمه تعليمات SendDone
التالية للانتظار إلى حين اكتمال عملية نقل البيانات. ويتألف السياق من صف من {Operand (shape), الطلب
(U32)} ولا يمكن استخدامه إلا من خلال تعليمات SendDone
.
SendDone(HloInstruction context)
بناءً على سياق تم إنشاؤه من خلال تعليمات Send
، يتم انتظار اكتمال عملية نقل البيانات. لا تعرض التعليمات أي بيانات.
جدولة تعليمات القناة
في ما يلي ترتيب تنفيذ التعليمات الأربعة لكل قناة (Recv
وRecvDone
وSend
وSendDone
).
- يحدث
Recv
قبلSend
- يحدث
Send
قبلRecvDone
- يحدث
Recv
قبلRecvDone
- يحدث
Send
قبلSendDone
عندما تنشئ برامج التحويل البرمجي للخلفية جدولاً خطيًا لكل عملية حاسوبية يتم نقلها عبر تعليمات القناة، يجب ألا تكون هناك دورات عبر العمليات الحسابية. على سبيل المثال، تؤدي الجداول الزمنية أدناه إلى حالات توقف تام.
شريحة
يمكنك أيضًا الاطّلاع على
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 |
ما إذا كان يجب استخدام الترتيب الثابت. |
في حال تقديم معامل واحد فقط:
إذا كان المعامل صفيفًا من الترتيب 1 (صفيف)، تكون النتيجة صفيفًا تم فرزه. إذا كنت تريد فرز الصفيفة بترتيب تصاعدي، فيجب على المقارِن إجراء مقارنة "أقل من". رسميًا، بعد فرز المصفوفة، فإنها تحتفظ بجميع مواضع الفهرس
i, j
التي تحتوي علىi < j
والتي تكونcomparator(value[i], value[j]) = comparator(value[j], value[i]) = false
أوcomparator(value[i], value[j]) = true
.إذا كان المعامل لديه ترتيب أعلى، يتم فرز المعامل وفقًا للبُعد المقدم. على سبيل المثال، بالنسبة إلى متعدّد الترتيب 2 (مصفوفة)، ستعمل قيمة البُعد
0
على ترتيب كل عمود بشكل مستقل، وستعمل قيمة البُعد1
على ترتيب كل صف بشكل مستقل. إذا لم يتم تقديم رقم سمة، يتم اختيار السمة الأخيرة تلقائيًا. بالنسبة للبُعد الذي يتم فرزه، ينطبق نفس ترتيب الفرز كما في حالة الترتيب 1.
في حال توفير معاملات n > 1
:
يجب أن تكون كل معاملات
n
عبارة عن دوال متسلسلة لها الأبعاد نفسها. قد تختلف أنواع العناصر من المتوترات.يتم فرز جميع المعاملات معًا، وليس بشكلٍ فردي. نظريًا، تُعامَل المعاملات كصف. عند التحقّق ممّا إذا كان يجب تبديل عناصر كل معامل في موضعَي الفهرس
i
وj
، يتم استدعاء المقارِن بمَعلمات عددية واحدة (2 * n
)، حيث تتجاوب المَعلمة2 * k
مع القيمة في الموضعi
من المعاملk-th
، وتتوافق المَعلمة2 * k + 1
مع القيمة في الموضعj
من المعاملk-th
. وهكذا، يقارن المقارِن عادةً المعلمتين2 * k
و2 * k + 1
ببعضهما البعض، وربما يستخدم أزواجًا من المعلّمات الأخرى كقواطع ربط.النتيجة هي صف يتكون من المعاملات بترتيب مرتّب (على طول البُعد المقدَّم، كما هو موضح أعلاه). يتجاوب المعامل
i-th
للصف مع معامل الترتيبi-th
.
على سبيل المثال، إذا كان هناك ثلاثة معاملات 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
تلقائيًا على "خطأ".
تبديل
راجِع أيضًا عملية tf.reshape
.
Transpose(operand)
الوسيطات | النوع | دلالات الألفاظ |
---|---|---|
operand |
XlaOp |
المعامل المراد تبديل الموضع. |
permutation |
ArraySlice<int64> |
طريقة السماح للسمات |
يؤدي إلى تبديل أبعاد المُعامِل مع التبديل المُعطى، وبالتالي
∀ i . 0 ≤ i < rank ⇒ input_dimensions[permutation[i]] = output_dimensions[i]
.
هذه الطريقة هي نفسها إعادة الشكل(العامل، التبديل، 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 |
صفيف ترتيب أكبر من 2 لنوع معقد أو نقطة عائمة بالشكل [..., 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
أبعاد مجمّعة متساوية.
صف
يمكنك أيضًا الاطّلاع على
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};
}