يوضِّح ما يلي دلالات العمليات المحدّدة في واجهة
XlaBuilder
. يتم عادةً ربط هذه العمليات واحدًا تلو الآخر للعمليات المحدّدة في واجهة RPC في xla_data.proto
.
ملاحظة حول التسمية: نوع البيانات المعممة الذي يتعامل معه XLA هو مصفوفة أبعاد N تحتوي على عناصر من نوع موحد (مثل مصفوفة عشرية 32 بت). في جميع المستندات، يتم استخدام صفيف للدلالة على مصفوفة عشوائية للأبعاد. للتيسير عليك، يكون للحالات الخاصة أسماء أكثر تحديدًا ومألوفة؛ على سبيل المثال، المتجه هو مصفوفة أحادية البُعد، والمصفوفة هي مصفوفة ثنائية الأبعاد.
AfterAll
يمكنك أيضًا الاطّلاع على
XlaBuilder::AfterAll
.
تأخذ AfterAll عددًا متنوعًا من الرموز المميزة وتنتج رمزًا مميزًا واحدًا. تُعد الرموز المميزة أنواعًا أولية يمكن تسلسلها بين عمليات التأثير الجانبي لفرض الطلب. يمكن استخدام AfterAll
كمجموعة من الرموز المميزة لطلب عملية ما بعد عملية معينة.
AfterAll(operands)
الوسيطات | النوع | دلالات |
---|---|---|
operands |
XlaOp |
عدد متنوع من الرموز المميزة |
AllGather
يمكنك أيضًا الاطّلاع على
XlaBuilder::AllGather
.
إجراء التسلسل عبر النسخ المتماثلة.
AllGather(operand, all_gather_dim, shard_count, replica_group_ids,
channel_id)
الوسيطات | النوع | دلالات |
---|---|---|
operand
|
XlaOp
|
مصفوفة للتسلسل عبر النسخ المكررة |
all_gather_dim |
int64 |
سمة التسلسل |
replica_groups
|
متّجهات int64 |
تشير المجموعات التي يتم تنفيذ التسلسل |
channel_id
|
اختياري int64
|
معرّف القناة الاختياري للتواصل بين الوحدات |
replica_groups
هي قائمة بالمجموعات المماثلة التي يتم تنفيذ التسلسل (يمكن استرداد المعرف المكرر للنسخة الحالية باستخدامReplicaId
). يحدد ترتيب النُسخ المكررة في كل مجموعة الترتيب الذي توجد به الإدخالات في النتيجة. يجب أن تكون السمةreplica_groups
فارغة (في هذه الحالة تنتمي جميع النسخ المتماثلة إلى مجموعة واحدة، مرتبة من0
إلىN - 1
)، أو أن تحتوي على العدد نفسه من العناصر كعدد النُسخ المتماثلة. على سبيل المثال، تُجريreplica_groups = {0, 2}, {1, 3}
تسلسلاً بين النسختين المتماثلتين0
و2
، و1
و3
.shard_count
هي حجم كل مجموعة مماثلة. نحتاج إلى هذه البيانات في الحالات التي يكون فيها حقلreplica_groups
فارغًا.- تُستخدم
channel_id
للاتصال عبر الوحدات: يمكن فقط لعملياتall-gather
التي تتضمّنchannel_id
ذاتها التواصل مع بعضها.
شكل الإخراج هو شكل الإدخال مع all_gather_dim
الذي تم جعل shard_count
أكبر مرة. على سبيل المثال، إذا كان هناك نسختان طبق الأصل والمعامل يتضمن القيمة [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 على البيانات الواردة من الخلاصة والبيانات التي يتم تغليفها تؤدي إلى تكرار التكرار الحلقي 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
.
يتم تحديد التدرجات الثلاثة من خلال الصيغ التالية (بافتراض أن مصفوفة 4 أبعاد مثل operand
ومع مؤشر أبعاد الميزة l
وحجم الدفعة m
والأحجام المكانية w
وh
):
\[ \begin{split} c_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sigma^2_l+\epsilon} \right) \\\\ d_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \\\\ \nabla x_{ijkl} &= \frac{\gamma_{l} }{\sqrt{\sigma^2_{l}+\epsilon} } \left( \nabla y_{ijkl} - d_l - c_l (x_{ijkl} - \mu_{l}) \right) \\\\ \nabla \gamma_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sqrt{\sigma^2_{l}+\epsilon} } \right) \\\\\ \nabla \beta_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \end{split} \]
يمثّل المدخلان mean
وvariance
قيم اللحظات على مستوى الأبعاد المجمّعة والمكانية.
نوع الإخراج عبارة عن صف من ثلاثة مؤشرات:
المُخرَجات | النوع | دلالات |
---|---|---|
grad_operand
|
XlaOp
|
التدرج بالنسبة للإدخال operand ($\nafla
x$) |
grad_scale
|
XlaOp
|
التدرج بالنسبة إلى الإدخال scale ($\nabla
\gamma$) |
grad_offset
|
XlaOp
|
التدرج بالنسبة للإدخال offset ($\nafla
\beta$) |
BatchNormInference
راجِع أيضًا
XlaBuilder::BatchNormInference
وورقة التسوية الأصلية المجمّعة
للحصول على وصف تفصيلي للخوارزمية.
تسوية صفيف على مستوى الأبعاد المجمّعة والمكانية
BatchNormInference(operand, scale, offset, mean, variance, epsilon, feature_index)
الوسيطات | النوع | دلالات |
---|---|---|
operand |
XlaOp |
صفيفة الأبعاد n المطلوب تسويتها |
scale |
XlaOp |
مصفوفة واحدة من الأبعاد |
offset |
XlaOp |
مصفوفة واحدة من الأبعاد |
mean |
XlaOp |
مصفوفة واحدة من الأبعاد |
variance |
XlaOp |
مصفوفة واحدة من الأبعاد |
epsilon |
float |
قيمة Epsilon |
feature_index |
int64 |
فهرس لسمة الميزة في operand |
بالنسبة إلى كل ميزة في سمة الميزة (يمثل feature_index
فهرس سمة الميزة في operand
)، تحتسب العملية المتوسط والتباين بين كل الأبعاد الأخرى وتستخدم المتوسط والتباين لتسوية كل عنصر في operand
. يجب أن يكون feature_index
فهرسًا صالحًا لبُعد الميزة في operand
.
تعادل BatchNormInference
استدعاء BatchNormTraining
بدون
احتساب mean
وvariance
لكل دفعة. وتستخدم المدخلات mean
وvariance
بدلاً من ذلك كقيم مقدَّرة. الغرض من هذه العملية هو تقليل وقت الاستجابة
في الاستنتاج، وبالتالي اسم BatchNormInference
.
المُخرج عبارة عن مصفوفة تمت تسويتها بأبعاد نية ولها شكل الإدخال 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
s:
المُخرَجات | النوع | دلالات |
---|---|---|
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
مقياسًا f32
بقيمة 2.0f
، وbroadcast_sizes
يساوي {2, 3}
، ستكون النتيجة مصفوفة شكل f32[2, 3]
وستكون جميع القيم في النتيجة 2.0f
.
BroadcastInDim
يمكنك أيضًا الاطّلاع على
XlaBuilder::BroadcastInDim
.
لتوسيع حجم وترتيب صفيف من خلال تكرار البيانات في الصفيفة.
BroadcastInDim(operand, out_dim_size, broadcast_dimensions)
الوسيطات | النوع | دلالات |
---|---|---|
operand |
XlaOp |
الصفيف المطلوب تكراره |
out_dim_size |
ArraySlice<int64> |
أحجام أبعاد الشكل المستهدف |
broadcast_dimensions |
ArraySlice<int64> |
أي البعد في الشكل المستهدف يتجاوب كل بُعد من أبعاد شكل المعامل مع |
يشبه البث، ولكنه يسمح بإضافة أبعاد في أي مكان وتوسيع الأبعاد الحالية بالحجم 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 |
تسلسل شمال 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 |
حساب XlaCom الطبي \(T_0 \to S\) |
false_operand |
XlaOp |
وسيطة من النوع \(T_1\) |
false_computation |
XlaComputation |
حساب XlaCom الطبي \(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 |
تسلسل شمال XlaComputation |
العمليات الحسابية لمعاملات XlaCom الطبي \(T_0 \to S , T_1 \to S , ..., T_{N-1} \to S\) |
branch_operands |
تسلسل شمال 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
.
مثل ConvertWithGeneralPadding، ولكن يتم تحديد المساحة المتروكة بطريقة مختصرة إما على أنها SAME أو صالحة. تعمل المساحة المتروكة نفسها على تزويد الإدخال (lhs
) بأصفار بحيث يكون للمخرجات نفس شكل الإدخال في حال عدم أخذ المخطَّط في الاعتبار. المساحة المتروكة "صالحة" تعني ببساطة عدم وجود مساحة متروكة.
ConvertWithGeneralPadding (الالتفاف)
يمكنك أيضًا الاطّلاع على
XlaBuilder::ConvWithGeneralPadding
.
تحسب التفافًا من النوع المستخدم في الشبكات العصبية. هنا، يمكن اعتبار الالتفاف على أنه نافذة ذات أبعاد صغيرة تتحرك عبر مساحة أساسية ذات أبعاد ن بعدية ويتم إجراء عملية حسابية لكل موضع محتمل للنافذة.
الوسيطات | النوع | دلالات |
---|---|---|
lhs |
XlaOp |
ترتيب صفيفة المدخلات ن+2 |
rhs |
XlaOp |
ترتيب صفيفة النواة بقيمة n+2 |
window_strides |
ArraySlice<int64> |
صفيفة n-d لخطوات النواة (النواة) |
padding |
ArraySlice< pair<int64,int64>> |
مصفوفة n-d للمساحة المتروكة (منخفضة أو عالية) |
lhs_dilation |
ArraySlice<int64> |
صفيف عامل التوسع n-d lhs |
rhs_dilation |
ArraySlice<int64> |
مصفوفة عامل التوسع n-d rhs |
feature_group_count |
int64 | عدد مجموعات الميزات |
batch_group_count |
int64 | عدد المجموعات المجمّعة |
لنفترض أن n تمثل عدد الأبعاد المكانية. الوسيطة lhs
عبارة عن صفيف مرتبة n+2
يصف منطقة القاعدة. وهذا ما يسمى بالمدخل، على الرغم من أن
rhs بالطبع هي أيضًا مدخل. في الشبكة العصبية، هذه هي عمليات تنشيط الإدخال.
وتكون السمات n+2 بالترتيب التالي:
batch
: يمثل كل إحداثي في هذا البُعد مدخلاً مستقلاً يتم من أجله إجراء الالتفاف.z/depth/features
: لكل موضع (y,x) في مساحة القاعدة خط متجه مرتبط به، يدخل في هذا البُعد.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 معًا لحساب 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
. على نحو فعّال، نقسّم كل دفعة hs إلى مجموعات 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] |
الكمية القياسية | ناتج الضرب النقطي |
مصفوفة [m x k] dot متجه [k] |
الخط المتجه [m] | ناتج ضرب الخط المتجه في المصفوفة |
مصفوفة [m x k] dot مصفوفة [k x n] |
مصفوفة [m x 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_indices
في الترتيب ==
1، على أن يكون حجم البُعد مساويًا لترتيب operand
.
DynamicSlice(operand, start_indices, size_indices)
الوسيطات | النوع | دلالات |
---|---|---|
operand |
XlaOp |
مصفوفة الأبعاد N من النوع T |
start_indices |
تسلسل شمال 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 |
تسلسل شمال 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،
الوسيطات | النوع | دلالات |
---|---|---|
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
واحد، يعني ذلك تطبيق سلسلة من عمليات النقل الآمن للإطارات على كل من المحاور الداخلية. لاحظ أنه بالنسبة للحالات الحقيقية > المعقدة والمعقدة-> ستكون تحويلات المحاور الأخرى
معقدة->معقدة.
تفاصيل التنفيذ
تتوافق ميزة CPU FFT مع أداة TensorFFT من Eigen. يستخدم بروتوكول 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 |
ما إذا كان سيتم ضمان ترتيب الفهارس حسب المتصل |
للتيسير عليك، نصنّف الأبعاد في مصفوفة الإخراج التي ليست في 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
(أي يساوي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
)] حيث يؤدي الدمج(أ، ب) إلى إدراج 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
تصاعديًا). وإذا لم تكن كذلك،
فيتم تحديد الدلالات.
وصف وأمثلة غير رسمية
بشكل غير رسمي، يتجاوب كل فهرس 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
في
الوصف الرسمي) و "تعيين الإزاحة" (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
من البيانات. يُسمَح بإجراء عمليات حسابية متعددة ضمن الخلاصة، ولكن يجب أن يكون هناك ترتيب إجمالي بين عمليات الإعلان ضمن الخلاصة. على سبيل المثال، لاثنتين من الخلاصات في التعليمة البرمجية أدناه ترتيب إجمالي نظرًا لوجود
تبعية بين التكرارات الحلقية while.
result1 = while (condition, init = init_value) {
Infeed(shape)
}
result2 = while (condition, init = result1) {
Infeed(shape)
}
أشكال الصفوف المتداخلة غير متوافقة. بالنسبة إلى شكل الصف الفارغ، تكون عملية الإعلان داخل الخلاصة عبارة عن عملية حظر وتتابع بدون قراءة أي بيانات من البيانات المضمّنة في الجهاز.
أمواج هادئة قصيرة
يمكنك أيضًا الاطّلاع على
XlaBuilder::Iota
.
Iota(shape, iota_dimension)
تنشئ نقلاً حرفيًا ثابتًا على الجهاز بدلاً من نقل المضيف الذي يُحتمل أن يكون كبيرًا. تنشئ صفيفًا حدد شكلاً محددًا ويحمل قيمًا تبدأ من الصفر وتزيد بمقدار واحد على طول البُعد المحدد. بالنسبة إلى أنواع النقاط العائمة، يكون الصفيف الناتج مساويًا لـ ConvertElementType(Iota(...))
حيث يكون Iota
من نوع التكامل والإحالة الناجحة إلى نوع النقطة العائمة.
الوسيطات | النوع | دلالات |
---|---|---|
shape |
Shape |
شكل الصفيف الذي تم إنشاؤه بواسطة Iota() |
iota_dimension |
int64 |
السمة المطلوب زيادتها. |
على سبيل المثال، يمكن إرجاع المشتريات مقابل Iota(s32[4, 8], 0)
.
[[0, 0, 0, 0, 0, 0, 0, 0 ],
[1, 1, 1, 1, 1, 1, 1, 1 ],
[2, 2, 2, 2, 2, 2, 2, 2 ],
[3, 3, 3, 3, 3, 3, 3, 3 ]]
يمكن إرجاع المشتريات مقابل Iota(s32[4, 8], 1)
.
[[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ]]
خريطة
يمكنك أيضًا الاطّلاع على
XlaBuilder::Map
.
Map(operands..., computation)
الوسيطات | النوع | دلالات |
---|---|---|
operands |
تسلسل n XlaOp 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
التالية لانتظار اكتمال عملية نقل البيانات. السياق هو صف من {begin 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 |
عدد عددي من أنواع 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 باستخدام دالة "إضافة":
لاحظ أن كلتا نتيجتي الاختزال هما صفائف أحادية البُعد. يُظهر الرسم التخطيطي أحدهما كعمود وآخر كصف فقط للراحة البصرية.
لمثال أكثر تعقيدًا، إليك صفيفة ثلاثية الأبعاد. ترتيبه هو 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 |
عدد وحدات بت mantisa بتنسيق منخفض الدقة |
النتيجة هي مصفوفة من النوع T
. ويتم تقريب قيم الإدخال إلى أقرب قيمة يمكن تمثيلها باستخدام عدد معين من وحدات بت mantissa (باستخدام دلالات "ربط بالعدد الزوجي")، وأي قيم تتجاوز النطاق المحدد بعدد وحدات بت الأس يتم تثبيتها على ما لا نهاية موجبة أو سالبة. يتم الاحتفاظ بقيم NaN
، ولكن يمكن تحويلها إلى قيم NaN
الأساسية
يجب أن يحتوي التنسيق المنخفض الدقة على وحدة بت أس واحدة على الأقل (من أجل التمييز بين القيمة الصفرية واللانهاية، بما أن كليهما يحتوي على قيمة صفرية)، ويجب أن يحتوي
على عدد غير سالب من وحدات بت mantisa. قد يتجاوز عدد وحدات بت الأس أو
الماتيسا القيمة المقابلة للنوع T
، وبالتالي فإن الجزء المقابل من الإحالة الناجحة يكون إذن "لا بيئة".
ReduceScatter
يمكنك أيضًا الاطّلاع على
XlaBuilder::ReduceScatter
.
إن عملية ClickScatter هي عملية جماعية مُجرية بشكل فعّال عملية AllReset ثم تبعثر النتيجة عن طريق تقسيمها إلى مجموعات 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، أو Padding::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)\). يجب أن تكون المعلمات ونوع عنصر الإخراج من النوع المنطقي أو نوع التكامل أو نوع النقطة العائمة، وأن تكون الأنواع متسقة. في الوقت الحالي، لا تتوافق خلفيات وحدة المعالجة المركزية (CPU) ووحدة معالجة الرسومات إلا مع 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 |
ما إذا كان سيتم ضمان ترتيب الفهارس حسب المتصل |
unique_indices |
bool |
ما إذا كان المتصل يضمن أن تكون الفهارس فريدة من نوعها |
المكان:
- ويجب أن تكون قيمة N أكبر من 1 أو تساويه.
operands
[0
] و... وoperands
[N-1
] يجب أن تكون لها السمات نفسها.updates
[0
] و... وupdates
[N-1
] يجب أن تكون لها السمات نفسها.- وإذا كانت قيمة الحقل "
N = 1
"، تكون قيمة الحقل "Collate(T)
" هي "T
". - إذا كانت
N > 1
، تكونCollate(T_0, ..., T_N)
صفًا من عناصرN
من النوعT
.
إذا كانت قيمة السمة index_vector_dim
تساوي scatter_indices.rank
، نعتبر أنّ
scatter_indices
ضمنًا كسمة "1
" لاحقة.
نعرّف update_scatter_dims
من النوع ArraySlice<int64>
على أنّه مجموعة السمات في الشكل updates
والتي ليست في update_window_dims
بترتيب تصاعدي.
يجب أن تتبع وسيطات التبعثر القيود التالية:
يجب أن تكون كل مصفوفة
updates
من الترتيبupdate_window_dims.size + scatter_indices.rank - 1
.يجب أن تتوافق حدود البُعد
i
في كل مصفوفةupdates
مع ما يلي:- إذا كانت السمة
i
موجودة فيupdate_window_dims
(أي يساويupdate_window_dims
[k
] لبعضk
)، يجب ألا يتجاوز حد البُعدi
فيupdates
الحد المقابل وهوoperand
بعد احتسابinserted_window_dims
(أيadjusted_window_bounds
[k
]، حيث يحتويadjusted_window_bounds
على حدودoperand
مع الحدود في الفهارسinserted_window_dims
). - إذا كانت السمة
i
متوفّرة فيupdate_scatter_dims
(أي أنّها تساويupdate_scatter_dims
[k
] لبعضk
)، يجب أن يكون حد السمةi
فيupdates
مساويًا للحد المقابل البالغscatter_indices
، مع تخطّيindex_vector_dim
(أيscatter_indices.shape.dims
[k
]، إذا كانتk
<index_vector_dim
وscatter_indices.shape.dims
[k+1
] في الحالات الأخرى).
- إذا كانت السمة
يجب أن تكون السمة
update_window_dims
بترتيب تصاعدي، وألا تتضمن أي أرقام سمات متكررة، وأن تكون في النطاق[0, updates.rank)
.يجب أن تكون السمة
inserted_window_dims
بترتيب تصاعدي، وألا تتضمن أي أرقام سمات متكررة، وأن تكون في النطاق[0, operand.rank)
.يجب أن يساوي
operand.rank
مجموعupdate_window_dims.size
وinserted_window_dims.size
.يجب أن تكون قيمة
scatter_dims_to_operand_dims.size
مساوية لـscatter_indices.shape.dims
[index_vector_dim
]، ويجب أن تكون قيمها ضمن النطاق[0, operand.rank)
.
بالنسبة إلى الفهرس U
المحدّد في كل مصفوفة updates
، يتم احتساب الفهرس المقابل I
في مصفوفة operands
المقابلة التي يجب تطبيق هذا التحديث عليها على النحو التالي:
- دع
G
= {U
[k
] لـk
فيupdate_scatter_dims
}. استخدِمG
للبحث عن متّجه فهرسS
في مصفوفةscatter_indices
بحيث يكونS
[i
] =scatter_indices
[دمج(G
,i
)] حيث يؤدي الدمج(A، ب) إلى إدراج 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
تصاعديًا). وإذا لم تكن كذلك،
فيتم تحديد الدلالات.
إذا تم ضبط unique_indices
على "صحيح"، يمكن لخوارزمية XLA افتراض أنّ جميع العناصر المتبعثرة فريدة. ولذلك يمكن أن تستخدم خوارزمية XLA العمليات غير الذرية. إذا تم ضبط unique_indices
على "صحيح" وكانت الفهارس المتبعثرة غير فريدة، يتم تحديد تنفيذ دلالات الألفاظ المستخدَمة.
بشكل غير رسمي، يمكن اعتبار عملية التبعثر معكوسًا لعملية جمع البيانات، أي أنّ عملية التبعثر تحدّث العناصر الموجودة في المدخل والتي يتم استخراجها من خلال عملية جمع البيانات المقابلة.
للحصول على وصف تفصيلي وأمثلة غير رسمية، يمكنك الاطّلاع على
قسم "الوصف غير الرسمي" ضمن Gather
.
اختيار
يمكنك أيضًا الاطّلاع على
XlaBuilder::Select
.
تنشئ هذه الدالة صفيفًا ناتجًا من عناصر صفيفتين للإدخال، استنادًا إلى قيم صفيفة إسناد.
Select(pred, on_true, on_false)
الوسيطات | النوع | دلالات |
---|---|---|
pred |
XlaOp |
مصفوفة من النوع PRED |
on_true |
XlaOp |
صفيفة من النوع T |
on_false |
XlaOp |
صفيفة من النوع T |
يجب أن يكون للصفيفَين on_true
وon_false
الشكل نفسه. هذا أيضًا شكل
صفيف الإخراج. يجب أن تكون للمصفوفة pred
نفس أبعاد
on_true
وon_false
، مع نوع العنصر PRED
.
لكل عنصر P
من pred
، يتم الحصول على العنصر المقابل في مصفوفة الإخراج من on_true
إذا كانت قيمة P
هي true
، ومن on_false
إذا كانت قيمة P
هي false
. باعتباره شكلاً مشروطًا من البث،
يمكن أن يكون pred
مقياسًا من النوع PRED
. في هذه الحالة، يتم الحصول على صفيف الإخراج بالكامل من on_true
إذا كانت قيمة pred
هي true
، ومن on_false
إذا كانت قيمة pred
هي false
.
مثال مع قيمة pred
غير رقمية:
let pred: PRED[4] = {true, false, false, true};
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 200, 300, 4};
مثال مع قيمة عددية pred
:
let pred: PRED = true;
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 2, 3, 4};
تتوفر إمكانية الاختيار بين الصفوف. تعتبر الصفوف أنواعًا
عددية لهذا الغرض. إذا كان 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 أو Padding::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> |
قائمة بعدد صحيح من الأعداد تحتوي على مؤشرات النهاية (حصريًا) للشريحة الخاصة بكل سمة. يجب أن تكون كل قيمة أكبر من قيمة 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 |
ما إذا كان يجب استخدام الفرز الثابت. |
في حال توفير معامل واحد فقط:
إذا كان المعامل صفيفًا من الدرجة الأولى (صفيف)، تكون النتيجة صفيفة مرتبة. إذا كنت تريد فرز الصفيفة بترتيب تصاعدي، فيجب أن يُجري المقارِن مقارنة "أقل من". رسميًا، بعد فرز الصفيفة، فإنها تحتفظ بجميع مواضع الفهرس
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
على "صحيح"، نضمن أن يكون الترتيب ثابتًا، أي أنّه إذا كانت هناك عناصر مساوية للمُقارِن، يتم الحفاظ على الترتيب النسبي للقيم المتساوية. اثنان من العناصر 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 true، [..., K, M] بخلاف ذلك. |
left_side |
bool |
تشير إلى ما إذا كان يجب حلّ نظام بالنموذج op(a) * x = b (true ) أو x * op(a) = b (false ). |
lower |
bool |
ما إذا كان سيتم استخدام المثلث العلوي أو السفلي في a . |
unit_diagonal |
bool |
إذا كانت السمة true ، يتم الافتراض أنّ العناصر القطرية لـ a هي 1 ولا يتم الوصول إليها. |
transpose_a |
Transpose |
ما إذا كان سيتم استخدام a كما هي أو تبديل موضعها أو استخدام موضعها المصاحب. |
تتم قراءة بيانات الإدخال فقط من المثلث السفلي/الأعلى في a
، بناءً على قيمة lower
. يتم تجاهل القيم من المثلث الآخر. يتم إرجاع بيانات الإخراج في نفس المثلث؛ القيم في المثلث الآخر
محددة التنفيذ وقد تكون أي شيء.
إذا كان الترتيب a
وb
أكبر من 2، سيتم التعامل معهما على شكل دفعات من المصفوفات، حيث تكون جميعها أبعادًا مجمّعة، باستثناء البعدين الثانويين. يجب أن تكون لكل من a
وb
أبعاد مجمّعة متساوية.
بنية Tuple
يمكنك أيضًا الاطّلاع على
XlaBuilder::Tuple
.
صف يحتوي على عدد متغير من مؤشرات البيانات، ولكل منها شكلها الخاص.
وهذا يماثل std::tuple
في C++. من الناحية النظرية:
let v: f32[10] = f32[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
let s: s32 = 5;
let t: (f32[10], s32) = tuple(v, s);
يمكن تفكيك الصفوف (الوصول إليها) من خلال عملية GetTupleElement
.
في حين
يمكنك أيضًا الاطّلاع على
XlaBuilder::While
.
While(condition, body, init)
الوسيطات | النوع | دلالات |
---|---|---|
condition |
XlaComputation |
تمثّل هذه السمة العمليات الحسابية من النوع T -> PRED التي تُحدِّد شرط إنهاء الحلقة. |
body |
XlaComputation |
يشير ذلك المصطلح إلى حساب XlaComput من النوع 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};
}