دلالات العمليات

يوضِّح ما يلي دلالات العمليات المحدّدة في واجهة 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 هي عملية جماعية ترسل البيانات من جميع النوى إلى جميع النوى. وهي تشمل مرحلتين:

  1. مرحلة التبعثر. في كل نواة، ينقسم المعامل إلى split_count عدد من الكتل على طول split_dimensions، وتنتشر الكتل على كل النوى، على سبيل المثال، يتم إرسال الكتلة إلى النواة الأولى.
  2. مرحلة جمع البيانات. وينشئ كل مركز تسلسلاً للكتل التي تم استلامها على طول 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\)

تتم إضافة قيمة إبسيلون، التي عادةً ما تكون عددًا صغيرًا، لتجنب أخطاء القسمة على صفر.

نوع الإخراج عبارة عن صف من ثلاث XlaOps:

المُخرَجات النوع دلالات
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 XlaOps وسيطات 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 XlaOps وسيطات 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 على النحو التالي:

  1. في حال توفّر السمة 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] في الحالات الأخرى).

  2. إذا كانت السمة 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 معيّن على النحو التالي:

  1. السماح G = { Out[k] لـ k في batch_dims }. استخدِم G لتقسيم الخط المتجه S بحيث S[i] = start_indices[دمج(G، i)] حيث يؤدي الدمج(أ، ب) إلى إدراج b في الموضع index_vector_dim في A. ملاحظة: تُحدَّد هذه القيمة بشكل جيد حتى إذا كانت قيمة G فارغة: إذا كانت قيمة G فارغة، تكون قيمة S = start_indices.

  2. أنشئ فهرس بدء، Sin، في operand باستخدام S من خلال توزيع S باستخدام start_index_map. بشكل أكثر دقة:

    1. Sin[start_index_map[k]] = S[k] إذا كانت k أقل من start_index_map.size.

    2. Sin[_] = 0 بخلاف ذلك.

  3. أنشِئ فهرسًا Oin في operand من خلال تشتيت الفهارس عند أبعاد الإزاحة في Out وفقًا للمجموعة collapsed_slice_dims. بشكل أكثر دقة:

    1. Oin[remapped_offset_dims(k)] = Out[offset_dims[k]] في حال كانت k أقل من offset_dims.size (يتم تحديد السمة remapped_offset_dims أدناه).

    2. Oin[_] = 0 بخلاف ذلك.

  4. القيمة In هي Oin + Sin حيث يكون الرمز + إضافة حسب العناصر.

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 هي {01, 13 و24 و35}.

إذا تم ضبط 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 وO0 وO1] وفهرس على شكل الإخراج ويربطه بعنصر في صفيف الإدخال على النحو التالي:

نختار أولاً الخط المتجه (X,Y) من صفيف الفهارس المجمّعة باستخدام G. العنصر في صفيف الإخراج عند الفهرس [G,O0,O1] هو العنصر في مصفوفة الإدخال عند الفهرس [X+O0,Y+O1].

slice_sizes هو [8,6]، وهو يحدد نطاق O0 وO1، وهذا بدوره يحدد حدود الشريحة.

تعمل عملية التجميع هذه كشريحة ديناميكية مجمّعة باستخدام G كبُعد مجمّع.

قد تكون مؤشرات التجميع متعددة الأبعاد. على سبيل المثال، النسخة الأكثر عمومية من المثال أعلاه باستخدام صفيف "فهارس جمع" للشكل [4,5,2] ستترجم الفهارس على النحو التالي:

مرة أخرى، تعمل هذه الطريقة كشريحة ديناميكية مجمّعة G0 وG1 كسمات المجموعة. لا يزال حجم الشريحة [8,6].

تُعمم عملية التجميع في XLA دلالات غير رسمية الموضحة أعلاه بالطرق التالية:

  1. يمكننا تحديد السمات في شكل الناتج التي تمثّل أبعاد الإزاحة (السمات التي تحتوي على O0 وO1 في المثال الأخير). يتم تحديد أبعاد دُفعات النتائج (السمات التي تحتوي على G0 وG1 في المثال الأخير) على أنّها أبعاد المخرجات التي لا تُعاد أبعادها.

  2. قد يكون عدد أبعاد إزاحة الإخراج الموجودة بوضوح في شكل الإخراج أصغر من ترتيب الإدخال. هذه السمات "المفقودة" والمُدرجة بشكل صريح على أنّها collapsed_slice_dims يجب أن تحتوي على حجم شريحة 1. وبما أنّ حجم الشريحة هو 1، فإنّ الفهرس الوحيد الصالح هو 0، وبالتالي لا تؤدي إزالتها إلى أي غموض.

  3. قد تحتوي الشريحة المستخرجة من مصفوفة "جمع المؤشرات" ((X، Y) في المثال الأخير) على عناصر أقل من ترتيب صفيف الإدخال، ويحدد التعيين الصريح كيفية توسيع الفهرس للحصول على نفس ترتيب الإدخال.

كمثال أخير، نستخدم (2) و (3) لتنفيذ tf.gather_nd:

يتم استخدام G0 وG1 لفصل فهرس البدء من مصفوفة فهارس التجميع كالمعتاد، باستثناء أنّ فهرس البداية يتضمّن عنصرًا واحدًا، وهو X. وبالمثل، لا يوجد سوى فهرس إزاحة واحد للمخرجات بالقيمة O0. ومع ذلك، قبل استخدام هذه المؤشرات كمؤشرات في صفيف الإدخال، يتم توسيعها وفقًا لخيار "جمع بيانات الفهرس" (start_index_map في الوصف الرسمي) و "تعيين الإزاحة" (remapped_offset_dims في الوصف الرسمي) إلى [X،0] و[0،O0] على التوالي، مع إضافة ما يصل إلى [X،O0]. أي قيمة00000OOGGGG11GatherIndicestf.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 XlaOps 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:

رسم بياني للنقاط المبعثرة

تنشئ عملية التبعثر 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 المقابلة التي يجب تطبيق هذا التحديث عليها على النحو التالي:

  1. دع G = { U[k] لـ k في update_scatter_dims }. استخدِم G للبحث عن متّجه فهرس S في مصفوفة scatter_indices بحيث يكون S[i] = scatter_indices[دمج(G, i)] حيث يؤدي الدمج(A، ب) إلى إدراج b عند الموضع index_vector_dim في A.
  2. أنشئ فهرس Sin في operand باستخدام S عن طريق توزيع S باستخدام خريطة scatter_dims_to_operand_dims. بشكل أكثر رسمية:
    1. Sin[scatter_dims_to_operand_dims[k]] = S[k] إذا k < scatter_dims_to_operand_dims.size.
    2. Sin[_] = 0 بخلاف ذلك.
  3. أنشِئ فهرسًا Win في كل صفيف operands من خلال توزيع الفهارس عند update_window_dims في U وفقًا لـ inserted_window_dims. بشكل أكثر رسمية:
    1. Win[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 هي {01 أو 13 أو 24 أو 35}).
    2. Win[_] = 0 بخلاف ذلك.
  4. القيمة I هي Win + Sin حيث يكون الرمز + إضافة حسب العناصر.

باختصار، يمكن تعريف عملية التبعثر على النحو التالي.

  • يجب إعداد 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 في كل فهرس محدد في صفيف الإخراج. حيث يتطلب معاملين عدديين:

  1. القيمة الحالية في الفهرس المحدّد في صفيف الإخراج
  2. القيمة المبعثرة من 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};
}