StableHLO Özelliği

StableHLO, makinedeki üst düzey işlemler (HLO) için kullanılan bir işlemdir. öğrenme (ML) modelleridir. StableHLO, farklı öğeler ile videolar arasında taşınabilirlik katmanı görevi görür. Makine öğrenimi çerçeveleri ve makine öğrenimi derleyicileri: StableHLO programları üreten makine öğrenimi çerçeveleri StableHLO programlarını kullanan makine öğrenimi derleyicileriyle uyumludur.

Hedefimiz makine öğrenimi geliştirmeyi basitleştirmek ve hızlandırmak Farklı makine öğrenimi çerçeveleri (ör. TensorFlow, JAX ve PyTorch) ve makine öğrenimi derleyicileri (XLA ve IREE gibi). Bu hedefe doğru belgesinde StableHLO programlama dili için bir spesifikasyon sunulmaktadır.

Bu spesifikasyon üç ana bölüm içermektedir. İlk olarak, Programlar bölümünde StableHLO programlarının yapısı açıklanmaktadır. Bunlar, StableHLO işlemlerinden oluşan StableHLO işlevlerinden oluşur. Bu yapıdaki Ops bölümü ayrı ayrı bağlıdır. Yürütme bölümü, bu işlemlerin bir program içinde birlikte yürütülmesini sağlamaktır. Son olarak, Notasyon bölümünde, bakın.

StableHLO'nun önceki bir sürümünün teknik özelliklerini görüntülemek için şurada depoyu açın: etiketli yayın ekleyin. Örneğin, StableHLO v0.19.0 Spec. StableHLO'nun her alt sürüm yükseltmesinde gerçekleşen değişiklikleri görüntülemek için şuraya bakın: VhloDialect.td adresindeki sürüm günlüğü.

Programlar

Program ::= {Func}

StableHLO programları isteğe bağlı sayıda StableHLO işlevinden oluşur. Aşağıda, 3 girişe sahip @main fonksiyonuna sahip örnek bir program verilmiştir. (%image, %weights ve %bias) ve 1 çıkış. İşlevin gövdesi 6 operasyonu var.

func.func @main(
  %image: tensor<28x28xf32>,
  %weights: tensor<784x10xf32>,
  %bias: tensor<1x10xf32>
) -> tensor<1x10xf32> {
  %0 = "stablehlo.reshape"(%image) : (tensor<28x28xf32>) -> tensor<1x784xf32>
  %1 = "stablehlo.dot"(%0, %weights) : (tensor<1x784xf32>, tensor<784x10xf32>) -> tensor<1x10xf32>
  %2 = "stablehlo.add"(%1, %bias) : (tensor<1x10xf32>, tensor<1x10xf32>) -> tensor<1x10xf32>
  %3 = "stablehlo.constant"() {value = dense<0.0> : tensor<1x10xf32>} : () -> tensor<1x10xf32>
  %4 = "stablehlo.maximum"(%2, %3) : (tensor<1x10xf32>, tensor<1x10xf32>) -> tensor<1x10xf32>
  "func.return"(%4): (tensor<1x10xf32>) -> ()
}

İşlevler

Func        ::= 'func' '.' 'func' FuncId FuncInputs FuncOutputs '{' FuncBody '}'
FuncInputs  ::= '(' [FuncInput {',' FuncInput}] `)`
FuncInput   ::= ValueId ':' ValueType
FuncOutputs ::= ['->' FuncOutput, {',' FuncOutput}]
FuncOutput  ::= ValueType
FuncBody    ::= {Op}

StableHLO işlevleri (adlandırılmış işlevler olarak da adlandırılır) bir tanımlayıcı, girişler/çıkışlar ve bir gövde. Gelecekte, Daha iyi uyumluluk sağlamak amacıyla işlevler için ek meta veriler sunmak HLO ile (#425, 626, #740, #744) girin.

Tanımlayıcılar

FuncId  ::= '@' letter {letter | digit}
ValueId ::= '%' digit {digit}
          | '%' letter {letter | digit}
letter  ::= 'a' | ... | 'z' | 'A' | ... | 'Z' | '_'
digit   ::= '0' | ... | '9'

StableHLO tanımlayıcıları çoğu programlamada tanımlayıcılara benzer iki özelliği vardır: 1) tüm tanımlayıcıların birlikte Farklı tanımlayıcı türlerini ayırt etme, 2) değer tanımlayıcıları StableHLO programlarının oluşturulmasını basitleştirmek için tamamen sayısal değerler.

Türler

Type         ::= ValueType | NonValueType
ValueType    ::= TensorType | QuantizedTensorType | TokenType | TupleType
NonValueType ::= TensorElementType | QuantizedTensorElementType | FunctionType | StringType

StableHLO türleri, değer türleri (diğer adıyla birinci sınıf türleri) içeren, StableHLO değerlerini ve değer olmayan türleri temsil eder. bir şablon görevi görür. StableHLO türleri, ana özelliği StableHLO'nun alana özgü bir yapıya sahip olup bu durum bazı olağan dışı sonuçlara (ör. skaler türler) yol açar değildir).

TensorType ::= 'tensor' '<' Shape TensorElementType '>'
Shape ::= {DimensionSize 'x'}
DimensionSize ::= digit {digit} | '?'

Tensör türleri, tensörleri, yani çok boyutlu dizileri temsil eder. Bir şekil ve öğe türü (burada şekil, negatif olmayan veya bilinmeyen boyut boyutları, 0 ile R-1 arasında numaralandırılan boyutlar (bunlar eksen olarak da adlandırılır). İlgili içeriği oluşturmak için kullanılan R boyut sayısına sıralama denir. Örneğin, tensor<2x3xf32> 2x3 şekline ve f32 öğe türüne sahip bir tensör türü. İki boyutu vardır. (veya başka bir deyişle, iki eksen) - 0. boyut ve 1. boyut; diğer bir deyişle 2 ve 3'tür. Sıralaması 2.

Şekiller kısmen veya tamamen bilinmez (dinamik) olabilir, ör. tensor<?x2xf64>. kısmen bilinmiyor ve tensor<?x?xf64> tamamen bilinmiyor. Dinamik boyut boyutları ? kullanılarak gösterilir. Şekillerin sıralaması geri alınamaz.

Gelecekte, Google Analytics 4'teki tensör türlerini boyutları ve öğe türlerini (örneğin, yerleşimleri dahil etmek için) (#629) ve yetersizlik (#1078).

QuantizedTensorType ::= 'tensor' '<' Shape QuantizedTensorElementType '>'
QuantizedTensorElementType ::= '!quant.uniform' '<'
                  QuantizationStorageType
                  ['<' QuantizationStorageMin ':' QuantizationStorageMax '>']
                  ':' QuantizationExpressedType
                  [':' QuantizationDimension]
                  ',' QuantizationParameters '>'
QuantizationStorageType ::= IntegerType
QuantizationStorageMin ::= IntegerConstant
QuantizationStorageMax ::= IntegerConstant
QuantizationExpressedType ::= FloatType
QuantizationDimension ::= IntegerConstant
QuantizationParameters ::= QuantizationParameter
                         | '{' QuantizationParameter {',' QuantizationParameter} '}'
QuantizationParameter ::= QuantizationScale ':' QuantizationZeroPoint
QuantizationScale ::= FloatConstant
QuantizationZeroPoint ::= IntegerConstant
Ad Tür Sınırlamalar
storage_type tam sayı türü (C1-C3), (C8)
storage_min tam sayı sabiti (C1), (C3), (C7)
storage_max tam sayı sabiti (C2), (C3), (C7)
expressed_type kayan nokta türü (C4)
quantization_dimension isteğe bağlı tam sayı sabiti (C10-C12)
scales değişken kayan nokta sabitlerinin sayısı (C4-C6), (C9), (C10), (C13)
zero_points tam sayı sabitlerinin değişken sayısı (C7-C9)

Nitelikli öğe türleri, depolama türünün tam sayı değerlerini şuna karşılık gelen storage_min - storage_max (dahil) aralığı ifade edilmiş bir türün kayan nokta değerleri. Belirli bir tam sayı değeri i için karşılık gelen kayan nokta değeri f şu şekilde hesaplanabilir: f = (i - zero_point) * scale, burada scale ve zero_point olarak adlandırılır nicelleştirme parametreleri. storage_min ve storage_max isteğe bağlıdır dilbilgisinde mevcut ancak varsayılan değerleri min_value(storage_type) ve Sırasıyla max_value(storage_type). Nicelleştirilmiş öğe türleri aşağıdaki sınırlamalara tabidir:

  • (C1) type(storage_min) = storage_type.
  • (C2) type(storage_max) = storage_type.
  • (C3) min_value(storage_type) <= storage_min < storage_max <= max_value(storage_type).
  • (C4) type(scales...) = expressed_type
  • (C5) 0 < scales
  • (C6) is_finite(scales...).
  • (C7) storage_min <= zero_points <= storage_max.
  • (C8) type(zero_points...) = storage_type
  • (C9) size(scales) = size(zero_points).
  • (C10) is_empty(quantization_dimension) ise size(scales) = 1.
  • (C11) 0 <= quantization_dimension

Şu anda QuantizationScale bir kayan nokta sabitidir, ancak çarpanları ve değerleri ile temsil edilen tamsayı tabanlı ölçeklere güçlü ilgi olur. Bu konuyu yakın gelecekte araştırmayı planlıyoruz (#1404).

QuantizationZeroPoint kelimesinin anlamı konusunda devam eden bir tartışma var. ve yalnızca bir veya daha fazla nicelleştirilmiş bir tensör türünde potansiyel olarak birden çok sıfır noktasıdır. Referans olarak Bu tartışmanın sonuçlarına göre, sıfır puan civarındaki spesifikasyonlar değişebilir. ileride bahsedeceğim (#1405).

Devam eden bir diğer tartışma da QuantizationStorageMin anlamıyla ilgili. ve kısıtlanması gerekip gerekmediğini belirlemek için QuantizationStorageMax bu değerlere ve nicelenmiş tensörlerin değerlerine (#1406).

Son olarak, bilinmeyen ölçekleri ve sıfır ölçeğini temsil ederek hesaplamayı planlıyoruz. araştırmalarımızda olduğu gibi, bilinmeyen noktaları temsil etmeyi planladığımız gibi boyut boyutlarını (#1407) tıklayın.

Nicelleştirilmiş tensör türleri, miktarlandırılmış öğelere sahip tensörleri temsil eder. Bu tensörler, elemanları dışında normal tensörlerle tamamen aynıdır. yerine miktarlandırılmış öğe türlerine sahip olmalıdır.

Miktarlandırılmış tensörlerde miktar tansör başına olabilir. Diğer bir deyişle, tensörün tamamı için bir scale ve zero_point olabilir veya eksen başına olabilir. yani, birden fazla scales ve zero_points (her bir öğe dilimi başına bir çift) belirli bir quantization_dimension boyutunu seçin. Daha resmi olarak, bir tensörde t eksen başına nicelemeyle, dim(t, quantization_dimension) dilim quantization_dimension tarihindekiler: t[:, ..., 0, ..., :], t[:, ..., 1, ..., :], vb. i. dilimdeki tüm öğeler, scales[i] ve zero_points[i] öğelerini ve niceleme parametrelerinden biridir. Nicel tensör türleri aşağıdaki gibidir sınırlamalar:

  • Tensör başına miktar belirleme için:
    • Ek kısıtlama yok.
  • Eksen başına nicelik için:
    • (C12) quantization_dimension < rank(self)
    • (C13) dim(self, quantization_dimension) = size(scales)
TokenType ::= 'token'

Jeton türleri jetonları, yani üretilen ve tüketilen opak değerleri temsil eder. neden olur. Jetonlar, işlemlere yürütme sırası uygulamak için kullanılır Yürütme bölümünde gösterildiği gibi.

TupleType ::= 'tuple' '<' TupleElementTypes '>'
TupleElementTypes ::= [ValueType {',' ValueType}]

Tuple türleri, grupları (heterojen listeler) temsil eder. Tuples bir miradır Bu özellik yalnızca HLO ile uyumluluk için kullanılabilir. HLO'da, delikler giriş ve çıkışları temsil etmek için kullanılır. StableHLO'da değişken girdiler ve çıkışlar yerel olarak desteklenir ve StableHLO'da tuple'ların tek kullanımı HLO ABI'ı (ör. T, tuple<T> ve tuple<tuple<T>>, belirli bir kullanım alanına bağlı olarak önemli ölçüde farklılık gösterebilir. hakkında bilgi edindiniz. Gelecekte HLO ABI'de değişiklikler yapmayı planlıyoruz. Bu işlem, StableHLO'dan öğe türlerini kaldırmamıza olanak tanır. (#598).

TensorElementType ::= BooleanType | IntegerType | FloatType | ComplexType
BooleanType ::= 'i1'
IntegerType ::= SignedIntegerType | UnsignedIntegerType
SignedIntegerType ::= 'si2' | 'si4' | 'si8' | 'si16' | 'si32' | 'si64'
UnsignedIntegerType ::= 'ui2' | 'ui4' | 'ui8' | 'ui16' | 'ui32' | 'ui64'
FloatType ::= 'f8E4M3FN' | 'f8E5M2' | 'f8E4M3FNUZ' | 'f8E5M2FNUZ'
            | 'f8E4M3B11FNUZ' | 'bf16' | 'f16' | 'f32' | 'f64'
TensorFloat32 ::= 'tf32'
ComplexType ::= 'complex' '<' ComplexElementType '>'
ComplexElementType ::= 'f32' | 'f64'

Öğe türleri, tensör türlerinin öğelerini temsil eder. Birçok programın aksine bu türler StableHLO'da birinci sınıf değildir. Bunun anlamı, StableHLO programları bu tür değerleri doğrudan temsil edemez (sonuç olarak 0 boyutlu tensörle T türünde skaler değerleri göstermek deyimseldir (tensor<T> türündeki değerler) seçin.

  • Boole türü, true ve false Boole değerlerini temsil eder.
  • Tam sayı türleri, imzalı (si) veya imzasız (ui) olabilir ve desteklenen bit genişliklerinden biri (2, 4, 8, 16, 32 veya 64). İmzalı siN türleri, -2^(N-1) ile 2^(N-1)-1 arasındaki tam sayı değerlerini temsil eder dahil ve imzasız uiN türleri, 0 - 0 arasındaki tam sayı değerlerini temsil eder 2^N-1 dahil.
  • Kayan nokta türleri aşağıdakilerden biri olabilir:
  • Karmaşık türler, gerçek bir bölümü olan karmaşık değerleri temsil eder ve aynı öğe türünün sanal bir kısmını içerir. Desteklenen kompleks türler, complex<f32> (her iki bölüm de f32 türündedir) ve complex<f64> şeklindedir (her iki bölüm de f64 türündedir).
FunctionType ::= '(' InputTypes ')' '->' '(' OutputTypes ')'
InputTypes ::= [ValueType {',' ValueType}]
OutputTypes ::= [ValueType {',' ValueType}]

İşlev türleri, hem adlandırılmış hem de anonim işlevleri temsil eder. Bunlar giriş türleri (-> öğesinin sol tarafındaki türler listesi) ve çıkış türleri (-> öğesinin sağındaki türler listesi). Birçok programlamada dil, işlev türleri birinci sınıftır ancak StableHLO'da yoktur.

StringType ::= 'string'

Dize türü, bayt dizilerini temsil eder. Birçok programın aksine dize türü StableHLO'da birinci sınıf değildir ve yalnızca program öğeleri için statik meta verileri belirtir.

İşlemler

StableHLO işlemleri (operasyon olarak da adlandırılır) kapalı bir kümeyi temsil eder üst düzey operasyonlar. Yukarıda açıklandığı gibi, StableHLO söz dizimi, büyük ölçüde MLIR’den esinlenilerek geliştirilmiştir. Ancak bu, ergonomik bir alternatif ancak muhtemelen StableHLO'nun makine öğrenimi çerçeveleri ile makine öğrenimi derleyicileri arasında daha fazla birlikte çalışabilirlik sağlar.

Op            ::= [OpOutputs] OpName OpInputs ':' OpSignature
OpName        ::= '"' 'stablehlo' '.' OpMnemonic '"'
OpMnemonic    ::= 'abs' | 'add' | ...

StableHLO işlemlerinin (işlem olarak da adlandırılır) bir adı vardır. giriş/çıkış ve bir imzadır. Ad, stablehlo. ön ekinden ve Desteklenen işlemlerden birini benzersiz şekilde tanımlayan bir hatırlatıcı. Aşağıdaki bilgilere göz atın desteklenen tüm operasyonların kapsamlı bir listesini içerir.

OpInputs        ::= OpInputValues OpInputFuncs OpInputAttrs
OpInputValues   ::= '(' [OpInputValue {',' OpInputValue}] ')'
OpInputValue    ::= ValueId
OpInputFuncs    ::= ['(' OpInputFunc {',' OpInputFunc} ')']
OpInputAttrs    ::= ['{' OpInputAttr {',' OpInputAttr} '}']
OpOutputs       ::= [OpOutput {',' OpOutput} '=']
OpOutput        ::= ValueId

İşlemler girişleri tüketir ve çıkışlar üretir. Girişler şu kategorilere ayrılır: giriş değerleri (yürütme sırasında hesaplanır), giriş işlevleri (sağlanan statiktir, çünkü StableHLO'da işlevler birinci sınıf değerler değildir) ve giriş özellikleri (statik olarak da sağlanır). Giriş ve çıkış türü işlem gücüne bağlıdır. Örneğin, add op, 2 giriş değeri tüketir ve 1 çıkış değeri üretir. Buna kıyasla, select_and_scatter işlemi 3 giriş değeri, 2 giriş işlevi tüketir ve 3 giriş özelliği.

OpInputFunc ::= '{' Unused FuncInputs ':' FuncBody '}'
Unused      ::= '^' digit {digit}
              | '^' letter {letter | digit}

Giriş işlevleri (anonim işlevler olarak da adlandırılır) Adlandırılmış işlevlere benzerdir. Tek fark: 1) bir tanımlayıcıları yoktur (dolayısıyla "anonim" olması gerekir, 2) çıkış türlerini bildirmezler (çıktı türleri işlevin içindeki return işleminden türetilir).

Giriş işlevlerinin söz dizimi, kullanılmayan bir bölümü içeriyor (bkz. Unused üretimi) gerekir. MLIR'de, "bölgeler" daha genel bir kavramdır birden fazla "engelleme" olabilen atlama operasyonlarıyla birbirine bağlanmış operasyonlar. Bu blokların, ilgili bloklara karşılık gelen birbirlerinden ayırt edilebilmeleri için Unused üretime atanır. StableHLO'da atlama işlemleri yoktur. Bu nedenle, MLIR söz diziminin karşılık gelen kısmı (ancak hâlâ oradadır).

OpInputAttr      ::= OpInputAttrName '=' OpInputAttrValue
OpInputAttrName  ::= letter {letter | digit}
OpInputAttrValue ::= Constant

Giriş özelliklerinin bir adı ve desteklenen bir değeri vardır sabitler. Bunlar, program için statik meta verileri belirtmenin birincil yoludur öğeler. Örneğin, concatenate operasyonu şunun için dimension özelliğini kullanır: giriş değerlerinin birleştirileceği boyutu belirtin. Aynı şekilde, slice işlemi, start_indices ve limit_indices gibi birden çok özellik kullanıyor. ifadesini girin.

Şu anda, doğadaki StableHLO programları bazen Bunlar bu dokümanda açıklanmamıştır. Gelecekte, ya bu özellikleri StableHLO işletim sistemine alır veya bunları StableHLO programlarında görünüyor. Bu arada sırada bu müzakerelerin özellikler:

  • layout (#629).
  • mhlo.frontend_attributes. (#628).
  • mhlo.sharding (#619).
  • output_operand_aliases. (#740).
  • Konum meta verileri (#594).
OpSignature ::= '(' [ValueType {',' ValueType}] ')' '->' '(' [ValueType {',' ValueType}] ')'

İşlem imzası, tüm giriş değeri türlerinden ( -> işaretinin sol tarafındaki) ve tüm çıkış değerlerinin türlerini (liste, türleri -> öğesinin sağ tarafında gösterilir). Özetle, giriş türleri ve çıkış türleri de neredeyse her zaman gereksizdir (çünkü en fazla StableHLO işlemi için, çıkış türleri girişlerden çıkarılabilir. Yine de operasyon imza, kasıtlı olarak MLIR ile uyumluluk için StableHLO söz diziminin bir parçasıdır.

Aşağıda, anımsatıcı select_and_scatter olan bir örnek işlem verilmiştir. 3 veri tüketir giriş değerleri (%operand, %source ve %init_value), 2 giriş işlevi ve 3 giriş özelliği (window_dimensions, window_strides ve padding). Operatörün imzasının yalnızca giriş değeri türlerini içerdiğini unutmayın (satır içi sağlanan giriş işlevlerinin ve özniteliklerinin türleri değil).

%result = "stablehlo.select_and_scatter"(%operand, %source, %init_value) ({
  ^bb0(%arg0: tensor<i32>, %arg1: tensor<i32>):
    %0 = "stablehlo.compare"(%arg0, %arg1) {
      comparison_direction = #stablehlo<comparison_direction GE>
    } : (tensor<i32>, tensor<i32>) -> tensor<i1>
    "stablehlo.return"(%0) : (tensor<i1>) -> ()
}, {
  ^bb0(%arg0: tensor<i32>, %arg1: tensor<i32>):
    %0 = "stablehlo.add"(%arg0, %arg1) : (tensor<i32>, tensor<i32>) -> tensor<i32>
    "stablehlo.return"(%0) : (tensor<i32>) -> ()
}) {
  window_dimensions = dense<[3, 1]> : tensor<2xi64>,
  window_strides = dense<[2, 1]> : tensor<2xi64>,
  padding = dense<[[0, 1], [0, 0]]> : tensor<2x2xi64>
} : (tensor<4x2xi32>, tensor<2x2xi32>, tensor<i32>) -> tensor<4x2xi32>

Sabitler

Constant ::= BooleanConstant
           | IntegerConstant
           | FloatConstant
           | ComplexConstant
           | TensorConstant
           | QuantizedTensorConstant
           | StringConstant
           | EnumConstant

StableHLO sabitleri bir değişmez değere ve birlikte şu değeri temsil eden bir türe sahiptir: StableHLO değerine sahip. Genellikle, tür sabit söz diziminin bir parçasıdır, belirsiz olduğunda (ör. bir boole sabiti açık bir şekilde i1 türündeyse, Buna karşın, tam sayı sabitinin birden fazla olası türü olabilir).

BooleanConstant ::= BooleanLiteral
BooleanLiteral  ::= 'true' | 'false'

Boole sabitleri, true ve false boole değerlerini temsil eder. Boole sabitler i1 türündedir.

IntegerConstant   ::= IntegerLiteral ':' IntegerType
IntegerLiteral    ::= ['-' | '+'] DecimalDigits
                    | ['-' | '+'] '0x' HexadecimalDigits
DecimalDigits     ::= decimalDigit {decimalDigit}
HexadecimalDigits ::= hexadecimalDigit {hexadecimalDigit}
decimalDigit      ::= '0' | ... | '9'
hexadecimalDigit  ::= decimalDigit | 'a' | ... | 'f' | 'A' | ... | 'F'

Tam sayı sabitleri, ondalık veya onaltılık gösterim. Diğer tabanlar, ör. ikili veya sekizlik desteklenmez. Tam sayı sabitlerinin kısıtlamaları aşağıdaki gibidir:

  • (C1) is_wellformed(integer_literal, integer_type).
FloatConstant  ::= FloatLiteral ':' FloatType
FloatLiteral   ::= SignPart IntegerPart FractionalPart ScientificPart
                 | '0x' [HexadecimalDigits]
SignPart       ::= ['-' | '+']
IntegerPart    ::= DecimalDigits
FractionalPart ::= ['.' [DecimalDigits]]
ScientificPart ::= [('e' | 'E') ['-' | '+'] DecimalDigits]

Kayan nokta sabitleri, kayan nokta değerlerini Ondalık veya bilimsel gösterim kullanabilirsiniz. Buna ek olarak, onaltılı gösterim temel bitleri kayan nokta biçiminde doğrudan belirtmek için kullanılır seçin. Kayan nokta sabitleri aşağıdaki kısıtlamalara sahiptir:

  • (C1) Onaltılı olmayan gösterim kullanılırsa is_wellformed(float_literal, float_type)
  • (C2) Onaltılı gösterim kullanılırsa size(hexadecimal_digits) = num_bits(float_type) / 4
ComplexConstant ::= ComplexLiteral ':' ComplexType
ComplexLiteral  ::= '(' RealPart ',' ImaginaryPart ')'
RealPart        ::= FloatLiteral
ImaginaryPart   ::= FloatLiteral

Karmaşık sabitler, gerçek bölümün listelerini kullanarak karmaşık değerleri temsil eder (önce gelir) ve hayali bir bölüm (ikinci sırada gelir) yer alır. Örneğin, (1.0, 0.0) : complex<f32>, 1.0 + 0.0i değerini ve (0.0, 1.0) : complex<f32>, 0.0 + 1.0i değerini temsil eder. Bu öğelerin daha sonra uygulama tarafından tanımlanmış şekilde saklanır. Karmaşık sabitler aşağıdaki sınırlamalara sahiptir:

  • (C1) is_wellformed(real_part, complex_element_type(complex_type)).
  • (C2) is_wellformed(imaginary_part, complex_element_type(complex_type)).
TensorConstant ::= TensorLiteral ':' TensorType
TensorLiteral  ::= 'dense' '<' (DenseLiteral | ElementLiteral) '>'
DenseLiteral   ::= DenseDimension | DenseElements
DenseDimension ::= '[' [DenseLiteral {',' DenseLiteral}] ']'
DenseElements  ::= [ElementLiteral {',' ElementLiteral}]
ElementLiteral ::= BooleanLiteral | IntegerLiteral | FloatLiteral | ComplexLiteral

Tensor sabitleri, NumPy gösterimi. Örneğin, dense<[[1, 2, 3], [4, 5, 6]]> : tensor<2x3xi32> dizinlerden öğelere aşağıdaki eşlemeyle birlikte bir tensör değerini temsil eder: {0, 0} => 1, {0, 1} => 2, {0, 2} => 3, {1, 0} => 4, {1, 1} => 5, {1, 2} => 6. Bu öğelerin bellekte depolanma sırası tanımlanmıştır. Tensor sabitleri için aşağıdaki kısıtlamalar bulunur:

  • (C1) has_syntax(tensor_literal, element_type(tensor_type)), burada:
    • has_syntax(element_literal: Syntax, element_type: Type) = is_wellformed(element_literal, type).
    • has_syntax(tensor_literal: List, element_type: Type) = has_syntax(tensor_literal..., element_type).
  • (C2) has_shape(tensor_literal, shape(tensor_type)), burada:
    • has_shape(element_literal: Syntax, []) = true.
    • has_shape(tensor_literal: List, shape: List) = size(tensor_literal) = shape[0] and has_shape(tensor_literal..., shape[1:]).
    • aksi takdirde false.
QuantizedTensorConstant ::= QuantizedTensorLiteral ':' QuantizedTensorType
QuantizedTensorLiteral  ::= 'dense' '<' (DenseLiteral | ElementLiteral) '>'

Nicelleştirilmiş tensör sabitleri, aynı tensör sabitleri olarak gösterim; elemanlar kendi sabit değerleri olarak belirtilir depolama alanı türü. Nicel tensör sabitleri aşağıdaki kısıtlamalara sahiptir:

  • (C1) has_syntax(quantized_tensor_literal, storage_type(quantized_tensor_type)).
  • (C2) has_shape(quantized_tensor_literal, shape(quantized_tensor_type)).
StringConstant  ::= StringLiteral
StringLiteral   ::= '"' {stringCharacter | escapeSequence} '"'
stringCharacter ::= all ASCII characters except '\00', '\01', ... '\1f' and '"'
escapeSequence  ::= '\' ('"' | '\' | 'n' | 't' | (hexadecimalDigit hexadecimalDigit))

Dize sabit değerleri, ASCII karakterleri kullanılarak belirtilen baytlardan oluşur. kaçış dizileridir. Kodlamadan bağımsız oldukları için bu kodların yorumlanması bayt, uygulama tanımlıdır. Dize değişmez değerleri string türündedir.

İşlemler

abs

Anlam

operand tensörü üzerinde öğe düzeyinde abs işlemi gerçekleştirir ve result üretir tensördür. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • İşaretli tam sayılar için: tam sayı modülü.
  • Kayan reklamlar için: IEEE-754'ten abs.
  • Karmaşık sayılar için: karmaşık modül.
  • Miktarlanmış türler için: dequantize_op_quantize(abs, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand işaretli tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensörün tensörü (C1-C2)

Çıkışlar

Ad Tür Sınırlamalar
result işaretli tam sayı veya kayan nokta türü ya da tensör başına miktarlandırılmış tensörün tensörü (C1-C2)

Sınırlamalar

  • (C1) shape(result) = shape(operand).
  • (C2) baseline_element_type(result) şu şekilde tanımlanır:
    • is_complex(operand) ise complex_element_type(element_type(operand)).
    • Aksi takdirde baseline_element_type(operand).

Örnekler

// %operand: [-2, 0, 2]
%result = "stablehlo.abs"(%operand) : (tensor<3xi32>) -> tensor<3xi32>
// %result: [2, 0, 2]

Diğer Örnekler

add

Anlam

İki tensoru (lhs ve rhs) eleman olarak ekler ve bir üretir result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Boolelar için: mantıksal VEYA.
  • Tam sayılar için: tamsayı toplama.
  • Kayan reklamlar için: IEEE-754'ten addition.
  • Karmaşık sayılar için: karmaşık toplama.
  • Miktarlanmış türler için: dequantize_op_quantize(add, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya nicel tensör (C1-C6)
(I2) rhs tensör veya nicel tensör (C1-C5), (C7)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C1-C7)

Sınırlamalar

  • İşlemde miktarlandırılmamış tensörler kullanılıyorsa:
    • (C1) type(lhs) = type(rhs) = type(result).
  • İşlemde nicel tensörler kullanılıyorsa:
    • (C2) is_quantized(lhs) and is_quantized(rhs) and is_quantized(result).
    • (C3) storage_type(lhs) = storage_type(rhs) = storage_type(result).
    • (C4) expressed_type(lhs) = expressed_type(rhs) = expressed_type(result)
    • (C5) (is_per_axis_quantized(lhs) or is_per_axis_quantized(rhs)) = is_per_axis_quantized(result)
    • (C6) is_per_axis_quantized(lhs) ise quantization_dimension(lhs) = quantization_dimension(result).
    • (C7) is_per_axis_quantized(rhs) ise quantization_dimension(rhs) = quantization_dimension(result).

Örnekler

// %lhs: [[1, 2], [3, 4]]
// %rhs: [[5, 6], [7, 8]]
%result = "stablehlo.add"(%lhs, %rhs) : (tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[6, 8], [10, 12]]

Diğer Örnekler

after_all

Anlam

inputs öğesini üreten işlemlerin herhangi bir tarihten önce yürütülmesini sağlar ve result türüne bağlı olan işlemler. Bu işlemi gerçekleştirmek hiçbir şey yapmaz, yalnızca result ile inputs arasındaki veri bağımlılıklarını oluşturmak için kullanılabilir.

Girişler

Şirket Ad Tür
(I1) inputs token değişken sayısı

Çıkışlar

Ad Tür
result token

Örnekler

// %input0: !stablehlo.token
// %input1: !stablehlo.token
%result = "stablehlo.after_all"(%input0, %input1) : (!stablehlo.token, !stablehlo.token) -> !stablehlo.token

Diğer Örnekler

all_gather

Anlam

StableHLO süreç ızgarasındaki her işlem grubu içinde, değerleri birleştirir. all_gather_dim boyunca her süreçten operands tensöründen results tensörü.

İşlem, StableHLO süreç ızgarasını process_groups olarak ayırır. şu şekilde tanımlanır:

  • cross_replica(replica_groups). (channel_id <= 0 and use_global_device_ids = false ise)
  • cross_replica_and_partition(replica_groups). (channel_id > 0 and use_global_device_ids = false ise)
  • flattened_ids(replica_groups). (channel_id > 0 and use_global_device_ids = true ise)

Daha sonra, her process_group içinde:

  • Tümü için operands...@receiver = [operand@sender for sender in process_group] process_group içinde receiver.
  • Tümü için results...@process = concatenate(operands...@process, all_gather_dim) process_group içinde process.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operands değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1), (C6)
(I2) all_gather_dim si64 türündeki sabit (C1), (C6)
(I3) replica_groups si64 türünde 2 boyutlu tensör sabiti (C2-C4)
(I4) channel_id si64 türündeki sabit (C5)
(I5) use_global_device_ids i1 türündeki sabit (C5)

Çıkışlar

Ad Tür Sınırlamalar
results değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C6)

Sınırlamalar

  • (C1) 0 <= all_gather_dim < rank(operands...).
  • (C2) is_unique(replica_groups).
  • (C3) size(replica_groups) şu şekilde tanımlanır:
    • cross_replica kullanılıyorsa num_replicas.
    • cross_replica_and_partition kullanılıyorsa num_replicas.
    • flattened_ids kullanılıyorsa num_processes.
  • (C4) 0 <= replica_groups < size(replica_groups)
  • (C5) use_global_device_ids = true ise channel_id > 0.
  • (C6) type(results...) = type(operands...) hariç:
    • dim(results..., all_gather_dim) = dim(operands..., all_gather_dim) * dim(process_groups, 1).

Örnekler

// num_replicas: 2
// num_partitions: 1
// %operand0@(0, 0): [[1, 2], [3, 4]]
// %operand0@(1, 0): [[5, 6], [7, 8]]
// %operand1@(0, 0): [[11, 12], [13, 14]]
// %operand1@(1, 0): [[15, 16], [17, 18]]
%result:2 = "stablehlo.all_gather"(%operand0, %operand1) {
  all_gather_dim = 1 : i64,
  replica_groups = dense<[[0, 1]]> : tensor<1x2xi64>,
  // channel_id = 0
  channel_handle = #stablehlo.channel_handle<handle = 0, type = 0>
  // use_global_device_ids = false
} : (tensor<2x2xi64>, tensor<2x2xi64>) -> (tensor<2x4xi64>, tensor<2x4xi64>)
// %result0@(0, 0): [[1, 2, 5, 6], [3, 4, 7, 8]]
// %result0@(1, 0): [[1, 2, 5, 6], [3, 4, 7, 8]]
// %result1@(0, 0): [[11, 12, 15, 16], [13, 14, 17, 18]]
// %result1@(1, 0): [[11, 12, 15, 16], [13, 14, 17, 18]]

Diğer Örnekler

all_reduce

Anlam

StableHLO süreç ızgarasındaki her süreç grubuna bir azaltma uygular her işlemdeki operands tensörlerinin değerlerine computation işlevi ve results tensör üretir.

İşlem, StableHLO süreç ızgarasını process_groups olarak ayırır. şu şekilde tanımlanır:

  • cross_replica(replica_groups). (channel_id <= 0 and use_global_device_ids = false ise)
  • cross_replica_and_partition(replica_groups). (channel_id > 0 and use_global_device_ids = false ise)
  • flattened_ids(replica_groups). (channel_id > 0 and use_global_device_ids = true ise)

Daha sonra, her process_group içinde:

  • Bazı ikili ağaçlar için results...@process[result_index] = exec(schedule) schedule burada:
    • exec(node) = computation(exec(node.left), exec(node.right)).
    • exec(leaf) = leaf.value.
  • schedule, sırasıyla geçiş to_destination_type(operands...@process_group...[result_index], type(func_inputs(computation)[0])).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operands değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C5) (C6)
(I2) replica_groups si64 türündeki 1 boyutlu tensör sabitlerinin değişken sayısı (C1-C3)
(I3) channel_id si64 türündeki sabit (C4)
(I4) use_global_device_ids i1 türündeki sabit (C4)
(I5) computation işlev (C5)

Çıkışlar

Ad Tür Sınırlamalar
results değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C6-C7)

Sınırlamalar

  • (C1) is_unique(replica_groups).
  • (C2) size(replica_groups) şu şekilde tanımlanır:
    • cross_replica kullanılıyorsa num_replicas.
    • cross_replica_and_partition kullanılıyorsa num_replicas.
    • flattened_ids kullanılıyorsa num_processes.
  • (C3) 0 <= replica_groups < size(replica_groups).
  • (C4) use_global_device_ids = true ise channel_id > 0.
  • (C5) computation, (tensor<E>, tensor<E>) -> (tensor<E>) türünde olup burada is_promotable(element_type(operand), E).
  • (C6) shape(results...) = shape(operands...).
  • (C7) element_type(results...) = E.

Örnekler

// num_replicas: 2
// num_partitions: 1
// %operand0@(0, 0): [1, 2, 3, 4]
// %operand0@(1, 0): [5, 6, 7, 8]
// %operand1@(0, 0): [9, 10, 11, 12]
// %operand1@(1, 0): [13, 14, 15, 16]
%result:2 = "stablehlo.all_reduce"(%operand0, %operand0) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %0 = "stablehlo.add"(%arg0, %arg1) : (tensor<i64>, tensor<i64>) -> tensor<i64>
    "stablehlo.return"(%0) : (tensor<i64>) -> ()
}) {
  replica_groups = dense<[[0, 1]]> : tensor<1x2xi64>,
  // channel_id = 0
  channel_handle = #stablehlo.channel_handle<handle = 0, type = 0>
  // use_global_device_ids = false
} : (tensor<4xi64>, tensor<4xi64>) -> (tensor<4xi64>, tensor<4xi64>)
// %result0@(0, 0): [6, 8, 10, 12]
// %result0@(1, 0): [6, 8, 10, 12]
// %result1@(0, 0): [22, 24, 26, 28]
// %result1@(1, 0): [22, 24, 26, 28]

Diğer Örnekler

all_to_all

Anlam

all_to_all

StableHLO süreç ızgarasındaki her süreç grubu içinde, split_dimension boyunca uzanan operands tensörleri parçalara ayırarak bölünmeyi dağıtır parçaları, sürekli olarak dağılmış parçaları birleştirerek concat_dimension ve results tensör üretir. İşlem, StableHLO süreç ızgarasını process_groups olarak ayırır. şu şekilde tanımlanır:

  • channel_id <= 0 ise cross_replica(replica_groups).
  • channel_id > 0 ise cross_partition(replica_groups).

Daha sonra, her process_group içinde:

  • split_parts...@sender = split(operands...@sender, split_count, split_dimension). process_group içindeki tüm sender için.
  • scattered_parts...@receiver = [split_parts...@sender[receiver_index] for sender in process_group] burada: receiver_index = process_group.index(receiver).
  • results...@process = concatenate(scattered_parts...@process, concat_dimension).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operands değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1-C3), (C9)
(I2) split_dimension si64 türündeki sabit (C1), (C2), (C9)
(I3) concat_dimension si64 türündeki sabit (C3) (C9)
(I4) split_count si64 türündeki sabit (C2), (C4), (C8), (C9)
(I5) replica_groups si64 türünde 2 boyutlu tensör sabiti (C5-C8)
(I6) channel_id si64 türündeki sabit

Çıkışlar

Ad Tür Sınırlamalar
results değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C9)

Sınırlamalar

  • (C1) 0 <= split_dimension < rank(operands...).
  • (C2) dim(operands..., split_dimension) % split_count = 0.
  • (C3) 0 <= concat_dimension < rank(operands...).
  • (C4) 0 < split_count
  • (C5) is_unique(replica_groups)
  • (C6) size(replica_groups) şu şekilde tanımlanır:
    • cross_replica kullanılıyorsa num_replicas.
    • cross_partition kullanılıyorsa num_partitions.
  • (C7) 0 <= replica_groups < size(replica_groups).
  • (C8) dim(replica_groups, 1) = split_count
  • (C9) type(results...) = type(operands...), şu durumlar dışında: split_dimension != concat_dimension:
    • dim(results..., split_dimension) = dim(operands..., split_dimension) / split_count.
    • dim(results..., concat_dimension) = dim(operands..., concat_dimension) * split_count.

Örnekler

// num_replicas: 2
// num_partitions: 1
// %operand1@(0, 0): [[1, 2, 3, 4],
//                    [5, 6, 7, 8]]
// %operand1@(1, 0): [[9, 10, 11, 12],
//                    [13, 14, 15, 16]]
// %operand2@(0, 0): [[17, 18, 19, 20],
//                    [21, 22, 23, 24]]
// %operand2@(1, 0): [[25, 26, 27, 28],
//                    [29, 30, 31, 32]]
%result:2 = "stablehlo.all_to_all"(%operand1, %operand2) {
  split_dimension = 1 : i64,
  concat_dimension = 0 : i64,
  split_count = 2 : i64,
  replica_groups = dense<[[0, 1]]> : tensor<1x2xi64>
  // channel_id = 0
} : (tensor<2x4xi64>, tensor<2x4xi64>) -> (tensor<4x2xi64>, tensor<4x2xi64>)
// %result#0@(0, 0): [[1, 2], [5, 6], [9, 10], [13, 14]]
// %result#0@(1, 0): [[3, 4], [7, 8], [11, 12], [15, 16]]
// %result#1@(0, 0): [[17, 18], [21, 22], [25, 26], [29, 30]]
// %result#1@(1, 0): [[19, 20], [23, 24], [27, 28], [31, 32]]

Diğer Örnekler

ve

Anlam

lhs ve rhs olmak üzere iki tensör için öğe düzeyinde VE işlemini gerçekleştirir ve bir result üretir tensördür. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Boolelar için: mantıksal VE.
  • Tam sayılar için: bit tabanlı VE.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs boole veya tam sayı türündeki tensor (C1)
(I2) rhs boole veya tam sayı türündeki tensor (C1)

Çıkışlar

Ad Tür Sınırlamalar
result boole veya tam sayı türündeki tensor (C1)

Sınırlamalar

  • (C1) type(lhs) = type(rhs) = type(result).

Örnekler

// %lhs: [[1, 2], [3, 4]]
// %rhs: [[5, 6], [7, 8]]
%result = "stablehlo.and"(%lhs, %rhs) : (tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[1, 2], [3, 0]]

Diğer Örnekler

atan2

Anlam

lhs ve rhs tensörü üzerinde öğe tabanlı atan2 işlemi gerçekleştirir ve result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten atan2.
  • Karmaşık sayılar için: karmaşık atan2.
  • Miktarlanmış türler için: dequantize_op_quantize(atan2, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)
(I2) rhs kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(lhs) = baseline_type(rhs) = baseline_type(result).

Örnekler

// %lhs: [0.0, 1.0, -1.0]
// %rhs: [0.0, 0.0, 0.0]
%result = "stablehlo.atan2"(%lhs, %rhs) : (tensor<3xf64>, tensor<3xf64>) -> tensor<3xf64>
// %result: [0.0, 1.57079637, -1.57079637] // [0.0, pi/2, -pi/2]

Diğer Örnekler

batch_norm_grad

Anlam

Geri çoğaltan çeşitli batch_norm_training girişlerinin gradyanlarını hesaplar grad_output üretir ve grad_operand, grad_scale ve grad_offset üretir tensörler. Daha resmi ifade etmek gerekirse bu işlem, aşağıdaki gibi Python söz dizimini kullanan mevcut StableHLO işlemlerini içerir:

def compute_sum(operand, feature_index):
  (sum,) = reduce(
      inputs=[operand],
      init_values=[constant(0, element_type(operand))],
      dimensions=[i for i in range(rank(operand)) if i != feature_index],
      body=lambda x, y: add(x, y))
  return sum

def compute_mean(operand, feature_index):
  sum = compute_sum(operand, feature_index)
  divisor = constant(size(operand) / dim(operand, feature_index),
                     element_type(operand))
  divisor_bcast = broadcast_in_dim(divisor, [], type(sum))
  return divide(sum, divisor_bcast)

def batch_norm_grad(operand, scale, mean, variance, grad_output, epsilon, feature_index):
  # Broadcast inputs to type(operand)
  scale_bcast = broadcast_in_dim(scale, [feature_index], type(operand))
  mean_bcast = broadcast_in_dim(mean, [feature_index], type(operand))
  variance_bcast = broadcast_in_dim(variance, [feature_index], type(operand))
  epsilon_bcast = broadcast_in_dim(constant(epsilon, element_type(operand)), [],
                                   type(operand))

  # Perform normalization using the provided `mean` and `variance`
  # Intermediate values will be useful for computing gradients
  centered_operand = subtract(operand, mean_bcast)
  stddev = sqrt(add(variance_bcast, epsilon_bcast))
  normalized_operand = divide(centered_operand, stddev)

  # Use the implementation from batchnorm_expander.cc in XLA
  # Temporary variables have exactly the same names as in the C++ code
  elements_per_feature = broadcast_in_dim(
      constant(divide(size(operand), dim(operand, feature_index)),
               element_type(grad_output)),
      [], type(operand))
  i1 = multiply(grad_output, elements_per_feature)
  i2 = broadcast_in_dim(
      compute_sum(grad_output, feature_index), [feature_index], type(operand))
  i3 = broadcast_in_dim(
      compute_sum(multiply(grad_output, centered_operand), feature_index),
      [feature_index], type(operand))
  i4 = multiply(i3, centered_operand)
  i5 = divide(i4, add(variance_bcast, epsilon_bcast))
  i6 = subtract(subtract(i1, i2), i5)

  grad_operand =
      multiply(divide(divide(scale_bcast, stddev), elements_per_feature), i6)
  grad_scale =
      compute_sum(multiply(grad_output, normalized_operand), feature_index)
  grad_offset = compute_sum(grad_output, feature_index)

  return grad_operand, grad_scale, grad_offset

Miktarı kullanılan türlerde, dequantize_batch_norm_grad_or_training_quantize(lambda operand, scale, mean, variance, grad_output: batch_norm_grad(operand, scale, mean, variance, grad_output, epsilon, feature_index), operand, scale, mean, variance, grad_output, type(grad_operand), type(grad_scale), type(feature_index))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1-C3), (C5)
(I2) scale Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C4), (C5)
(I3) mean Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C4)
(I4) variance Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C4)
(I5) grad_output kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C2), (C3)
(I6) epsilon f32 türündeki sabit
(I7) feature_index si64 türündeki sabit (C1), (C5)

Çıkışlar

Ad Tür Sınırlamalar
grad_operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C2), (C3)
grad_scale Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C4)
grad_offset Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C4)

Sınırlamalar

  • (C1) 0 <= feature_index < rank(operand).
  • (C2) operand, scale, mean, variance, grad_output, grad_operand, grad_scale ve grad_offset aynı baseline_element_type değerine sahip.
  • (C3) operand, grad_output ve grad_operand aynı şekle sahip.
  • (C4) scale, mean, variance, grad_scale ve grad_offset sahip anlamına gelir.
  • (C5) size(scale) = dim(operand, feature_index)

Örnekler

// %operand: [
//            [[1.0, 2.0], [3.0, 4.0]],
//            [[3.0, 4.0], [1.0, 2.0]]
//           ]
// %scale: [1.0, 1.0]
// %mean: [2.0, 3.0]
// %variance: [1.0, 1.0]
// %grad_output: [
//                [[0.1, 0.1], [0.1, 0.1]],
//                [[0.1, 0.1], [0.1, 0.1]]
//               ]
%grad_operand, %grad_scale, %grad_offset =
"stablehlo.batch_norm_grad"(%operand, %scale, %mean, %variance, %grad_output) {
  epsilon = 0.0 : f32,
  feature_index = 2 : i64
} : (tensor<2x2x2xf64>, tensor<2xf64>, tensor<2xf64>, tensor<2xf64>,
     tensor<2x2x2xf64>) -> (tensor<2x2x2xf64>, tensor<2xf64>, tensor<2xf64>)
// %grad_operand: [
//                 [[0.0, 0.0], [0.0, 0.0]],
//                 [[0.0, 0.0], [0.0, 0.0]]
//                ]
// %grad_scale:  [0.0, 0.0]
// %grad_offset: [0.4, 0.4]

batch_norm_inference

Anlam

operand tensörünü şu boyut hariç tüm boyutlarda normalleştirir: feature_index boyutunu belirler ve bir result tensörü oluşturur. Daha resmi ifade etmek gerekirse işlem, mevcut StableHLO işlemlerine ayrışma olarak ifade edilebilir aşağıdaki gibi bir Python söz dizimi kullanarak:

def batch_norm_inference(operand, scale, offset, mean, variance, epsilon, feature_index):
  # Broadcast inputs to shape(operand)
  scale_bcast = broadcast_in_dim(scale, [feature_index], type(operand))
  offset_bcast = broadcast_in_dim(offset, [feature_index], type(operand))
  mean_bcast = broadcast_in_dim(mean, [feature_index], type(operand))
  variance_bcast = broadcast_in_dim(variance, [feature_index], type(operand))
  epsilon_bcast = broadcast_in_dim(constant(epsilon, element_type(operand)), [],
                                   type(operand))

  # Perform normalization using the provided `mean` and `variance` instead of
  # computing them like `batch_norm_training` does.
  centered_operand = subtract(operand, mean_bcast)
  stddev = sqrt(add(variance_bcast, epsilon_bcast))
  normalized_operand = divide(centered_operand, stddev)
  return add(multiply(scale_bcast, normalized_operand), offset_bcast)

Miktarı kullanılan türlerde, dequantize_op_quantize(lambda operand, scale, offset, mean, variance: batch_norm_inference(operand, scale, offset, mean, variance, epsilon, feature_index), operand, scale, offset, mean, variance, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1-C7)
(I2) scale Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C3)
(I3) offset Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C4)
(I4) mean Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C5)
(I5) variance Kayan nokta veya tensör başına miktarlandırılmış türde 1 boyutlu tensör (C2), (C6)
(I6) epsilon f32 türündeki sabit
(I7) feature_index si64 türündeki sabit (C1), (C3-C6)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C2), (C7)

Sınırlamalar

  • (C1) 0 <= feature_index < rank(operand).
  • (C2) operand, scale, offset, mean, variance ve result sahip aynı baseline_element_type.
  • (C3) size(scale) = dim(operand, feature_index).
  • (C4) size(offset) = dim(operand, feature_index)
  • (C5) size(mean) = dim(operand, feature_index)
  • (C6) size(variance) = dim(operand, feature_index).
  • (C7) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [
//            [[1.0, 2.0], [3.0, 4.0]],
//            [[3.0, 4.0], [1.0, 2.0]]
//           ]
// %scale: [1.0, 1.0]
// %offset: [1.0, 1.0]
// %mean: [2.0, 3.0]
// %variance: [1.0, 1.0]
%result = "stablehlo.batch_norm_inference"(%operand, %scale, %offset, %mean, %variance) {
  epsilon = 0.0 : f32,
  feature_index = 2 : i64
} : (tensor<2x2x2xf64>, tensor<2xf64>, tensor<2xf64>, tensor<2xf64>, tensor<2xf64>) -> tensor<2x2x2xf64>
// %result: [
//           [[0.0, 0.0], [2.0, 2.0]],
//           [[2.0, 2.0], [0.0, 0.0]]
//          ]

batch_norm_training

Anlam

feature_index hariç tüm boyutlardaki ortalamayı ve varyansı hesaplar boyut ve output, batch_mean üreten operand tensörü normalleştirir ve batch_var tensör. Daha resmi ifade etmek gerekirse bu işlem mevcut StableHLO işlemlerine ayrıştırmak için Python sözdizimini şöyle olur:

def compute_mean(operand, feature_index):
  (sum,) = reduce(
      inputs=[operand],
      init_values=[constant(0, element_type(operand))],
      dimensions=[i for i in range(rank(operand)) if i != feature_index],
      body=lambda x, y: add(x, y))
  divisor = constant(size(operand) / dim(operand, feature_index),
                     element_type(operand))
  divisor_bcast = broadcast_in_dim(divisor, [], type(sum))
  return divide(sum, divisor_bcast)

def compute_variance(operand, feature_index):
  mean = compute_mean(operand, feature_index)
  mean_bcast = broadcast_in_dim(mean, [feature_index], type(operand))
  centered_operand = subtract(operand, mean_bcast)
  return compute_mean(mul(centered_operand, centered_operand), feature_index)

def batch_norm_training(operand, scale, offset, epsilon, feature_index):
  mean = compute_mean(operand, feature_index)
  variance = compute_variance(operand, feature_index)
  return batch_norm_inference(operand, scale, offset, mean, variance, epsilon,
                              feature_index),
         mean, variance

Miktarı kullanılan türlerde, dequantize_batch_norm_grad_or_training_quantize(lambda operand, scale, offset: batch_norm_training(operand, scale, offset, epsilon, feature_index), operand, scale, offset, type(output), type(batch_mean), type(batch_var))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)
(I2) scale Kayan nokta veya tensör başına miktarlandırılmış 1 boyutlu tensör (C2), (C3)
(I3) offset Kayan nokta veya tensör başına miktarlandırılmış 1 boyutlu tensör (C2), (C4)
(I4) epsilon f32 türündeki sabit (C1), (C3-C6)
(I5) feature_index si64 türündeki sabit (C1), (C3-C6)

Çıkışlar

Ad Tür Sınırlamalar
output kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C7)
batch_mean Kayan nokta veya tensör başına miktarlandırılmış 1 boyutlu tensör (C2), (C5)
batch_var Kayan nokta veya tensör başına miktarlandırılmış 1 boyutlu tensör (C2), (C6)

Sınırlamalar

  • (C1) 0 <= feature_index < rank(operand).
  • (C2) operand, scale, offset, batch_mean, batch_var ve output var aynı baseline_element_type.
  • (C3) size(scale) = dim(operand, feature_index).
  • (C4) size(offset) = dim(operand, feature_index)
  • (C5) size(batch_mean) = dim(operand, feature_index)
  • (C6) size(batch_var) = dim(operand, feature_index).
  • (C7) baseline_type(output) = baseline_type(operand).

Örnekler

// %operand: [
//            [[1.0, 2.0], [3.0, 4.0]],
//            [[3.0, 4.0], [1.0, 2.0]]
//           ]
// %scale: [1.0, 1.0]
// %offset: [1.0, 1.0]
%output, %batch_mean, %batch_var = "stablehlo.batch_norm_training"(%operand, %scale, %offset) {
  epsilon = 0.0 : f32,
  feature_index = 2 : i64
} : (tensor<2x2x2xf64>, tensor<2xf64>, tensor<2xf64>) ->
    (tensor<2x2x2xf64>, tensor<2xf64>, tensor<2xf64>)
// %output: [
//           [[0.0, 0.0], [2.0, 2.0]],
//           [[2.0, 2.0], [0.0, 0.0]]
//          ]
// %batch_mean: [2.0, 3.0]
// %batch_var: [1.0, 1.0]

bitcast_convert

Anlam

operand tensörü üzerinde bir bitcast işlemi gerçekleştirir ve result tensörü üretir Bu örnekte, operand tensörünün tamamının bitleri result tensör türü.

Daha resmî bir şekilde ifade etmek gerekirse E = element_type(operand), E' = element_type(result), ve R = rank(operand):

  • num_bits(E') < num_bits(E) ise bits(result[i0, ..., iR-1, :]) = bits(operand[i0, ..., iR-1]).
  • num_bits(E') > num_bits(E) ise bits(result[i0, ..., iR-2]) = bits(operand[i0, ..., iR-2, :]).
  • num_bits(E') = num_bits(E) ise bits(result[i0, ..., iR-1]) = bits(operand[i0, ..., iR-1]).

bits, belirli bir değerin ve davranışının bellekteki gösterimini döndürür uygulama tanımlıdır çünkü tensörlerin tam gösterimi öğe türlerinin tam gösterimi şöyledir: tanımlanabilir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya nicel tensör (C1-C2)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C1-C2)

Sınırlamalar

  • (C1) E = is_quantized(operand) ? storage_type(operand) : element_type(operand), E' = is_quantized(result) ? storage_type(result) : element_type(result) ve R = rank(operand) dikkate alınarak:
    • num_bits(E') = num_bits(E) ise shape(result) = shape(operand).
    • Eğer num_bits(E') < num_bits(E):
    • rank(result) = R + 1.
    • Tüm 0 <= i < R için dim(result, i) = dim(operand, i).
    • dim(result, R) * num_bits(E') = num_bits(E).
    • Eğer num_bits(E') > num_bits(E):
    • rank(result) = R - 1.
    • Tüm 0 <= i < R için dim(result, i) = dim(operand, i).
    • dim(operand, R - 1) * num_bits(E) = num_bits(E').
  • (C2) is_complex(operand) or is_complex(result) ise, is_complex(operand) and is_complex(result).

Örnekler

// %operand: 0x0123456789ABCDEF
%result = "stablehlo.bitcast_convert"(%operand) : (tensor<f64>) -> tensor<4xf16>
// %result: [0xCDEF, 0x89AB, 0x4567, 0x0123] // little-endian representation

Diğer Örnekler

broadcast_in_dim

Anlam

Verileri çoğaltarak bir giriş tensörünün boyutlarını ve/veya sıralamasını genişletir operand tensöründe çalışır ve bir result tensörü üretir. Daha resmi ifade etmek gerekirse result[result_index] = operand[operand_index] burada tüm d için axes(operand):

  • dim(operand, d) = 1 ise operand_index[d] = 0.
  • Aksi takdirde operand_index[d] = result_index[broadcast_dimensions[d]].

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya nicel tensör (C1-C2), (C5-C6)
(I2) broadcast_dimensions si64 türünde 1 boyutlu tensör sabiti (C2-C6)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C1), (C3), (C5-C6)

Sınırlamalar

  • (C1) element_type(result) değerini sağlayan:
    • !is_per_axis_quantized(operand) ise element_type(operand).
    • element_type(operand) (bu quantization_dimension(operand) hariç) scales(operand) ve zero_points(operand) şundan farklı olabilir: quantization_dimension(result), scales(result) ve zero_points(result) resp., aksi takdirde.
  • (C2) size(broadcast_dimensions) = rank(operand).
  • (C3) 0 <= broadcast_dimensions < rank(result).
  • (C4) is_unique(broadcast_dimensions)
  • (C5) axes(operand) bünyesindeki tüm d için:
    • dim(operand, d) = 1 veya
    • dim(operand, d) = dim(result, broadcast_dimensions[d]).
  • (C6) is_per_axis_quantized(result) ise:
    • quantization_dimension(result) = broadcast_dimensions[quantization_dimension(operand)].
    • dim(operand, quantization_dimension(operand)) = 1 ise, scales(result)[i] = scales(operand)[0] and zero_points(result)[i] = zero_points(operand)[0] for i in range(dim(result, quantization_dimension(result))).

Örnekler

// %operand: [
//            [1, 2, 3]
//           ]
%result = "stablehlo.broadcast_in_dim"(%operand) {
  broadcast_dimensions = array<i64: 2, 1>
} : (tensor<1x3xi32>) -> tensor<2x3x2xi32>
// %result: [
//            [
//             [1, 1],
//             [2, 2],
//             [3, 3]
//            ],
//            [
//             [1, 1],
//             [2, 2],
//             [3, 3]
//            ]
//          ]

Diğer Örnekler

kılıf

Anlam

branches kaynağındaki tam olarak bir işlevin yürütülmesiyle elde edilen çıktıyı oluşturur (index değerine bağlıdır). Daha resmi dilde: result = selected_branch() burada:

  • 0 <= index < size(branches) ise selected_branch = branches[index].
  • Aksi takdirde selected_branch = branches[-1].

Girişler

Şirket Ad Tür Sınırlamalar
(I1) index si32 türünde 0 boyutlu tensör
(I2) branches değişken fonksiyon sayısı (C1-C4)

Çıkışlar

Ad Tür Sınırlamalar
results değişken tensör, nicel tensör veya jeton sayısı (C4)

Sınırlamalar

  • (C1) 0 < size(branches).
  • (C2) input_types(branches...) = [].
  • (C3) same(output_types(branches...)).
  • (C4) type(results...) = output_types(branches[0])

Örnekler

// %index: -1
// %result_branch0: [0, 0]
// %result_branch1: [1, 1]
%result0, %result1 = "stablehlo.case"(%index) ({
  "stablehlo.return"(%result_branch0, %result_branch0) : (tensor<2xi64>, tensor<2xi64>) -> ()
}, {
  "stablehlo.return"(%result_branch1, %result_branch1) : (tensor<2xi64>, tensor<2xi64>) -> ()
}) : (tensor<i32>) -> (tensor<2xi64>, tensor<2xi64>)
// %result0: [1, 1]
// %result1: [1, 1]

Diğer Örnekler

CBrt

Anlam

operand tensörü üzerinde öğe tabanlı kübik kök işlemi gerçekleştirir ve result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten rootn(x, 3).
  • Karmaşık sayılar için: karmaşık küpik kök.
  • Miktarı ölçülmüş türler için: dequantize_op_quantize(cbrt, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [0.0, 1.0, 8.0, 27.0]
%result = "stablehlo.cbrt"(%operand) : (tensor<4xf64>) -> tensor<4xf64>
// %result: [0.0, 1.0, 2.0, 3.0]

Diğer Örnekler

ceil

Anlam

Element tabanlı operand tensörü gerçekleştirir ve bir result tensörü üretir. IEEE-754'teki roundToIntegralTowardPositive işlemini uygular bakın. Miktarı kullanılan türlerde, dequantize_op_quantize(ceil, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [-0.8166, -0.2530, 0.2530, 0.8166, 2.0]
%result = "stablehlo.ceil"(%operand) : (tensor<5xf32>) -> tensor<5xf32>
// %result: [-0.0, -0.0, 1.0, 1.0, 2.0]

Diğer Örnekler

Cholesky

Anlam

Bir dizi matrisin Cholesky ayrışmasını hesaplar.

Daha resmî bir şekilde ifade etmek gerekirse index_space(result) bölgesindeki tüm i için result[i0, ..., iR-3, :, :], aşağıdaki değerin bir Cholesky ayrışmasıdır a[i0, ..., iR-3, :, :], alt üçgenden biri biçiminde (lower true ise) veya üst üçgen (lower false ise) matrisi. Karşıt üçgende gösterilen çıkış değerleri (ör. katı üst üçgen veya katı alt üçgenler ise uygulama tanımlıdır.

Girdi matrisinin Hermitian pozitif tanımlı olmadığı i varsa söz konusu olduğunda, davranış tanımsızdır.

Miktarı kullanılan türlerde, dequantize_op_quantize(lambda operand: cholesky(operand, lower), a, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) a kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1-C3)
(I2) lower i1 türünde 0 boyutlu tensör sabiti

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(a) = baseline_type(result).
  • (C2) 2 <= rank(a).
  • (C3) dim(a, -2) = dim(a, -1).

Örnekler

// %a: [
//      [1.0, 2.0, 3.0],
//      [2.0, 20.0, 26.0],
//      [3.0, 26.0, 70.0]
//     ]
%result = "stablehlo.cholesky"(%a) {
  lower = true
} : (tensor<3x3xf32>) -> tensor<3x3xf64>
// %result: [
//           [1.0, 0.0, 0.0],
//           [2.0, 4.0, 0.0],
//           [3.0, 5.0, 6.0]
//          ]

kenetleme

Anlam

operand tensörünün her öğesini minimum ile maksimum arasında sabitler değerini döndürür ve bir result tensörü üretir. Daha resmi dilde: result[result_index] = minimum(maximum(operand[result_index], min_element), max_element), burada min_element = rank(min) = 0 ? min[] : min[result_index], max_element = rank(max) = 0 ? max[] : max[result_index]. Miktarı kullanılan türlerde dequantize_op_quantize(clamp, min, operand, max, type(result)) gerçekleştiriyor.

Karmaşık sayılarda sıralama yaratmak, şaşırtıcı anlamlar ya da Bu nedenle gelecekte karmaşık sayılar için desteği kaldırmayı planlıyoruz. (#560).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) min tensör veya tensör başına miktarlandırılmış tensör (C1), (C3)
(I2) operand tensör veya tensör başına miktarlandırılmış tensör (C1-C4)
(I3) max tensör veya tensör başına miktarlandırılmış tensör (C2), (C3)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C4)

Sınırlamalar

  • (C1) rank(min) = 0 or shape(min) = shape(operand).
  • (C2) rank(max) = 0 or shape(max) = shape(operand).
  • (C3) baseline_element_type(min) = baseline_element_type(operand) = baseline_element_type(max).
  • (C4) baseline_type(operand) = baseline_type(result)

Örnekler

// %min: [5, 10, 15]
// %operand: [3, 13, 23]
// %max: [10, 15, 20]
%result = "stablehlo.clamp"(%min, %operand, %max) : (tensor<3xi32>, tensor<3xi32>, tensor<3xi32>) -> tensor<3xi32>
// %result: [5, 13, 20]

Diğer Örnekler

collective_broadcast

Anlam

StableHLO süreç tablosundaki her süreç grubunda, operand tensörü kaynak süreçten hedef süreçlere aktarır ve result tensörü.

İşlem, StableHLO süreç ızgarasını process_groups olarak ayırır. şu şekilde tanımlanır:

  • channel_id <= 0 ise cross_replica(replica_groups).
  • channel_id > 0 ise cross_partition(replica_groups).

Daha sonra, result@process sağlayan:

  • Sürecin geçerli olması için gereken i varsa operand@process_groups[i, 0] process_groups[i] içinde.
  • broadcast_in_dim(constant(is_quantized(result) ? quantize(0, element_type(result)) : 0, element_type(result)), [], type(result)). aksi takdirde.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C3)
(I2) replica_groups si64 türündeki 1 boyutlu tensör sabitlerinin değişken sayısı (C1), (C2)
(I3) channel_id si64 türündeki sabit

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C3)

Sınırlamalar

  • (C1) is_unique(replica_groups).
  • (C2) 0 <= replica_groups < N burada N şu şekilde tanımlanır:
    • cross_replica kullanılıyorsa num_replicas.
    • cross_partition kullanılıyorsa num_partitions.
  • (C3) type(result) = type(operand).

Örnekler

// num_replicas: 4
// num_partitions: 1
// %operand@(0, 0): [[1, 2]]
// %operand@(1, 0): [[3, 4]]
// %operand@(2, 0): [[5, 6]]
// %operand@(3, 0): [[7, 8]]
%result = "stablehlo.collective_broadcast"(%operand) {
  replica_groups = dense<[[2, 1]]> : tensor<1x2xi64>,
  channel_handle = #stablehlo.channel_handle<handle = 0, type = 0>
} : (tensor1x2xi64>) -> tensor<1x2xi64>
// %result@(0, 0): [[0, 0]]
// %result@(1, 0): [[5, 6]]
// %result@(2, 0): [[5, 6]]
// %result@(3, 0): [[0, 0]]

collective_permute

Anlam

StableHLO süreç ızgarasındaki her işlem grubu içinde, operand tensörü kaynak süreçten hedef sürece çıkar ve result tensörü.

İşlem, StableHLO süreç ızgarasını process_groups olarak ayırır. şu şekilde tanımlanır:

  • channel_id <= 0 ise cross_replica(source_target_pairs).
  • channel_id > 0 ise cross_partition(source_target_pairs).

Daha sonra, result@process sağlayan:

  • operand@process_groups[i, 0] gibi bir i varsa process_groups[i, 1] = process.
  • broadcast_in_dim(constant(is_quantized(result) ? quantize(0, element_type(result)) : 0, element_type(result)), [], type(result)). aksi takdirde.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C5)
(I2) source_target_pairs si64 türünde 2 boyutlu tensör sabiti (C1-C4)
(I3) channel_id si64 türündeki sabit

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1)

Sınırlamalar

  • (C1) dim(source_target_pairs, 1) = 2.
  • (C2) is_unique(source_target_pairs[:, 0]).
  • (C3) is_unique(source_target_pairs[:, 1]).
  • (C4) 0 <= source_target_pairs < N; burada N şu şekilde tanımlanır:
    • cross_replica kullanılıyorsa num_replicas.
    • cross_partition kullanılıyorsa num_partitions.
  • (C5) type(result) = type(operand)

Örnekler

// num_replicas: 3
// num_partitions: 1
// %operand@(0, 0): [[1, 2], [3, 4]]
// %operand@(1, 0): [[5, 6], [7, 8]]
// %operand@(2, 0): [[9, 10], [11, 12]]
%result = "stablehlo.collective_permute"(%operand) {
  source_target_pairs = dense<[[0, 1], [1, 2]]> : tensor<2x2xi64>,
  channel_handle = #stablehlo.channel_handle<handle = 0, type = 0>
} : (tensor<2x2xi64>) -> tensor<2x2xi64>
//
// %result@(0, 0): [[0, 0], [0, 0]]
// %result@(1, 0): [[1, 2], [3, 4]]
// %result@(2, 0): [[5, 6], [7, 8]]

Diğer Örnekler

karşılaştır

Anlam

Şuna göre lhs ve rhs tensörlerinin öğe bazında karşılaştırmasını yapar: comparison_direction ve compare_type ile aynı ve bir result tensörü üretir.

comparison_direction ve compare_type değerleri şuna sahiptir: anlambilim:

Boole ve tam sayı öğe türleri için:

  • EQ: lhs = rhs.
  • NE: lhs != rhs.
  • GE: lhs >= rhs.
  • GT: lhs > rhs.
  • LE: lhs <= rhs.
  • LT: lhs < rhs.

op, compare_type = FLOAT içeren kayan nokta öğe türlerinde aşağıdaki IEEE-754 işlemleri için geçerlidir:

  • EQ: compareQuietEqual.
  • NE: compareQuietNotEqual.
  • GE: compareQuietGreaterEqual.
  • GT: compareQuietGreater.
  • LE: compareQuietLessEqual.
  • LT: compareQuietLess.

compare_type = TOTALORDER içeren kayan nokta öğe türlerinde op şuna ait totalOrder ve compareQuietEqual işlemlerinin birleşimini kullanır: IEEE-754.

Karmaşık öğe türleri için (real, imag) çiftlerinin sözlüksel karşılaştırması sağlanan comparison_direction ve compare_type kullanılarak gerçekleştirildi. Karmaşık sayılarda sıralama yaratmak, şaşırtıcı anlamlar ya da Bu nedenle gelecekte karmaşık sayılar için desteği kaldırmayı planlıyoruz. comparison_direction GE, GT, LE veya LT olduğunda (#560).

Miktarı ölçülmüş türler için. dequantize_compare(lhs, rhs, comparison_direction) gerçekleştiriyor.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya tensör başına miktarlandırılmış tensör (C1-C3)
(I2) rhs tensör veya tensör başına miktarlandırılmış tensör (C1-C2)
(I3) comparison_direction EQ, NE, GE, GT, LE ve LT sıralaması
(I4) compare_type FLOAT, TOTALORDER, SIGNED ve UNSIGNED sıralaması (C3)

Çıkışlar

Ad Tür Sınırlamalar
result boole türündeki tensor (C2)

Sınırlamalar

  • (C1) baseline_element_type(lhs) = baseline_element_type(rhs).
  • (C2) shape(lhs) = shape(rhs) = shape(result).
  • (C3) compare_type şu şekilde tanımlanır:
    • is_signed_integer(element_type(lhs)) ise SIGNED.
    • is_unsigned_integer(element_type(lhs)) or is_boolean(element_type(lhs)) ise UNSIGNED.
    • is_float(element_type(lhs)) ise FLOAT veya TOTALORDER.
    • is_complex(element_type(lhs)) ise FLOAT.

Örnekler

// %lhs: [1.0, 3.0]
// %rhs: [1.1, 2.9]
%result = "stablehlo.compare"(%lhs, %rhs) {
  comparison_direction = #stablehlo<comparison_direction LT>,
  compare_type = #stablehlo<comparison_type FLOAT>
} : (tensor<2xf32>, tensor<2xf32>) -> tensor<2xi1>
// %result: [true, false]

Diğer Örnekler

karmaşık

Anlam

Gerçek ve eşleştirilmiş değer çiftinden karmaşık bir değere element tabanlı dönüşüm gerçekleştirir. lhs ve rhs ile sanal değerler arasında bir olarak belirleyip bir result tensörü üretir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs f32 veya f64 türündeki tensör (C1-C3)
(I2) rhs f32 veya f64 türündeki tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result karmaşık türde tensor (C2), (C3)

Sınırlamalar

  • (C1) type(lhs) = type(rhs).
  • (C2) shape(result) = shape(lhs).
  • (C3) element_type(result), complex<E> türünde olup burada E = element_type(lhs).

Örnekler

// %lhs: [1.0, 3.0]
// %rhs: [2.0, 4.0]
%result = "stablehlo.complex"(%lhs, %rhs) : (tensor<2xf64>, tensor<2xf64>) -> tensor<2xcomplex<f64>>
// %result: [(1.0, 2.0), (3.0, 4.0)]

Diğer Örnekler

birleşik

Anlam

Diğer StableHLO işlemlerinden oluşan (oluşturulan) bir işlemi içerir. inputs ve composite_attributes alıp results üretiyoruz. İlgili içeriği oluşturmak için kullanılan işlemin anlamı, decomposition özelliği tarafından uygulanır. İlgili içeriği oluşturmak için kullanılan composite işlemi, program değiştirilmeden ayrıştırılmasıyla değiştirilebilir anlambilim. Ayrıştırmayı satır içine almak aynı işlem semantiği, custom_call kullanmayı tercih edin.

version alanı (varsayılan olarak 0 değerine ayarlanır), bir bileşenin anlamsal değişikliği vardır.

Girişler

Şirket Ad Tür
(I1) inputs değişken değer sayısı
(I2) name string türündeki sabit
(I3) composite_attributes özellik sözlüğü
(I4) decomposition string türündeki sabit
(I5) version si32 türündeki sabit

Çıkışlar

Ad Tür
results değişken değer sayısı

Sınırlamalar

  • (C1) is_namespaced_op_name(name)
  • (C2) is_defined_in_parent_scope(decomposition)
  • (C3) types(inputs...) == input_types(decomposition)
  • (C4) types(results...) == output_types(decomposition)

Örnekler

%results = "stablehlo.composite"(%input0, %input1) {
  name = "my_namespace.my_op",
  composite_attributes = {
    my_attribute = "my_value"
  },
  decomposition = @my_op,
  version = 1 : i32
} : (tensor<f32>, tensor<f32>) -> tensor<f32>

Diğer Örnekler

birleştirmek

Anlam

inputs değerini, verilen sırada dimension boyutu boyunca birleştirir bağımsız değişkenlerini kullanır ve bir result tensörü üretir. Daha resmi ifade etmek gerekirse result[i0, ..., id, ..., iR-1] = inputs[k][i0, ..., kd, ..., iR-1], burada:

  1. id = d0 + ... + dk-1 + kd.
  2. d, dimension değerine eşit, d0, ... ise d. boyut boyutudur / inputs.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) inputs değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1-C6)
(I2) dimension si64 türündeki sabit (C2), (C4), (C6)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C5-C6)

Sınırlamalar

  • (C1) same(element_type(inputs...)).
  • (C2) dim(inputs..., dimension) hariç same(shape(inputs...)).
  • (C3) 0 < size(inputs).
  • (C4) 0 <= dimension < rank(inputs[0])
  • (C5) element_type(result) = element_type(inputs[0])
  • (C6) shape(result) = shape(inputs[0]) hariç:
    • dim(result, dimension) = dim(inputs[0], dimension) + ....

Örnekler

// %input0: [[1, 2], [3, 4], [5, 6]]
// %input1: [[7, 8]]
%result = "stablehlo.concatenate"(%input0, %input1) {
  dimension = 0 : i64
} : (tensor<3x2xi64>, tensor<1x2xi64>) -> tensor<4x2xi64>
// %result: [[1, 2], [3, 4], [5, 6], [7, 8]]

Diğer Örnekler

sabit

Anlam

Sabit bir value değerinden bir output tensörü üretir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) value sabit (C1)

Çıkışlar

Ad Tür Sınırlamalar
output tensör veya nicel tensör (C1)

Sınırlamalar

  • (C1) type(value) = type(output).

Örnekler

%output = "stablehlo.constant"() {
  value = dense<[[0.0, 1.0], [2.0, 3.0]]> : tensor<2x2xf32>
} : () -> tensor<2x2xf32>
// %output: [[0.0, 1.0], [2.0, 3.0]]

Diğer Örnekler

Dönüşüm gerçekleştirme

Anlam

Şu durumda bir öğe türünden diğerine öğe tabanlı dönüşüm gerçekleştirir: operand tensörü ve result tensörü üretir.

boolean-to-any-supported-type dönüşümleri için false değeri sıfıra dönüştürülür ve true değeri bire dönüştürülür. Örneğin, any-supported-type-to-boolean dönüşümlerini içeren bir dönüşüm yoksa sıfır değeri şuna dönüştürülür: false ve sıfır olmayan değerler true biçimine dönüştürülür. Bunun nasıl yapılacağını karmaşık türler için geçerlidir.

Tamsayıdan tam sayıya, tamsayıdan kayan noktaya geçiş içeren dönüşümler için veya floating-point-to-floating-point (kayan-nokta-kayan-nokta) hedef türünde temsil edildiğinde, sonuç değeri, söz konusu temsil eder. Aksi takdirde, davranış henüz belli değil (#180).

floating-point-to-integer dönüşüm içeren dönüşümlerde kesirli kısım kısaltılır. Kısaltılmış değer hedef türünde temsil edilemiyorsa davranış TBD'dir (#180).

Karmaşıktan karmaşa içeren dönüşümlerde aynı davranışı izler. floating-point-to-floating-point dönüşümler, gerçek ve hayali parçalar içerir.

complex-to-any-other-type ve any-other-type-to-complex dönüşümleri için kaynak sanal değeri yok sayılır veya hedef sanal değeri sıfırdır. Gerçek parçanın dönüştürülmesinde, kayan nokta dönüşümleridir.

Prensipte, bu işlem, ayrışmayı (deneyim, nicelenmiş tensörlerden normal tensörlere), nicelleştirme (normalden tensörlerden miktarlandırılmış tensörlere ve yeniden niceleme (nicelleştirilmiş tensörler), ancak şu anda bunun için özel operasyonlarımız var. İlk kullanım alanı için uniform_dequantize veuniform_quantize kullanım alanlarından bahsedeceğiz. Gelecekte bu iki operasyon birleştirilebilir convert (#1576) olarak değiştirin.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand Tensor (C1)

Çıkışlar

Ad Tür Sınırlamalar
result Tensor (C1)

Sınırlamalar

  • (C1) shape(operand) = shape(result).

Örnekler

// %operand: [-1, 0, 1]
%result = "stablehlo.convert"(%operand) : (tensor<3xi64>) -> tensor<3xcomplex<f64>>
// %result: [(-1.0, 0.0), (0.0, 0.0), (1.0, 0.0)]

Diğer Örnekler

konvolüsyon

Anlam

lhs pencereleri ile rhs dilimleri arasındaki nokta ürünlerini hesaplar ve şunları üretir: result. Aşağıdaki şemada, result içindeki öğelerin Somut bir örnek kullanarak lhs ve rhs.

konvolüsyon

Daha resmî bir şekilde, girişlerin lhs açısından aşağıdaki şekilde yeniden kavranmasını sağlayabilirsiniz. lhs pencerelerini ifade edebilmek için:

  • lhs_window_dimensions = lhs_shape(dim(lhs, input_batch_dimension), dim(rhs, kernel_spatial_dimensions), dim(lhs, input_feature_dimension)).
  • lhs_window_strides = lhs_shape(1, window_strides, 1).
  • lhs_padding = lhs_shape([0, 0], padding, [0, 0]).
  • lhs_base_dilations = lhs_shape(1, lhs_dilation, 1).
  • lhs_window_dilations = lhs_shape(1, rhs_dilation, 1).

Bu yeniden çerçeveleme aşağıdaki yardımcı işlevleri kullanır:

  • lhs_shape(n, hw, c) = permute([n] + hw + [c], [input_batch_dimension] + input_spatial_dimensions + [input_feature_dimension]).
  • result_shape(n1, hw, c1) = permute([n1] + hw + [c1], [output_batch_dimension] + output_spatial_dimensions + [output_feature_dimension]).
  • permute([j0, j1, ..., jR-1], permutation) = [i0, i1, ..., iR-1] burada j[d] = i[permutation[d]].

feature_group_count = 1 ve batch_group_count = 1 ise herkes için index_space(dim(result, output_spatial_dimensions...)) konumunda output_spatial_index, result[result_shape(:, output_spatial_index, :)] = dot_product burada:

  • padding_value = constant(0, element_type(lhs)).
  • padded_lhs = pad(lhs, padding_value, lhs_padding[:, 0], lhs_padding[:, 1], lhs_base_dilations - 1).
  • lhs_window_start = lhs_shape(0, output_spatial_index, 0) * lhs_window_strides.
  • lhs_window = slice(padded_lhs, lhs_window_start, lhs_window_start + lhs_window_dimensions, lhs_window_dilations).
  • reversed_lhs_window = reverse(lhs_window, [input_spatial_dimensions[dim] for dim in range(size(window_reversal)) if window_reversal[dim] = true]) Bu özellik kullanılmadığından ileride uygulamayı kaldırmayı planlıyoruz. bu (#1181).
  • dot_product = dot_general(reversed_lhs_window, rhs, lhs_batching_dimensions=[], lhs_contracting_dimensions=input_spatial_dimensions + [input_feature_dimension], rhs_batching_dimensions=[], rhs_contracting_dimensions=kernel_spatial_dimensions + [kernel_input_feature_dimension]).

Eğer feature_group_count > 1:

  • lhses = split(lhs, feature_group_count, input_feature_dimension).
  • rhses = split(rhs, feature_group_count, kernel_output_feature_dimension).
  • results... = convolution(lhses..., rhses..., ..., feature_group_count=1, ...).
  • result = concatenate(results, output_feature_dimension).

Eğer batch_group_count > 1:

  • lhses = split(lhs, batch_group_count, input_batch_dimension).
  • rhses = split(rhs, batch_group_count, kernel_output_feature_dimension).
  • results... = convolution(lhses..., rhses..., ..., batch_group_count=1, ...).
  • result = concatenate(results, output_feature_dimension)

Miktarı ölçülmüş türlerde, dequantize_op_quantize( lambda lhs, rhs: convolution(lhs, rhs, window_strides, padding, lhs_dilation, rhs_dilation, window_reversal, input_batch_dimension, input_feature_dimension, input_spatial_dimensions, kernel_input_feature_dimension, kernel_output_feature_dimension, kernel_spatial_dimensions, output_batch_dimension, output_feature_dimension, output_spatial_dimensions, feature_group_count, batch_group_count, precision_config), lhs, rhs, type(result)) gerçekleştirir.

Karma miktarlandırılmış türlerde hybrid_dequantize_then_op( lambda lhs, rhs: convolution(lhs, rhs, window_strides, padding, lhs_dilation, rhs_dilation, window_reversal, input_batch_dimension, input_feature_dimension, input_spatial_dimensions, kernel_input_feature_dimension, kernel_output_feature_dimension, kernel_spatial_dimensions, output_batch_dimension, output_feature_dimension, output_spatial_dimensions, feature_group_count, batch_group_count, precision_config), lhs, rhs) performans gösterir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya tensör başına miktarlandırılmış tensör (C1), (C10-C11), (C14) (C25), (C27-C28), (C31-C32), (C34)
(I2) rhs tensör veya nicel tensör (C1), (C14-C16), (C25), (C27-C29), (C31-C34)
(I3) window_strides si64 türünde 1 boyutlu tensör sabiti (C2-C3), (C25)
(I4) padding si64 türünde 2 boyutlu tensör sabiti (C4), (C25)
(I5) lhs_dilation si64 türünde 1 boyutlu tensör sabiti (C5-C6), (C25)
(I6) rhs_dilation si64 türünde 1 boyutlu tensör sabiti (C7-C8), (C25)
(I7) window_reversal i1 türünde 1 boyutlu tensör sabiti (C9)
(I8) input_batch_dimension si64 türündeki sabit (C10), (C13), (C25)
(I9) input_feature_dimension si64 türündeki sabit (C11), (C13-C14)
(I10) input_spatial_dimensions si64 türünde 1 boyutlu tensör sabiti (C12), (C13), (C25)
(I11) kernel_input_feature_dimension si64 türündeki sabit (C14), (C18)
(I12) kernel_output_feature_dimension si64 türündeki sabit (C15-C16), (C18), (C25), (C29)
(I13) kernel_spatial_dimensions si64 türünde 1 boyutlu tensör sabiti (C17-C18), (C25)
(I14) output_batch_dimension si64 türündeki sabit (C20), (C25)
(I15) output_feature_dimension si64 türündeki sabit (C20), (C25), (C30)
(I16) output_spatial_dimensions si64 türünde 1 boyutlu tensör sabiti (C19-C20), (C25)
(I17) feature_group_count si64 türündeki sabit (C11), (C14), (C16), (C21), (C23)
(I18) batch_group_count si64 türündeki sabit (C10), (C15), (C22), (C23), (C25)
(I19) precision_config DEFAULT, HIGH ve HIGHEST sıralamalarının değişken sayısı (C24)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C25-C28), (C30), (C32-34)

Sınırlamalar

  • (C1) N = rank(lhs) = rank(rhs).
  • (C2) size(window_strides) = N - 2.
  • (C3) 0 < window_strides.
  • (C4) shape(padding) = [N - 2, 2]
  • (C5) size(lhs_dilation) = N - 2
  • (C6) 0 < lhs_dilation.
  • (C7) size(rhs_dilation) = N - 2.
  • (C8) 0 < rhs_dilation
  • (C9) size(window_reversal) = N - 2.
  • (C10) dim(lhs, input_batch_dimension) % batch_group_count = 0
  • (C11) dim(lhs, input_feature_dimension) % feature_group_count = 0
  • (C12) size(input_spatial_dimensions) = N - 2
  • (C13) input_dimensions = [input_batch_dimension] + input_spatial_dimensions + [input_feature_dimension] ile ilgili:
    • is_unique(input_dimensions).
    • 0 <= input_dimensions < N.
  • (C14) dim(rhs, kernel_input_feature_dimension) = dim(lhs, input_feature_dimension) / feature_group_count
  • (C15) dim(rhs, kernel_output_feature_dimension) % batch_group_count = 0
  • (C16) dim(rhs, kernel_output_feature_dimension) % feature_group_count = 0
  • (C17) size(kernel_spatial_dimensions) = N - 2
  • (C18) kernel_dimensions = kernel_spatial_dimensions + [kernel_input_feature_dimension] + [kernel_output_feature_dimension] ile ilgili:
    • is_unique(kernel_dimensions).
    • 0 <= kernel_dimensions < N.
  • (C19) size(output_spatial_dimensions) = N - 2
  • (C20) output_dimensions = [output_batch_dimension] + output_spatial_dimensions + [output_feature_dimension] ile ilgili:
    • is_unique(output_dimensions).
    • 0 <= output_dimensions < N.
  • (C21) 0 < feature_group_count
  • (C22) 0 < batch_group_count
  • (C23) feature_group_count = 1 or batch_group_count = 1
  • (C24) size(precision_config) = 2
  • (C25) dim(result, result_dim) şu şekilde tanımlanır:
    • result_dim = output_batch_dimension ise dim(lhs, input_batch_dimension) / batch_group_count.
    • result_dim = output_feature_dimension ise dim(rhs, kernel_output_feature_dimension).
    • Aksi takdirde, şu koşullarda num_windows:
    • output_spatial_dimensions[spatial_dim] = result_dim.
    • lhs_dim = input_spatial_dimensions[spatial_dim].
    • rhs_dim = kernel_spatial_dimensions[spatial_dim].
    • dilated_input_shape[lhs_dim] = dim(lhs, lhs_dim) = 0 ? 0 : (dim(lhs, lhs_dim) - 1) * lhs_dilation[spatial_dim] + 1.
    • padded_input_shape[lhs_dim] = padding[spatial_dim, 0] + dilated_input_shape[lhs_dim] + padding[spatial_dim, 1].
    • dilated_window_shape[lhs_dim] = dim(rhs, rhs_dim) = 0 ? 0 : (dim(rhs, rhs_dim) - 1) * rhs_dilation[spatial_dim] + 1.
    • is_empty_window[lhs_dim] = padded_input_shape[lhs_dim] = 0 || dilated_window_shape[lhs_dim] > padded_input_shape[lhs_dim].
    • num_windows = is_empty_window[lhs_dim] ? 0 : floor((padded_input_shape[lhs_dim] - dilated_window_shape[lhs_dim]) / window_strides[spatial_dim]) + 1.
  • (C26) rank(result) = N
  • İşlemde miktarlandırılmamış tensörler kullanılıyorsa:
    • (C27) element_type(lhs) = element_type(rhs) = element_type(result)
  • İşlemde nicel tensörler kullanılıyorsa:
    • (C28) is_quantized(lhs) = is_quantized(result) and is_quantized(rhs)
    • (C29) is_per_axis_quantized(rhs) ise ardından quantization_dimension(rhs) = kernel_output_feature_dimension.
    • (C30) is_per_axis_quantized(result) ise quantization_dimension(result) = output_feature_dimension.
    • Eğer is_quantized(lhs):
    • (C31) storage_type(lhs) = storage_type(rhs)
    • (C32) expressed_type(lhs) = expressed_type(rhs) = expressed_type(result)
    • (C33) is_per_tensor_quantized(rhs) ise is_per_tensor_quantized(result).
    • Eğer !is_quantized(lhs):
    • (C34) element_type(lhs) = expressed_type(rhs) = element_type(result).

Örnekler

// %lhs: [[
//        [
//          [1], [2], [5], [6]
//        ],
//        [
//          [3], [4], [7], [8]
//        ],
//        [
//          [10], [11], [14], [15]
//        ],
//        [
//          [12], [13], [16], [17]
//        ]
//      ]]
//
// %rhs: [
//        [[[1]], [[1]], [[1]]],
//        [[[1]], [[1]], [[1]]],
//        [[[1]], [[1]], [[1]]]
//       ]
%result = "stablehlo.convolution"(%lhs, %rhs) {
  window_strides = array<i64: 4, 4>,
  padding = dense<0> : tensor<2x2xi64>,
  lhs_dilation = array<i64: 2, 2>,
  rhs_dilation = array<i64: 1, 1>,
  window_reversal = array<i1: false, false>,
  // In the StableHLO dialect, dimension numbers are encoded via:
  // `[<input dimensions>]x[<kernel dimensions>]->[output dimensions]`.
  // "b" is batch dimension, "f" is feature dimension,
  // "i" is input feature dimension, "o" is output feature dimension,
  // "0/1/etc" are spatial dimensions.
  dimension_numbers = #stablehlo.conv<[b, 0, 1, f]x[0, 1, i, o]->[b, 0, 1, f]>,
  batch_group_count = 1 : i64,
  feature_group_count = 1 : i64,
  precision_config = [#stablehlo<precision DEFAULT>, #stablehlo<precision DEFAULT>]
} : (tensor<1x4x4x1xi64>, tensor<3x3x1x1xi64>) -> tensor<1x2x2x1xi64>
// %result: [[
//            [[10], [26]],
//            [[46], [62]]
//          ]]

Diğer Örnekler

kosinüs

Anlam

operand tensörü üzerinde element düzeyinde kosinüs işlemi gerçekleştirir ve bir result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten cos.
  • Karmaşık sayılar için: karmaşık kosinüs.
  • Miktarlanmış türler için: dequantize_op_quantize(cosine, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [
//            [0.0, 1.57079632],       // [0, pi/2]
//            [3.14159265, 4.71238898] // [pi, 3pi/2]
//           ]
%result = "stablehlo.cosine"(%operand) : (tensor<2x2xf32>) -> tensor<2x2xf32>
// %result: [[1.0, 0.0], [-1.0, 0.0]]

Diğer Örnekler

count_leading_zeros

Anlam

operand hücresinin başındaki sıfır bit sayısını öğe bazında sayar ve bir result tensörü üretir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tam sayı türündeki tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı türündeki tensör (C1)

Sınırlamalar

  • (C1) type(operand) = type(result).

Örnekler

// %operand: [[0, 1], [128, -1]]
%result = "stablehlo.count_leading_zeros"(%operand) : (tensor<2x2xi64>) -> tensor<2x2xi64>
// %result: [[64, 63], [56, 0]]

Diğer Örnekler

custom_call

Anlam

Aşağıdaki işlemler için gereken uygulama tanımlı call_target_name işlemini içerir: inputs ve called_computations ile results üretir. has_side_effect, backend_config ve api_version, ek bilgi sağlamak için kullanılabilir. meta verilerdir.

Şu anda bu işlem oldukça dağınık bir meta verileridir. Meta veriler XLA derleyicisi olur. Gelecekte bu meta verileri birleştirmeyi planlıyoruz. (#741).

Girişler

Şirket Ad Tür
(I1) inputs değişken değer sayısı
(I2) call_target_name string türündeki sabit
(I3) has_side_effect i1 türündeki sabit
(I4) backend_config string türünün sabiti veya özellik sözlüğü
(I5) api_version si32 türündeki sabit
(I6) called_computations string türündeki değişken sabit sayı

Çıkışlar

Ad Tür
results değişken değer sayısı

Örnekler

%results = "stablehlo.custom_call"(%input0) {
  call_target_name = "foo",
  has_side_effect = false,
  backend_config = {bar = 42 : i32},
  api_version = 4 : i32,
  called_computations = [@foo]
} : (tensor<f64>) -> tensor<f64>

bölü

Anlam

lhs bölünme ve bölünen rhs tensörlerini element düzeyinde böler ve bir result tensörü üretir. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Tam sayılar için: herhangi bir sayıdaki cebirsel bölümü oluşturan tam sayı bölme kısmen silindi.
  • Kayan reklamlar için: IEEE-754'ten division.
  • Karmaşık sayılar için: karmaşık bölme.
  • Ölçülen türler için:
    • dequantize_op_quantize(divide, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)
(I2) rhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(lhs) = baseline_type(rhs) = baseline_type(result).

Örnekler

// %lhs: [17.1, -17.1, 17.1, -17.1]
// %rhs: [3.0, 3.0, -3.0, -3.0]
%result = "stablehlo.divide"(%lhs, %rhs) : (tensor<4xf32>, tensor<4xf32>) -> tensor<4xf32>
// %result: [5.66666651, -5.66666651, -5.66666651, 5.66666651]

Diğer Örnekler

dot_general

Anlam

lhs dilimleri ile rhs dilimleri arasındaki nokta ürünlerini hesaplar ve result tensörü.

Daha resmi olarak, result[result_index] = dot_product, burada:

  • lhs_result_dimensions = [d for d in axes(lhs) and d not in lhs_batching_dimensions and d not in lhs_contracting_dimensions].
  • rhs_result_dimensions = [d for d in axes(rhs) and d not in rhs_batching_dimensions and d not in rhs_contracting_dimensions].
  • result_batching_index + result_lhs_index + result_rhs_index = result_index. burada size(result_batching_index) = size(lhs_batching_dimensions), size(result_lhs_index) = size(lhs_result_dimensions) ve size(result_rhs_index) = size(rhs_result_dimensions).
  • transposed_lhs = transpose(lhs, lhs_batching_dimensions + lhs_result_dimensions + lhs_contracting_dimensions).
  • transposed_lhs_slice = slice(transposed_lhs, result_batching_index + result_lhs_index + [:, ..., :]).
  • reshaped_lhs_slice = reshape(transposed_lhs_slice, dims(lhs, lhs_contracting_dimensions)).
  • transposed_rhs = transpose(rhs, rhs_batching_dimensions + rhs_result_dimensions + rhs_contracting_dimensions).
  • transposed_rhs_slice = slice(transposed_rhs, result_batching_index + result_rhs_index + [:, ..., :]).
  • reshaped_rhs_slice = reshape(transposed_rhs_slice, dims(rhs, rhs_contracting_dimensions)).
  • dot_product = reduce( inputs=[multiply(reshaped_lhs_slice, reshaped_rhs_slice)], init_values=[constant(0, element_type(result))], dimensions=range(size(lhs_contracting_dimensions)), body=lambda x, y: add(x, y))

Miktarı ölçülmüş türlerde, dequantize_op_quantize( lambda lhs, rhs: dot_general(lhs, rhs, lhs_batching_dimensions, rhs_batching_dimensions, lhs_contracting_dimensions, rhs_contracting_dimensions, precision_config), lhs, rhs, type(result)) gerçekleştirir.

Karma miktarlandırılmış türlerde hybrid_dequantize_then_op( lambda lhs, rhs: dot_general(lhs, rhs, lhs_batching_dimensions, rhs_batching_dimensions, lhs_contracting_dimensions, rhs_contracting_dimensions, precision_config), lhs, rhs) performans gösterir.

precision_config, veriler için hız ile doğruluk arasındaki dengeyi kontrol eder hesaplamalarına yardımcı olur. Bu, aşağıdakilerden biri olabilir ( bu sıralama değerlerinin anlamı eksik olsa da, bu konuyu ele almayı #755):

  • DEFAULT: En hızlı hesaplama, ancak orijinal sayı.
  • HIGH: Hesaplama daha yavaştır ancak orijinal sayı.
  • HIGHEST: En yavaş hesaplama, ancak hedefe en doğru tahmin orijinal sayı.

DotAlgorithm, aşağıdakileri uygulamak için kullanılan algoritmanın ana özelliklerini tanımlar: nokta işlemidir. Bu işlem, hassasiyeti de tanımlar. Algoritma alanları ayarlanırsa precision_config, DEFAULT olmalıdır. DotAlgorithms. varsayılan parametreler uygulandığından, varsayılan bir değere sahip değildir tanımlanmıştır. Bu nedenle, tüm nokta algoritması alanları None olarak ayarlanabilir boş nokta algoritması bulunur. Bunun yerine, precision_config değeri kullanılır.

DotAlgorithm alanları şunları içerir:

  • lhs_precision_type ve rhs_precision_type, LHS ve LHS ile İşlemin sağ tarafı yuvarlanır. Hassasiyet türleri giriş ve çıkışların depolama türleri.
  • accumulation_type, toplama için kullanılan hassasiyet.
  • lhs_component_count, rhs_component_count ve num_primitive_operations ve/veya RHS'yi ayıran bir algoritma yaptığımızda uygulanır. birden fazla bileşene sahip ve birden çok "temel" öğe bu satırlarda genellikle daha yüksek bir hassasiyet emülasyonu yapmak için (ör. Daha Yüksek Hassasiyetli Hesaplamalar İçin bfloat16 Yapay Zeka Veri Türünden Yararlanma: bf16_6x tf32_3x vb.) Ayrıştırılması olmayan algoritmalar için bu değerler 1 olarak ayarlanmalıdır.
  • Toplama işleminin daha düşük kesinlikte olup olmadığını belirtmek için allow_imprecise_accumulation bazı adımlarda izin verilir (ör. CUBLASLT_MATMUL_DESC_FAST_ACCUM).

Örnek DotAlgorithm özellikleri:

// Inputs are casted to tf32, and then accumulated in f32:
{lhs_precision_type = tf32,
 rhs_precision_type = tf32,
 accumulation_type = f32,
 lhs_component_count = 1,
 rhs_component_count = 1,
 num_primitive_operations = 1,
 allow_imprecise_accumulation = false}


// bf16_6x: each input is decomposed to 3 bf16 components, then 6 dot operations are done on those components, and the result is accumulated in f32.
{lhs_precision_type = bf16,
 rhs_precision_type = bf16,
 accumulation_type = f32,
 lhs_component_count = 3,
 rhs_component_count = 3,
 num_primitive_operations = 6,
 allow_imprecise_accumulation = false}


// Inputs are (casted to) f8e5m2, and we accumulate in f32, but for some steps we may accumulate in lower precision.
{lhs_precision_type = f8e5m2,
 rhs_precision_type = f8e5m2,
 accumulation_type = f32,
 lhs_component_count = 1,
 rhs_component_count = 1,
 num_primitive_operations = 1,
 allow_imprecise_accumulation = true}

Hangi kombinasyonların desteklendiğine karar vermek uygulamalara bağlıdır. İçinde her algoritmanın tek bir algoritmada desteklendiği garanti edilmez. hızlandırıcı türünü ayarlayın. Belirli bir algoritma geri dönmek yerine bir hata alternatifidir. StableHLO doğrulaması mümkün olan en iyi doğrulamayı sağlar. herhangi bir donanımda desteklenmediği bilinen algoritmaları önleme amaçlıdır.

Bkz. xla_data.proto > Algorithm . 2483 numaralı bilet, bir olası satış yaratma planını algoritmalarla ilgili merkezi bir belge hazırladık.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya tensör başına miktarlandırılmış tensör (C5-C6), (C9-C10), (C12-C14), (C17-C18), (C20)
(I2) rhs tensör veya nicel tensör (C7-C10), (C12-C20)
(I3) lhs_batching_dimensions si64 türünde 1 boyutlu tensör sabiti (C1), (C3), (C5), (C9), (C12)
(I4) rhs_batching_dimensions si64 türünde 1 boyutlu tensör sabiti (C1), (C4), (C7), (C9)
(I5) lhs_contracting_dimensions si64 türünde 1 boyutlu tensör sabiti (C2), (C3), (C6), (C10)
(I6) rhs_contracting_dimensions si64 türünde 1 boyutlu tensör sabiti (C2), (C4), (C8), (C10), (C16)
(I7) precision_config DEFAULT, HIGH ve HIGHEST sıralamalarının değişken sayısı (C11), (C21)
(I8) lhs_precision_type floatType veya Tensorfloat32 (C21)
(I9) rhs_precision_type floatType veya Tensorfloat32 (C21)
(I10) accumulation_type floatType veya Tensorfloat32 (C21)
(I11) lhs_component_count si32 türündeki sabit (C21), (C22)
(I12) rhs_component_count si32 türündeki sabit (C21), (C23)
(I13) num_primitive_operations si32 türündeki sabit (C21), (C24)
(I14) allow_imprecise_accumulation bool türündeki sabit (C21)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C12), (C14), (C18-C20)

Sınırlamalar

  • (C1) size(lhs_batching_dimensions) = size(rhs_batching_dimensions).
  • (C2) size(lhs_contracting_dimensions) = size(rhs_contracting_dimensions).
  • (C3) is_unique(lhs_batching_dimensions + lhs_contracting_dimensions).
  • (C4) is_unique(rhs_batching_dimensions + rhs_contracting_dimensions)
  • (C5) 0 <= lhs_batching_dimensions < rank(lhs)
  • (C6) 0 <= lhs_contracting_dimensions < rank(lhs).
  • (C7) 0 <= rhs_batching_dimensions < rank(rhs).
  • (C8) 0 <= rhs_contracting_dimensions < rank(rhs)
  • (C9) dim(lhs, lhs_batching_dimensions...) = dim(rhs, rhs_batching_dimensions...).
  • (C10) dim(lhs, lhs_contracting_dimensions...) = dim(rhs, rhs_contracting_dimensions...)
  • (C11) size(precision_config) = 2
  • (C12) shape(result) = dim(lhs, lhs_batching_dimensions) + dim(lhs, lhs_result_dimensions) + dim(rhs, rhs_result_dimensions)
  • İşlemde miktarlandırılmamış tensörler kullanılıyorsa:
    • (C13) element_type(lhs) = element_type(rhs)
  • İşlemde nicel tensörler kullanılıyorsa:
    • (C14) is_quantized(lhs) = is_quantized(result) and is_quantized(rhs)
    • (C15) zero_points(rhs) = 0
    • (C16) is_per_axis_quantized(rhs) ise quantization_dimension(rhs), rhs_contracting_dimensions içinde yer almıyor.
    • Eğer is_quantized(lhs):
    • (C17) storage_type(lhs) = storage_type(rhs)
    • (C18) expressed_type(lhs) = expressed_type(rhs) = expressed_type(result)
    • (C19) is_per_tensor_quantized(rhs) ise is_per_tensor_quantized(result).
    • Eğer !is_quantized(lhs):
    • (C20) element_type(lhs) = expressed_type(rhs) = element_type(result).
  • Eğer !is_empty_algorithm(lhs_precision_type, rhs_precision_type, accumulation_type, lhs_component_count, rhs_component_count, num_primitive_operations allow_imprecise_accumulation):
    • (C21) precision_config... = DEFAULT
    • (C22) 0 < lhs_component_count
    • (C23) 0 < rhs_component_count
    • (C24) 0 < num_primitive_operations

Örnekler

// %lhs: [
//        [[1, 2],
//         [3, 4]],
//        [[5, 6],
//         [7, 8]]
//       ]
// %rhs: [
//        [[1, 0],
//         [0, 1]],
//        [[1, 0],
//         [0, 1]]
//       ]
%result = "stablehlo.dot_general"(%lhs, %rhs) {
  dot_dimension_numbers = #stablehlo.dot<
    lhs_batching_dimensions = [0],
    rhs_batching_dimensions = [0],
    lhs_contracting_dimensions = [2],
    rhs_contracting_dimensions = [1]
  >,
  precision_config = [#stablehlo<precision DEFAULT>, #stablehlo<precision DEFAULT>],
  algorithm = #stablehlo.dot_algorithm<
    lhs_precision_type = tf32,
    rhs_precision_type = tf32,
    accumulation_type = f32,
    lhs_component_count = 1,
    rhs_component_count = 1,
    num_primitive_operations = 1,
    allow_imprecise_accumulation = false
  >
} : (tensor<2x2x2xi64>, tensor<2x2x2xi64>) -> tensor<2x2x2xi64>
// %result: [
//           [[1, 2],
//            [3, 4]],
//           [[5, 6],
//            [7, 8]]
//          ]

Diğer Örnekler

dynamic_broadcast_in_dim

Anlam

Bu işlem işlevsel olarak broadcast_in_dim op, ancak sonuç şekli output_dimensions aracılığıyla dinamik olarak belirtilir.

İşlemde isteğe bağlı known_expanding_dimensions, known_non_expanding_dimensions özellikleri de kabul edilir. , boyutların genişleme davranışı hakkındaki statik bilgiyi ifade etmek için kullanılır. Belirtilmezse tüm boyutların genişlemiş olabileceği varsayılır.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya nicel tensör (C1-C2), (C5-C6), (C9)
(I2) output_dimensions Tam sayı türünde 1 boyutlu tensör (C7)
(I3) broadcast_dimensions Tam sayı türünde 1 boyutlu sabit tensör (C2-C6)
(I4) known_expanding_dimensions Tam sayı türünde 1 boyutlu sabit tensör (C8-C9)
(I5) known_non_expanding_dimensions Tam sayı türünde 1 boyutlu sabit tensör (C8-C9)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C1), (C3), (C5-C7)

Sınırlamalar

  • (C1) element_type(result) değerini sağlayan:
    • !is_per_axis_quantized(operand) ise element_type(operand).
    • element_type(operand) (bu quantization_dimension(operand) hariç) scales(operand) ve zero_points(operand) şundan farklı olabilir: quantization_dimension(result), scales(result) ve zero_points(result) resp., aksi takdirde.
  • (C2) size(broadcast_dimensions) = rank(operand).
  • (C3) 0 <= broadcast_dimensions < rank(result).
  • (C4) is_unique(broadcast_dimensions)
  • (C5) axes(operand) bünyesindeki tüm d için:
    • dim(operand, d) = 1 veya
    • dim(operand, d) = dim(result, broadcast_dimensions[d]).
  • (C6) is_per_axis_quantized(result) ise:
    • quantization_dimension(result) = broadcast_dimensions[quantization_dimension(operand)].
    • dim(operand, quantization_dimension(operand)) = 1 ise, scales(result)[i] = scales(operand)[0] and zero_points(result)[i] = zero_points(operand)[0] for i in range(dim(result, quantization_dimension(result))).
  • (C7) size(output_dimensions) = rank(result).
  • (C8) is_unique(known_expanding_dimensions + known_non_expanding_dimensions)
  • (C9) 0 <= known_expanding_dimensions < rank(operand).
  • (C10) 0 <= known_non_expanding_dimensions < rank(operand)

Örnekler

// %operand: [
//            [1, 2, 3]
//           ]
%operand = stablehlo.constant dense<[[1, 2, 3]]> : tensor<1x3xi64>
%output_dimensions = stablehlo.constant dense<[2, 3, 2]> : tensor<3xi64>
%result = "stablehlo.dynamic_broadcast_in_dim"(%operand, %output_dimensions) {
  broadcast_dimensions = array<i64: 2, 1>,
  known_expanding_dimensions = array<i64: 0>,
  known_non_expanding_dimensions = array<i64: 1>
} : (tensor<1x3xi64>, tensor<3xi64>) -> tensor<2x3x2xi64>
// %result: [
//            [
//             [1, 1],
//             [2, 2],
//             [3, 3]
//            ],
//            [
//             [1, 1],
//             [2, 2],
//             [3, 3]
//            ]
//          ]

Diğer Örnekler

dynamic_conv

Anlam

Bu işlem işlevsel olarak konvolüsyon ancak dolgu padding aracılığıyla dinamik olarak belirtilir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya tensör başına miktarlandırılmış tensör (C1), (C10-C11), (C14) (C25), (C26-C27), (C30-C31), (C33)
(I2) rhs tensör veya nicel tensör (C1), (C14-C16), (C26-C28), (C30-C33)
(I3) padding Tam sayı türünde 2 boyutlu tensör (C4)
(I4) window_strides si64 türünde 1 boyutlu tensör sabiti (C2-C3)
(I5) lhs_dilation si64 türünde 1 boyutlu tensör sabiti (C5-C6)
(I6) rhs_dilation si64 türünde 1 boyutlu tensör sabiti (C7-C8)
(I7) window_reversal i1 türünde 1 boyutlu tensör sabiti (C9)
(I8) input_batch_dimension si64 türündeki sabit (C10), (C13)
(I9) input_feature_dimension si64 türündeki sabit (C11), (C13-C14)
(I10) input_spatial_dimensions si64 türünde 1 boyutlu tensör sabiti (C12), (C13)
(I11) kernel_input_feature_dimension si64 türündeki sabit (C14), (C18)
(I12) kernel_output_feature_dimension si64 türündeki sabit (C15-C16), (C18), (C28)
(I13) kernel_spatial_dimensions si64 türünde 1 boyutlu tensör sabiti (C17-C18)
(I14) output_batch_dimension si64 türündeki sabit (C20)
(I15) output_feature_dimension si64 türündeki sabit (C20), (C29)
(I16) output_spatial_dimensions si64 türünde 1 boyutlu tensör sabiti (C19-C20)
(I17) feature_group_count si64 türündeki sabit (C11), (C14), (C16), (C21), (C23)
(I18) batch_group_count si64 türündeki sabit (C10), (C15), (C22), (C23)
(I19) precision_config DEFAULT, HIGH ve HIGHEST sıralamalarının değişken sayısı (C24)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C25-C27), (C29), (C31-C33)

Sınırlamalar

  • (C1) N = rank(lhs) = rank(rhs).
  • (C2) size(window_strides) = N - 2.
  • (C3) 0 < window_strides.
  • (C4) shape(padding) = [N - 2, 2]
  • (C5) size(lhs_dilation) = N - 2
  • (C6) 0 < lhs_dilation.
  • (C7) size(rhs_dilation) = N - 2.
  • (C8) 0 < rhs_dilation
  • (C9) size(window_reversal) = N - 2.
  • (C10) dim(lhs, input_batch_dimension) % batch_group_count = 0
  • (C11) dim(lhs, input_feature_dimension) % feature_group_count = 0
  • (C12) size(input_spatial_dimensions) = N - 2
  • (C13) input_dimensions = [input_batch_dimension] + input_spatial_dimensions + [input_feature_dimension] ile ilgili:
    • is_unique(input_dimensions).
    • 0 <= input_dimensions < N.
  • (C14) dim(rhs, kernel_input_feature_dimension) = dim(lhs, input_feature_dimension) / feature_group_count
  • (C15) dim(rhs, kernel_output_feature_dimension) % batch_group_count = 0
  • (C16) dim(rhs, kernel_output_feature_dimension) % feature_group_count = 0
  • (C17) size(kernel_spatial_dimensions) = N - 2
  • (C18) kernel_dimensions = kernel_spatial_dimensions + [kernel_input_feature_dimension] + [kernel_output_feature_dimension] ile ilgili:
    • is_unique(kernel_dimensions).
    • 0 <= kernel_dimensions < N.
  • (C19) size(output_spatial_dimensions) = N - 2
  • (C20) output_dimensions = [output_batch_dimension] + output_spatial_dimensions + [output_feature_dimension] ile ilgili:
    • is_unique(output_dimensions).
    • 0 <= output_dimensions < N.
  • (C21) 0 < feature_group_count
  • (C22) 0 < batch_group_count
  • (C23) feature_group_count = 1 or batch_group_count = 1
  • (C24) size(precision_config) = 2
  • (C25) dim(result, result_dim) şu şekilde tanımlanır:
    • result_dim = output_batch_dimension ise dim(lhs, input_batch_dimension) / batch_group_count.
    • result_dim = output_feature_dimension ise dim(rhs, kernel_output_feature_dimension).
    • Aksi takdirde, şu koşullarda num_windows:
    • output_spatial_dimensions[spatial_dim] = result_dim.
    • lhs_dim = input_spatial_dimensions[spatial_dim].
    • rhs_dim = kernel_spatial_dimensions[spatial_dim].
    • dilated_input_shape[lhs_dim] = dim(lhs, lhs_dim) = 0 ? 0 : (dim(lhs, lhs_dim) - 1) * lhs_dilation[spatial_dim] + 1.
    • padded_input_shape[lhs_dim] = padding[spatial_dim, 0] + dilated_input_shape[lhs_dim] + padding[spatial_dim, 1].
    • dilated_window_shape[lhs_dim] = dim(rhs, rhs_dim) = 0 ? 0 : (dim(rhs, rhs_dim) - 1) * rhs_dilation[spatial_dim] + 1.
    • is_empty_window[lhs_dim] = padded_input_shape[lhs_dim] = 0 || dilated_window_shape[lhs_dim] > padded_input_shape[lhs_dim].
    • num_windows = is_empty_window[lhs_dim] ? 0 : floor((padded_input_shape[lhs_dim] - dilated_window_shape[lhs_dim]) / window_strides[spatial_dim]) + 1.
  • (C26) rank(result) = N
  • İşlemde miktarlandırılmamış tensörler kullanılıyorsa:
    • (C27) element_type(lhs) = element_type(rhs) = element_type(result)
  • İşlemde nicel tensörler kullanılıyorsa:
    • (C28) is_quantized(lhs) = is_quantized(result) and is_quantized(rhs)
    • (C29) is_per_axis_quantized(rhs) ise ardından quantization_dimension(rhs) = kernel_output_feature_dimension.
    • (C30) is_per_axis_quantized(result) ise quantization_dimension(result) = output_feature_dimension.
    • Eğer is_quantized(lhs):
    • (C31) storage_type(lhs) = storage_type(rhs)
    • (C32) expressed_type(lhs) = expressed_type(rhs) = expressed_type(result)
    • (C33) is_per_tensor_quantized(rhs) ise is_per_tensor_quantized(result).
    • Eğer !is_quantized(lhs):
    • (C34) element_type(lhs) = expressed_type(rhs) = element_type(result).

Örnekler

// %lhs: [[
//        [[1], [2], [5], [6]],
//        [[3], [4], [7], [8]],
//        [[10], [11], [14], [15]],
//        [[12], [13], [16], [17]]
//      ]]
//
// %rhs: [
//         [[[1]], [[1]], [[1]]],
//         [[[1]], [[1]], [[1]]],
//         [[[1]], [[1]], [[1]]]
//        ]
// %padding: [[1, 1],
//            [1, 1]]
%result = "stablehlo.dynamic_conv"(%lhs, %rhs, %padding) {
  window_strides = array<i64: 4, 4>,
  lhs_dilation = array<i64: 2, 2>,
  rhs_dilation = array<i64: 1, 1>,
  window_reversal = array<i1: false, false>,
  dimension_numbers = #stablehlo.conv<raw
    input_batch_dimension = 0,
    input_feature_dimension = 3,
    input_spatial_dimensions = [0, 1],
    kernel_input_feature_dimension = 2,
    kernel_output_feature_dimension = 3,
    kernel_spatial_dimensions = [0, 1],
    output_batch_dimension = 0,
    output_feature_dimension = 3,
    output_spatial_dimensions = [1, 2]
  >,
  feature_group_count = 1 : i64,
  batch_group_count = 1 : i64,
  precision_config = [#stablehlo<precision DEFAULT>, #stablehlo<precision DEFAULT>]
} : (tensor<1x4x4x1xi64>, tensor<3x3x1x1xi64>, tensor<2x2xi64>) -> tensor<1x2x2x1xi64>
// %result: [[
//            [[1], [5]],
//            [[10], [14]]
//          ]]

Diğer Örnekler

dynamic_gather

Anlam

Bu işlem işlevsel olarak topla slice_sizes ile dinamik bir şekilde değer olarak belirtilir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1), (C7), (C10-C12), (C14)
(I2) start_indices tam sayı türündeki tensör (C2), (C3), (C13)
(I3) slice_sizes Tam sayı türünde 1 boyutlu tensör (C8), (C11-C13)
(I4) offset_dims si64 türünde 1 boyutlu tensör sabiti (C1), (C4-C5), (C13)
(I5) collapsed_slice_dims si64 türünde 1 boyutlu tensör sabiti (C1), (C6-C8), (C13)
(I6) start_index_map si64 türünde 1 boyutlu tensör sabiti (C3), (C9), (C10)
(I7) index_vector_dim si64 türündeki sabit (C2), (C3), (C13)
(I8) indices_are_sorted i1 türündeki sabit

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C5), (C13-C14)

Sınırlamalar

  • (C1) rank(operand) = size(offset_dims) + size(collapsed_slice_dims).
  • (C2) 0 <= index_vector_dim <= rank(start_indices).
  • (C3) size(start_index_map) = index_vector_dim < rank(start_indices) ? dim(start_indices, index_vector_dim) : 1.
  • (C4) is_unique(offset_dims) and is_sorted(offset_dims)
  • (C5) 0 <= offset_dims < rank(result)
  • (C6) is_unique(collapsed_slice_dims) and is_sorted(collapsed_slice_dims).
  • (C7) 0 <= collapsed_slice_dims < rank(operand).
  • (C8) slice_sizes[collapsed_slice_dims...] <= 1
  • (C9) is_unique(start_index_map).
  • (C10) 0 <= start_index_map < rank(operand)
  • (C11) size(slice_sizes) = rank(operand)
  • (C12) 0 <= slice_sizes <= shape(operand)
  • (C13) shape(result) = combine(batch_dim_sizes, offset_dim_sizes); burada:
    • batch_dim_sizes = shape(start_indices) (boyut boyutu hariç) index_vector_dim öğesine karşılık gelen start_indices dahil edilmemiştir.
    • offset_dim_sizes = shape(slice_sizes) (boyut boyutları hariç) 'deki slice_sizes dilindeki collapsed_slice_dims dahil edilmemiştir.
    • combine, batch_dim_sizes değerini batch_dims ve offset_dims değerine karşılık gelen eksenlerde offset_dim_sizes.
  • (C14) element_type(operand) = element_type(result)

Örnekler

// %operand: [
//            [[1, 2], [3, 4], [5, 6], [7, 8]],
//            [[9, 10],[11, 12], [13, 14], [15, 16]],
//            [[17, 18], [19, 20], [21, 22], [23, 24]]
//           ]
// %start_indices: [
//                  [[0, 0], [1, 0], [2, 1]],
//                  [[0, 1], [1, 1], [0, 2]]
//                 ]
// %slize_sizes: [1, 2, 2]
%result = "stablehlo.dynamic_gather"(%operand, %start_indices, %slize_sizes) {
  dimension_numbers = #stablehlo.gather<
    offset_dims = [2, 3],
    collapsed_slice_dims = [0],
    start_index_map = [1, 0],
    index_vector_dim = 2>,
  indices_are_sorted = false
} : (tensor<3x4x2xi64>, tensor<2x3x2xi64>, tensor<3xi64>) -> tensor<2x3x2x2xi64>
// %result: [
//            [
//              [[1, 2], [3, 4]],
//              [[3, 4], [5, 6]],
//              [[13, 14], [15, 16]]
//            ],
//            [
//              [[9, 10], [11, 12]],
//              [[11, 12], [13, 14]],
//              [[17, 18], [19, 20]]
//            ]
//          ]

Diğer Örnekler

dynamic_iota

Anlam

Bu işlem işlevsel olarak iota op, ancak sonuç şekli output_shape aracılığıyla dinamik olarak belirtilir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) output_shape Tam sayı türünde 1 boyutlu tensör (C1), (C2)
(I2) iota_dimension si64 (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C2)

Sınırlamalar

  • (C1) 0 <= iota_dimension < size(output_shape).
  • (C2) rank(result) = size(output_shape).

Örnekler

%output_shape = stablehlo.constant dense<[4, 5]> : tensor<2xi64>
%result = "stablehlo.dynamic_iota"(%output_shape) {
  iota_dimension = 0 : i64
} : (tensor<2xi64>) -> tensor<4x5xi64>
// %result: [
//           [0, 0, 0, 0, 0],
//           [1, 1, 1, 1, 1],
//           [2, 2, 2, 2, 2],
//           [3, 3, 3, 3, 3]
//          ]

Diğer Örnekler

dynamic_pad

Anlam

Bu işlem işlevsel olarak pad işlem, ancak edge_padding_low, edge_padding_high ve interior_padding ile şeklinde dinamik bir şekilde değer olarak belirtilir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1), (C2), (C4)
(I2) padding_value 0 boyutlu tensör veya tensör başına miktarlandırılmış tensör (C1)
(I3) edge_padding_low Tam sayı türünde 1 boyutlu tensör (C1), (C4)
(I4) edge_padding_high Tam sayı türünde 1 boyutlu tensör (C1), (C4)
(I5) interior_padding Tam sayı türünde 1 boyutlu tensör (C2-C4)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C3-C6)

Sınırlamalar

  • (C1) element_type(operand) = element_type(padding_value) = element_type(result).
  • (C2) size(edge_padding_low) = size(edge_padding_high) = size(interior_padding) = rank(operand).
  • (C3) 0 <= interior_padding.
  • (C4) shape(result) = shape(operand) + edge_padding_low + max(shape(operand) - 1, 0) * interior_padding + edge_padding_high

Örnekler

// %operand: [
//            [1, 2, 3],
//            [4, 5, 6]
//           ]
// %padding_value: 0
// %edge_padding_low: [0, 1]
// %edge_padding_high: [2, 1]
// %interior_padding: [1, 2]
%result = "stablehlo.dynamic_pad"(%operand, %padding_value,
  %edge_padding_low, %edge_padding_high, %interior_padding
) : (tensor<2x3xi64>, tensor<i64>, tensor<2xi64>, tensor<2xi64>, tensor<2xi64>) -> tensor<5x9xi64>
// %result: [
//           [0, 1, 0, 0, 2, 0, 0, 3, 0],
//           [0, 0, 0, 0, 0, 0, 0, 0, 0],
//           [0, 4, 0, 0, 5, 0, 0, 6, 0],
//           [0, 0, 0, 0, 0, 0, 0, 0, 0],
//           [0, 0, 0, 0, 0, 0, 0, 0, 0]
//          ]

Diğer Örnekler

dynamic_reshape

Anlam

Bu işlem işlevsel olarak yeniden şekillendirme op, ancak sonuç şekli output_shape aracılığıyla dinamik olarak belirtilir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya nicel tensör (C1-C3)
(I2) output_shape Tam sayı türünde 1 boyutlu tensör (C4)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C1-C4)

Sınırlamalar

  • (C1) element_type(result) değerini sağlayan:
    • !is_per_axis_quantized(operand) ise element_type(operand).
    • element_type(operand) yalnızca quantization_dimension(operand) ve Aksi takdirde quantization_dimension(result) farklı olabilir.
  • (C2) size(operand) = size(result).
  • (C3) is_per_axis_quantized(operand) ise:
    • reduce(dims(operand, [0, 1, ..., quantization_dimension(operand) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y) = reduce(dims(result, [0, 1, ..., quantization_dimension(result) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y).
    • dim(operand, quantization_dimension(operand)) = dim(result, quantization_dimension(result)).
    • reduce(dims(operand, [quantization_dimension(operand) + 1, ..., rank(operand) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y) = reduce(dims(result, [quantization_dimension(result) + 1, ..., rank(result) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y).
  • (C4) size(output_shape) = rank(result)

Örnekler

// %operand: [[1, 2, 3], [4, 5, 6]]
// %output_shape: [3, 2]
%result = "stablehlo.dynamic_reshape"(%operand, %output_shape) : (tensor<2x3xi64>, tensor<2xi64>) -> tensor<3x2xi64>
// %result: [[1, 2], [3, 4], [5, 6]]

Diğer Örnekler

dynamic_slice

Anlam

Dinamik olarak hesaplanan başlangıç dizinlerini kullanarak operand öğesinden bir dilim çıkarır ve bir result tensörü üretir. start_indices, şunun başlangıç dizinlerini içeriyor: olası düzenlemeye tabi her bir boyuta ait dilim ve slice_sizes her boyut için dilimin boyutlarını içermelidir. Daha resmi ifade etmek gerekirse result[result_index] = operand[operand_index]; burada:

  • adjusted_start_indices = clamp(0, start_indices, shape(operand) - slice_sizes).
  • operand_index = adjusted_start_indices + result_index.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1), (C2), (C4)
(I2) start_indices tam sayı türündeki 0 boyutlu tensörlerin değişken sayısı (C2), (C3)
(I3) slice_sizes si64 türünde 1 boyutlu tensör sabiti (C2), (C4), (C5)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1), (C5)

Sınırlamalar

  • (C1) element_type(operand) = element_type(result).
  • (C2) size(start_indices) = size(slice_sizes) = rank(operand).
  • (C3) same(type(start_indices...)).
  • (C4) 0 <= slice_sizes <= shape(operand)
  • (C5) shape(result) = slice_sizes

Örnekler

// %operand: [
//            [0, 0, 1, 1],
//            [0, 0, 1, 1],
//            [0, 0, 0, 0],
//            [0, 0, 0, 0]
//           ]
// %start_indices0: -1
// %start_indices1: 3
%result = "stablehlo.dynamic_slice"(%operand, %start_indices0, %start_indices1) {
  slice_sizes = array<i64: 2, 2>
} : (tensor<4x4xi32>, tensor<i64>, tensor<i64>) -> tensor<2x2xi32>
// %result: [
//           [1, 1],
//           [1, 1]
//          ]

Diğer Örnekler

dynamic_update_slice

Anlam

Şu hariç operand tensörüne eşit bir result tensörü üretir: start_indices ile başlayan dilim, update içindeki değerlerle güncellenir. Daha resmi olarak, result[result_index] şu şekilde tanımlanır:

  • 0 <= update_index < shape(update) ise update[update_index]:
    • adjusted_start_indices = clamp(0, start_indices, shape(operand) - shape(update)).
    • update_index = result_index - adjusted_start_indices.
  • Aksi takdirde operand[result_index].

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1-C4), (C6)
(I2) update tensör veya tensör başına miktarlandırılmış tensör (C2), (C3), (C6)
(I3) start_indices tam sayı türündeki 0 boyutlu tensörlerin değişken sayısı (C4), (C5)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1)

Sınırlamalar

  • (C1) type(operand) = type(result).
  • (C2) element_type(update) = element_type(operand).
  • (C3) rank(update) = rank(operand).
  • (C4) size(start_indices) = rank(operand)
  • (C5) same(type(start_indices...))
  • (C6) 0 <= shape(update) <= shape(operand).

Örnekler

// %operand: [
//            [1, 1, 0, 0],
//            [1, 1, 0, 0],
//            [1, 1, 1, 1],
//            [1, 1, 1, 1]
//           ]
// %update: [
//           [1, 1],
//           [1, 1]
//          ]
// %start_indices0: -1
// %start_indices1: 3
%result = "stablehlo.dynamic_update_slice"(%operand, %update, %start_indices0, %start_indices1)
  : (tensor<4x4xi32>, tensor<2x2xi32>, tensor<i64>, tensor<i64>) -> tensor<4x4xi32>
// %result: [
//           [1, 1, 1, 1],
//           [1, 1, 1, 1],
//           [1, 1, 1, 1],
//           [1, 1, 1, 1]
//          ]

Diğer Örnekler

üstel

Anlam

operand tensörü üzerinde öğe düzeyinde üstel işlem gerçekleştirir ve bir result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten exp.
  • Karmaşık sayılar için: karmaşık üstel.
  • Ölçülen türler için: dequantize_op_quantize(exponential, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [[0.0, 1.0], [2.0, 3.0]]
%result = "stablehlo.exponential"(%operand) : (tensor<2x2xf64>) -> tensor<2x2xf64>
// %result: [[1.0, 2.7182818284590451], [7.3890560989306504, 20.085536923187668]]

Diğer Örnekler

exponential_minus_one

Anlam

operand tensörü üzerinde öğe tabanlı üslü eksi bir işlem gerçekleştirir ve bir result tensörü üretir. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten expm1.
  • Karmaşık sayılar için: karmaşık üslü sayı eksi bir.
  • Ölçülen türler için: dequantize_op_quantize(exponential_minus_one, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [0.0, 1.0]
%result = "stablehlo.exponential_minus_one"(%operand) : (tensor<2xf64>) -> tensor<2xf64>
// %result: [0.0, 1.71828187]

Diğer Örnekler

fft

Anlam

Gerçek ve karmaşık süreçler için ileri ve ters Fourier dönüşümlerini gerçekleştirir giriş/çıkışları kontrol edin.

fft_type şunlardan biridir:

  • FFT: Karmaşıkdan karmaşık FFT'ye yönlendir.
  • IFFT: Ters karmaşıktan karmaşıka FFT.
  • RFFT: Gerçekten karmaşık FFT'yi yönlendir.
  • IRFFT: Ters gerçeğe dayalı FFT (ör. karmaşık alır, gerçek sonucu döndürür).

Daha resmi ifade etmek gerekirse, 1 boyutlu tensörleri alan fft fonksiyonu iki boyutlu tensörler üreterek aynı türde 1 boyutlu tensörler çıktısını verir ve ayrı Fourier dönüşümünü hesaplar:

fft_type = FFT için result, bir L dizisinin nihai sonucu olarak tanımlanır hesaplamalar için L = size(fft_length). Örneğin, L = 3 için:

  • result1[i0, ..., :] = fft(operand[i0, ..., :]).
  • result2[i0, ..., :, iR-1] = fft(result1[i0, ..., :, iR-1]).
  • result[i0, ..., :, iR-2, iR-1] = fft(result2[i0, ..., :, iR-2, iR-1]).

Ayrıca, aynı tür imzaya veifft fft değerinin tersini hesaplar:

fft_type = IFFT için result, hesaplamaların tersi olarak tanımlanır fft_type = FFT için. Örneğin, L = 3 için:

  • result1[i0, ..., :, iR-2, iR-1] = ifft(operand[i0, ..., :, iR-2, iR-1]).
  • result2[i0, ..., :, iR-1] = ifft(result1[i0, ..., :, iR-1]).
  • result[i0, ..., :] = ifft(result2[i0, ..., :]).

Ayrıca, 1 boyutlu tensörleri alan rfft fonksiyonu kayan nokta türleri, bir dizi karmaşık öğenin 1 boyutlu tensörlerini aynı kayan nokta semantiğiyle çalışır ve aşağıdaki gibi çalışır:

  • rfft(real_operand) = truncated_result burada:
  • complex_operand... = (real_operand..., 0.0).
  • complex_result = fft(complex_operand).
  • truncated_result = complex_result[:(rank(complex_result) / 2 + 1)].

(Gerçek işlenenler için ayrık Fourier dönüşümü hesaplandığında, Sonucun N/2 + 1 öğeleri, sonucun geri kalanını açık bir şekilde tanımlar. bu nedenle, gereksiz öğelerin hesaplamasını önlemek için rfft işlevinin sonucu kısaltılır.

fft_type = RFFT için result, bir L dizisinin nihai sonucu olarak tanımlanır hesaplamalar için L = size(fft_length). Örneğin, L = 3 için:

  • result1[i0, ..., :] = rfft(operand[i0, ..., :]).
  • result2[i0, ..., :, iR-1] = fft(result1[i0, ..., :, iR-1]).
  • result[i0, ..., :, iR-2, iR-1] = fft(result2[i0, ..., :, iR-2, iR-1]).

Son olarak, aynı tür imzaya veirfft rfft değerinin tersini hesaplar:

fft_type = IRFFT için result, hesaplamaların tersi olarak tanımlanır fft_type = RFFT için. Örneğin, L = 3 için:

  • result1[i0, ..., :, iR-2, iR-1] = ifft(operand[i0, ..., :, iR-2, iR-1]).
  • result2[i0, ..., :, iR-1] = ifft(result1[i0, ..., :, iR-1]).
  • result[i0, ..., :] = irfft(result2[i0, ..., :]).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık türde tensor (C1), (C2), (C4), (C5)
(I2) fft_type FFT, IFFT, RFFT ve IRFFT sıralaması (C2), (C5)
(I3) fft_length si64 türünde 1 boyutlu tensör sabiti (C1), (C3), (C4)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık türde tensor (C2), (C4), (C5)

Sınırlamalar

  • (C1) size(fft_length) <= rank(operand).
  • (C2) operand ile result öğe türleri arasındaki ilişki değişiklik gösterir:
    • Eğer fft_type = FFT, element_type(operand) ve element_type(result) aynı karmaşık türdedir.
    • Eğer fft_type = IFFT, element_type(operand) ve element_type(result) aynı karmaşık türdedir.
    • fft_type = RFFT ise element_type(operand) kayan nokta türüdür ve element_type(result), aynı kayan noktanın karmaşık bir türüdür anlambilim.
    • fft_type = IRFFT ise element_type(operand) karmaşık bir türdür ve element_type(result), aynı kayan noktanın bir kayan nokta türüdür anlambilim.
  • (C3) 1 <= size(fft_length) <= 3.
  • (C4) operand ve result arasındaysa tensor real var ardından shape(real)[-size(fft_length):] = fft_length'e gidin.
  • (C5) shape(result) = shape(operand) hariç:
    • fft_type = RFFT ise dim(result, -1) = dim(operand, -1) = 0 ? 0 : dim(operand, -1) / 2 + 1.
    • fft_type = IRFFT ise dim(operand, -1) = dim(result, -1) = 0 ? 0 : dim(result, -1) / 2 + 1.

Örnekler

// %operand: [(1.0, 0.0), (0.0, 0.0), (0.0, 0.0), (0.0, 0.0)]
%result = "stablehlo.fft"(%operand) {
  fft_type = #stablehlo<fft_type FFT>,
  fft_length = array<i64: 4>
} : (tensor<4xcomplex<f32>>) -> tensor<4xcomplex<f32>>
// %result: [(1.0, 0.0), (1.0, 0.0), (1.0, 0.0), (1.0, 0.0)]

floor

Anlam

Element tabanlı tabanda operand tensörü gerçekleştirir ve bir result tensörü üretir. IEEE-754'teki roundToIntegralTowardNegative işlemini uygular bakın. Miktarı kullanılan türlerde, dequantize_op_quantize(floor, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [-0.8166, -0.2530, 0.2530, 0.8166, 2.0]
%result = "stablehlo.floor"(%operand) : (tensor<5xf32>) -> tensor<5xf32>
// %result: [-1.0, -1.0, 0.0, 0.0, 2.0]

Diğer Örnekler

toplamak

Anlam

start_indices içinde belirtilen ofsetlerden operand tensöründen dilimleri toplar ve bir result tensörü üretir.

Aşağıdaki şemada result içindeki öğelerin, Somut bir örnek kullanarak operand. Diyagramda birkaç örnek result .operand

toplamak

Daha resmi dilde, result[result_index] = operand[operand_index] burada:

  • batch_dims = [d for d in axes(result) and d not in offset_dims].
  • batch_index = result_index[batch_dims...].
  • start_index şu şekilde tanımlanır:
    • bi öğesinin bağımsız öğeler olduğu start_indices[bi0, ..., :, ..., biN] Aşağıdaki koşul karşılandığında index_vector_dim dizinine batch_index ve : eklenir index_vector_dim < rank(start_indices).
    • Aksi takdirde [start_indices[batch_index]].
  • axes(operand) içindeki d_operand için,
    • full_start_index[d_operand] = clamp(start_index[d_start], 0, dim(operand, d_operand) - slice_sizes[d_operand]). (d_operand = start_index_map[d_start] ise)
    • Aksi takdirde full_start_index[d_operand] = 0.
  • axes(operand) içindeki d_operand için,
    • full_batching_index[d_operand] = batch_index[d_start - (d_start < index_vector_dim ? 0 : 1)]. eğer d_operand = operand_batching_dims[i_batching] ve d_start = start_indices_batching_dims[i_batching].
    • Aksi takdirde full_batching_index[d_operand] = 0.
  • offset_index = result_index[offset_dims...].
  • oi bireysel olduğu full_offset_index = [oi0, ..., 0, ..., oiN] öğeleri offset_index içindeki dizinlere eklenir ve 0, collapsed_slice_dims ve operand_batching_dims.
  • operand_index = full_start_index + full_batching_index + full_offset_index

indices_are_sorted değeri true ise uygulama, start_indices, start_index_map ölçütüne göre sıralanır, aksi takdirde tanımlanmamıştır. Daha resmî bir şekilde ifade etmek gerekirse indices(result) kaynaklı tüm i1 < i2 için full_start_index(i1) <= full_start_index(i2).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1), (C8), (C11), (C17), (C19-C21), (C23)
(I2) start_indices tam sayı türündeki tensör (C2-C3), (C14), (C17), (C22)
(I3) offset_dims si64 türünde 1 boyutlu tensör sabiti (C1), (C4-C5), (C22)
(I4) collapsed_slice_dims si64 türünde 1 boyutlu tensör sabiti (C1), (C6-C9), (C22)
(I5) operand_batching_dims si64 türünde 1 boyutlu tensör sabiti (C1), (C6), (C10-C12), (C16-C18), (C22)
(I6) start_indices_batching_dims si64 türünde 1 boyutlu tensör sabiti (C13-C17)
(I7) start_index_map si64 türünde 1 boyutlu tensör sabiti (C3), (C18-C19)
(I8) index_vector_dim si64 türündeki sabit (C2-C3), (C15), (C22)
(I9) slice_sizes si64 türünde 1 boyutlu tensör sabiti (C9), (C12), (C20-C22)
(I10) indices_are_sorted i1 türündeki sabit

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C5), (C22-C23)

Sınırlamalar

  • (C1) rank(operand) = size(offset_dims) + size(collapsed_slice_dims) + size(operand_batching_dims).
  • (C2) 0 <= index_vector_dim <= rank(start_indices).
  • (C3) size(start_index_map) = index_vector_dim < rank(start_indices) ? dim(start_indices, index_vector_dim) : 1.
  • (C4) is_unique(offset_dims) and is_sorted(offset_dims)
  • (C5) 0 <= offset_dims < rank(result)
  • (C6) is_unique(concatenate(collapsed_slice_dims, operand_batching_dims))
  • (C7) is_sorted(collapsed_slice_dims).
  • (C8) 0 <= collapsed_slice_dims < rank(operand)
  • (C9) slice_sizes[collapsed_slice_dims...] <= 1.
  • (C10) is_sorted(operand_batching_dims)
  • (C11) 0 <= operand_batching_dims < rank(operand)
  • (C12) slice_sizes[operand_batching_dims...] <= 1
  • (C13) is_unique(start_indices_batching_dims)
  • (C14) 0 <= start_indices_batching_dims < rank(start_indices)
  • (C15) index_vector_dim not in start_indices_batching_dims
  • (C16) size(operand_batching_dims) == size(start_indices_batching_dims)
  • (C17) dim(operand, operand_batching_dims...) = dim(start_indices, start_indices_batching_dims...)
  • (C18) is_unique(concatenate(start_index_map, operand_batching_dims))
  • (C19) 0 <= start_index_map < rank(operand)
  • (C20) size(slice_sizes) = rank(operand).
  • (C21) 0 <= slice_sizes <= shape(operand)
  • (C22) shape(result) = combine(batch_dim_sizes, offset_dim_sizes); burada:
    • batch_dim_sizes = shape(start_indices) (boyut boyutu hariç) index_vector_dim öğesine karşılık gelen start_indices dahil edilmemiştir.
    • offset_dim_sizes = slice_sizes dışında, şu boyuttaki boyutlar slice_sizes collapsed_slice_dims ve operand_batching_dims dahil edilmedi.
    • combine, batch_dim_sizes değerini batch_dims ve offset_dims değerine karşılık gelen eksenlerde offset_dim_sizes.
  • (C23) element_type(operand) = element_type(result)

Örnekler

// %operand: [
//            [
//             [[1, 2], [3, 4], [5, 6], [7, 8]],
//             [[9, 10],[11, 12], [13, 14], [15, 16]],
//             [[17, 18], [19, 20], [21, 22], [23, 24]]
//            ],
//            [
//             [[25, 26], [27, 28], [29, 30], [31, 32]],
//             [[33, 34], [35, 36], [37, 38], [39, 40]],
//             [[41, 42], [43, 44], [45, 46], [47, 48]]
//            ]
//           ]
// %start_indices: [
//                  [
//                   [[0, 0], [1, 0], [2, 1]],
//                   [[0, 1], [1, 1], [0, 9]]
//                  ],
//                  [
//                   [[0, 0], [2, 1], [2, 2]],
//                   [[1, 2], [0, 1], [1, 0]]
//                  ]
//                 ]
%result = "stablehlo.gather"(%operand, %start_indices) {
  dimension_numbers = #stablehlo.gather<
    offset_dims = [3, 4],
    collapsed_slice_dims = [1],
    operand_batching_dims = [0],
    start_indices_batching_dims = [1],
    start_index_map = [2, 1],
    index_vector_dim = 3>,
  slice_sizes = array<i64: 1, 1, 2, 2>,
  indices_are_sorted = false
} : (tensor<2x3x4x2xi32>, tensor<2x2x3x2xi64>) -> tensor<2x2x3x2x2xi32>
// %result: [
//           [
//            [
//             [[1, 2], [3, 4]],
//             [[3, 4], [5, 6]],
//             [[13, 14], [15, 16]]
//            ],
//            [
//             [[33, 34], [35, 36]],
//             [[35, 36], [37, 38]],
//             [[41, 42], [43, 44]]
//            ]
//           ],
//           [
//            [
//             [[1, 2], [3, 4]],
//             [[13, 14], [15, 16]],
//             [[21, 22], [23, 24]]
//            ],
//            [
//             [[43, 44], [45, 46]],
//             [[33, 34], [35, 36]],
//             [[27, 28], [29, 30]]
//            ]
//           ]
//          ]

Diğer Örnekler

get_dimension_size

Anlam

operand için belirtilen dimension öğesinin boyutunu oluşturur. Daha resmi ifade etmek gerekirse result = dim(operand, dimension) Anlamsal açıdan yalnızca şekille ilgilidir. türünün bileşenidir. Öğe türü herhangi bir şey olabilir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya nicel tensör (C1)
(I2) dimension si64 türündeki sabit (C1)

Çıkışlar

Ad Tür
result si32 türünde 0 boyutlu tensör

Sınırlamalar

  • (C1) 0 <= dimension < rank(operand).

Örnekler

// %operand: [[1, 2, 3], [4, 5, 6]]
%result = "stablehlo.get_dimension_size"(%operand) {
  dimension = 1 : i64
} : (tensor<2x3xi64>) -> tensor<i32>
// %result: 3

Diğer Örnekler

get_tuple_element

Anlam

operand unsurunun index konumundaki öğeyi çıkarır ve bir result. Daha resmi olarak, result = operand[index].

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tuple (C1), (C2)
(I2) index si32 türündeki sabit (C1), (C2)

Çıkışlar

Ad Tür Sınırlamalar
result desteklenen tüm türler (C2)

Sınırlamalar

  • (C1) 0 <= index < size(operand).
  • (C2) type(result) = tuple_element_types(operand)[index].

Örnekler

// %operand: ([1.0, 2.0], (3))
  index = 0 : i32
} : (tuple<tensor<2xf32>, tuple<tensor<i32>>>) -> tensor<2xf32>
// %result: [1.0, 2.0]

Diğer Örnekler

koşul:

Anlam

true_branch veya pred değerine bağlı olarak false_branch. Daha resmi olarak, result = pred ? true_branch() : false_branch().

Girişler

Şirket Ad Tür Sınırlamalar
(I1) pred i1 türünde 0 boyutlu tensör
(I2) true_branch işlev (C1-C3)
(I3) false_branch işlev (C1), (C2)

Çıkışlar

Ad Tür Sınırlamalar
results değişken tensör, nicel tensör veya jeton sayısı (C3)

Sınırlamalar

  • (C1) input_types(true_branch) = input_types(false_branch) = [].
  • (C2) output_types(true_branch) = output_types(false_branch).
  • (C3) type(results...) = output_types(true_branch).

Örnekler

// %result_true_branch: 10
// %result_false_branch: 11
// %pred: true
%result = "stablehlo.if"(%pred) ({
  "stablehlo.return"(%result_true_branch) : (tensor<i32>) -> ()
}, {
  "stablehlo.return"(%result_false_branch) : (tensor<i32>) -> ()
}) : (tensor<i1>) -> tensor<i32>
// %result: 10

Diğer Örnekler

hayal etmek

Anlam

Öğe tabanlı sanal bölümü operand öğesinden çıkarır ve bir result tensörü. Daha resmi olarak, her öğe için x: imag(x) = is_complex(x) ? imaginary_part(x) : constant(0, element_type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık türde tensor (C1), (C2)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta türünün tensörü (C1), (C2)

Sınırlamalar

  • (C1) shape(result) = shape(operand).
  • (C2) element_type(result) şu şekilde tanımlanır:
    • is_complex(operand) ise complex_element_type(element_type(operand)).
    • Aksi takdirde element_type(operand).

Örnekler

// %operand: [(1.0, 2.0), (3.0, 4.0)]
%result = "stablehlo.imag"(%operand) : (tensor<2xcomplex<f32>>) -> tensor<2xf32>
// %result: [2.0, 4.0]

Diğer Örnekler

feed içi

Anlam

Feed içinden verileri okur ve results üretir.

infeed_config anlamı, uygulama tanımlıdır.

results, başta gelen yük değerlerinden ve bakın. Gelecekte yükü ve jetonu ikiye bölmeyi planlıyoruz. Netliği artırmak için ayrı çıktılar (#670).

Girişler

Şirket Ad Tür
(I1) token token
(I2) infeed_config string türündeki sabit

Çıkışlar

Ad Tür Sınırlamalar
results değişken tensör, nicel tensör veya jeton sayısı (C1-C3)

Sınırlamalar

  • (C1) 0 < size(results).
  • (C2) is_empty(result[:-1]) veya is_tensor(type(results[:-1])).
  • (C3) is_token(type(results[-1])).

Örnekler

// %token: !stablehlo.token
// infeed_queue[0]: [[1, 2], [3, 4]]
// infeed_queue[1]: [[5, 6], [7, 8]]
%results0:2 = "stablehlo.infeed"(%token) {
  infeed_config = ""
} : (!stablehlo.token) -> (tensor<2x2xi64>, !stablehlo.token)
// results0#0: [[1, 2], [3, 4]]
%results1:2 = "stablehlo.infeed"(%token) {
  infeed_config = ""
} : (!stablehlo.token) -> (tensor<2x2xi64>, !stablehlo.token)
// results1#0: [[5, 6], [7, 8]]

Diğer Örnekler

Iota

Anlam

Bir output tensörünü sıfırdan başlayarak artan sırayla değerlerle doldurur iota_dimension boyutu boyunca görüntülenir. Daha resmi ifade etmek gerekirse

output[output_index] = constant(is_quantized(output) ? quantize(output_index[iota_dimension], element_type(output)) : output_index[iota_dimension], element_type(output)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) iota_dimension si64 (C1)

Çıkışlar

Ad Tür Sınırlamalar
output tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) 0 <= iota_dimension < rank(output).

Örnekler

%output = "stablehlo.iota"() {
  iota_dimension = 0 : i64
} : () -> tensor<4x5xi32>
// %output: [
//           [0, 0, 0, 0, 0],
//           [1, 1, 1, 1, 1],
//           [2, 2, 2, 2, 2],
//           [3, 3, 3, 3, 3]
//          ]

%output = "stablehlo.iota"() {
  iota_dimension = 1 : i64
} : () -> tensor<4x5xi32>
// %output: [
//           [0, 1, 2, 3, 4],
//           [0, 1, 2, 3, 4],
//           [0, 1, 2, 3, 4],
//           [0, 1, 2, 3, 4]
//          ]

Diğer Örnekler

is_finite

Anlam

x öğesindeki değerin sonlu olup olmadığını (yani +Inf, -Inf, veya NaN) çevirir ve bir y tensörü üretir. isFinite öğesini uygular IEEE-754 spesifikasyonundan bu işlemi yapma. Miktarlandırılmış türlerde sonuç, her zaman true.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) x kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
y boole türündeki tensor (C1)

Sınırlamalar

  • (C1) shape(x) = shape(y).

Örnekler

// Logical values: -Inf, +Inf, NaN, ...
// %x: [0xFFF0000000000000, 0x7FF0000000000000, 0x7FF8000000000000, -10.0, -0.0, 0.0, 10.0]
%y = "stablehlo.is_finite"(%x) : (tensor<7xf64) -> tensor<7xi1>
// %y: [false, false, false, true, true, true, true]

Diğer Örnekler

log

Anlam

operand tensörü üzerinde öğe tabanlı logaritma işlemi gerçekleştirir ve result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten log.
  • Karmaşık sayılar için: karmaşık logaritma.
  • Miktarlanmış türler için: dequantize_op_quantize(log, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [[1.0, 2.0], [3.0, 4.0]]
%result = "stablehlo.log"(%operand) : (tensor<2x2xf64>) -> tensor<2x2xf64>
// %result: [[0.0, 0.69314718055994529], [1.0986122886681098, 1.3862943611198906]]

Diğer Örnekler

log_plus_one

Anlam

operand tensörü üzerinde eleman tabanlı logaritma artı bir işlem gerçekleştirir ve bir result tensörü üretir. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten logp1.
  • Karmaşık sayılar için: karmaşık logaritma artı bir.
  • Ölçülen türler için: dequantize_op_quantize(log_plus_one, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [0.0, -0.999, 7.0, 6.38905621, 15.0]
%result = "stablehlo.log_plus_one"(%operand) : (tensor<5xf64>) -> tensor<5xf64>
// %result: [0.0, -6.90776825, 2.07944155, 2.0, 2.77258873]

Diğer Örnekler

lojistik

Anlam

operand tensörü üzerinde öğe tabanlı lojistik işlem gerçekleştirir ve result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten division(1, addition(1, exp(-x))).
  • Karmaşık sayılar için: karmaşık lojistik.
  • Ölçülen türler için: dequantize_op_quantize(logistic, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [[0.0, 1.0], [2.0, 3.0]]
%result = "stablehlo.logistic"(%operand) : (tensor<2x2xf64>) -> tensor<2x2xf64>
// %result: [[0.5, 0.73105858], [0.88079708, 0.95257413]]

Diğer Örnekler

harita

Anlam

dimensions boyunca inputs konumuna computation harita işlevini uygular ve bir result tensörü üretir.

Daha resmi olarak, result[result_index] = computation(inputs...[result_index]).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) inputs değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1-C4)
(I2) dimensions si64 türünde 1 boyutlu tensör sabiti (C3)
(I3) computation işlev (C4)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1), (C4)

Sınırlamalar

  • (C1) shape(inputs...) = shape(result).
  • (C2) 0 < size(inputs) = N.
  • (C3) dimensions = range(rank(inputs[0])).
  • (C4) computation, (tensor<E0>, ..., tensor<EN-1>) -> tensor<E'> türünde burada Ei = element_type(inputs[i]) ve E' = element_type(result).

Örnekler

// %input0: [[0, 1], [2, 3]]
// %input1: [[4, 5], [6, 7]]
%result = "stablehlo.map"(%input0, %input1) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %0 = stablehlo.multiply %arg0, %arg1 : tensor<i64>
    stablehlo.return %0 : tensor<i64>
}) {
  dimensions = array<i64: 0, 1>
} : (tensor<2x2xi64>, tensor<2x2xi64>) -> tensor<2x2xi64>
// %result: [[0, 5], [12, 21]]

Diğer Örnekler

maksimum

Anlam

lhs ve rhs tensörleri üzerinde öğe bazında maksimum işlemi gerçekleştirir ve bir result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Booleler için: mantıksal VEYA.
  • Tam sayılar için: Maksimum tam sayı.
  • Kayan reklamlar için: IEEE-754'ten maximum.
  • Karmaşık sayılar için: (real, imaginary) çifti için sözlüksel maksimum değer. Karmaşık sayılarda sıralama yaratmak, şaşırtıcı anlamlar ya da Bu nedenle gelecekte karmaşık sayılar için desteği kaldırmayı planlıyoruz. (#560).
  • Ölçülen türler için:
    • dequantize_op_quantize(maximum, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya tensör başına miktarlandırılmış tensör (C1)
(I2) rhs tensör veya tensör başına miktarlandırılmış tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1)

Sınırlamalar

  • (C1) baseline_type(lhs) = baseline_type(rhs) = baseline_type(result).

Örnekler

// %lhs: [[1, 2], [7, 8]]
// %rhs: [[5, 6], [3, 4]]
%result = "stablehlo.maximum"(%lhs, %rhs) : (tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[5, 6], [7, 8]]

Diğer Örnekler

minimum

Anlam

lhs ve rhs tensörleri üzerinde öğe bazında minimum işlem gerçekleştirir ve result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Boolelar için: mantıksal VE.
  • Tam sayılar için: Minimum tam sayı.
  • Kayan reklamlar için: IEEE-754'ten minimum.
  • Karmaşık sayılar için: (real, imaginary) çifti için sözlüksel minimum. Karmaşık sayılarda sıralama yaratmak, şaşırtıcı anlamlar ya da Bu nedenle gelecekte karmaşık sayılar için desteği kaldırmayı planlıyoruz. (#560).
  • Ölçülen türler için:
    • dequantize_op_quantize(minimum, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya tensör başına miktarlandırılmış tensör (C1)
(I2) rhs tensör veya tensör başına miktarlandırılmış tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1)

Sınırlamalar

  • (C1) baseline_type(lhs) = baseline_type(rhs) = baseline_type(result).

Örnekler

// %lhs: [[1, 2], [7, 8]]
// %rhs: [[5, 6], [3, 4]]
%result = "stablehlo.minimum"(%lhs, %rhs) : (tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[1, 2], [3, 4]]

Diğer Örnekler

Çarpma

Anlam

İki lhs ve rhs tensöründen element düzeyinde ürün gerçekleştirir ve bir üretir result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Boolelar için: mantıksal VE.
  • Tam sayılar için: tamsayıları çarpma.
  • Kayan reklamlar için: IEEE-754'ten multiplication.
  • Karmaşık sayılar için: karmaşık çarpma.
  • Ölçülen türler için:
    • dequantize_op_quantize(multiply, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tensör veya tensör başına miktarlandırılmış tensör (C1)
(I2) rhs tensör veya tensör başına miktarlandırılmış tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %lhs: [[1, 2], [3, 4]]
// %rhs: [[5, 6], [7, 8]]
%result = "stablehlo.multiply"(%lhs, %rhs) : (tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[5, 12], [21, 32]]

Diğer Örnekler

işareti değiştir

Anlam

operand tensörü için öğe tabanlı olumsuzlama gerçekleştirir ve bir result üretir tensördür. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • İşaretli tam sayılar için: Tam sayı olumsuzlama.
  • İmzasız tam sayılar için: bitcast'ten işaretli tam sayıya, tamsayı olumsuzlama, bitcast imzasız tam sayıya geri döner.
  • Kayan reklamlar için: IEEE-754'ten negate.
  • Karmaşık sayılar için: karmaşık olumsuzlama.
  • Ölçülen türler için: dequantize_op_quantize(negate, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// Negation operation with integer Tensors
// %operand: [0, -2]
%result = "stablehlo.negate"(%operand) : (tensor<2xi32>) -> tensor<2xi32>
// %result: [0, 2]

// Negation operation with with complex tensors
// %operand: (2.5, 0.0)
%result = "stablehlo.negate"(%operand) : (tensor<1xcomplex<f32>>) -> tensor<1xcomplex<f32>>
// %result: [-2.5, -0.0]

Diğer Örnekler

değil

Anlam

operand tensörü için öğe düzeyinde NOT gerçekleştirir ve bir result tensörü üretir. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Boolelar için: mantıksal DEĞİL.
  • Tam sayılar için: bit tabanlı DEĞİL.

Bağımsız değişkenler

Ad Tür Sınırlamalar
operand boole veya tam sayı türündeki tensor (C1)

Çıkışlar

Ad Tür Sınırlamalar
result boole veya tam sayı türündeki tensor (C1)

Sınırlamalar

  • (C1) type(operand) = type(result).

Örnekler

// Bitwise operation with with integer tensors
// %operand: [[1, 2], [3, 4]]
%result = "stablehlo.not"(%operand) : (tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[-2, -3], [-4, -5]]

// Bitwise operation with with boolean tensors
// %operand: [true, false]
%result = "stablehlo.not"(%operand) : (tensor<2xi1>) -> tensor<2xi1>
// %result: [false, true]

Diğer Örnekler

optimization_barrier

Anlam

operand öğesini oluşturan işlemlerin, result öğesine bağlı olan ve derleyici dönüşümlerini engelleyen işlemler engelleri aşmanızı sağlar. Bunun dışında, işlem bir kimlik (ör. result = operand).

Bağımsız değişkenler

Ad Tür Sınırlamalar
operand değişken tensör, tensör başına miktarlandırılmış tensör veya jeton sayısı (C1)

Çıkışlar

Ad Tür Sınırlamalar
result değişken tensör, tensör başına miktarlandırılmış tensör veya jeton sayısı (C1)

Sınırlamalar

  • (C1) type(operand...) = type(result...).

Örnekler

// %operand0: 0.0
// %operand1: 1.0
%result0, %result1 = "stablehlo.optimization_barrier"(%operand0, %operand1) : (tensor<f32>, tensor<f32>) -> (tensor<f32>, tensor<f32>)
// %result0: 0.0
// %result1: 1.0

Diğer Örnekler

veya

Anlam

lhs ve rhs iki tensörü için öğe düzeyinde VEYA gerçekleştirir ve bir result üretir tensördür. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Boolelar için: mantıksal VEYA.
  • Tam sayılar için: bit tabanlı VEYA.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı veya boole türündeki tensör (C1)
(I2) rhs tam sayı veya boole türündeki tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı veya boole türündeki tensör (C1)

Sınırlamalar

  • (C1) type(lhs) = type(rhs) = type(result).

Örnekler

// Bitwise operation with with integer tensors
// %lhs: [[1, 2], [3, 4]]
// %rhs: [[5, 6], [7, 8]]
%result = "stablehlo.or"(%lhs, %rhs) : (tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[5, 6], [7, 12]]

// Logical operation with with boolean tensors
// %lhs: [[false, false], [true, true]]
// %rhs: [[false, true], [false, true]]
%result = "stablehlo.or"(%lhs, %rhs) : (tensor<2x2xi1>, tensor<2x2xi1>) -> tensor<2x2xi1>
// %result: [[false, true], [true, true]]

Diğer Örnekler

feed dışı

Anlam

Out feed'e inputs yazar ve result jetonu oluşturur.

outfeed_config anlamı, uygulama tanımlıdır.

Girişler

Şirket Ad Tür
(I1) inputs değişken sayıda tensör veya nicel tensör
(I2) token token
(I3) outfeed_config string türündeki sabit

Çıkışlar

Ad Tür
result token

Örnekler

%result = "stablehlo.outfeed"(%input0, %token) {
  outfeed_config = ""
} : (tensor<2x2x2xi64>, !stablehlo.token) -> !stablehlo.token

Diğer Örnekler

dolgu

Anlam

operand öğesini, tensörün çevresindeki ve öğeler arasında dolgu yaparak genişletir değeri verilen padding_value ile tensörün değeri.

edge_padding_low ve edge_padding_high, eklenen dolgu miktarını belirtir düşük uçta (endeks 0'ın yanında) ve üst uçta (en yüksek endeks yanında) tıklayın. Dolgu miktarı negatif olabilir. Burada, negatif dolgunun mutlak değeri, kaldırılacak öğe sayısını gösterir belirtilen boyuttan çıkarılacak.

interior_padding, herhangi bir ikisi arasına eklenen dolgu miktarını belirtir öğeler eklemekten çekinmeyin. İç dolgu meydana geliyor negatif kenar dolgusu, öğeleri kenar dolgusundan kaldıracak şekilde iç dolgulu işlenene göre.

Daha resmi olarak, result[result_index] şu şekilde tanımlanır:

  • Şu durumda operand[operand_index] result_index = edge_padding_low + operand_index * (interior_padding + 1).
  • Aksi takdirde padding_value.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1), (C2), (C4)
(I2) padding_value 0 boyutlu tensör veya tensör başına miktarlandırılmış tensör (C1)
(I3) edge_padding_low si64 türünde 1 boyutlu tensör sabiti (C1), (C4)
(I4) edge_padding_high si64 türünde 1 boyutlu tensör sabiti (C1), (C4)
(I5) interior_padding si64 türünde 1 boyutlu tensör sabiti (C2-C4)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C3-C6)

Sınırlamalar

  • (C1) element_type(operand) = element_type(padding_value) = element_type(result).
  • (C2) size(edge_padding_low) = size(edge_padding_high) = size(interior_padding) = rank(operand).
  • (C3) 0 <= interior_padding.
  • (C4) shape(result) = shape(operand) + edge_padding_low + max(shape(operand) - 1, 0) * interior_padding + edge_padding_high

Örnekler

// %operand: [
//            [1, 2, 3],
//            [4, 5, 6]
//           ]
// %padding_value: 0
%result = "stablehlo.pad"(%operand, %padding_value) {
  edge_padding_low = array<i64: 0, 1>,
  edge_padding_high = array<i64: 2, 1>,
  interior_padding = array<i64: 1, 2>
} : (tensor<2x3xi32>, tensor<i32>) -> tensor<5x9xi32>
// %result: [
//           [0, 1, 0, 0, 2, 0, 0, 3, 0],
//           [0, 0, 0, 0, 0, 0, 0, 0, 0],
//           [0, 4, 0, 0, 5, 0, 0, 6, 0],
//           [0, 0, 0, 0, 0, 0, 0, 0, 0],
//           [0, 0, 0, 0, 0, 0, 0, 0, 0]
//          ]

Diğer Örnekler

partition_id

Anlam

Mevcut işlemin partition_id kadarını oluşturur.

Çıkışlar

Ad Tür
result ui32 türünde 0 boyutlu tensör

Örnekler

%result = "stablehlo.partition_id"() : () -> tensor<ui32>

Diğer Örnekler

patlatma

Anlam

operand tensöründe ayarlanan bit sayısının öğe bazında sayımını yapar ve bir result tensörü üretir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tam sayı türündeki tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı türündeki tensör (C1)

Sınırlamalar

  • (C1) type(operand) = type(result).

Örnekler

// %operand: [0, 1, 2, 127]
%result = "stablehlo.popcnt"(%operand) : (tensor<4xi64>) -> tensor<4xi64>
// %result: [0, 1, 1, 7]

Diğer Örnekler

güç

Anlam

rhs tensörü ile lhs tensörü için öğe düzeyinde üsleme gerçekleştirir ve bir result tensörü üretir. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Tam sayılar için: tam sayı üssü.
  • Kayan reklamlar için: IEEE-754'ten pow.
  • Karmaşık sayılar için: karmaşık üsleme.
  • Miktarlanmış türler için: dequantize_op_quantize(power, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)
(I2) rhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %lhs: [-2.0, -0.0, -36.0, 5.0, 3.0, 10000.0]
// %rhs: [2.0, 2.0, 1.1, 2.0, -1.0, 10.0]
%result = "stablehlo.power"(%lhs, %rhs) : (tensor<6xf64>, tensor<6xf64>) -> tensor<6xf64>
// %result: [4.0, 0.0, -nan, 25.0, 0.333333343, inf]

Diğer Örnekler

gerçek

Anlam

operand öğesinden gerçek kısmı eleman olarak çıkarır ve bir result üretir tensördür. Daha resmi olarak, her öğe için x: real(x) = is_complex(x) ? real_part(x) : x.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık türde tensor (C1), (C2)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta türünün tensörü (C1), (C2)

Sınırlamalar

  • (C1) shape(result) = shape(operand).
  • (C2) element_type(result) şu şekilde tanımlanır:
    • is_complex(operand) ise complex_element_type(element_type(operand)).
    • Aksi takdirde element_type(operand).

Örnekler

// %operand: [(1.0, 2.0), (3.0, 4.0)]
%result = "stablehlo.real"(%operand) : (tensor<2xcomplex<f32>>) -> tensor<2xf32>
// %result: [1.0, 3.0]

Diğer Örnekler

gelen

Anlam

channel_id ile bir kanaldan veri alır ve results üretir.

is_host_transfer değeri true ise işlem, ana bilgisayar. Aksi takdirde, verileri başka bir cihazdan aktarır. Bu, tanımlanmıştır. Bu işaret, channel_type, gelecekte bunlardan yalnızca birini tutmayı planlıyoruz (#666).

results, başta gelen yük değerlerinden ve bakın. Gelecekte yükü ve jetonu ikiye bölmeyi planlıyoruz. Netliği artırmak için ayrı çıktılar (#670).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) token token (C4)
(I2) channel_id si64 türündeki sabit
(I3) channel_type DEVICE_TO_DEVICE ve HOST_TO_DEVICE sıralaması (C1)
(I4) is_host_transfer i1 türündeki sabit (C1)

Çıkışlar

Ad Tür Sınırlamalar
results değişken tensör, nicel tensör veya jeton sayısı (C2-C4)

Sınırlamalar

  • (C1) channel_type şu şekilde tanımlanır:
    • is_host_transfer = true ise HOST_TO_DEVICE,
    • Aksi takdirde DEVICE_TO_DEVICE.
  • (C2) 0 < size(results).
  • (C3) is_empty(result[:-1]) veya is_tensor(type(results[:-1])).
  • (C4) is_token(type(results[-1]))

Örnekler

%results0, %results1 = "stablehlo.recv"(%token) {
  channel_handle = #stablehlo.channel_handle<handle = 1, type = 3>,
  is_host_transfer = true
} : (!stablehlo.token) -> (tensor<2x2xi64>, !stablehlo.token)

Diğer Örnekler

reduce

Anlam

inputs ve init_values aralığına body azaltma işlevi uygular dimensions olup results tensör üretir.

İndirimlerin sırası uygulama tanımlıdır. Diğer bir deyişle body ve init_values, işlemin şunu ürettiğini garanti etmek için bir monoid oluşturmalıdır: tüm uygulamalarda aynı sonuçlar elde edilmesine yardımcı olur. Ancak bu koşul pek çok popüler indirim için geçerli değildir. Ör. kayan nokta eklemesi init_values için body ve sıfır değerleri monoid oluşturmaz çünkü kayan nokta eklemesi ilişkisel değildir.

Daha resmi dilde, results...[j0, ..., jR-1] = reduce(input_slices_converted) burada:

  • input_slices = inputs...[j0, ..., :, ..., jR-1], burada : eklenir saat: dimensions.
  • input_slices_converted = to_destination_type(input_slices..., type(func_inputs(body)[:len(func_inputs(body))//2])...).
  • init_values_converted = to_destination_type(init_values..., type(func_inputs(body)[len(func_inputs(body))//2:])...).
  • Bazı ikili ağaçlar için reduce(input_slices_converted) = exec(schedule) schedule burada:
    • exec(node) = body(exec(node.left), exec(node.right)).
    • exec(leaf) = leaf.value.
  • schedule, sırasıyla şunları içerir:
    • Şu kampanyadaki tüm index için input_slices_converted...[index] değerleri: index_space(input_slices_converted), artan sözlük sıralamasında / index.
    • Uygulamanın tanımlı bir Uygulama tanımlı konumlarda init_values_converted.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) inputs değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1-C4), (C6), (C7)
(I2) init_values 0 boyutlu tensörlerin veya tensör başına miktarlandırılmış tensörlerin değişken sayısı (C2), (C3)
(I3) dimensions si64 türünde 1 boyutlu tensör sabiti (C4), (C5), (C7)
(I4) body işlev (C6)

Çıkışlar

Ad Tür Sınırlamalar
results değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C3), (C7), (C8)

Sınırlamalar

  • (C1) same(shape(inputs...)).
  • (C2) element_type(inputs...) = element_type(init_values...).
  • (C3) 0 < size(inputs) = size(init_values) = size(results) = N.
  • (C4) 0 <= dimensions < rank(inputs[0])
  • (C5) is_unique(dimensions)
  • (C6) body, (tensor<E0>, ..., tensor<EN-1>, tensor<E0>, ..., türünde tensor<EN-1>) -> (tensor<E0>, ..., tensor<EN-1>) burada: is_promotable(element_type(inputs[i]), Ei).
  • (C7) shape(results...) = shape(inputs...) dışında, boyut dimensions değerine karşılık gelen inputs... boyutları dahil edilmemiştir.
  • (C8) [0,N) kapsamındaki tüm i için element_type(results[i]) = Ei.

Örnekler

// %input = [[0, 1, 2, 3, 4, 5]]
// %init_value = 0
%result = "stablehlo.reduce"(%input, %init_value) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %0 = "stablehlo.add"(%arg0, %arg1) : (tensor<i64>, tensor<i64>) -> tensor<i64>
    "stablehlo.return"(%0) : (tensor<i64>) -> ()
}) {
  dimensions = array<i64: 1>
} : (tensor<1x6xi64>, tensor<i64>) -> tensor<1xi64>
// %result = [15]

Diğer Örnekler

reduce_precision

Anlam

operand değerini başka bir kayan nokta türüne öğe bazında dönüştürür exponent_bits ve mantissa_bits kullanan ve orijinal haline döndüren bir sürüm kayan nokta türünü ifade eder ve bir output tensörü oluşturur.

Daha resmi dilde:

  • Orijinal değerin mantissa bitleri orijinal değeri yuvarlayacak şekilde güncellenir değeri, mantissa_bits ile temsil edilebilecek en yakın değere roundToIntegralTiesToEven semantiği.
  • Bu durumda mantissa_bits, şu mantissa bitlerinden küçükse, orijinal değer ise mantissa bitleri mantissa_bits olacak şekilde kısaltılır.
  • Bu durumda, ara sonucun üs bitleri exponent_bits tarafından sağlanan aralık: Ara sonuç sonsuza kadar gider veya orijinal imza.
  • Miktarı ölçülmüş türlerde, dequantize_op_quantize( lambda operand: reduce_precision(operand, exponent_bits, mantissa_bits), operand, type(result)) gerçekleştirir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)
(I2) exponent_bits si32 türündeki sabit (C2)
(I3) mantissa_bits si32 türündeki sabit (C3)

Çıkışlar

Ad Tür Sınırlamalar
output kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(output).
  • (C2) 1 <= exponent_bits.
  • (C3) 0 <= mantissa_bits.

Örnekler

// Logical values: +Inf, NaN, +Denormal, 0.0, 65519.0, 65520.0
// %operand: [0x7FF0000000000000, 0x7FFFFFFFFFFFFFFF, 0x0000000000000001, 0.0, 65519.0, 65520.0]
%output = "stablehlo.reduce_precision"(%operand) {
  exponent_bits = 5 : i32,
  mantissa_bits = 10 : i32
} : (tensor<6xf64>) -> tensor<6xf64>
// Logical values: +Inf, NaN, 0.0, 0.0, 65504.0, +Inf
// %output: [0x7FF0000000000000, 0x7FFFFFFFFFFFFFFF, 0.0, 0.0, 65504.0, 0x7FF0000000000000]

Diğer Örnekler

reduce_scatter

Anlam

reduce_scatter

StableHLO süreç ızgarasındaki her süreç grubunda azaltma, her işlemdeki operand tensörü değerleri üzerinden computations kullanılarak, scatter_dimension boyunca azaltma sonucunu parçalara ve parçalara böler result oluşturmak için işlemler arasındaki bölünen kısımları ayırın.

İşlem, StableHLO süreç ızgarasını process_groups olarak ayırır. şu şekilde tanımlanır:

  • cross_replica(replica_groups). (channel_id <= 0 and use_global_device_ids = false ise)
  • cross_replica_and_partition(replica_groups). (channel_id > 0 and use_global_device_ids = false ise)
  • flattened_ids(replica_groups). (channel_id > 0 and use_global_device_ids = true ise)

Daha sonra, her process_group içinde:

  • reduced_value = all_reduce(operand, replica_groups, channel_id, use_global_device_ids, computation).
  • parts@sender = split(reduced_value@sender, dim(process_groups, 1), scatter_dimension).
  • Şu kapsamdaki tüm sender için result@receiver = parts@sender[receiver_index]: process_group (burada receiver_index = process_group.index(receiver)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1), (C2), (C7), (C8)
(I2) scatter_dimension si64 türündeki sabit (C1), (C2), (C8)
(I3) replica_groups si64 türünde 2 boyutlu tensör sabiti (C3-C5)
(I4) channel_id si64 türündeki sabit (C6)
(I5) use_global_device_ids i1 türündeki sabit (C6)
(I6) computation işlev (C7)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C8-C9)

Sınırlamalar

  • (C1) dim(operand, scatter_dimension) % dim(process_groups, 1) = 0.
  • (C2) 0 <= scatter_dimension < rank(operand).
  • (C3) is_unique(replica_groups).
  • (C4) size(replica_groups) şu şekilde tanımlanır:
    • cross_replica kullanılıyorsa num_replicas.
    • cross_replica_and_partition kullanılıyorsa num_replicas.
    • flattened_ids kullanılıyorsa num_processes.
  • (C5) 0 <= replica_groups < size(replica_groups)
  • (C6) use_global_device_ids = true ise channel_id > 0.
  • (C7) computation, (tensor<E>, tensor<E>) -> (tensor<E>) türünde olup burada is_promotable(element_type(operand), E).
  • (C8) shape(result) = shape(operand) hariç:
    • dim(result, scatter_dimension) = dim(operand, scatter_dimension) / dim(process_groups, 1).
  • (C9) element_type(result) = E.

Örnekler

// num_replicas: 2
// num_partitions: 1
// %operand@(0, 0): [[1, 2, 3, 4],
//                   [5, 6, 7, 8]]
// %operand@(1, 0): [[9, 10, 11, 12],
//                   [13, 14, 15, 16]]
%result = "stablehlo.reduce_scatter"(%operand) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
  %0 = "stablehlo.add"(%arg0, %arg1) : (tensor<i64>, tensor<i64>) -> tensor<i64>
  "stablehlo.return"(%0) : (tensor<i64>) -> ()
}) {
  scatter_dimension = 1 : i64,
  replica_groups = dense<[[0, 1]]> : tensor<1x2xi64>,
  channel_handle = #stablehlo.channel_handle<handle = 0, type = 0>
} : (tensor<2x4xi64>) -> tensor<2x2xi64>
//
// %result@(0, 0): [[10, 12],
//                  [18, 20]]
// %result@(1, 0): [[14, 16],
//                  [22, 24]]

Diğer Örnekler

reduce_window

Anlam

inputs ve init_values aralıklarına body azaltma işlevi uygular ve results üretir.

Aşağıdaki şemada, results... içindeki öğelerin Somut bir örnek kullanarak inputs....

reduce_window

Daha resmi ifade etmek gerekirse results...[result_index] = reduce(windows, init_values, axes(inputs...), body). (bkz. azaltma) burada:

  • padded_inputs = pad(inputs..., init_values..., padding[:, 0], padding[:, 1], base_dilations - 1).
  • window_start = result_index * window_strides.
  • window_end = window_start + (window_dimensions - 1) * window_dilations + 1.
  • windows = slice(padded_inputs..., window_start, window_end, window_dilations).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) inputs değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1-C4), (C6), (C8), (C10), (C12), (C13), (C15)
(I2) init_values 0 boyutlu tensörlerin veya tensör başına miktarlandırılmış tensörlerin değişken sayısı (C1), (C13)
(I3) window_dimensions si64 türünde 1 boyutlu tensör sabiti (C4), (C5), (C15)
(I4) window_strides si64 türünde 1 boyutlu tensör sabiti (C6), (C7), (C15)
(I5) base_dilations si64 türünde 1 boyutlu tensör sabiti (C8), (C9), (C15)
(I6) window_dilations si64 türünde 1 boyutlu tensör sabiti (C10), (C11), (C15)
(I7) padding si64 türünde 2 boyutlu tensör sabiti (C12), (C15)
(I8) body işlev (C13)

Çıkışlar

Ad Tür Sınırlamalar
results değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1), (C14-C16)

Sınırlamalar

  • (C1) 0 < size(inputs) = size(init_values) = size(results) = N.
  • (C2) same(shape(inputs...)).
  • (C3) element_type(inputs...) = element_type(init_values...).
  • (C4) size(window_dimensions) = rank(inputs[0])
  • (C5) 0 < window_dimensions
  • (C6) size(window_strides) = rank(inputs[0]).
  • (C7) 0 < window_strides.
  • (C8) size(base_dilations) = rank(inputs[0])
  • (C9) 0 < base_dilations.
  • (C10) size(window_dilations) = rank(inputs[0])
  • (C11) 0 < window_dilations
  • (C12) shape(padding) = [rank(inputs[0]), 2]
  • (C13) body, (tensor<E0>, ..., tensor<EN-1>, tensor<E0>, ..., türünde tensor<EN-1>) -> (tensor<E0>, ..., tensor<EN-1>) burada: is_promotable(element_type(inputs[i]), Ei).
  • (C14) same(shape(results...))
  • (C15) shape(results[0]) = num_windows; burada:
    • dilated_input_shape = shape(inputs[0]) = 0 ? 0 : (shape(inputs[0]) - 1) * base_dilations + 1.
    • padded_input_shape = padding[:, 0] + dilated_input_shape + padding[:, 1].
    • dilated_window_shape = (window_dimensions - 1) * window_dilations + 1.
    • is_empty_window = padded_input_shape = 0 || dilated_window_shape > padded_input_shape.
    • num_windows = is_empty_window ? 0 : floor((padded_input_shape - dilated_window_shape) / window_strides) + 1.
  • (C16) [0,N) kapsamındaki tüm i için element_type(results[i]) = Ei.

Örnekler

// %input = [[1, 2], [3, 4], [5, 6]]
// %init_value = 0
%result = "stablehlo.reduce_window"(%input, %init_value) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %0 = "stablehlo.add"(%arg0, %arg1) : (tensor<i64>, tensor<i64>) -> tensor<i64>
    "stablehlo.return"(%0) : (tensor<i64>) -> ()
}) {
  window_dimensions = array<i64: 2, 1>,
  window_strides = array<i64: 4, 1>,
  base_dilations = array<i64: 2, 1>,
  window_dilations = array<i64: 3, 1>,
  padding = dense<[[2, 1], [0, 0]]> : tensor<2x2xi64>
} : (tensor<3x2xi64>, tensor<i64>) -> tensor<2x2xi64>
// %result = [[0, 0], [3, 4]]

Diğer Örnekler

kalan

Anlam

lhs bölünme ve bölen rhs tensörlerinin öğe bazında kalanlarını gerçekleştirir ve bir result tensörü üretir.

Daha resmi ifade etmek gerekirse, sonucun işareti bölmeden alınır ve sonucun mutlak değeri, her zaman bölenin mutlak değerinden küçüktür. Kalan değer lhs - d * rhs olarak hesaplanır. Burada d değeri şu şekilde bulunur:

  • Tam sayılar için: stablehlo.divide(lhs, rhs).
  • Kayan reklamlar için: IEEE-754'ten yuvarlama özellikli division(lhs, rhs) roundTowardZero.
  • Karmaşık sayılar için: TBD (#997).
  • Ölçülen türler için:
    • dequantize_op_quantize(remainder, lhs, rhs, type(result)).

Kayan nokta öğe türlerinde bu işlem, IEEE-754 spesifikasyonundan d integral bir değer olduğu remainder işlemi çift değerine eşit olan lhs/rhs tam değerine en yakın.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)
(I2) rhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %lhs: [17, -17, 17, -17]
// %rhs: [3, 3, -3, -3]
%result = "stablehlo.remainder"(%lhs, %rhs) : (tensor<4xi64>, tensor<4xi64>) -> tensor<4xi64>
// %result: [2, -2, 2, -2]

Diğer Örnekler

replica_id

Anlam

Mevcut işlemin replica_id kadarını oluşturur.

Çıkışlar

Ad Tür
result ui32 türünde 0 boyutlu tensör

Örnekler

%result = "stablehlo.replica_id"() : () -> tensor<ui32>

Diğer Örnekler

yeniden şekillendirme

Anlam

operand tensörünü bir result tensörüne yeniden şekillendirir. Kavramsal olarak aynı standart gösterime sahip olmaya devam eder ancak potansiyel olarak değişir. şekil, ör. tensor<2x3xf32> - tensor<3x2xf32> veya tensor<6xf32>.

Daha resmi dilde, result[result_index] = operand[operand_index]; result_index ve operand_index, sözlükte aynı konuma sahip index_space(result) ve index_space(operand) siparişi.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya nicel tensör (C1-C3)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C1-C3)

Sınırlamalar

  • (C1) element_type(result) değerini sağlayan:
    • !is_per_axis_quantized(operand) ise element_type(operand).
    • element_type(operand) yalnızca quantization_dimension(operand) ve Aksi takdirde quantization_dimension(result) farklı olabilir.
  • (C2) size(operand) = size(result).
  • (C3) is_per_axis_quantized(operand) ise:
    • reduce(dims(operand, [0, 1, ..., quantization_dimension(operand) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y) = reduce(dims(result, [0, 1, ..., quantization_dimension(result) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y).
    • dim(operand, quantization_dimension(operand)) = dim(result, quantization_dimension(result)).
    • reduce(dims(operand, [quantization_dimension(operand) + 1, ..., rank(operand) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y) = reduce(dims(result, [quantization_dimension(result) + 1, ..., rank(result) - 1]), init_values=1, dimensions=[0], body=lambda x, y: x * y).

Örnekler

// %operand: [[1, 2, 3], [4, 5, 6]]
%result = "stablehlo.reshape"(%operand) : (tensor<2x3xi32>) -> tensor<3x2xi32>
// %result: [[1, 2], [3, 4], [5, 6]]

Diğer Örnekler

geri al

Anlam

Belirtilen dimensions boyunca operand içindeki öğelerin sırasını tersine çevirir ve bir result tensörü üretir. Daha resmi ifade etmek gerekirse result[result_index] = operand[operand_index]; burada:

  • operand_index[d] = dim(result, d) - result_index[d] - 1. dimensions içinde d ise.
  • Aksi takdirde operand_index[d] = result_index[d].

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1), (C3)
(I2) dimensions si64 türünde 1 boyutlu tensör sabiti (C2), (C3)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1), (C3)

Sınırlamalar

  • (C1) type(operand) = type(result).
  • (C2) is_unique(dimensions).
  • (C3) 0 <= dimensions < rank(result).

Örnekler

// %operand = [[1, 2], [3, 4], [5, 6]]
%result = "stablehlo.reverse"(%operand) {
  dimensions = array<i64: 1>
} : (tensor<3x2xi32>) -> tensor<3x2xi32>
// %result: [[2, 1], [4, 3], [6, 5]]

Diğer Örnekler

ng

Anlam

rng_distribution algoritmasını kullanarak rastgele sayılar üretir ve şu sonucu verir: Belirli bir shape şeklinin result tensörü.

rng_distribution = UNIFORM ise rastgele sayılar oluşturulur [a, b) aralığı üzerinde tek tip dağılım uygulanarak. a >= b ise davranış tanımsızdır.

rng_distribution = NORMAL ise rastgele sayılar oluşturulur ortalama = a ve standart sapma = b ile normal dağılımdan sonra. b < 0 ise davranış tanımsızdır.

Rastgele sayıların tam olarak nasıl oluşturulduğu, uygulama tarafından tanımlanır. Örneğin, deterministik olabilir ya da olmayabilir ve farklı gizli durum:

Birçok paydaşla yapılan görüşmelerde bu fırsat, desteği sonlandırıldı. Bu nedenle gelecekte bu özelliği kaldırmayı planlıyoruz. (#597).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) a Tam sayı, boole veya kayan nokta türünün 0 boyutlu tensörü (C1), (C2)
(I2) b Tam sayı, boole veya kayan nokta türünün 0 boyutlu tensörü (C1), (C2)
(I3) shape si64 türünde 1 boyutlu tensör sabiti (C3)
(I4) rng_distribution UNIFORM ve NORMAL sıralaması (C2)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı, boole veya kayan nokta türünde tensör (C1-C3)

Sınırlamalar

  • (C1) element_type(a) = element_type(b) = element_type(result).
  • (C2) rng_distribution = NORMAL ise is_float(a).
  • (C3) shape(result) = shape.

Örnekler

// %a = 0
// %b = 2
// %shape = [3, 3]
%result = "stablehlo.rng"(%a, %b, %shape) {
  rng_distribution = #stablehlo<rng_distribution UNIFORM>
} : (tensor<i32>, tensor<i32>, tensor<2xi64>) -> tensor<3x3xi32>
// %result: [
//           [1, 0, 1],
//           [1, 1, 1],
//           [0, 0, 0]
//          ]

rng_bit_generator

Anlam

Tek tip rastgele bitlerle ve güncellenmiş bir çıkış durumuyla doldurulmuş bir output döndürür Rastgele sayı oluşturma aracı rng_algorithm kullanılarak output_state ilk durumu initial_state olarak belirler. Çıkışın deterministik initial_state işlevi vardır, ancak belirleyecek olan kişidir.

rng_algorithm şunlardan biridir:

  • DEFAULT: Uygulama tanımlı algoritma.
  • THREE_FRY: Threefry algoritmasının uygulama tanımlı varyantı.*
  • PHILOX: Philox algoritmasının uygulama tanımlı varyantı.*

* Bkz. Salmon ve diğerleri. SC 2011 Paralel rastgele sayılar: 1, 2, 3 kadar kolay. ziyaret edin.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) rng_algorithm DEFAULT, THREE_FRY ve PHILOX sıralaması (C2)
(I2) initial_state ui64 türünde 1 boyutlu tensör (C1), (C2)

Çıkışlar

Ad Tür Sınırlamalar
output_state ui64 türünde 1 boyutlu tensör (C1)
output tam sayı veya kayan nokta türünde tensör

Sınırlamalar

  • (C1) type(initial_state) = type(output_state).
  • (C2) size(initial_state) şu şekilde tanımlanır:
    • rng_algorithm = DEFAULT durumunda uygulama tanımlanır.
    • rng_algorithm = THREE_FRY ise 2.
    • rng_algorithm = PHILOX ise 2 veya 3.

Örnekler

// %initial_state: [1, 2]
%output_state, %output = "stablehlo.rng_bit_generator"(%initial_state) {
  rng_algorithm = #stablehlo<rng_algorithm THREE_FRY>
} : (tensor<2xui64>) -> (tensor<2xui64>, tensor<2x2xui64>)
// %output_state: [1, 6]
// %output: [
//           [9236835810183407956, 16087790271692313299],
//           [18212823393184779219, 2658481902456610144]
//          ]

round_nearest_afz

Anlam

En yakın tam sayıya eleman tabanlı yuvarlama yaparak bağları kopararak operand tensöründe sıfırdan başlayarak result tensörü üretir. Uygulama IEEE-754 spesifikasyonundan roundToIntegralTiesToAway işlemini. Örneğin, nicelikselleştirilmiş türler, dequantize_op_quantize(round_nearest_afz, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand = [-2.5, 0.4, 0.5, 0.6, 2.5]
%result = "stablehlo.round_nearest_afz"(%operand) : (tensor<5xf64>) -> tensor<5xf64>
// %result: [-3.0, 0.0, 1.0, 1.0, 3.0]

Diğer Örnekler

round_nearest_even

Anlam

En yakın tam sayıya eleman tabanlı yuvarlama yaparak bağları bozar operand tensörü üzerinde çift tam sayıya eşittir ve bir result üretir tensördür. IEEE-754'teki roundToIntegralTiesToEven işlemini uygular bakın. Miktarı kullanılan türlerde, dequantize_op_quantize(round_nearest_even, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta tipi veya tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand = [-2.5, 0.4, 0.5, 0.6, 2.5]
%result = "stablehlo.round_nearest_even"(%operand) : (tensor<5xf64>) -> tensor<5xf64>
// %result: [-2.0, 0.0, 0.0, 1.0, 2.0]

Diğer Örnekler

rsqrt

Anlam

operand tensörü üzerinde öğe tabanlı ters karekök işlemi gerçekleştirir. bir result tensörü üretir. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten rSqrt.
  • Karmaşık sayılar için: karmaşık ters karekök.
  • Miktarlanmış türler için: dequantize_op_quantize(rsqrt, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [[1.0, 4.0], [9.0, 25.0]]
%result = "stablehlo.rsqrt"(%operand) : (tensor<2x2xf32>) -> tensor<2x2xf32>
// %result: [[1.0, 0.5], [0.33333343, 0.2]]

Diğer Örnekler

dağılım

Anlam

Şu hariç inputs tensöre eşit results tensör üretir: scatter_indices tarafından belirtilen bazı dilimler ilgili değerlerle güncellenir updates, update_computation kullanılıyor.

Aşağıdaki şemada updates... içindeki öğelerin, Somut bir örnek kullanarak results.... Diyagramda birkaç örnek updates..., hangi results... indekslerinin anlamına gelir.

dağılım

Daha resmi dilde, index_space(updates[0]) içindeki tüm update_index için:

  • update_scatter_dims = [d for d in axes(updates[0]) and d not in update_window_dims].
  • update_scatter_index = update_index[update_scatter_dims...].
  • start_index şu şekilde tanımlanır:
    • si bireysel olduğu scatter_indices[si0, ..., :, ..., siN] update_scatter_index ve : içine eklenen öğeler index_vector_dim < ise index_vector_dim dizini rank(scatter_indices).
    • Aksi takdirde [scatter_indices[update_scatter_index]].
  • axes(inputs[0]) içindeki d_input için,
    • Şu durumda full_start_index[d_input] = start_index[d_start] d_input = scatter_dims_to_operand_dims[d_start].
    • Aksi takdirde full_start_index[d_input] = 0.
  • axes(inputs[0]) içindeki d_input için,
    • full_batching_index[d_input] = update_scatter_index[d_start - (d_start < index_vector_dim ? 0 : 1)]. eğer d_input = input_batching_dims[i_batching] ve d_start = scatter_indices_batching_dims[i_batching].
    • Aksi takdirde full_batching_index[d_input] = 0.
  • update_window_index = update_index[update_window_dims...].
  • wi bireysel olduğu full_window_index = [wi0, ..., 0, ..., wiN] öğeleri update_window_index içindeki dizinlere eklenir ve 0, inserted_window_dims ve input_batching_dims.
  • result_index = full_start_index + full_batching_index + full_window_index.

Buna göre results = exec(schedule, inputs), şu şekilde:

  • schedule, şunun uygulama tanımlı permütasyonudur: index_space(updates[0]).
  • exec([update_index, ...], results) = exec([...], updated_results); burada:
    • result_index, shape(results...) için sınırların içindeyse
    • updates_converted = to_destination_type( updates...[update_index], type(func_inputs(update_computation) [len(func_inputs(update_computation))//2:])... )
    • updated_values = update_computation(results...[result_index], updates_converted)
    • updated_results, results...[result_index] içeren results öğesinin bir kopyası updated_values... olarak ayarlandı.
    • Aksi halde
    • updated_results = results.
  • exec([], results) = results.

indices_are_sorted değeri true ise uygulama, scatter_indices, scatter_dims_to_operand_dims ölçütüne göre sıralanır, Aksi takdirde davranış tanımsızdır. Daha resmi dilde, şu ülkeden gelen tüm i1 < i2 için: indices(result), full_start_index(i1) <= full_start_index(i2).

unique_indices değeri true ise uygulama, tüm öğelerin Dağılım yapılan result_index dizin benzersizdir. unique_indices ise true ancak dağılımların dağılımındaki dizinler benzersiz değil, o zaman davranış tanımlanmadı.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) inputs değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1), (C2), (C4-C6), (C11), (C13), (C18), (C21), (C23-C24)
(I2) scatter_indices tam sayı türündeki tensör (C4), (C15), (C19), (C22)
(I3) updates değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C3-C6), (C8)
(I4) update_window_dims si64 türünde 1 boyutlu tensör sabiti (C2), (C4), (C7-C8)
(I5) inserted_window_dims si64 türünde 1 boyutlu tensör sabiti (C2), (C4), (C9-C11)
(I6) input_batching_dims si64 türünde 1 boyutlu tensör sabiti (C2), (C4), (C9), (C12-13), (C17-18), (C20)
(I7) scatter_indices_batching_dims si64 türünde 1 boyutlu tensör sabiti (C14-C18)
(I8) scatter_dims_to_operand_dims si64 türünde 1 boyutlu tensör sabiti (C19-C21)
(I9) index_vector_dim si64 türündeki sabit (C4), (C16), (C19), (C22)
(I10) indices_are_sorted i1 türündeki sabit
(I11) unique_indices i1 türündeki sabit
(I12) update_computation işlev (C23)

Çıkışlar

Ad Tür Sınırlamalar
results değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C24-C25)

Sınırlamalar

  • (C1) same(shape(inputs...)).
  • (C2) `rank(inputs[0]) = boyut(update_window_dims) + boyut(inserted_window_dims)
    • size(input_batching_dims)`.
  • (C3) same(shape(updates...)).
  • (C4) shape(updates[0]) = combine(update_scatter_dim_sizes, update_window_dim_sizes) burada:
    • Bunun dışında update_scatter_dim_sizes = shape(scatter_indices) şuna karşılık gelen scatter_indices boyut boyutu: index_vector_dim dahil edilmedi.
    • Bunun dışında update_window_dim_sizes <= shape(inputs[0]) inserted_window_dims değerine karşılık gelen inputs[0] içindeki boyut boyutları ve input_batching_dims dahil edilmedi.
    • combine, update_scatter_dim_sizes değerini İlgili eksenlerde update_scatter_dims ve update_window_dim_sizes kime: update_window_dims.
  • (C5) 0 < size(inputs) = size(updates) = N
  • (C6) element_type(updates...) = element_type(inputs...).
  • (C7) is_unique(update_window_dims) and is_sorted(update_window_dims).
  • (C8) 0 <= update_window_dims < rank(updates[0])
  • (C9) is_unique(concatenate(inserted_window_dims, input_batching_dims))
  • (C10) is_sorted(inserted_window_dims)
  • (C11) 0 <= inserted_window_dims < rank(inputs[0])
  • (C12) is_sorted(input_batching_dims)
  • (C13) 0 <= input_batching_dims < rank(inputs[0]))
  • (C14) is_unique(scatter_indices_batching_dims)
  • (C15) 0 <= scatter_indices_batching_dims < rank(scatter_indices)
  • (C16) index_vector_dim not in scatter_indices_batching_dims
  • (C17) size(input_batching_dims) == size(scatter_indices_batching_dims)
  • (C18) dim(inputs[0], input_batching_dims...) = dim(scatter_indices, scatter_indices_batching_dims...)
  • (C19) size(scatter_dims_to_operand_dims) = index_vector_dim < rank(scatter_indices) ? dim(scatter_indices, index_vector_dim) : 1
  • (C20) is_unique(concatenate(scatter_dims_to_operand_dims, input_batching_dims)).
  • (C21) 0 <= scatter_dims_to_operand_dims < rank(inputs[0])
  • (C22) 0 <= index_vector_dim <= rank(scatter_indices)
  • (C23) update_computation, (tensor<E0>, ..., tensor<EN-1>, tensor<E0>, ..., tensor<EN-1>) -> (tensor<E0>, ..., tensor<EN-1>) türünde, burada is_promotable(element_type(inputs[i]), Ei).
  • (C24) shape(inputs...) = shape(results...)
  • (C25) [0,N) kapsamındaki tüm i için element_type(results[i]) = Ei.

Örnekler

// %input: [
//          [
//           [[1, 2], [3, 4], [5, 6], [7, 8]],
//           [[9, 10],[11, 12], [13, 14], [15, 16]],
//           [[17, 18], [19, 20], [21, 22], [23, 24]]
//          ],
//          [
//           [[25, 26], [27, 28], [29, 30], [31, 32]],
//           [[33, 34], [35, 36], [37, 38], [39, 40]],
//           [[41, 42], [43, 44], [45, 46], [47, 48]]
//          ]
//         ]
// %scatter_indices: [
//                    [
//                     [[0, 0], [1, 0], [2, 1]],
//                     [[0, 1], [1, 1], [0, 9]]
//                    ],
//                    [
//                     [[0, 0], [2, 1], [2, 2]],
//                     [[1, 2], [0, 1], [1, 0]]
//                    ]
//                   ]
// %update: [
//           [
//            [[1, 1], [1, 1], [1, 1]],
//            [[1, 1], [1, 1], [1, 1]]
//           ],
//           [
//            [[1, 1], [1, 1], [1, 1]],
//            [[1, 1], [1, 1], [1, 1]]
//           ]
//          ]
%result = "stablehlo.scatter"(%input, %scatter_indices, %update) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %0 = "stablehlo.add"(%arg0, %arg1) : (tensor<i64>, tensor<i64>) -> tensor<i64>
    "stablehlo.return"(%0) : (tensor<i64>) -> ()
}) {
  scatter_dimension_numbers = #stablehlo.scatter<
    update_window_dims = [3, 4],
    inserted_window_dims = [1],
    input_batching_dims = [0],
    scatter_indices_batching_dims = [1],
    scatter_dims_to_operand_dims = [2, 1],
    index_vector_dim = 3>,
  indices_are_sorted = false,
  unique_indices = false
} : (tensor<2x3x4x2xi64>, tensor<2x2x3x2xi64>, tensor<2x2x3x2x2xi64>) -> tensor<2x3x4x2xi64>
// %result: [
//           [
//            [[3, 4], [6, 7], [6, 7], [7, 8]],
//            [[9, 10],[11, 12], [15, 16], [17, 18]],
//            [[17, 18], [19, 20], [22, 23], [24, 25]]
//           ],
//           [
//            [[25, 26], [28, 29], [30, 31], [31, 32]],
//            [[35, 36], [38, 39], [38, 39], [39, 40]],
//            [[41, 42], [44, 45], [46, 47], [47, 48]]
//           ]
//          ]

Diğer Örnekler

seç

Anlam

Her öğenin on_true veyaresult Karşılık gelen pred öğesinin değerine göre on_false tensörü. Daha resmi olarak, result[result_index] = pred_element ? on_true[result_index] : on_false[result_index] (pred_element = rank(pred) = 0 ? pred[] : pred[result_index]). Miktarı kullanılan türlerde, dequantize_select_quantize(pred, on_true, on_false, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) pred i1 türündeki tensör (C1)
(I2) on_true tensör veya tensör başına miktarlandırılmış tensör (C1-C2)
(I3) on_false tensör veya tensör başına miktarlandırılmış tensör (C2)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C2)

Sınırlamalar

  • (C1) rank(pred) = 0 or shape(pred) = shape(on_true).
  • (C2) baseline_type(on_true) = baseline_type(on_false) = baseline_type(result).

Örnekler

// %pred: [[false, true], [true, false]]
// %on_true: [[1, 2], [3, 4]]
// %on_false: [[5, 6], [7, 8]]
%result = "stablehlo.select"(%pred, %on_true, %on_false) : (tensor<2x2xi1>, tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[5, 2], [3, 8]]

Diğer Örnekler

select_and_scatter

Anlam

Şu özelliğe göre scatter kullanarak source tensöründen gelen değerleri dağıtır: input tensöründen reduce_window sonucun select kullanılıp şu şekilde üretilir: bir result tensör.

Aşağıdaki şemada, result içindeki öğelerin Somut bir örnek kullanarak operand ve source.

select_and_scatter

Daha resmi dilde:

  • Aşağıdaki girişlerle selected_values = reduce_window_without_init(...):

    • inputs = [operand].
    • window_dimensions, window_strides ve padding olduğu gibi kullanılır.
    • base_dilations = windows_dilations = 1.
    • body şu şekilde tanımlanır:
    def body(arg0: tensor<E>, arg1: tensor<E>) -> tensor<E>:
      return select(arg0, arg1) ? arg0 : arg1;
    

    Burada E = element_type(operand) ve reduce_window_without_init çalışır aynen reduce_window gibidir, ancak temelde kullanılan schedule reduce (azaltma bölümüne bakın) başlangıç değerlerini içermez. Şu anda ilgili pencerede değer bulunmazsa ne olacağı belirtilmedi (#731).

  • result[result_index] = reduce([source_values], [init_value], [0], scatter). burada:

    • source_values = [source[source_index] for source_index in source_indices].
    • Şu durumda selected_index(source_index) = operand_index selected_values[source_index], operand öğesine sahip operand_index başlangıç fiyatıyla.
    • source_indices = [source_index for source_index in indices(source) if selected_index(source_index) = result_index].

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1-C4), (C6), (C8-C11)
(I2) source tensör veya tensör başına miktarlandırılmış tensör (C1), (C2)
(I3) init_value 0 boyutlu tensör veya tensör başına miktarlandırılmış tensör (C3)
(I4) window_dimensions si64 türünde 1 boyutlu tensör sabiti (C2), (C4), (C5)
(I5) window_strides si64 türünde 1 boyutlu tensör sabiti (C2), (C6), (C7)
(I6) padding si64 türünde 2 boyutlu tensör sabiti (C2), (C8)
(I7) select işlev (C9)
(I8) scatter işlev (C10)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C11-C12)

Sınırlamalar

  • (C1) element_type(operand) = element_type(source).
  • (C2) shape(source) = num_windows burada:
    • padded_operand_shape = padding[:, 0] + shape(operand) + padding[:, 1].
    • is_empty_window = padded_operand_shape = 0 || window_dimensions > padded_operand_shape.
    • num_windows = is_empty_window ? 0 : floor((padded_operand_shape - window_dimensions) / window_strides) + 1.
  • (C3) element_type(init_value) = element_type(operand).
  • (C4) size(window_dimensions) = rank(operand)
  • (C5) 0 < window_dimensions
  • (C6) size(window_strides) = rank(operand).
  • (C7) 0 < window_strides.
  • (C8) shape(padding) = [rank(operand), 2]
  • (C9) select, (tensor<E>, tensor<E>) -> tensor<i1> türünde olup burada E = element_type(operand).
  • (C10) scatter, (tensor<E>, tensor<E>) -> tensor<E> türünde olup burada is_promotable(element_type(operand), E).
  • (C11) shape(operand) = shape(result)
  • (C12) element_type(result) = E

Örnekler

// %operand: [[1, 5], [2, 5], [3, 6], [4, 4]]
// %source: [[5, 6], [7, 8]]
// %init_value: 0
%result = "stablehlo.select_and_scatter"(%operand, %source, %init_value) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %0 = "stablehlo.compare"(%arg0, %arg1) {
      comparison_direction = #stablehlo<comparison_direction GE>
    } : (tensor<i64>, tensor<i64>) -> tensor<i1>
    "stablehlo.return"(%0) : (tensor<i1>) -> ()
}, {
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %0 = "stablehlo.add"(%arg0, %arg1) : (tensor<i64>, tensor<i64>) -> tensor<i64>
    "stablehlo.return"(%0) : (tensor<i64>) -> ()
}) {
  window_dimensions = array<i64: 3, 1>,
  window_strides = array<i64: 2, 1>,
  padding = dense<[[0, 1], [0, 0]]> : tensor<2x2xi64>
} : (tensor<4x2xi64>, tensor<2x2xi64>, tensor<i64>) -> tensor<4x2xi64>
// %result: [[0, 0], [0, 0], [5, 14], [7, 0]]

Diğer Örnekler

gönder

Anlam

channel_id kanalına inputs gönderir ve result jetonu oluşturur.

is_host_transfer değeri true ise işlem, verileri ana bilgisayar. Aksi takdirde veriler başka bir cihaza aktarılır. Bu, tanımlanmıştır. Bu işaret, channel_type, gelecekte bunlardan yalnızca birini tutmayı planlıyoruz (#666).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) inputs değişken sayıda tensör veya nicel tensör
(I2) token token
(I3) channel_id si64 türündeki sabit
(I4) channel_type DEVICE_TO_DEVICE ve DEVICE_TO_HOST sıralaması (C1)
(I5) is_host_transfer i1 türündeki sabit (C1)

Çıkışlar

Ad Tür
result token

Sınırlamalar

  • (C1) channel_type şu şekilde tanımlanır:
    • is_host_transfer = true ise DEVICE_TO_HOST,
    • Aksi takdirde DEVICE_TO_DEVICE.

Örnekler

%result = "stablehlo.send"(%operand, %token) {
  channel_handle = #stablehlo.channel_handle<handle = 1, type = 2>,
  is_host_transfer = true
} : (tensor<2x2xi64>, !stablehlo.token) -> !stablehlo.token

Diğer Örnekler

shift_left

Anlam

lhs tensörü üzerinde rhs sayısına kadar öğe düzeyinde sola kaydırma işlemi gerçekleştirir ve bir result tensörü üretir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı türündeki tensör (C1)
(I2) rhs tam sayı türündeki tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı türündeki tensör (C1)

Sınırlamalar

  • (C1) type(lhs) = type(rhs) = type(result).

Örnekler

// %lhs: [-1, 0, 1]
// %rhs: [1, 2, 3]
%result = "stablehlo.shift_left"(%lhs, %rhs): (tensor<3xi64>, tensor<3xi64>) -> tensor<3xi64>
// %result: [-2, 0, 8]

Diğer Örnekler

shift_right_arithmetic

Anlam

lhs tensörü üzerinde element tabanlı aritmetik sağ kaydırma işlemi şu şekilde gerçekleştirir: rhs bit sayısını verir ve result tensörü üretir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı türündeki tensör (C1)
(I2) rhs tam sayı türündeki tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı türündeki tensör (C1)

Sınırlamalar

  • (C1) type(lhs) = type(rhs) = type(result).

Örnekler

// %lhs: [-1, 0, 8]
// %rhs: [1, 2, 3]
%result = "stablehlo.shift_right_arithmetic"(%lhs, %rhs): (tensor<3xi64>, tensor<3xi64>) -> tensor<3xi64>
// %result: [-1, 0, 1]

Diğer Örnekler

shift_right_logical

Anlam

rhs ile lhs tensörü üzerinde öğe bazında mantıksal sağ kaydırma işlemi gerçekleştirir bit sayısı ile bir result tensörü üretir.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı türündeki tensör (C1)
(I2) rhs tam sayı türündeki tensör (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı türündeki tensör (C1)

Sınırlamalar

  • (C1) type(lhs) = type(rhs) = type(result).

Örnekler

// %lhs: [-1, 0, 8]
// %rhs: [1, 2, 3]
%result = "stablehlo.shift_right_logical"(%lhs, %rhs): (tensor<3xi64>, tensor<3xi64>) -> tensor<3xi64>
// %result: [9223372036854775807, 0, 1]

Diğer Örnekler

işaret

Anlam

Öğe tabanlı operand işaretini döndürür ve bir result tensörü üretir. Daha resmi bir ifadeyle, her bir öğe (x) için anlam şu şekilde ifade edilebilir: Python söz dizimi şöyledir:

def sign(x):
  if is_integer(x):
    if compare(x, 0, LT, SIGNED): return -1
    if compare(x, 0, EQ, SIGNED): return 0
    return 1
  elif is_float(x):
    if is_nan(x): return NaN
    if compare(x, -0.0, EQ, FLOAT): return -0.0
    if compare(x, +0.0, EQ, FLOAT): return +0.0
    if compare(x, 0.0, LT, FLOAT): return -1.0
    return 1.0
  elif is_complex(x):
    if is_nan(real(x)) or is_nan(imag(x)): return (NaN, NaN)
    if compare(x, (0.0, 0.0), EQ, FLOAT): return (0.0, 0.0)
    return divide(x, convert(abs(x), type(x)))

Miktarı kullanılan türlerde, dequantize_op_quantize(sign, operand, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand işaretli tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensörün tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result işaretli tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensörün tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// Logical values: +NaN, -1.0, -0.0, +0.0, 1.0
// operand: [0x7FFFFFFFFFFFFFFF, -1.0, -0.0, 0.0, 1.0]
%result = "stablehlo.sign"(%operand) : (tensor<5xf64>) -> tensor<5xf64>
// Logical values: +NaN, -1.0, -0.0, +0.0, 1.0
// %result: [0x7FFFFFFFFFFFFFFF, -1.0, -0.0, 0.0, 1.0]

Diğer Örnekler

sinüs

Anlam

operand tensörü üzerinde element düzeyinde sinüs işlemi gerçekleştirir ve result üretir tensördür. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten sin.
  • Karmaşık sayılar için: karmaşık sinüs.
  • Miktarlanmış türler için: dequantize_op_quantize(sine, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [
//            [0.0, 1.57079632],       // [0, pi/2]
//            [3.14159265, 4.71238898] // [pi, 3pi/2]
//           ]
%result = "stablehlo.sine"(%operand) : (tensor<2x2xf32>) -> tensor<2x2xf32>
// %result: [[0.0, 1.0], [0.0, -1.0]]

Diğer Örnekler

slice

Anlam

Statik olarak hesaplanmış başlangıç dizinlerini kullanarak operand öğesinden bir dilim çıkarır ve bir result tensörü üretir. start_indices, şunun başlangıç dizinlerini içeriyor: her boyuta ait dilimi, limit_indices bitiş dizinlerini içerir (hariç) ve strides, adımları içeriyor tıklayın.

Daha resmi dilde, result[result_index] = operand[operand_index]; operand_index = start_indices + result_index * strides.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya tensör başına miktarlandırılmış tensör (C1-C3), (C5)
(I2) start_indices si64 türünde 1 boyutlu tensör sabiti (C2), (C3), (C5)
(I3) limit_indices si64 türünde 1 boyutlu tensör sabiti (C2), (C3), (C5)
(I4) strides si64 türünde 1 boyutlu tensör sabiti (C2), (C4)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya tensör başına miktarlandırılmış tensör (C1), (C5)

Sınırlamalar

  • (C1) element_type(operand) = element_type(result).
  • (C2) size(start_indices) = size(limit_indices) = size(strides) = rank(operand).
  • (C3) 0 <= start_indices <= limit_indices <= shape(operand).
  • (C4) 0 < strides
  • (C5) shape(result) = ceil((limit_indices - start_indices) / strides)

Örnekler

// %operand: [
//            [0, 0, 0, 0],
//            [0, 0, 1, 1],
//            [0, 0, 1, 1]
//           ]
%result = "stablehlo.slice"(%operand) {
  start_indices = array<i64: 1, 2>,
  limit_indices = array<i64: 3, 4>,
  strides = array<i64: 1, 1>
} : (tensor<3x4xi64>) -> tensor<2x2xi64>
// % result: [
//            [1, 1],
//            [1, 1]
//           ]

Diğer Örnekler

sıralama

Anlam

dimension boyutu boyunca 1 boyutlu inputs dilimlerini birlikte sıralar. bir comparator parametresine göre ve results üretir.

Diğer işlemlerdeki benzer girişlerin aksine dimension, negatif değerlere izin verir. aşağıdaki anlamlara gelir. Gelecekte, buna izin verilmeyebilir (ör. tutarlılık nedeniyle) (#1377).

is_stable doğru değerine ayarlanırsa sıralama sabittir, yani karşılaştırıcının eşit olduğu kabul edilen öğeler korunur. Kılıf için tek bir giriş olduğunda e1 ve e2 adlı iki öğe şu şekilde kabul edilir: ancak ve yalnızca, karşılaştırıcıya eşittir comparator(e1, e2) = comparator(e2, e1) = false. Aşağıdaki biçimi inceleyin birden fazla girişe genelleştiğini göreceksiniz.

Daha resmi dilde, index_space(results[0]) içindeki tüm result_index için:

  • adjusted_dimension = dimension >= 0 ? dimension : rank(inputs[0]) + dimension.
  • riN bireysel olduğu result_slice = [ri0, ..., :, ..., riR-1] öğeler result_index içinde ve :, adjusted_dimension konumuna eklenir.
  • inputs_together = (inputs[0]..., ..., inputs[N-1]...).
  • results_together[result_slice] = sort(inputs_together[result_slice], comparator_together).
  • Burada sort, 1 boyutlu bir dilimi azalan düzende sıralar ve beklenen şekilde sol taraftaki bağımsız değişken şöyle ise comparator_together, true değerini döndürür: daha az olabilir.
  • def comparator_together(lhs_together, rhs_together):
      args = []
      for (lhs_el, rhs_el) in zip(lhs_together, rhs_together):
        args.append(lhs_el)
        args.append(rhs_el)
      return comparator(*args)
    
  • (results[0]..., ..., results[N-1]...) = results_together.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) inputs değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C1-C5)
(I2) dimension si64 türündeki sabit (C4)
(I3) is_stable i1 türündeki sabit
(I4) comparator işlev (C5)

Çıkışlar

Ad Tür Sınırlamalar
results değişken sayıda tensör veya tensör başına miktarlandırılmış tensör (C2), (C3)

Sınırlamalar

  • (C1) 0 < size(inputs).
  • (C2) type(inputs...) = type(results...).
  • (C3) same(shape(inputs...) + shape(results...)).
  • (C4) -R <= dimension < R, burada R = rank(inputs[0]).
  • (C5) comparator şu türe sahip: (tensor<E1>, tensor<E1>, ..., tensor<EN-1>, tensor<EN-1>) -> tensor<i1>, burada Ei = element_type(inputs[i]).

Örnekler

// %input0 = [[1, 2, 3], [3, 2, 1]]
// %input1 = [[3, 2, 1], [1, 2, 3]]
%result0, %result1 = "stablehlo.sort"(%input0, %input1) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>, %arg2: tensor<i64>, %arg3: tensor<i64>):
    %predicate = "stablehlo.compare"(%arg0, %arg1) {
      comparison_direction = #stablehlo<comparison_direction GT>
    } : (tensor<i64>, tensor<i64>) -> tensor<i1>
    "stablehlo.return"(%predicate) : (tensor<i1>) -> ()
}) {
  dimension = 0 : i64,
  is_stable = true
} : (tensor<2x3xi64>, tensor<2x3xi64>) -> (tensor<2x3xi64>, tensor<2x3xi64>)
// %result0 = [[3, 2, 3], [1, 2, 1]]
// %result1 = [[1, 2, 1], [3, 2, 3]]

Diğer Örnekler

sqrt

Anlam

operand tensörü üzerinde öğe tabanlı karekök işlemi gerçekleştirir ve result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten squareRoot.
  • Karmaşık sayılar için: karmaşık karekök.
  • Miktarlanmış türler için: dequantize_op_quantize(sqrt, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [[0.0, 1.0], [4.0, 9.0]]
%result = "stablehlo.sqrt"(%operand) : (tensor<2x2xf32>) -> tensor<2x2xf32>
// %result: [[0.0, 1.0], [2.0, 3.0]]

Diğer Örnekler

çıkarma

Anlam

İki lhs ve rhs tensöründen öğe tabanlı çıkarma işlemi gerçekleştirir ve bir üretir result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Tam sayılar için: tam sayı çıkarma.
  • Kayan reklamlar için: IEEE-754'ten subtraction.
  • Karmaşık sayılar için: karmaşık çıkarma işlemi.
  • Ölçülen türler için:
    • dequantize_op_quantize(subtract, lhs, rhs, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)
(I2) rhs tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tam sayı, kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(lhs) = baseline_type(rhs) = baseline_type(result).

Örnekler

// %lhs: [[6, 8], [10, 12]]
// %rhs: [[5, 6], [7, 8]]
%result = "stablehlo.subtract"(%lhs, %rhs) : (tensor<2x2xf32>, tensor<2x2xf32>) -> (tensor<2x2xf32>)
// %result: [[1, 2], [3, 4]]

Diğer Örnekler

tan

Anlam

operand tensörü üzerinde öğe tabanlı teğet işlemi gerçekleştirir ve result tensörü. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten tan.
  • Karmaşık sayılar için: karmaşık tanjant.
  • Miktarlanmış türler için: dequantize_op_quantize(tan, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [
//            [0.0, 1.57079632],       // [0, pi/2]
//            [3.14159265, 4.71238898] // [pi, 3pi/2]
//           ]
%result = "stablehlo.tan"(%operand) : (tensor<2x2xf64>) -> tensor<2x2xf64>
// %result: [
//           [0.0, 1.63312e+16],
//           [0.0, 5.44375e+15]
//          ]

Diğer Örnekler

tanh

Anlam

operand tensörü üzerinde element tabanlı hiperbolik tanjant işlemi gerçekleştirir ve bir result tensörü üretir. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Kayan reklamlar için: IEEE-754'ten tanh.
  • Karmaşık sayılar için: karmaşık hiperbolik tanjant.
  • Ölçülen türler için:
    • dequantize_op_quantize(tanh, operand, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_type(operand) = baseline_type(result).

Örnekler

// %operand: [-1.0, 0.0, 1.0]
%result = "stablehlo.tanh"(%operand) : (tensor<3xf32>) -> tensor<3xf32>
// %result: [-0.76159416, 0.0, 0.76159416]

Diğer Örnekler

ters çevir

Anlam

permutation kullanarak operand tensörünün boyutlarını ayarlar ve result tensörü. Daha resmi dilde: result[result_index] = operand[operand_index] burada result_index[d] = operand_index[permutation[d]].

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand tensör veya nicel tensör (C1-C4)
(I2) permutation si64 türünde 1 boyutlu tensör sabiti (C2-C4)

Çıkışlar

Ad Tür Sınırlamalar
result tensör veya nicel tensör (C1), (C3-C4)

Sınırlamalar

  • (C1) element_type(result) değerini sağlayan:
    • !is_per_axis_quantized(operand) ise element_type(operand).
    • element_type(operand) yalnızca quantization_dimension(operand) ve Aksi takdirde quantization_dimension(result) farklı olabilir.
  • (C2) permutation, range(rank(operand)) permütasyonudur.
  • (C3) shape(result) = dim(operand, permutation...).
  • (C4) is_per_axis_quantized(result) ise quantization_dimension(operand) = permutation(quantization_dimension(result)).

Örnekler

// %operand: [
//            [[1,2], [3,4], [5,6]],
//            [[7,8], [9,10], [11,12]]
//           ]
%result = "stablehlo.transpose"(%operand) {
  permutation = array<i64: 2, 1, 0>
} : (tensor<2x3x2xi32>) -> tensor<2x3x2xi32>
// %result: [
//           [[1,7], [3,9], [5,11]],
//           [[2,8], [4,10], [6,12]]
//          ]

Diğer Örnekler

triangular_solve

Anlam

Küçük veya üst üçgenlere sahip doğrusal denklem sistemlerini toplu çözebilme katsayı matrislerini kullanır.

Daha resmî bir şekilde ifade etmek gerekirse a ve b için çözüm result[i0, ..., iR-3, :, :] left_side şu durumda op(a[i0, ..., iR-3, :, :]) * x = b[i0, ..., iR-3, :, :] adresine: Şu durumda true veya x * op(a[i0, ..., iR-3, :, :]) = b[i0, ..., iR-3, :, :]: left_side, false. Burada, op(a) değerine sahip x değişkeni çözülür transpose_a tarihine kadar. Bu, aşağıdakilerden biri olabilir:

  • NO_TRANSPOSE: a öğesini olduğu gibi kullanarak işlemi gerçekleştirin.
  • TRANSPOSE: a ifadesinin ters çevirme işlemini gerçekleştirin.
  • ADJOINT: a hücresinin eşlenik ters çevirme işlemini gerçekleştirin.

lower değeri true ise giriş verileri yalnızca a öğesinin alt üçgeninden okunur a üst üçgeni, aksi takdirde. Çıkış verileri aynı üçgen içinde döndürülür; diğer üçgendeki değerler uygulama tanımlıdır.

unit_diagonal doğru ise uygulama, köşegenin a elemanları 1'e eşittir, aksi takdirde davranış tanımsızdır.

Miktarı kullanılan türlerde, dequantize_op_quantize(lambda x, y: triangular_solve(x, y, left_side, lower, unit_diagonal, transpose_a), a, b, type(result))

Girişler

Şirket Ad Tür Sınırlamalar
(I1) a kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1-C3)
(I2) b kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1-C4)
(I3) left_side i1 türündeki sabit (C3)
(I4) lower i1 türündeki sabit
(I5) unit_diagonal i1 türündeki sabit
(I6) transpose_a NO_TRANSPOSE, TRANSPOSE ve ADJOINT sıralaması

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta veya karmaşık tür ya da tensör başına miktarlandırılmış tensör tensörü (C1)

Sınırlamalar

  • (C1) baseline_element_type(a) = baseline_element_type(b).
  • (C2) 2 <= rank(a) = rank(b) = R.
  • (C3) shape(a) ile shape(b) arasındaki ilişki aşağıdaki gibi tanımlanır:
    • shape(a)[:-3] = shape(b)[:-3].
    • dim(a, -2) = dim(a, -1) = dim(b, left_side ? -2 : -1).
  • (C4) baseline_type(b) = baseline_type(result)

Örnekler

// %a = [
//       [1.0, 0.0, 0.0],
//       [2.0, 4.0, 0.0],
//       [3.0, 5.0, 6.0]
//      ]
// %b = [
//       [2.0, 0.0, 0.0],
//       [4.0, 8.0, 0.0],
//       [6.0, 10.0, 12.0]
//      ]
%result = "stablehlo.triangular_solve"(%a, %b) {
  left_side = true,
  lower = true,
  unit_diagonal = false,
  transpose_a = #stablehlo<transpose NO_TRANSPOSE>
} : (tensor<3x3xf32>, tensor<3x3xf32>) -> tensor<3x3xf32>
// %result: [
//           [2.0, 0.0, 0.0],
//           [0.0, 2.0, 0.0],
//           [0.0, 0.0, 2.0]
//          ]

tuple

Anlam

val değerlerinden bir result delmesi oluşturur.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) val değişken değer sayısı (C1)

Çıkışlar

Ad Tür Sınırlamalar
result tuple (C1)

Sınırlamalar

  • (C1) result, Ei = type(val[i]) olduğunda tuple<E0, ..., EN-1> türünde.

Örnekler

// %val0: [1.0, 2.0]
// %val1: (3)
%result = "stablehlo.tuple"(%val0, %val1) : (tensor<2xf32>, tuple<tensor<i32>>) -> tuple<tensor<2xf32>, tuple<tensor<i32>>>
// %result: ([1.0, 2.0], (3))

Diğer Örnekler

uniform_dequantize

Anlam

Ölçülen operand tensörünü öğe bazında bir Tanımlanan miktar belirleme parametrelerine göre result kayan nokta tensörü operand türüne göre.

Daha resmi olarak, result = dequantize(operand).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand nicel tensör (C1), (C2)

Çıkışlar

Ad Tür Sınırlamalar
result kayan nokta türünün tensörü (C1), (C2)

Sınırlamalar

  • (C1) shape(operand) = shape(result).
  • (C2) element_type(result) = expressed_type(operand).

Örnekler

// %operand: [10, 10]
%result = "stablehlo.uniform_dequantize"(%operand) : (tensor<2x!quant.uniform<i8:f32:0, {0.1:-30,0.5:-20}>>) -> tensor<2xf32>
// %result: [4.0, 15.0]

uniform_quantize

Anlam

Kayan nokta tensörünün veya nicelenmiş tensörün öğe tabanlı dönüşümünü gerçekleştirir Miktara göre, result nicelleştirilmiş bir tensöre operand result türü tarafından tanımlanan parametreler.

Daha resmi ifade etmek gerekirse

  • Eğer is_float(operand):
    • result = quantize(operand, type(result)).
  • Eğer is_quantized(operand):
    • float_result = dequantize(operand).
    • result = quantize(float_result, type(result)).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand kayan nokta veya nicelenmiş türde tensor (C1), (C2)

Çıkışlar

Ad Tür Sınırlamalar
result nicel tensör (C1), (C2)

Sınırlamalar

  • (C1) shape(operand) = shape(result).
  • (C2) expressed_type(result) = is_float(operand) ? element_type(operand) : expressed_type(operand).

Örnekler

// %operand: [4.0, 15.0]
%result = "stablehlo.uniform_quantize"(%operand) : (tensor<2xf32>) -> tensor<2x!quant.uniform<i8:f32:0, {0.1:-30,0.5:-20}>>
// %result: [10, 10]

// %operand: [10, 10]
%result = "stablehlo.uniform_quantize"(%operand) : (tensor<2x!quant.uniform<i8:f32:0, {0.1:-30,0.5:-20}>>) -> tensor<2x!quant.uniform<i8:f32:0, {0.1:-20,0.2:-30}>>
// %result: [20, 45]

ancak

Anlam

body işlevinin yürütülmesinden elde edilen çıktıyı 0 veya daha fazla kez üretir. cond işlevi, true çıktısını verir. Daha resmi bir ifadeyle, anlamlar aşağıdaki gibi bir Python söz dizimi kullanarak:

internal_state = operand
while cond(*internal_state):
  internal_state = body(*internal_state)
results = internal_state

Sonsuz döngünün davranışı henüz belli değil (#383).

Girişler

Şirket Ad Tür Sınırlamalar
(I1) operand değişken tensör, nicel tensör veya jeton sayısı (C1-C3)
(I2) cond işlev (C1)
(I3) body işlev (C2)

Çıkışlar

Ad Tür Sınırlamalar
results değişken tensör, nicel tensör veya jeton sayısı (C3)

Sınırlamalar

  • (C1) cond, (T0, ..., TN-1) -> tensor<i1> türünde olup burada Ti = type(operand[i]).
  • (C2) body, (T0, ..., TN-1) -> (T0, ..., TN-1) türünde olup burada Ti = type(operand[i]).
  • (C3) type(results...) = type(operand...).

Örnekler

// %init_i: 1
// %init_sum: 0
// %one: 1
// %ten: 10
%results0, %results1 = "stablehlo.while"(%init_i, %init_sum) ({
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %cond = "stablehlo.compare"(%arg0, %ten) {
      comparison_direction = #stablehlo<comparison_direction LT>
    } : (tensor<i64>, tensor<i64>) -> tensor<i1>
    stablehlo.return %cond : tensor<i1>
  }, {
  ^bb0(%arg0: tensor<i64>, %arg1: tensor<i64>):
    %new_sum = stablehlo.add %arg1, %one : tensor<i64>
    %new_i = stablehlo.add %arg0, %one : tensor<i64>
    stablehlo.return %new_i, %new_sum : tensor<i64>, tensor<i64>
}) : (tensor<i64>, tensor<i64>) -> (tensor<i64>, tensor<i64>)
// %results0: 10
// %results1: 10

Diğer Örnekler

Xor

Anlam

lhs ve rhs iki tensörü için öğe tabanlı XOR gerçekleştirir ve bir result üretir tensördür. Öğe türüne bağlı olarak aşağıdakiler gerçekleşir:

  • Boolelar için: mantıksal XOR.
  • Tam sayılar için: bit tabanlı XOR.

Girişler

Şirket Ad Tür Sınırlamalar
(I1) lhs boole veya tam sayı türündeki tensor (C1)
(I2) rhs boole veya tam sayı türündeki tensor (C1)

Çıkışlar

Ad Tür Sınırlamalar
result boole veya tam sayı türündeki tensor (C1)

Sınırlamalar

  • (C1) type(lhs) = type(rhs) = type(result).

Örnekler

// Bitwise operation with with integer tensors
// %lhs: [[1, 2], [3, 4]]
// %rhs: [[5, 6], [7, 8]]
%result = "stablehlo.xor"(%lhs, %rhs) : (tensor<2x2xi32>, tensor<2x2xi32>) -> tensor<2x2xi32>
// %result: [[4, 4], [4, 12]]

// Logical operation with with boolean tensors
// %lhs: [[false, false], [true, true]]
// %rhs: [[false, true], [false, true]]
%result = "stablehlo.xor"(%lhs, %rhs) : (tensor<2x2xi1>, tensor<2x2xi1>) -> tensor<2x2xi1>
// %result: [[false, true], [true, false]]

Diğer Örnekler

Dialkt Birlikte Çalışabilirlik

Şu anda, doğadaki StableHLO programları bazen StableHLO tarafından tanımlanmaz.

Modül, İşlev, Arama ve İade

StableHLO; ModuleOp, FuncOp, CallOp ve için yukarı akış MLIR işlemlerini kullanır ReturnOp. Bu, mevcut MLIR makineleriyle daha iyi bir faydalı kartlar, FuncOp ile ModuleOp'u hedefleyen yazılı belgeler ve birçok derleme ardışık düzenler bu işlemlerin mevcut olmasını bekler. Tam uyumluluk garantileri bu işlemlere uygulandı. Bu işlemlerde herhangi bir değişiklik olursa uyumlu olmayan bir yöntemle (ör. kaldırma işlemi), StableHLO eşdeğerleri uyumluluk.

CHLO

CHLO işlem kümesi, StableHLO'ya ayrıştırılan üst düzey işlemler içerir. Şu anda CHLO için uyumluluk garantisi yoktur. Uyumluluk için chlo-legalize-to-stablehlo kartı serileştirmeden önce kullanılmalıdır.

Şekil İşlemleri

Temelden belirli işlemlerin kullanılması toplulukta yaygın bir kullanım örneğidir. Dinamik StableHLO programlarında MLIR, şekil hesaplamaları yapmak için diyalekt kullanır. Bunlar en yaygın olarak shape lehçesini içerir. shape_of veya num_elements gibi işlemler, tensor diyalekt dim veya from_elements gibi işlemler ve yerleşik index türü.

Dynamism RFC > O2 bunları kapsam dışı olarak belirtir, ancak index türleri için bazı destek birlikte çalışabilirlik amacıyla kullanılabilir. Bunlar için uyumluluk garantisi yoktur olanak sağlar. shape-legalize-to-stablehlo bu işlemleri tam olarak desteklenen StableHLO operasyonlarına dönüştürmek için kullanılabilir.

Kullanımdan Kaldırılan İşlemler

Devralınan birkaç StableHLO işlemi var: MHLO ve artık StableHLO'dan çıkacaklar. Bu konularla ilgili tüm ayrıntılar kaldırma işlemlerini StableHLO v1.0 Temizleme #2283 içinde bulabilirsiniz. Bu kullanımdan kaldırmalarla ilgili takip sorunu #2340'tır.

Bu işlemler birkaç kategoriye ayrılır:

  • "HLO yok" Bunlar, StableHLO operasyonları kategorisiydi. Bunlar başlangıçta StableHLO işletim sistemini, ancak daha sonra uygun olmadığına karar verildi: broadcast, create_token, cross-replica-sum, dot, einsum, torch_index_select, unary_einsum (#3).
  • Kullanılmayan işlemler: Bu işlemler bir noktada yararlı olabilir, ancak ya da bu işlemleri kullanan ardışık düzenler gereklilikleri ortadan kaldıracak şekilde yeniden düzenlendi. Bunlar arasında map, tuple (#598), get_tuple_element, rng, complex karşılaştırma #560, ve evrişim window_reversal (#1181).

Bu işlemlerden bazıları mevcut işlemler (broadcast, create_token, cross-replica-sum, dot, unary_einsum) ve mevcut uyumluluk penceresinden sonra kaldırılacak. kullanım hakkı (6 ay). Diğerleri kaldırılmak üzere araştırılıyor (einsum, get_tuple_element, map, rng torch_index_select, tuple, complex karşılaştırmalar, window_reversal). Topluluk geri bildirimi bekliyorum, bu işlemler kaldırılacak veya tam destekle spesifikasyona eklenecektir. Bitiş bu işlem gelecekleri biliniyor, yalnızca 6 ay uyumluluğu garanti edilir.

Yürütme

Sıralı yürütme

Bir StableHLO programı, main işlevine giriş değerleri sağlanarak yürütülür ve çıkış değerlerini hesaplayabilirsiniz. Bir fonksiyonun çıkış değerleri şöyle hesaplanır: karşılık gelen return işlemindeki kök işlemleri grafiğini yürütme

Yürütme siparişi, veri akışı (ör. işlemler kullanımlarından önce yürütülürse). StableHLO'daki tüm Operasyonel bir jeton tüketip bir jeton üretir (birden fazla jeton after_all aracılığıyla tek bir jetonda çoğulalan) olması gerekir; bu nedenle, ve efektler de veri akışıyla uyumludur. Örneğin, bu programda Olası iki yürütme siparişi vardır: %0%1%2return ve %1%0%2return.

func.func @main() -> tensor<f64> {
  %0 = stablehlo.constant dense<1.0> : tensor<f64>
  %1 = stablehlo.constant dense<2.0> : tensor<f64>
  %2 = stablehlo.add %0, %1 : tensor<f64>
  return %2 : tensor<f64>
}

Daha resmi bir ifadeyle, StableHLO süreci şunların birleşiminden oluşur: 1) StableHLO programı, 2) çalışma durumları (henüz yürütülmemiştir, zaten yürütülmüş olması) ve 3) sürecin üzerinde çalıştığı ara değerler. İşlem, main işlevine giriş değerleriyle başlar ve süreç boyunca işlem durumlarını ve ara değerleri güncelleyen işlemlerin grafiği bitiş değerleriyle bitirir. Daha resmi açıklama henüz belli değil (#484).

Paralel yürütme

StableHLO programları, 2D süreç ızgarası şeklinde düzenlenmiş, paralel olarak yürütülebilir (her ikisi de ui32 türünde olan) num_partitions bazında num_replicas.

StableHLO süreç ızgarasında, StableHLO'nun num_replicas * num_partitions aynı anda yürütüldüğünden emin olmanız gerekir. Her sürecin kendine özgü bir process_id = (replica_id, partition_id), burada: replica_ids = range(num_replicas) içinde replica_id ve partition_ids = range(num_partitions) içinde her ikisi de olan partition_id ui32 yazın.

Süreç çizelgesinin boyutu her program için statik olarak bilinir ( gelecekte bunu StableHLO programlarının bir parçası yapmayı planlıyoruz. #650) ve konumun her süreç için statik olarak bilinir. Her süreç ve onun süreç tablosundaki konumuna replica_id ve partition_id işlem

Süreç çizelgesinde programların tümü aynı olabilir ("Tek Program, Çoklu Veri" stili) tümü farklı olabilir ("Birden Çok Program'da, Çoklu Veri" veya bunların arasında başka bir şey vardır. Gelecekte, paralel StableHLO programları tanımlamaya yönelik diğer deyimler için destek sağlamak GSPMD (#619) dahil.

Süreç çizelgesinde süreçler büyük ölçüde birbirinden bağımsızdır. ayrı işlem durumları, ayrı giriş/ara/çıkış değerleri vardır İşlemlerin çoğu süreçler arasında ayrı ayrı yürütülür, (aşağıda açıklanan az sayıda ortak işlem hariçtir.)

Çoğu işlemin yürütülmesi sırasında yalnızca aynı bu değerlere adlarıyla atıfta bulunmak genellikle belirsizdir. Ancak toplu işlemlerin anlamını açıklarken bu yeterli değildir ve name değerini ifade etmek için name@process_id gösterimini oluşturan belirli bir süreç içinde yürütülür. (Bu açıdan bakıldığında, uygun olmayan name (name@(replica_id(), partition_id()) için kısaltma olarak görüntülendi).

Süreçlerdeki yürütme sırası, Noktadan noktaya iletişim ve toplu işlemlerle sağlanan senkronizasyon gerekir.

Bire bir iletişim

StableHLO süreçleri StableHLO kanalları. Kanal, pozitif bir kimlik türü ile temsil edilir si64 Çeşitli operasyonlar yoluyla, kanallara ve değerlerine, anlayabiliyoruz.

Daha resmi hale getirme, ör. ve bu kanal kimliklerinin nereden geldiğini farkında olmasını sağlayan işlemler ve bu süreçlerin tarafından başlatılmış, henüz belli değil (#484).

Akış iletişimi

Her StableHLO işleminin iki akış arayüzüne erişimi vardır:

  • Okunabilen feed içi öğeler.
  • Yazılabilecek özet feed'i.

Süreçler arasında iletişim kurmak için kullanılan kanalların aksine, Her iki ucunda da süreçlere sahip olmakla birlikte, feed içi ve çıkışların tanımlanmıştır.

Daha resmi hale getirme, ör. Akışlı iletişimin yürütmeyi nasıl etkilediği bu işlemin ne tür bir senkronizasyona yol açtığına dair (#484).

Ortak operasyonlar

StableHLO'da altı ortak operasyon vardır: all_gather, all_reduce, all_to_all, collective_broadcast, collective_permute ve reduce_scatter. Tüm bu işlemler, StableHLO sürecindeki süreçleri böler StableHLO süreç gruplarına ayırır ve diğer süreç gruplarından bağımsız olarak her işlem grubuna atanır.

Her işlem grubu içinde toplu işlemler bir senkronizasyona neden olabilir. engel oluşturabilirsiniz. Daha resmi hale getirme, ör. tam olarak bunun ne zaman süreçlerin bu engele tam olarak nasıl ulaştığını, yoksa ne olacağı ise henüz belli değil. (#484).

Süreç grubunda bölümler arası iletişim varsa (diğer bir deyişle, işlem grubunda, bölüm kimlikleri farklı olan işlemler ve ardından yürütme kolektif operasyonun bir kanala ihtiyacı var; kolektif operasyonun ise si64 türünde pozitif channel_id. Çapraz kopya iletişimde kanallar.

Toplu işlemler tarafından gerçekleştirilen hesaplamalar, bağımsız operasyonlara özgüdür ve yukarıdaki bağımsız operasyon bölümlerinde açıklanmaktadır. Ancak proje yöneticilerinin Kılavuz, süreç gruplarına ayrılır ve bu operasyonlar arasında paylaşılır. ve bu bölümde açıklanmıştır. Daha resmi bir ifadeyle, StableHLO dört strateji uygulayarak.

cross_replica

Her işlem grubu içinde yalnızca çapraz replikalı iletişimler gerçekleşir. Bu stratejisi, replica_groups (replika kimlikleri listesi) ve hesaplamalar listesi alır partition_ids tarafından replica_groups ürününe ait bir Kartezyen ürün. replica_groups. benzersiz öğelere sahip olmalı ve tüm replica_ids öğelerini kapsamalıdır. Daha resmi ifade etmek gerekirse Python söz dizimi:

def cross_replica(replica_groups: List[List[ReplicaId]]) -> List[List[ProcessId]]:
  for replica_group in replica_groups:
    for partition_id in partition_ids:
      process_group = []
      for replica_id in replica_group:
        process_group.append((replica_id, partition_id))
      yield process_group

Örneğin, replica_groups = [[0, 1], [2, 3]] ve num_partitions = 2 için cross_replica şunu üretecek: [[(0, 0), (1, 0)], [(0, 1), (1, 1)], [(2, 0), (3, 0)], [(2, 1), (3, 1)]].

cross_partition

Her süreç grubu içinde yalnızca bölümler arası iletişimler gerçekleşir. Bu stratejisi partition_groups (bölüm kimlik listesi listesi) ve replica_ids tarafından partition_groups değerindeki bir Kartezyen ürünü hesaplar. partition_groups benzersiz öğelere sahip olmalı ve tüm partition_ids öğelerini kapsamalıdır. Daha resmi bir ifadeyle, Python söz dizimini kullanarak:

def cross_partition(partition_groups: List[List[PartitionId]]) -> List[List[ProcessId]]:
  for partition_group in partition_groups:
    for replica_id in replica_ids:
      process_group = []
      for partition_id in partition_group:
        process_group.append((replica_id, partition_id))
      yield process_group

Örneğin, partition_groups = [[0, 1]] ve num_replicas = 4 için cross_partition şunu üretecek: [[(0, 0), (0, 1)], [(1, 0), (1, 1)], [(2, 0), (2, 1)], [(3, 0), (3, 1)]].

cross_replica_and_partition

Her ikisinde de hem çapraz hem de bölümler arası iletişimler gerçekleşebilir işlem grubudur. Bu strateji replica_groups - replika kimlikleri - ve her bir replica_group öğesinin Kartezyen ürünlerini partition_ids. replica_groups benzersiz öğelere sahip olmalı ve tüm öğeleri kapsamalıdır replica_ids. Daha resmi bir ifadeyle, Python söz dizimini kullanarak:

def cross_replica_and_partition(replica_groups: List[List[ReplicaId]]) -> List[List[ProcessId]]:
  for replica_group in replica_groups:
    process_group = []
    for partition_id in partition_ids:
      for replica_id in replica_group:
        process_group.append((replica_id, partition_id))
    yield process_group

Örneğin, replica_groups = [[0, 1], [2, 3]] ve num_partitions = 2 için cross_replica_and_partition şunu üretecek: [[(0, 0), (1, 0), (0, 1), (1, 1)], [(2, 0), (3, 0), (2, 1), (3, 1)]].

flattened_ids

Bu strateji flattened_id_groups ("birleştirilmiş" listelerden oluşan bir liste) alıyor replica_id * num_partitions + partition_id biçiminde işlem kimlikleri - ve bunları işlem kimliklerine dönüştürür. flattened_id_groups benzersiz öğelere sahip olmalıdır ve tüm process_ids öğelerini kapsamalıdır. Daha resmi bir ifadeyle, Python söz dizimini kullanarak:

def flattened_ids(flattened_id_groups: List[List[ui32]]) -> List[List[ProcessId]]:
  for flattened_id_group in flattened_id_groups:
    process_group = []
    for flattened_id in flattened_id_group:
      replica_id = flattened_id // num_partitions
      partition_id = flattened_id % num_partitions
      process_group.append((replica_id, partition_id))
    yield process_group

Örneğin, flattened_id_groups = [[0, 1, 2, 3], [4, 5, 6, 7]] için num_replicas = 4 ve num_partitions = 2, flattened_ids şunları üretecek: [[(0, 0), (0, 1), (1, 0), (1, 1)], [(2, 0), (2, 1), (3, 0), (3, 1)]].

Doğruluk

Şu anda StableHLO, sayısal doğruluk ve ancak bu durum ileride değişebilir (#1156).

Ölçülen işlemin yürütme anlamı

Ölçülen StableHLO işlemlerinin yorumlanması donanım gereksinimleri ve özellikleri. Örneğin, bazı donanımlar "dequantize, gerçekleştirme kayan nokta ve son olarak da nicel olarak üzerine konuşacağız. Bazıları ise tüm etkinliği tamsayı aritmetiği ile hesaplama. Sonuç olarak, miktarlandırılmış StableHLO işlemleri, hakkında bilgi edindiniz. Karma niceliğin yorumlanması (#1575) değeri, teknik özellikleri belirtildiği gibi ( 1792).

Hatalar

StableHLO programları, ayrı ayrı işlem yapılmasını sağlar. Bu yöntem, çalışma zamanından önce birçok hata sınıfını ortadan kaldırır. Ancak hata koşulları yine de mümkündür, ör. tamsayı taşmaları sayesinde sınır dışı erişimler vb. olabilir. Açıkça belirtilmediği sürece tüm bu hatalar tanımlı davranışla sonuçlanır, ancak bu durum (#1157).

Kayan nokta istisnaları

Bu kurala bir istisna olarak, StableHLO programlarındaki kayan nokta istisnaları iyi tanımlanmış davranışlara sahiptir. IEEE-754 standardı (geçersiz işlem, sıfıra bölme, taşma, yetersiz veya kesin olmayan istisnalar) üretmesi (standartta tanımlandığı şekilde) ve karşılık gelen durum işaretini kaldırmadan yürütmeye devam etme; şunlara benzer: Standarttan raiseNoFlag istisna işleme. Standart dışı durumlar için istisnalar işlemler (ör. karmaşık aritmetik ve belirli yüksek sayıdaki fonksiyonlar) tanımlanmıştır.

Şekil uyuşmazlıkları

StableHLO, dinamik olarak şekilli tensörleri destekler. Ancak şekillerin hemfikir olması hem de aksi takdirde davranış tanımsızdır. StableHLO, bir tensörün çalışma zamanında belirli bir şekle sahip olduğunu gösterebilecek bir işlem sağlar. Doğru kodun oluşturulması yapımcının sorumluluğundadır.

Somut bir örnek vermek gerekirse aşağıdaki programın geçerliliği vardır. Ancak çalışma zamanında %arg0 ve %arg1 tam şekillerinin aynı olması gerekir, aksi halde programın davranışı tanımsızdır:

func.func @foo(%arg0: tensor<?xi32>, %arg1: tensor<?xi32>) -> tensor<?xi32> {
    %0 = stablehlo.add %arg0, %arg1 : tensor<?xi32>
    return %0 : tensor<?xi32>
}

Notasyon

Bu dokümanda, söz diziminin açıklanması için EBNF'nin değiştirilmiş ISO biçimi kullanılmaktadır söz dizimine (ISO/IEC 14977:1996, Vikipedi), iki değişiklikle birlikte: 1) kurallar = yerine ::= kullanılarak tanımlanır,

2) birleştirme, , yerine yan yana konum kullanılarak ifade edilir.

Anlamları açıklamak için (ör. "Türler", "Sabitler" ve "İşlemler" bölümlerinde) Python söz dizimine dayalı formüller kullanıyoruz. dizi işlemlerini aşağıda açıklandığı gibi kısa bir şekilde ifade etmek için kullanılır. Bu, işe yarıyor küçük kod snippet'leri için, ancak nadiren de olsa daha büyük kod snippet'leri her zaman açıkça ortaya konulan vanilla Python söz dizimini kullanırız.

Formüller

dot_general bakın. Bu işlemin kısıtlamalarından biri şu şekilde görünür: dim(lhs, lhs_batching_dimensions...) = dim(rhs, rhs_batching_dimensions...)

Bu formülde kullanılan adlar iki kaynaktan gelir: 1) genel işlevler, Ör. dim, 2) ilgili program öğesinin üye tanımları, ör. lhs, lhs_batching_dimensions, rhs ve rhs_batching_dimensions girişleri "Girişler" bölümünde bölümünde (dot_general) görebilirsiniz.

Yukarıda belirtildiği gibi, bu formülün söz dizimi Python tabanlıdır ve uzantılarınızın kısa ve öz olmasını sağlayın. Formülü anlamak için, dönüşüm izlemeyi vanil Python söz dizimine dönüştürmenizi sağlar.

A) Bu formüllerde eşitliği temsil etmek için = kullanıyoruz, bu nedenle ilk adım = değerini == ile değiştirmek, Python söz dizimini elde etmek için aşağıdaki gibidir: dim(lhs, lhs_batching_dimensions...) == dim(rhs, rhs_batching_dimensions...).

B) Ayrıca, bu formüller skaler ifadeleri dönüştüren elipsleri (...) destekler tensör ifadelerine dönüştürebilirsiniz. Özetle, f(xs...) kabaca "her biri için xs tensöründeki skaler x, bir skaler f(x) hesaplayın ve ardından hepsini döndürün bu skaler sonuçları bir tensör sonucu olarak birleştiriyoruz". Vanilla Python söz diziminde, örnek formülümüz şuna dönüşür: [dim(lhs, dim1) for dim1 in lhs_batching_dimensions] == [dim(rhs, dim2) for dim2 in rhs_batching_dimensions]

Elipsler sayesinde genelde sabit bir seviyede çalışmak kullanabilirsiniz. Ancak bazı yanıltıcı örneklerde, daha düşük düzeyde söz dizimi, start_indices[bi0, ..., :, ..., biN] formülündeki gibi kullanılabilir gather spesifikasyonundan. Kısa ve öz yazım sağlamak amacıyla bu tür söz dizimini vanilla Python'a çevirmek için kesin bir biçimsellik sağlamak her örnek için sezgisel olarak anlaşılır olmasını umuyor. Bazı formüller opak görünüyorsa lütfen bize bildirin. Bu durumda, yardımcı olabilir.

Ayrıca, formüllerin her tür listeyi genişletmek için elipsler kullandığını fark edeceksiniz. tensörler ve tensör listeleri de dahil olmak üzere (örneğin, tensör sayısı) veriyorum. Bu, kesin bir veri sağlamadığımız bir başka alandır. biçimsellik (örneğin, listeler StableHLO türü sistemin bir parçası bile değildir) ve sezgisel anlaşılabilirliğe dayanır.

C) Kullandığımız son önemli notasyon aracı, üstü kapalıdır yayınlama. StableHLO işletim sistemi örtülü yayını desteklemese de aynı zamanda kısa ve öz yazın. Özetle, skaler bir veri bir tensörün beklendiği durumlarda kullanıldığında, skaler sağlayabilir.

dot_general örneğine devam etmek için başka bir kısıtlama şu şekildedir: 0 <= lhs_batching_dimensions < rank(lhs). dot_general içinde tanımlandığı şekilde spesifikasyonlarında, lhs_batching_dimensions bir tensördür, ancak hem 0 hem de rank(lhs) skaler değerlerdir. Dolaylı yayın uygulandıktan sonra, formül [0, ..., 0] <= lhs_batching_dimensions < [rank(lhs), ..., rank(lhs)] olur.

Bu formül belirli bir dot_general işlemine uygulandığında boole tensörüne dönüştürün. Formüller kısıtlama olarak kullanıldığında, kısıt, formül true veya sonuç veren bir tensör olarak değerlendirilirse yalnızca true öğeleri içeriyor.

Adlar

Formüllerde sözlüksel kapsam şunları içerir: 1) genel işlevler, 2) üye tanımları,

3) yerel tanımlar. Genel işlevlerin listesi aşağıda verilmiştir. Liste öğe tanımları, gösterimin temsil edildiği program öğesine bağlıdır uygulandı:

  • İşlemler için üye tanımları, "Girişler"de sunulan adları da içerir. ve "Çıkışlar" bölümlerini kontrol edin.
  • Diğer her şey için de üye tanımları, program öğesi. Çoğu Bu yapısal parçaların adları, zaman içinde yılan şeklinde büyük/küçük harfe duyarlı olmayan terminallerin adları (ör. IntegerLiteral => integer_literal), ancak bazen adlar işlem sırasında kısaltılır (ör. QuantizationStorageType => storage_type) olmalıdır; bu durumda adlar "Girdiler"e açıkça benzer şekilde tanıtıldı / "Çıkışlar" faaliyetteki bölümler özellikler.
  • Ayrıca, üye tanımlarındaself ilgili program öğesine dokunun.

Değerler

Formüller değerlendirilirken aşağıdaki değer türleriyle çalışır: 1) Value (gerçek değerler, ör. dense<[[1, 2], [3, 4]]> : tensor<2x2xi32>; türlerini daima bilirler.) 2) Placeholder (gelecekteki değerler, ör. lhs, rhs veya result; asıl değerleri değerler henüz bilinmiyor, yalnızca türleri bilinmektedir). 3) Type ("Türler" bölümünde tanımlandığı şekilde türler), 4) Function ("İşlevler" bölümünde tanımlandığı şekliyle genel işlevler).

Bağlama göre adlar farklı değerleri ifade ediyor olabilir. Daha fazla “Anlambilim” işlemler (ve diğer programın eşdeğerleri) bölümü öğeleri) çalışma zamanı mantığını tanımlar. Bu nedenle, tüm girişler Value olarak kullanılabilir. Öte yandan "Sınırlamalar" bölümünde, DMAIC ve Yalın Altı Sigma yaklaşımının "derleme-süresi" mantıksal, yani genellikle çalışma zamanından önce yürütülen bir işlem, Bu nedenle, Value olarak sadece sabit girişler kullanılabilir ve diğer girişler yalnızca Placeholder olarak kullanılabilir.

Adlar "Anlambilim" bölümünde "Kısıtlamalar" bölümünde
Genel işlevler Function Function
Sabit girişler Value Value
Sabit olmayan girişler Value Placeholder
Çıkışlar Value Placeholder
Yerel tanımlar Tanıma bağlıdır. Tanıma bağlıdır.

Örnek bir transpose işlemini inceleyelim:

%result = "stablehlo.transpose"(%operand) {
  permutation = dense<[2, 1, 0]> : tensor<3xi64>
} : (tensor<2x3x2xi32>) -> tensor<2x3x2xi32>

Bu işlem için permutation sabit olduğundan Value olarak kullanılabilir ve kısıtları yoktur. Öte yandan operand ve result, anlamsal olarak bir Value olarak, ancak kısıtlamalarda yalnızca Placeholder olarak kullanılabilir.

İşlevler

Tür oluşturma

Türleri oluşturmak için kullanılabilecek işlev yoktur. Bunun yerine genelde daha kısa ve öz olduğundan tür söz dizimini kullanın. Ör. function_type( [tensor_type([], E), tensor_type([], E)], [tensor_type([], E)]) yerine (tensor<E>, tensor<E>) -> (tensor<E>).

Türlerdeki işlevler

  • element_type, tensör türlerinde ve nicelenmiş tensör türlerinde tanımlanır ve sırasıyla TensorElementType veya QuantizedTensorElementType değerini döndürür (ilgili TensorType veya QuantizedTensorType)
def element_type(x: Value | Placeholder | Type):
 if type(x) == TensorType:
    return tensor_element_type(x)
  if type(x) == QuantizedTensorType:
    return quantized_tensor_element_type(x)
  if type(x) is not Type:
    return element_type(type(x))
  • is_per_axis_quantized(x: Value | Placeholder | Type) -> Value bir kısayoldur (is_quantized(x) and quantization_dimension(x) is not None için).

  • is_per_tensor_quantized(x: Value | Placeholder | Type) -> Value bir is_quantized(x) and quantization_dimension(x) is None kısayolu.

  • is_promotable(x: Type, y: Type) -> bool, x türünün tanıtılıp tanıtılamayacağını kontrol eder y yazın. x ve y QuantizedTensorElementType olduğunda promosyon yalnızca storage_type öğesine uygulanır. Promosyonun bu versiyonu şu anda indirgenme hesaplaması bağlamında kullanılmaktadır (bkz. RFC'de bulabilirsiniz).

def is_promotable(x: Type, y: Type) -> Value:
  is_same_type = (is_bool(x) and is_bool(y)) or
    (is_integer(x) and is_integer(y)) or (is_float(x) and is_float(y)) or
    (is_complex(x) and is_complex(y)) or
    (is_quantized(x) and is_quantized(y) and expressed_type(x) = expressed_type(y))

  if is_same_type == False:
    return False

  if is_integer(x) or is_float(x):
    return bitwidth(x) <= bitwidth(y)

  if is_complex(x):
    return bitwidth(element_type(x)) <= bitwidth(element_type(y))

  if is_quantized(x):
    return bitwidth(storage_type(x)) <= bitwidth(storage_type(y))

  return false
  • is_quantized(x: Value | Placeholder | Type) -> Value şunun kısayoludur: is_quantized_tensor_element_type(x).

  • is_type_name(x: Value | Placeholder | Type) -> Value Herkes için kullanılabilir bulunur. Örneğin, x bir FloatType ise is_float(x), true değerini döndürür. x bir değer veya yer tutucuysa bu işlev is_type_name(type(x)).

  • max_value(x: Type) -> Value, TensorElementType. x bir TensorElementType değilse None değerini döndürür.

  • min_value(x: Type) -> Value, bir TensorElementType. x bir TensorElementType değilse None değerini döndürür.

  • member_name(x: Value | Placeholder | Type) -> Any Tüm üyeler tarafından kullanılabilir her türden member_name tanımlar. Örneğin, tensor_element_type(x) karşılık gelen TensorType öğesinin TensorElementType bölümünü döndürür. x bir değer veya yer tutucuysa bu işlev member_name(type(x)). x, uygun üyeye sahip bir tür değilse veya bir değer veya böyle bir tür yer tutucusu None değerini döndürür.

  • is_empty_algorithm(*args: Type), tüm nokta algoritması alanlarının ayarlanıp ayarlanmadığını kontrol eder Hedef: None. Nokta algoritmalarında uygulama tanımı yapıldığından bu gereklidir bu nedenle değer belirtmek yanlış olur.

Değerlerin oluşturulması

  • operation_name(*xs: Value | Type) -> Value Tüm işlemler için kullanılabilir. Örneğin, add(lhs, rhs), lhs ve rhs olmak üzere iki tensör değeri alır ve add işlemini bu girişlerle değerlendirmenin sonucunu döndürür. Bazı işlemler için, ör. broadcast_in_dim, çıkış türleri "yük taşıyan", yani bir işlemi değerlendirmek için gereklidir. Bu durumda, bunları bağımsız değişken olarak kabul eder.

Değerlere dayalı işlevler

  • Python'un tüm operatörleri ve işlevleri kullanılabilir. Ör. her ikisi abonelik ve dilimlere ayırma Python'daki gösterimler, tensörlere, miktarlandırılmış tensörlere dizine eklemek için kullanılabilir ve demetler.

  • to_destination_type(x: Value, destination_type: Type) -> Value şurada tanımlandı: tensörler ile type(x) ve özelliklerine göre dönüştürülmüş x değerini döndürür destination_type şu şekildedir:

def to_destination_type(x: Value, destination_type: Type) -> Value:
  if type(x) == destination_type:
    return x

  if is_quantized(destination_type):
    if is_quantized(type(x)):
      return quantize(x, destination_type)
    assert is_float(type(x))
    return quantize(x, destination_type)

  if is_quantized(type(x)):
    assert destination_type = expressed_type(type(x))
    return dequantize(type(x))

  return convert(x, destination_type)

convert, uniform_quantize ve uniform_dequantize işlemleri (#1576). Birleştirmeden sonra yukarıdaki işleve gerek duymayız ve işlem adını kullanabiliriz. Bunun yerine convert için.

  • is_nan(x: Value) -> Value, tensörlerde tanımlanır ve şu durumlarda true değerini döndürür: x öğesinin tüm öğeleri NaN veya false öğesidir. x bir tensör değilse None değerini döndürür.

  • is_sorted(x: Value) -> Value, tensörlerde tanımlanır ve şu durumlarda true değerini döndürür: x öğeleri artan düzende, artan düzende sıralanır veya false kullanılması şart değildir. x bir tensor, None değerini döndürür.

  • is_unique(x: Value) -> Value, tensörlerde tanımlanır ve x ise true değerini döndürür yinelenen öğeler veya false içermiyor. x bir tensör değilse None değerini döndürür.

  • Tüm üye tanımları için member_name(x: Value) -> Any tanımlandı Tüm değerlerin member_name kadarı. Örneğin, real_part(x), RealPart değerini döndürür. bir bölümü için ödeme yaparsınız.ComplexConstant x, uygun üye, None değerini döndürür.

  • same(x: Value) -> Value, tensörlerde tanımlanır ve şu durumlarda true değerini döndürür: x öğelerinin tümü birbirine eşit veya aksi takdirde false. Tensör "hepsi birbirine eşit" olarak kabul edilen, yani işlevi true değerini döndürür. x bir tensör değilse None değerini döndürür.

  • split(x: Value, num_results: Value, axis: Value) -> Value şurada tanımlandı: tensörler ve axis ekseni üzerinde num_results x dilimleri döndürür. x bir tensör veya dim(x, axis) % num_results != 0 değilse None değerini döndürür.

  • is_defined_in_parent_scope(x: Value) -> Value dizelerde tanımlı ve x aynı kapsamda tanımlanan bir işlevin adıysa true değerini döndürür ilgili işlemin ana işlevi olarak kullanılır.

  • is_namespaced_op_name(x: Value) -> Value, dizelerde ve iadelerde tanımlanır x geçerli bir işlem adıysa true ifade: [a-zA-Z][a-zA-Z0-9_]*([.][a-zA-Z0-9_$]+)+

Şekil hesaplamaları

  • axes(x: Value | Placeholder | Type) -> Value şunun kısayoludur: range(rank(x)).

  • dim(x: Value | Placeholder | Type, axis: Value) -> Value şunun kısayoludur: shape(x)[axis].

  • dims(x: Value | Placeholder | Type, axes: List) -> List şunun kısayoludur: list(map(lambda axis: dim(x, axis), axes)).

  • index_space(x: Value | Placeholder | Type) -> Value, tensörlerde tanımlandı ve aşağıdaki dizinde sıralanmış karşılık gelen TensorType için size(x) dizin döndürür artan sözlük sıralaması, ör. [0, ..., 0], [0, ..., 1], ..., shape(x) - 1. x bir tensör türü, nicelenmiş tensör türü veya bir değer değilse veya bu türlerden birinin yer tutucusu None değerini döndürür.

  • rank(x: Value | Placeholder | Type) -> Value şunun kısayoludur: size(shape(x)).

  • shape(x: Value | Placeholder | Type) -> Value, "İşlevler" içinde tanımlanmış türlerde" bölümüne member_name üzerinden ulaşabilirsiniz.

  • size(x: Value | Placeholder | Type) -> Value şunun kısayoludur: reduce(lambda x, y: x * y, shape(x)).

Nicelendirme hesaplamaları

  • def baseline_element_type(x: Value | Placeholder | Type) -> Type bir element_type(baseline_type(x)) kısayolu.

  • baseline_type, tensör türlerinde ve nicelenmiş tensör türlerinde tanımlanır ve bunları "referans çizgisine" (yani aynı şekle sahip ancak öğe türünün niceleme parametreleri varsayılan değerlere sıfırlanır. Bu tensör ve nicel tensör türlerini karşılaştırmak için kullanışlı bir yöntem olarak kullanılmıştır eşit şekilde çalışıyor. Bu da oldukça sık ihtiyaç duyuyor. Bu, miktarlandırılmış türlerde yok sayarak türlerin karşılaştırılması (shape, storage_type, expressed_type, storage_min, storage_max ve quantization_dimension (eksen başına miktarlandırılmış tür için) değerinin tümü eşleşmelidir, ancak scales ile zero points farklı olabilir.

def baseline_type(x: Value | Placeholder | Type) -> Type:
  if type(x) == TensorType:
    return x
  if type(x) == QuantizedTensorType:
    element_type = quantized_tensor_element_type(x)
    baseline_element_type = QuantizedTensorElementType(
      storage_type = storage_type(element_type),
      storage_min = storage_min(element_type),
      storage_max = storage_max(element_type),
      expressed_type = expressed_type(element_type),
      quantization_dimension = quantization_dimension(element_type),
      scales = [constant(1.0, expressed_type(element_type))] * dim(x, quantization_dimension(element_type)),
      zero_points = [constant(0, storage_type(element_type))] * dim(x, quantization_dimension(element_type)))
    return QuantizedTensorType(shape(x), baseline_element_type)
  if type(x) is not Type:
    return baseline_element_type(type(x))
  • dequantize, nicel tensör türlerinde tanımlanır ve bunları şuna dönüştürür: kayan nokta tensörü türlerine örnek verilebilir. Bu, nicelenmiş öğelerin dönüştürülmesiyle gerçekleşir depolama türünün tam sayı değerlerini karşılık gelen sıfır noktası ve ölçeği kullanılarak ifade edilen türün kayan nokta değerleri ölçülebilir öğe türüyle ilişkilidir.
def compute_zero_points(quantized_type, result_type):
  if is_per_tensor_quantized(quantized_type):
    return broadcast_in_dim(constant(zero_point(quantized_type), storage_type(quantized_type)), [], result_type)
  if is_per_axis_quantized(quantized_type):
    for i in index_space(result_type):
      d = quantization_dimension(quantized_type)
      zero_points[i] = zero_points(quantized_type)[i[d]]
    return zero_points

def compute_scales(quantized_type, result_type):
  if is_per_tensor_quantized(quantized_type):
    return broadcast_in_dim(constant(scale(quantized_type), expressed_type(quantized_type)), [],
            type(result_type))
  if is_per_axis_quantized(quantized_type):
    for i in index_space(result_type):
      d = quantization_dimension(quantized_type)
      scales[i] = scales(quantized_type)[i[d]]
    return scales

def dequantize(x: Value) -> Value:
  assert is_quantized(x)
  x_storage = bitcast_convert(x, storage_type(x))
  x_storage_sub = x_storage - compute_zero_points(type(x), type(x_storage))
  x_expressed_sub = convert(x_storage_sub, expressed_type(x))
  return x_expressed_sub * compute_scales(type(x), type(x_expressed_sub))
  • quantize, kayan nokta tensör türlerinde tanımlanır ve bunları şuna dönüştürür: nicel tensör türlerine bakalım. Bu, kayan nokta değerlerini dönüştürerek gerçekleşir depolama türünün karşılık gelen tam sayı değerlerine ifade edilen türün kullanılan öğe türüyle ilişkili sıfır noktası ve ölçeğin kullanılmasıdır.
def quantize(x: Value, result_type: Type) -> Value:
  assert is_float(x) and is_quantized(result_type)
  zero_points = compute_zero_points(result_type, TensorType(shape(x), storage_type(result_type)))
  converted_zero_points = convert(zero_points, expressed_type(result_type))
  converted_min = convert(storage_min(result_type), expressed_type(result_type))
  converted_max = convert(storage_max(result_type), expressed_type(result_type))

  x_scaled = x / compute_scales(result_type, type(x))
  x_scaled_add_zp = x_scaled + converted_zero_points
  x_clamped = clamp(converted_min, x_scaled_add_zp, converted_max)
  x_rounded = round_nearest_even(x_clamped)
  return convert(x_rounded, result_type)
  • dequantize_op_quantize, nicelleştirilmiş tensörler. Miktarı belirler, yani nicelleştirilmiş öğeleri ardından bir işlem gerçekleştirir ve ardından nicelik olarak ifade eder. Diğer bir deyişle, depolama türüne geri döner. Şu anda bu işlev yalnızca tensör başına miktar belirleme için kullanılır. Eksen başına miktar belirleme işlemi devam ediyor (#1574).
def dequantize_op_quantize(op, *inputs_and_output_type):
  inputs = inputs_and_output_type[:-1]
  output_type = inputs_and_output_type[-1]

  float_inputs = map(dequantize, inputs)
  float_result = op(*float_inputs)
  return quantize(float_result, output_type)

def dequantize_batch_norm_grad_or_training_quantize(op, *inputs_and_output_types):
  inputs = inputs_and_output_type[:-3]
  float_inputs = map(dequantize, inputs)
  float_results = op(*float_inputs)
  return map(quantize, float_results, inputs_and_output_type[-3:])

def dequantize_compare(lhs, rhs, comparison_direction):
  float_lhs = dequantize(lhs)
  float_rhs = dequantize(rhs)
  return compare(float_lhs, float_rhs, comparison_direction, FLOAT)

def dequantize_select_quantize(pred, on_true, on_false, output_type):
  float_on_true = dequantize(on_true)
  float_on_false = dequantize(on_false)
  float_result = select(pred, float_on_true, float_on_false)
  return quantize(float_result, output_type)
  • hybrid_dequantize_then_op, şunlar için yalnızca ağırlık miktarını belirtmek için kullanılır: Kayan noktalı türlerde lh ve rhs kabul eden karma işlem. Google nicel girdileri ifade edilen türlerine göre ayırır ve hesaplama yapar kullanabilirsiniz. Kayan lhs tensörünün öğe türü ve ölçülen rh'lerin ifade edilen türü tensör aynı olmalıdır.
def hybrid_dequantize_then_op(op, lhs, rhs):
  assert(is_float(lhs) and is_quantized(rhs) and element_type(lhs) == expressed_type(rhs))
  return op(lhs, dequantize(rhs))

Izgara hesaplamaları

  • cross_partition(replica_groups: Value) -> Value "cross_replica" ifadesini inceleyin. bölümüne bakın.

  • cross_replica(replica_groups: Value) -> Value "cross_replica" ifadesini inceleyin. bölümüne bakın.

  • cross_replica_and_partition(replica_groups: Value) -> Value Bkz. &quot;cross_replica_and_partition&quot; bölümüne bakın.

  • flattened_ids(replica_groups: Value) -> Value "flattened_ids" değerini inceleyin bölümüne bakın.

Dinamik

StableHLO değerlerinin dinamik boyut boyutları olabilir (ör. tensor<?xi64> Ancak StableHLO değerleri dinamik sayıda boyuta (sıralanmamış) sahip olamaz. dinamik, ör. tensor<*xi64>) bilgileri gösterilir. İşlem görenler ve sonuçların dinamik boyut kısıtlamaları mevcut olsa bile bu boyuta izin verilmez. Kısıtlamalar mümkünse statik olarak doğrulanır, aksi takdirde çalışma zamanına belirsiz davranışa neden olur. Örnekler için aşağıya bakın.

Tekli öğe bazlı işlemler için şekil uyuşmazlıkları

Şu oyuncak programını kullanabilirsiniz:

func.func @foo(%arg0: tensor<?xf64>) {
  %0 = stablehlo.abs %arg0 : (tensor<?xf64>) -> tensor<2xf64>
  return
}

Bu tür bir program olağan dışıdır, çünkü girdinin şeklini belirtmez. Yine de bu, geçerli bir StableHLO çok önemli. Bu öğede abs işlemini statik olarak doğrulamak mümkün değildir programda bulunabilir. Bunun nedeni, işlenenin tam şekli bilinmemektedir. Ancak şekiller kesinlikle uyumludur ve bu durum statik olarak kontrol edilebilir: ? 2 olacak ve hiç sorun olmayacak. Ancak ? ortaya çıkan başka bir tam sayı olacaktır. Bu durumda, davranış tanımlanmamış olur.

Sonuçta dinamik boyut boyutu varsa olabilir. Gerçekten de, hiç "beklenen" büyüklükte olduğundan uyuşmazlığı.

İkili öğe tabanlı işlemler için şekil uyuşmazlıkları

Şu oyuncak programını kullanabilirsiniz:

func.func @foo(%arg0: tensor<?xf64>, %arg1: tensor<?xf64>) {
  %0 = stablehlo.add %arg0, %arg0 : (tensor<?xf64>, tensor<?xf64>) -> tensor<?xf64>
  return
}

İkili element tabanlı işlemler söz konusu olduğunda, girişlerin ve girdilerin şekilleri sonucu çalışma zamanında aynı olmalıdır. Derleme sırasında statik boyutlar, Aksi takdirde, tek yapmaları gereken uyumlu olmaları gerekir. Girişlerde herhangi bir boyut dinamikse tanımlanmamış olabilir genellikle çalışma zamanında istenen davranışa işaret etmesidir, çünkü dinamik boyut diğer işlenendeki boyut (statik veya dinamik) olmalıdır. Tüm girişler sonucun dinamik olup olmaması önemli değildir: statik olarak bilinen boyutlar statik olarak kontrol edilir. Dinamik boyutlar ise ve kısıtları yoktur.

Çıktı şeklini işlenen olarak alan işlemler için şekil uyuşmazlıkları

Şu oyuncak programını kullanabilirsiniz:

func.func @foo(%arg0: tensor<2xi32>) {
  %0 = stablehlo.dynamic_iota %arg0, dim = 0 : (tensor<2xi32>) -> tensor<3x4xi64>
  return
}

Çalışma zamanında şekil işlenenindeki değerler sonucun şekliyle eşleşmelidir. Aksi takdirde davranış tanımsızdır. Yani, çalışma zamanında %arg0 için dense<[3, 4]> : tensor<2xi32> değerine ayarlanır. Şekil işleneni sabitse statik olarak doğrulanabilir. Sonuç şekli tamamen dinamikse uyuşmuyor olabilir.