Ngữ nghĩa hoạt động

Phần sau đây mô tả ngữ nghĩa của các thao tác được xác định trong giao diện XlaBuilder. Thông thường, các toán tử này liên kết một với một với các toán tử đã xác định trong giao diện RPC trong xla_data.proto.

Lưu ý về cách gọi tên: loại dữ liệu tổng quát XLA liên quan đến là một mảng chiều N chứa các phần tử thuộc một số kiểu đồng nhất (chẳng hạn như số thực 32 bit). Trong suốt tài liệu, mảng được dùng để biểu thị một mảng thứ nguyên tùy ý. Để thuận tiện, các trường hợp đặc biệt sẽ có tên cụ thể và quen thuộc hơn; ví dụ: vectơ là mảng 1 chiều và ma trận là mảng 2 chiều.

AfterAll

Hãy xem thêm XlaBuilder::AfterAll.

AfterAll lấy một số lượng mã thông báo khác nhau và tạo ra một mã thông báo duy nhất. Mã thông báo là các loại dữ liệu nguyên gốc có thể được tạo luồng giữa các hoạt động có hiệu ứng phụ để thực thi thứ tự. Bạn có thể sử dụng AfterAll làm mã kết hợp để sắp xếp một thao tác sau một thao tác đã đặt.

AfterAll(operands)

Đối số Loại Ngữ nghĩa
operands XlaOp số lượng mã thông báo biến thiên

AllGather

Hãy xem thêm XlaBuilder::AllGather.

Thực hiện việc nối trên các bản sao.

AllGather(operand, all_gather_dim, shard_count, replica_group_ids, channel_id)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng để nối các bản sao
all_gather_dim int64 Phương diện nối
replica_groups vectơ của các vectơ của int64 Các nhóm thực hiện việc nối
channel_id int64 không bắt buộc Mã nhận dạng kênh không bắt buộc để giao tiếp trên nhiều mô-đun
  • replica_groups là danh sách các nhóm bản sao thực hiện việc nối (bạn có thể truy xuất mã bản sao của bản sao hiện tại bằng ReplicaId). Thứ tự của các bản sao trong mỗi nhóm sẽ xác định thứ tự đặt dữ liệu đầu vào của các bản sao đó trong kết quả. replica_groups phải trống (trong trường hợp đó, tất cả các bản sao thuộc về một nhóm duy nhất, được sắp xếp theo thứ tự từ 0 đến N - 1) hoặc chứa cùng số phần tử với số lượng bản sao. Ví dụ: replica_groups = {0, 2}, {1, 3} thực hiện việc nối các bản sao 02, cũng như 1 với 3.
  • shard_count là kích thước của mỗi nhóm bản sao. Chúng ta cần điều này trong trường hợp replica_groups trống.
  • channel_id được dùng để giao tiếp trên nhiều mô-đun: chỉ các thao tác all-gather có cùng channel_id mới có thể giao tiếp với nhau.

Hình dạng đầu ra là hình dạng dữ liệu đầu vào với all_gather_dim có kích thước lớn hơn shard_count lần. Ví dụ: nếu có 2 bản sao và toán hạng có giá trị [1.0, 2.5][3.0, 5.25] lần lượt trên 2 bản sao, thì giá trị đầu ra của op này, trong đó all_gather_dim0 sẽ là [1.0, 2.5, 3.0, 5.25] trên cả hai bản sao.

AllReduce

Hãy xem thêm XlaBuilder::AllReduce.

Thực hiện phép tính tuỳ chỉnh trên các bản sao.

AllReduce(operand, computation, replica_group_ids, channel_id)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng hoặc một bộ dữ liệu mảng không trống để giảm dữ liệu trên các bản sao
computation XlaComputation Phép tính rút gọn
replica_groups vectơ của các vectơ của int64 Những nhóm thực hiện các phép rút gọn
channel_id int64 không bắt buộc Mã nhận dạng kênh không bắt buộc để giao tiếp trên nhiều mô-đun
  • Khi operand là một bộ dữ liệu mảng, thao tác rút gọn sẽ được thực hiện trên từng phần tử của bộ dữ liệu.
  • replica_groups là danh sách các nhóm bản sao diễn ra quá trình rút gọn (có thể truy xuất mã bản sao của bản sao hiện tại bằng ReplicaId). replica_groups phải trống (trong trường hợp này, mọi bản sao đều thuộc về một nhóm duy nhất) hoặc chứa cùng số lượng phần tử như số lượng bản sao. Ví dụ: replica_groups = {0, 2}, {1, 3} thực hiện rút gọn giữa các bản sao 02, cũng như 13.
  • channel_id được dùng để giao tiếp trên nhiều mô-đun: chỉ các thao tác all-reduce có cùng channel_id mới có thể giao tiếp với nhau.

Hình dạng đầu ra giống với hình dạng đầu vào. Ví dụ: nếu có hai bản sao và toán hạng có giá trị [1.0, 2.5][3.0, 5.25] tương ứng trên hai bản sao, thì giá trị đầu ra của phép tính toán tử và tổng này sẽ là [4.0, 7.75] trên cả hai bản sao. Nếu dữ liệu đầu vào là một bộ dữ liệu, thì đầu ra cũng sẽ là một bộ dữ liệu.

Việc tính toán kết quả của AllReduce yêu cầu phải có một dữ liệu đầu vào từ mỗi bản sao. Vì vậy, nếu một bản sao thực thi nút AllReduce nhiều lần hơn bản sao khác, thì bản sao cũ sẽ đợi vĩnh viễn. Vì các bản sao đều đang chạy cùng một chương trình, nên không có nhiều cách để điều đó xảy ra, nhưng có thể xảy ra khi điều kiện của vòng lặp phụ thuộc vào dữ liệu từ nguồn cấp dữ liệu và dữ liệu được cung cấp khiến vòng lặp while lặp lại nhiều lần trên một bản sao hơn so với một bản sao khác.

AllToAll

Hãy xem thêm XlaBuilder::AllToAll.

AllToAll là một hoạt động tập thể gửi dữ liệu từ tất cả các lõi đến tất cả các lõi. Quy trình này gồm 2 giai đoạn:

  1. Giai đoạn tán xạ. Trên mỗi lõi, toán hạng được chia thành số khối split_count dọc theo split_dimensions và các khối này được phân tán đến tất cả các lõi, ví dụ: khối thứ i được gửi đến lõi thứ i.
  2. Giai đoạn thu thập. Mỗi lõi liên kết các khối đã nhận cùng với concat_dimension.

Các lõi tham gia có thể được định cấu hình bằng:

  • replica_groups: mỗi ReplicaGroup chứa một danh sách các mã bản sao tham gia vào việc tính toán (mã bản sao của bản sao hiện tại có thể được truy xuất bằng cách sử dụng ReplicaId). AllToAll sẽ được áp dụng trong các nhóm con theo thứ tự đã chỉ định. Ví dụ: replica_groups = { {1,2,3}, {4,5,0} } có nghĩa là AllToAll sẽ được áp dụng trong các bản sao {1, 2, 3} và trong giai đoạn thu thập, đồng thời các khối đã nhận sẽ được nối theo cùng thứ tự 1, 2, 3. Sau đó, một AllToAll khác sẽ được áp dụng trong các bản sao 4, 5, 0 và thứ tự nối cũng là 4, 5, 0. Nếu replica_groups trống, mọi bản sao đều thuộc về một nhóm, theo thứ tự nối mà chúng xuất hiện.

Điều kiện tiên quyết:

  • Kích thước kích thước của toán hạng trên split_dimension là chia hết cho split_count.
  • Hình dạng của toán hạng không phải là bộ dữ liệu.

AllToAll(operand, split_dimension, concat_dimension, split_count, replica_groups)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng đầu vào thứ nguyên n
split_dimension int64 Một giá trị trong khoảng [0, n) đặt tên cho chiều theo đó toán hạng được phân tách
concat_dimension int64 Một giá trị trong khoảng thời gian [0, n) đặt tên cho kích thước mà các khối phân tách được nối với nhau
split_count int64 Số lõi tham gia hoạt động này. Nếu replica_groups trống, thì đây sẽ là số bản sao; nếu không, giá trị này phải bằng số bản sao trong mỗi nhóm.
replica_groups Vectơ ReplicaGroup Mỗi nhóm chứa một danh sách mã nhận dạng bản sao.

Dưới đây là ví dụ về Alltoall.

XlaBuilder b("alltoall");
auto x = Parameter(&b, 0, ShapeUtil::MakeShape(F32, {4, 16}), "x");
AllToAll(x, /*split_dimension=*/1, /*concat_dimension=*/0, /*split_count=*/4);

Trong ví dụ này, có 4 lõi tham gia vào Alltoall. Trên mỗi lõi, toán hạng được chia thành 4 phần dọc theo chiều 0, vì vậy, mỗi phần có hình dạng f32[4,4]. 4 phần này được phân tán đến tất cả các lõi. Sau đó, mỗi lõi nối các phần đã nhận với chiều 1, theo thứ tự từ lõi 0 đến 4. Vì vậy, đầu ra trên mỗi lõi có hình dạng f32[16,4].

BatchNormGrad

Hãy xem thêm XlaBuilder::BatchNormGradbài viết chuẩn hoá hàng loạt gốc để biết nội dung mô tả chi tiết về thuật toán.

Tính toán độ dốc của định mức lô.

BatchNormGrad(operand, scale, mean, variance, grad_output, epsilon, feature_index)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng phương diện n cần chuẩn hoá (x)
scale XlaOp Mảng 1 phương diện (\(\gamma\))
mean XlaOp Mảng 1 phương diện (\(\mu\))
variance XlaOp Mảng 1 phương diện (\(\sigma^2\))
grad_output XlaOp Đã chuyển độ dốc đến BatchNormTraining (\(\nabla y\))
epsilon float Giá trị epsilon (\(\epsilon\))
feature_index int64 Chỉ mục cho phương diện của tính năng trong operand

Đối với mỗi đối tượng trong phương diện tính năng (feature_index là chỉ mục cho phương diện tính năng trong operand), thao tác sẽ tính toán độ chuyển màu tương ứng với operand, offsetscale trên tất cả các phương diện khác. feature_index phải là một chỉ mục hợp lệ cho phương diện tính năng trong operand.

Ba độ dốc được xác định bằng các công thức sau (giả sử một mảng 4 chiều là operand và có chỉ mục kích thước tính năng l, kích thước lô m cũng như kích thước không gian wh):

\[ \begin{split} c_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sigma^2_l+\epsilon} \right) \\\\ d_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \\\\ \nabla x_{ijkl} &= \frac{\gamma_{l} }{\sqrt{\sigma^2_{l}+\epsilon} } \left( \nabla y_{ijkl} - d_l - c_l (x_{ijkl} - \mu_{l}) \right) \\\\ \nabla \gamma_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sqrt{\sigma^2_{l}+\epsilon} } \right) \\\\\ \nabla \beta_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \end{split} \]

Giá trị đầu vào meanvariance biểu thị giá trị khoảnh khắc trên các phương diện lô và phương diện không gian.

Loại đầu ra là một bộ gồm 3 ô điều khiển:

Kết quả đầu ra Loại Ngữ nghĩa
grad_operand XlaOp độ dốc đối với đầu vào operand ($\nabla x$)
grad_scale XlaOp độ dốc đối với đầu vào scale ($\nabla \gamma$)
grad_offset XlaOp độ dốc đối với đầu vào offset($\nabla \beta$)

BatchNormInference

Hãy xem thêm XlaBuilder::BatchNormInferencebài viết chuẩn hoá hàng loạt gốc để biết nội dung mô tả chi tiết về thuật toán.

Chuẩn hoá một mảng trên các phương diện theo lô và không gian.

BatchNormInference(operand, scale, offset, mean, variance, epsilon, feature_index)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng phương diện n cần chuẩn hoá
scale XlaOp Mảng 1 phương diện
offset XlaOp Mảng 1 phương diện
mean XlaOp Mảng 1 phương diện
variance XlaOp Mảng 1 phương diện
epsilon float Giá trị Epsilon
feature_index int64 Chỉ mục cho phương diện của tính năng trong operand

Đối với mỗi đối tượng trong phương diện tính năng (feature_index là chỉ mục cho phương diện tính năng trong operand), toán tử sẽ tính giá trị trung bình và phương sai trên tất cả các phương diện khác, đồng thời sử dụng giá trị trung bình và phương sai để chuẩn hoá từng phần tử trong operand. feature_index phải là một chỉ mục hợp lệ cho phương diện tính năng trong operand.

BatchNormInference tương đương với việc gọi BatchNormTraining mà không tính toán meanvariance cho mỗi lô. Phương thức này sử dụng dữ liệu đầu vào meanvariance làm giá trị ước tính. Mục đích của hoạt động này là giảm độ trễ trong suy luận nên có tên là BatchNormInference.

Đầu ra là một mảng n chiều (n-dimensional array) được chuẩn hoá có cùng hình dạng với đầu vào operand.

BatchNormTraining

Xem thêm XlaBuilder::BatchNormTrainingthe original batch normalization paper để biết nội dung mô tả chi tiết về thuật toán.

Chuẩn hoá một mảng trên các phương diện theo lô và không gian.

BatchNormTraining(operand, scale, offset, epsilon, feature_index)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng phương diện n cần chuẩn hoá (x)
scale XlaOp Mảng 1 phương diện (\(\gamma\))
offset XlaOp Mảng 1 phương diện (\(\beta\))
epsilon float Giá trị epsilon (\(\epsilon\))
feature_index int64 Chỉ mục cho phương diện của tính năng trong operand

Đối với mỗi đối tượng trong phương diện tính năng (feature_index là chỉ mục cho phương diện tính năng trong operand), toán tử sẽ tính giá trị trung bình và phương sai trên tất cả các phương diện khác, đồng thời sử dụng giá trị trung bình và phương sai để chuẩn hoá từng phần tử trong operand. feature_index phải là một chỉ mục hợp lệ cho phương diện tính năng trong operand.

Thuật toán như sau đối với mỗi lô trong operand \(x\) chứa các phần tử mwh là kích thước của các phương diện không gian (giả sử operand là một mảng 4 phương diện):

  • Tính toán giá trị trung bình theo lô \(\mu_l\) cho từng tính năng l trong phương diện tính năng:\(\mu_l=\frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h x_{ijkl}\)

  • Tính toán phương sai lô \(\sigma^2_l\): $\sigma^2l=\frac{1}{mWh}\sum{i=1}^m\sum{j=1}^w\sum{k=1}^h (x_{ijkl} - \mu_l)^2$

  • Chuẩn hoá, điều chỉnh theo tỷ lệ và thay đổi: \(y_{ijkl}=\frac{\gamma_l(x_{ijkl}-\mu_l)}{\sqrt[2]{\sigma^2_l+\epsilon} }+\beta_l\)

Giá trị epsilon (thường là một số nhỏ) được thêm vào để tránh lỗi chia cho 0.

Loại đầu ra là một bộ dữ liệu gồm 3 XlaOp:

Kết quả đầu ra Loại Ngữ nghĩa
output XlaOp mảng thứ nguyên n có cùng hình dạng với dữ liệu đầu vào operand (y)
batch_mean XlaOp Mảng 1 phương diện (\(\mu\))
batch_var XlaOp Mảng 1 phương diện (\(\sigma^2\))

batch_meanbatch_var là các khoảnh khắc được tính toán theo lô và phương diện không gian bằng cách sử dụng các công thức nêu trên.

BitcastConvertType

Hãy xem thêm XlaBuilder::BitcastConvertType.

Tương tự như tf.bitcast trong TensorFlow, bạn có thể thực hiện thao tác bitcast theo thành phần từ hình dạng dữ liệu đến hình dạng mục tiêu. Kích thước đầu vào và đầu ra phải khớp nhau: ví dụ: các phần tử s32 trở thành phần tử f32 thông qua quy trình bitcast và một phần tử s32 sẽ trở thành bốn phần tử s8. Bitcast được triển khai dưới dạng truyền cấp thấp, vì vậy, các máy có các cách biểu diễn dấu phẩy động khác nhau sẽ cho kết quả khác nhau.

BitcastConvertType(operand, new_element_type)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng loại T với độ mờ D
new_element_type PrimitiveType loại U

Kích thước của toán hạng và hình dạng mục tiêu phải khớp nhau, ngoài kích thước cuối cùng sẽ thay đổi theo tỷ lệ kích thước gốc trước và sau khi chuyển đổi.

Loại phần tử nguồn và đích không được là bộ dữ liệu.

Chuyển đổi Bitcast sang loại gốc có độ rộng khác nhau

Lệnh HLO BitcastConvert hỗ trợ trường hợp kích thước của loại phần tử đầu ra T' không bằng kích thước của phần tử đầu vào T. Vì về mặt lý thuyết, toàn bộ thao tác đều là bitcast và không thay đổi các byte cơ bản, nên hình dạng của phần tử đầu ra phải thay đổi. Đối với B = sizeof(T), B' = sizeof(T'), có 2 trường hợp có thể xảy ra.

Trước tiên, khi B > B', hình dạng đầu ra sẽ có một kích thước nhỏ mới nhất là kích thước B/B'. Ví dụ:

  f16[10,2]{1,0} %output = f16[10,2]{1,0} bitcast-convert(f32[10]{0} %input)

Quy tắc vẫn giữ nguyên đối với các đại lượng vô hướng hiệu dụng:

  f16[2]{0} %output = f16[2]{0} bitcast-convert(f32[] %input)

Ngoài ra, đối với B' > B, lệnh này yêu cầu chiều logic cuối cùng của hình dạng dữ liệu đầu vào phải bằng với B'/B và chiều này sẽ bị loại bỏ trong quá trình chuyển đổi:

  f32[10]{0} %output = f32[10]{0} bitcast-convert(f16[10,2]{1,0} %input)

Lưu ý rằng các lượt chuyển đổi giữa các bitwidth khác nhau không phải là phần tử theo phần tử.

Truyền

Hãy xem thêm XlaBuilder::Broadcast.

Thêm phương diện vào một mảng bằng cách sao chép dữ liệu trong mảng đó.

Broadcast(operand, broadcast_sizes)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng cần sao chép
broadcast_sizes ArraySlice<int64> Kích thước của các phương diện mới

Các kích thước mới được chèn vào bên trái, tức là nếu broadcast_sizes có giá trị {a0, ..., aN} và hình dạng toán hạng có kích thước {b0, ..., bM} thì hình dạng của dữ liệu đầu ra có kích thước {a0, ..., aN, b0, ..., bM}.

Các phương diện mới lập chỉ mục thành các bản sao của toán hạng, tức là

output[i0, ..., iN, j0, ..., jM] = operand[j0, ..., jM]

Ví dụ: nếu operand là một f32 vô hướng có giá trị 2.0fbroadcast_sizes{2, 3}, thì kết quả sẽ là một mảng có hình dạng f32[2, 3] và tất cả giá trị trong kết quả sẽ là 2.0f.

BroadcastInDim

Hãy xem thêm XlaBuilder::BroadcastInDim.

Mở rộng kích thước và thứ hạng của một mảng bằng cách sao chép dữ liệu trong mảng.

BroadcastInDim(operand, out_dim_size, broadcast_dimensions)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng cần sao chép
out_dim_size ArraySlice<int64> Kích thước của kích thước của hình dạng mục tiêu
broadcast_dimensions ArraySlice<int64> Kích thước trong hình dạng mục tiêu mà mỗi chiều của hình dạng toán hạng tương ứng với

Tương tự như Truyền phát, nhưng cho phép thêm kích thước ở bất kỳ đâu và mở rộng các kích thước hiện có với kích thước 1.

operand được truyền đến hình dạng do out_dim_size mô tả. broadcast_dimensions ánh xạ kích thước của operand với kích thước của hình dạng mục tiêu, tức là chiều thứ i của toán hạng được ánh xạ với kích thước thứ i của hình dạng đầu ra. Kích thước của operand phải có kích thước 1 hoặc có cùng kích thước với kích thước trong hình dạng đầu ra mà chúng được liên kết. Các kích thước còn lại được điền bằng các kích thước 1. Phát sóng phương diện suy giảm rồi truyền phát dọc theo các chiều bị suy giảm này để đạt được hình dạng đầu ra. Ngữ nghĩa được mô tả chi tiết trên trang truyền phát.

Gọi

Hãy xem thêm XlaBuilder::Call.

Gọi một phép tính với các đối số đã cho.

Call(computation, args...)

Đối số Loại Ngữ nghĩa
computation XlaComputation tính toán kiểu T_0, T_1, ..., T_{N-1} -> S với N tham số kiểu tuỳ ý
args chuỗi N XlaOp giây N đối số thuộc kiểu tuỳ ý

Tính chất và loại của args phải khớp với các tham số của computation. Được phép không có args.

Cholesky

Hãy xem thêm XlaBuilder::Cholesky.

Tính toán quá trình Phân rã Cholesky của một loạt ma trận xác định dương đối xứng (Hermitian).

Cholesky(a, lower)

Đối số Loại Ngữ nghĩa
a XlaOp một mảng > 2 của một kiểu dấu phẩy động hoặc phức tạp.
lower bool xem nên sử dụng tam giác trên hay dưới của a.

Nếu lowertrue, tính các ma trận tam giác dưới l sao cho $a = l . l^T$. Nếu lowerfalse, tính các ma trận tam giác trên u sao cho\(a = u^T . u\).

Dữ liệu đầu vào chỉ được đọc từ tam giác dưới/trên của a, tuỳ thuộc vào giá trị của lower. Giá trị của tam giác còn lại sẽ bị bỏ qua. Dữ liệu đầu ra được trả về trong cùng một tam giác; các giá trị trong tam giác khác được xác định theo phương thức triển khai và có thể là bất kỳ giá trị nào.

Nếu hạng của a lớn hơn 2, thì a được coi là một lô ma trận, trong đó tất cả ngoại trừ 2 chiều phụ đều là các chiều lô.

Nếu a không phải là giá trị dương đối xứng (Hermitian), kết quả sẽ được xác định theo phương thức triển khai.

Kẹp

Hãy xem thêm XlaBuilder::Clamp.

Gắn một toán hạng vào trong phạm vi từ giá trị tối thiểu đến tối đa.

Clamp(min, operand, max)

Đối số Loại Ngữ nghĩa
min XlaOp mảng thuộc loại T
operand XlaOp mảng thuộc loại T
max XlaOp mảng thuộc loại T

Cho sẵn một toán hạng và các giá trị tối thiểu và tối đa, sẽ trả về toán hạng nếu nằm trong khoảng từ giá trị tối thiểu đến tối đa, nếu không sẽ trả về giá trị nhỏ nhất nếu toán hạng nằm dưới phạm vi này hoặc giá trị tối đa nếu toán hạng nằm trên phạm vi này. Tức là clamp(a, x, b) = min(max(a, x), b).

Cả 3 mảng phải có cùng hình dạng. Ngoài ra, ở dạng thông báo truyền tin bị hạn chế, min và/hoặc max có thể là đại lượng vô hướng thuộc kiểu T.

Ví dụ với minmax vô hướng:

let operand: s32[3] = {-1, 5, 9};
let min: s32 = 0;
let max: s32 = 6;
==>
Clamp(min, operand, max) = s32[3]{0, 5, 6};

Thu gọn

Hãy xem thêm XlaBuilder::Collapse và thao tác tf.reshape.

Thu gọn các phương diện của một mảng thành một phương diện.

Collapse(operand, dimensions)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng thuộc loại T
dimensions Vectơ int64 tập hợp con liên tiếp, theo thứ tự của các tham số T.

Thao tác thu gọn sẽ thay thế tập hợp con các kích thước đã cho của toán hạng bằng một chiều duy nhất. Các đối số đầu vào là một mảng tuỳ ý loại T và một vectơ không đổi thời gian biên dịch của các chỉ mục kích thước. Chỉ mục kích thước phải là một chỉ mục theo thứ tự (số kích thước từ thấp đến cao), tập hợp con liên tiếp của các chiều. Do đó, {0, 1, 2}, {0, 1} hoặc {1, 2} đều là các tập hợp phương diện hợp lệ, nhưng {1, 0} hoặc {0, 2} thì không. Các kích thước này được thay thế bằng một kích thước mới, ở cùng vị trí trong trình tự kích thước với các kích thước mà chúng thay thế, với kích thước mới bằng tích của kích thước kích thước ban đầu. Số lượng phương diện thấp nhất trong dimensions là kích thước thay đổi chậm nhất (chủ yếu nhất) trong lồng vòng lặp thu gọn các kích thước này, và số kích thước cao nhất biến động nhanh nhất (hầu hết nhỏ). Hãy xem toán tử tf.reshape nếu cần thêm thứ tự thu gọn chung.

Ví dụ: giả sử v là một mảng gồm 24 phần tử:

let v = f32[4x2x3] { { {10, 11, 12},  {15, 16, 17} },
{ {20, 21, 22},  {25, 26, 27} },
{ {30, 31, 32},  {35, 36, 37} },
{ {40, 41, 42},  {45, 46, 47} } };

// Collapse to a single dimension, leaving one dimension.
let v012 = Collapse(v, {0,1,2});
then v012 == f32[24] {10, 11, 12, 15, 16, 17,
20, 21, 22, 25, 26, 27,
30, 31, 32, 35, 36, 37,
40, 41, 42, 45, 46, 47};

// Collapse the two lower dimensions, leaving two dimensions.
let v01 = Collapse(v, {0,1});
then v01 == f32[4x6] { {10, 11, 12, 15, 16, 17},
{20, 21, 22, 25, 26, 27},
{30, 31, 32, 35, 36, 37},
{40, 41, 42, 45, 46, 47} };

// Collapse the two higher dimensions, leaving two dimensions.
let v12 = Collapse(v, {1,2});
then v12 == f32[8x3] { {10, 11, 12},
{15, 16, 17},
{20, 21, 22},
{25, 26, 27},
{30, 31, 32},
{35, 36, 37},
{40, 41, 42},
{45, 46, 47} };

CollectivePermute

Hãy xem thêm XlaBuilder::CollectivePermute.

CollectivePermute là một hoạt động tập thể gửi và nhận các bản sao dữ liệu chéo.

CollectivePermute(operand, source_target_pairs)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng đầu vào thứ nguyên n
source_target_pairs Vectơ <int64, int64> Danh sách các cặp (source_replica_id, target_replica_id). Đối với mỗi cặp, toán hạng được gửi từ bản sao nguồn đến bản sao đích.

Lưu ý rằng có các hạn chế sau đối với source_target_pair:

  • Hai cặp bất kỳ không được có cùng một mã bản sao mục tiêu và không được có cùng một mã bản sao nguồn.
  • Nếu mã bản sao không phải là mục tiêu trong bất kỳ cặp nào, thì đầu ra trên bản sao đó sẽ là một tensor bao gồm 0(các) có cùng hình dạng với đầu vào.

Nối

Hãy xem thêm XlaBuilder::ConcatInDim.

Phép nối kết hợp một mảng từ nhiều toán hạng mảng. Mảng này có cùng thứ hạng với các toán hạng mảng đầu vào (phải có cùng thứ hạng với nhau) và chứa các đối số theo thứ tự đã được chỉ định.

Concatenate(operands..., dimension)

Đối số Loại Ngữ nghĩa
operands chuỗi N XlaOp N mảng thuộc loại T có kích thước [L0, L1, ...]. Yêu cầu N >= 1.
dimension int64 Một giá trị trong khoảng [0, N) đặt tên cho chiều cần được nối giữa operands.

Ngoại trừ dimension, tất cả phương diện đều phải giống nhau. Điều này là do XLA không hỗ trợ các mảng "càng nhiều". Ngoài ra, xin lưu ý rằng bạn không thể nối các giá trị xếp hạng 0 (vì không thể đặt tên cho kích thước mà việc nối xảy ra).

Ví dụ 1 chiều:

Concat({ {2, 3}, {4, 5}, {6, 7} }, 0)
>>> {2, 3, 4, 5, 6, 7}

Ví dụ 2 chiều:

let a = {
{1, 2},
{3, 4},
{5, 6},
};
let b = {
{7, 8},
};
Concat({a, b}, 0)
>>> {
{1, 2},
{3, 4},
{5, 6},
{7, 8},
}

Sơ đồ:

Câu lệnh có điều kiện

Hãy xem thêm XlaBuilder::Conditional.

Conditional(pred, true_operand, true_computation, false_operand, false_computation)

Đối số Loại Ngữ nghĩa
pred XlaOp Giá trị vô hướng thuộc kiểu PRED
true_operand XlaOp Đối số thuộc loại \(T_0\)
true_computation XlaComputation XlaComputation thuộc loại \(T_0 \to S\)
false_operand XlaOp Đối số thuộc loại \(T_1\)
false_computation XlaComputation XlaComputation thuộc loại \(T_1 \to S\)

Thực thi true_computation nếu predtrue, false_computation nếu predfalse và trả về kết quả.

true_computation phải lấy một đối số duy nhất thuộc loại \(T_0\) và sẽ được gọi bằng true_operand phải cùng kiểu. false_computation phải lấy một đối số duy nhất thuộc loại \(T_1\) và sẽ được gọi bằng false_operand. Đối số này phải cùng kiểu. Loại giá trị được trả về của true_computationfalse_computation phải giống nhau.

Xin lưu ý rằng chỉ một trong số true_computationfalse_computation sẽ được thực thi tuỳ thuộc vào giá trị của pred.

Conditional(branch_index, branch_computations, branch_operands)

Đối số Loại Ngữ nghĩa
branch_index XlaOp Giá trị vô hướng thuộc kiểu S32
branch_computations chuỗi N XlaComputation XlaComputation thuộc loại \(T_0 \to S , T_1 \to S , ..., T_{N-1} \to S\)
branch_operands chuỗi N XlaOp Đối số thuộc kiểu \(T_0 , T_1 , ..., T_{N-1}\)

Thực thi branch_computations[branch_index] và trả về kết quả. Nếu branch_index là một S32 < 0 hoặc >= N, thì branch_computations[N-1] sẽ được thực thi làm nhánh mặc định.

Mỗi branch_computations[b] phải nhận một đối số duy nhất thuộc loại \(T_b\) và sẽ được gọi bằng branch_operands[b]. Đối số này phải cùng kiểu. Loại giá trị được trả về của mỗi branch_computations[b] phải giống nhau.

Xin lưu ý rằng chỉ một trong các branch_computations sẽ được thực thi tuỳ thuộc vào giá trị của branch_index.

Chuyển đổi (tích chập)

Hãy xem thêm XlaBuilder::Conv.

Là ConvWithGeneralPadding, nhưng khoảng đệm được chỉ định theo cách ngắn gọn là CÙNG MỘT hoặc HỢP LỆ. Khoảng đệm SAME sẽ đệm đầu vào (lhs) bằng các số 0 để đầu ra có cùng hình dạng với đầu vào khi không tính đến. Khoảng đệm VALID chỉ có nghĩa là không có khoảng đệm.

ConvWithGeneralPadding (tích chập)

Hãy xem thêm XlaBuilder::ConvWithGeneralPadding.

Tính toán tích chập của kiểu dùng trong mạng nơron. Ở đây, tích chập có thể được coi là cửa sổ n chiều di chuyển trên một vùng cơ sở n chiều và một phép tính được thực hiện cho từng vị trí có thể có của cửa sổ.

Đối số Loại Ngữ nghĩa
lhs XlaOp xếp hạng n+2 mảng đầu vào
rhs XlaOp mảng xếp hạng n+2 của trọng số hạt nhân
window_strides ArraySlice<int64> Mảng n-d của sải chân hạt nhân
padding ArraySlice< pair<int64,int64>> Mảng n-d của khoảng đệm (thấp, cao)
lhs_dilation ArraySlice<int64> Mảng hệ số giãn nở n-d lhs
rhs_dilation ArraySlice<int64> Mảng hệ số giãn nở n-d rhs
feature_group_count int64 số lượng nhóm tính năng
batch_group_count int64 số lượng nhóm theo lô

Gọi n là số lượng phương diện không gian. Đối số lhs là một mảng xếp hạng n+2 mô tả diện tích cơ sở. Đây được gọi là dữ liệu đầu vào, mặc dù tất nhiên rhs cũng là dữ liệu đầu vào. Trong mạng nơron, đó là các hoạt động kích hoạt dữ liệu đầu vào. Chiều n+2 theo thứ tự sau:

  • batch: Mỗi toạ độ trong chiều này đại diện cho một đầu vào độc lập thực hiện phép tích chập.
  • z/depth/features: Mỗi vị trí (y, x) trong vùng cơ sở đều có một vectơ liên kết với vị trí đó. Vectơ này nằm trong chiều này.
  • spatial_dims: Mô tả các kích thước không gian n xác định vùng cơ sở mà cửa sổ di chuyển qua.

Đối số rhs là một mảng hạng n+2 mô tả bộ lọc/hạt nhân/cửa sổ tích chập. Các phương diện theo thứ tự sau:

  • output-z: Phương diện z của đầu ra.
  • input-z: Kích thước của kích thước này nhân với feature_group_count phải bằng kích thước của kích thước z tính theo lhs.
  • spatial_dims: Mô tả các kích thước không gian n xác định cửa sổ n-d di chuyển trên vùng cơ sở.

Đối số window_strides chỉ định bước của cửa sổ tích chập trong kích thước không gian. Ví dụ: nếu sải chân trong thứ nguyên không gian đầu tiên là 3, thì cửa sổ chỉ có thể được đặt tại các toạ độ mà chỉ mục không gian đầu tiên chia hết cho 3.

Đối số padding chỉ định khoảng đệm bằng 0 sẽ áp dụng cho vùng cơ sở. Số lượng khoảng đệm có thể là số âm – giá trị tuyệt đối của khoảng đệm âm cho biết số lượng phần tử cần xoá khỏi thứ nguyên được chỉ định trước khi thực hiện tích chập. padding[0] chỉ định khoảng đệm cho kích thước ypadding[1] chỉ định khoảng đệm cho kích thước x. Mỗi cặp có khoảng đệm thấp là phần tử đầu tiên và khoảng đệm cao là phần tử thứ hai. Khoảng đệm thấp được áp dụng theo hướng của các chỉ mục thấp hơn trong khi khoảng đệm cao được áp dụng theo hướng của các chỉ mục cao hơn. Ví dụ: nếu padding[1](2,3) thì sẽ có một khoảng đệm với 2 số 0 ở bên trái và 3 số 0 ở bên phải trong chiều không gian thứ hai. Việc sử dụng khoảng đệm tương đương với việc chèn cùng các giá trị 0 đó vào đầu vào (lhs) trước khi thực hiện tích chập.

Các đối số lhs_dilationrhs_dilation chỉ định hệ số giãn nở sẽ được áp dụng tương ứng cho lhs và rhs trong mỗi chiều không gian. Nếu hệ số giãn nở trong một chiều không gian là d, thì các lỗ d-1 sẽ được ngầm đặt giữa mỗi mục nhập trong chiều đó, làm tăng kích thước của mảng. Các lỗ được lấp đầy bằng một giá trị không hoạt động, mà đối với tích chập có nghĩa là các số 0.

Sự giãn nở của rhs còn được gọi là sự tích chập trous. Để biết thêm thông tin, hãy xem tf.nn.atrous_conv2d. Sự giãn nở của lhs còn được gọi là tích chập chuyển đổi. Để biết thêm thông tin, hãy xem tf.nn.conv2d_transpose.

Bạn có thể sử dụng đối số feature_group_count (giá trị mặc định 1) cho các tích chập được nhóm. feature_group_count cần phải là số chia của cả kích thước tính năng đầu vào và đầu ra. Nếu feature_group_count lớn hơn 1, thì về mặt lý thuyết, kích thước của tính năng đầu vào và đầu ra và kích thước của tính năng đầu ra rhs được chia đều thành nhiều nhóm feature_group_count, mỗi nhóm bao gồm một chuỗi con liên tiếp của các tính năng. Kích thước của tính năng đầu vào của rhs cần phải bằng với phương diện của tính năng đầu vào lhs chia cho feature_group_count (vì vậy, đối tượng này đã có kích thước bằng một nhóm các tính năng đầu vào). Các nhóm thứ i được dùng cùng nhau để tính toán feature_group_count cho nhiều tích chập riêng biệt. Kết quả của những tích chập này được nối với nhau trong kích thước tính năng đầu ra.

Để tích chập theo chiều sâu, đối số feature_group_count sẽ được đặt thành kích thước của tính năng đầu vào và bộ lọc sẽ được định hình lại từ [filter_height, filter_width, in_channels, channel_multiplier] thành [filter_height, filter_width, 1, in_channels * channel_multiplier]. Để biết thêm thông tin chi tiết, hãy xem tf.nn.depthwise_conv2d.

Bạn có thể sử dụng đối số batch_group_count (giá trị mặc định 1) cho các bộ lọc được nhóm trong quá trình truyền ngược. batch_group_count cần phải là số chia sẻ kích thước của kích thước lô lhs (đầu vào). Nếu batch_group_count lớn hơn 1, điều đó có nghĩa là kích thước của lô đầu ra phải có kích thước input batch / batch_group_count. batch_group_count phải là số chia của kích thước của tính năng đầu ra.

Hình dạng đầu ra có các kích thước sau, theo thứ tự sau:

  • batch: Kích thước của kích thước này nhân với batch_group_count phải bằng với kích thước của kích thước batch tính theo lhs.
  • z: Cùng kích thước với output-z trên hạt nhân (rhs).
  • spatial_dims: Một giá trị cho mỗi vị trí hợp lệ của cửa sổ tích chập.

Hình trên cho thấy cách hoạt động của trường batch_group_count. Một cách hiệu quả là chúng tôi chia từng lô lhs thành các nhóm batch_group_count và làm tương tự cho các tính năng đầu ra. Sau đó, đối với mỗi nhóm này, chúng ta sẽ tích chập theo cặp và nối dữ liệu đầu ra dọc theo kích thước của tính năng đầu ra. Ngữ nghĩa hoạt động của tất cả các phương diện khác (tính năng và không gian) vẫn giữ nguyên.

Vị trí hợp lệ của cửa sổ tích chập được xác định bằng các sải chân và kích thước của vùng cơ sở sau khoảng đệm.

Để mô tả tích chập, hãy xem xét tích chập 2d và chọn một số toạ độ batch, z, y, x cố định trong kết quả. Khi đó, (y,x) là vị trí của một góc của cửa sổ trong khu vực cơ sở (ví dụ: góc trên bên trái, tuỳ thuộc vào cách bạn diễn giải các kích thước không gian). Bây giờ, chúng ta có một cửa sổ 2d, được lấy từ vùng cơ sở, trong đó mỗi điểm 2d được liên kết với một vectơ 1d, vì vậy chúng ta sẽ có một hộp 3d. Từ nhân tích chập, vì chúng ta đã cố định toạ độ đầu ra z, nên chúng ta cũng có một hộp 3d. Hai hộp có cùng kích thước nên chúng ta có thể lấy tổng của các phần tử tương ứng giữa hai hộp (tương tự như tích của dấu chấm). Đó là giá trị đầu ra.

Lưu ý rằng nếu output-z chẳng hạn, 5, thì mỗi vị trí của cửa sổ sẽ tạo ra 5 giá trị ở đầu ra vào chiều z của đầu ra. Các giá trị này khác nhau ở phần nào của hạt nhân tích chập được sử dụng – có một hộp giá trị 3d riêng biệt được dùng cho mỗi toạ độ output-z. Bạn có thể coi đây là 5 tích chập riêng biệt với một bộ lọc riêng cho mỗi tích chập.

Dưới đây là mã giả cho phép tích chập 2d có khoảng đệm và nét vẽ:

for (b, oz, oy, ox) {  // output coordinates
  value = 0;
  for (iz, ky, kx) {  // kernel coordinates and input z
    iy = oy*stride_y + ky - pad_low_y;
    ix = ox*stride_x + kx - pad_low_x;
    if ((iy, ix) inside the base area considered without padding) {
      value += input(b, iz, iy, ix) * kernel(oz, iz, ky, kx);
    }
  }
  output(b, oz, oy, ox) = value;
}

ConvertElementType

Hãy xem thêm XlaBuilder::ConvertElementType.

Tương tự như static_cast tương tự như phần tử trong C++, thực hiện thao tác chuyển đổi phần tử từ hình dạng dữ liệu sang hình dạng mục tiêu. Kích thước phải khớp và lượt chuyển đổi là phần tử tương ứng; ví dụ: các phần tử s32 trở thành phần tử f32 thông qua quy trình chuyển đổi s32 thành f32.

ConvertElementType(operand, new_element_type)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng loại T với độ mờ D
new_element_type PrimitiveType loại U

Kích thước của toán hạng và hình dạng mục tiêu phải khớp nhau. Các loại phần tử nguồn và đích đến không được là bộ dữ liệu.

Một lượt chuyển đổi như T=s32 thành U=f32 sẽ thực hiện quy trình chuyển đổi int-to-float chuẩn hoá, chẳng hạn như làm tròn đến gần nhất.

let a: s32[3] = {0, 1, 2};
let b: f32[3] = convert(a, f32);
then b == f32[3]{0.0, 1.0, 2.0}

CrossReplicaSum

Thực hiện AllReduce với phép tính tổng.

CustomCall

Hãy xem thêm XlaBuilder::CustomCall.

Gọi một hàm do người dùng cung cấp trong một phép tính.

CustomCall(target_name, args..., shape)

Đối số Loại Ngữ nghĩa
target_name string Tên của hàm. Một hướng dẫn gọi sẽ được phát ra để nhắm mục tiêu đến tên biểu tượng này.
args chuỗi N XlaOp giây N đối số thuộc kiểu tuỳ ý, sẽ được truyền vào hàm.
shape Shape Hình dạng đầu ra của hàm

Chữ ký hàm là giống nhau, bất kể sự khác biệt hay loại đối số:

extern "C" void target_name(void* out, void** in);

Ví dụ: nếu CustomCall được sử dụng như sau:

let x = f32[2] {1,2};
let y = f32[2x3] { {10, 20, 30}, {40, 50, 60} };

CustomCall("myfunc", {x, y}, f32[3x3])

Dưới đây là ví dụ về cách triển khai myfunc:

extern "C" void myfunc(void* out, void** in) {
  float (&x)[2] = *static_cast<float(*)[2]>(in[0]);
  float (&y)[2][3] = *static_cast<float(*)[2][3]>(in[1]);
  EXPECT_EQ(1, x[0]);
  EXPECT_EQ(2, x[1]);
  EXPECT_EQ(10, y[0][0]);
  EXPECT_EQ(20, y[0][1]);
  EXPECT_EQ(30, y[0][2]);
  EXPECT_EQ(40, y[1][0]);
  EXPECT_EQ(50, y[1][1]);
  EXPECT_EQ(60, y[1][2]);
  float (&z)[3][3] = *static_cast<float(*)[3][3]>(out);
  z[0][0] = x[1] + y[1][0];
  // ...
}

Hàm do người dùng cung cấp không được có tác dụng phụ và việc thực thi hàm đó phải không thay đổi.

Chấm

Hãy xem thêm XlaBuilder::Dot.

Dot(lhs, rhs)

Đối số Loại Ngữ nghĩa
lhs XlaOp mảng thuộc loại T
rhs XlaOp mảng thuộc loại T

Ngữ nghĩa chính xác của toán tử này phụ thuộc vào thứ hạng của toán hạng:

Đầu vào Đầu ra Ngữ nghĩa
vectơ [n] dot vectơ [n] đại lượng vô hướng tích chấm vectơ
ma trận [m x k] vectơ dot [k] vectơ [m] phép nhân vectơ
ma trận [m x k] ma trận dot [k x n] ma trận [m x n] phép nhân ma trận

Phép toán này thực hiện tổng số sản phẩm qua chiều thứ hai của lhs (hoặc chiều đầu tiên nếu có thứ hạng 1) và chiều đầu tiên là rhs. Đây là các kích thước "được thu gọn". Kích thước theo hợp đồng của lhsrhs phải có cùng kích thước. Trong thực tế, bạn có thể dùng tính năng này để thực hiện các phép tính điểm giữa các vectơ, phép nhân vectơ/ma trận hoặc phép nhân ma trận/ma trận.

DotGeneral

Hãy xem thêm XlaBuilder::DotGeneral.

DotGeneral(lhs, rhs, dimension_numbers)

Đối số Loại Ngữ nghĩa
lhs XlaOp mảng thuộc loại T
rhs XlaOp mảng thuộc loại T
dimension_numbers DotDimensionNumbers số kích thước theo lô và hợp đồng

Tương tự như Dot, nhưng cho phép chỉ định số kích thước theo lô và hợp đồng cho cả lhsrhs.

Trường DotDimensionNumbers Loại Ngữ nghĩa
lhs_contracting_dimensions int64 lặp lại lhs số kích thước ký hợp đồng
rhs_contracting_dimensions int64 lặp lại rhs số kích thước ký hợp đồng
lhs_batch_dimensions int64 lặp lại Số kích thước lô lhs
rhs_batch_dimensions int64 lặp lại Số kích thước lô rhs

DotGeneral thực hiện tổng số sản phẩm theo kích thước ký hợp đồng được chỉ định trong dimension_numbers.

Số kích thước hợp đồng được liên kết từ lhsrhs không cần phải giống nhau nhưng phải có cùng kích thước kích thước.

Ví dụ về số kích thước ký hợp đồng:

lhs = { {1.0, 2.0, 3.0},
{4.0, 5.0, 6.0} }

rhs = { {1.0, 1.0, 1.0},
{2.0, 2.0, 2.0} }

DotDimensionNumbers dnums;
dnums.add_lhs_contracting_dimensions(1);
dnums.add_rhs_contracting_dimensions(1);

DotGeneral(lhs, rhs, dnums) -> { {6.0, 12.0},
{15.0, 30.0} }

Các số phương diện lô được liên kết từ lhsrhs phải có cùng kích thước phương diện.

Ví dụ với số kích thước lô (kích thước lô 2, ma trận 2x2):

lhs = { { {1.0, 2.0},
{3.0, 4.0} },
{ {5.0, 6.0},
{7.0, 8.0} } }

rhs = { { {1.0, 0.0},
{0.0, 1.0} },
{ {1.0, 0.0},
{0.0, 1.0} } }

DotDimensionNumbers dnums;
dnums.add_lhs_contracting_dimensions(2);
dnums.add_rhs_contracting_dimensions(1);
dnums.add_lhs_batch_dimensions(0);
dnums.add_rhs_batch_dimensions(0);

DotGeneral(lhs, rhs, dnums) -> { { {1.0, 2.0},
{3.0, 4.0} },
{ {5.0, 6.0},
{7.0, 8.0} } }
Đầu vào Đầu ra Ngữ nghĩa
[b0, m, k] dot [b0, k, n] [b0, m, n] lô matmul
[b0, b1, m, k] dot [b0, b1, k, n] [b0, b1, m, n] lô matmul

Theo đó, số kích thước thu được bắt đầu bằng kích thước lô, sau đó là kích thước lhs không theo hợp đồng/không theo lô và cuối cùng là kích thước rhs không theo hợp đồng/không theo lô.

DynamicSlice

Hãy xem thêm XlaBuilder::DynamicSlice.

DynamicSlice trích xuất một mảng con từ mảng đầu vào tại start_indices động. Kích thước của lát cắt trong mỗi phương diện được truyền vào size_indices để chỉ định điểm kết thúc của các khoảng thời gian của lát cắt độc quyền trong mỗi phương diện: [bắt đầu, bắt đầu + kích thước). Hình dạng của start_indices phải có thứ hạng == 1, với kích thước kích thước bằng thứ hạng của operand.

DynamicSlice(operand, start_indices, size_indices)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng thứ nguyên N thuộc loại T
start_indices chuỗi N XlaOp Danh sách N số nguyên vô hướng có chứa các chỉ mục bắt đầu của lát cắt cho mỗi chiều. Giá trị phải lớn hơn hoặc bằng 0.
size_indices ArraySlice<int64> Danh sách N số nguyên chứa kích thước lát cắt cho mỗi phương diện. Mỗi giá trị phải lớn hơn 0 và kích thước bắt đầu + kích thước phải nhỏ hơn hoặc bằng kích thước của kích thước để tránh gói kích thước theo mô-đun.

Các chỉ mục lát cắt hiệu quả được tính toán bằng cách áp dụng phép biến đổi sau cho từng chỉ mục i trong [1, N) trước khi thực hiện lát cắt đó:

start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - size_indices[i])

Điều này đảm bảo rằng lát cắt được trích xuất luôn liên kết với mảng toán hạng. Nếu lát cắt nằm trong giới hạn trước khi áp dụng phép biến đổi, thì phép biến đổi đó sẽ không có hiệu lực.

Ví dụ 1 chiều:

let a = {0.0, 1.0, 2.0, 3.0, 4.0}
let s = {2}

DynamicSlice(a, s, {2}) produces:
{2.0, 3.0}

Ví dụ 2 chiều:

let b =
{ {0.0,  1.0,  2.0},
{3.0,  4.0,  5.0},
{6.0,  7.0,  8.0},
{9.0, 10.0, 11.0} }
let s = {2, 1}

DynamicSlice(b, s, {2, 2}) produces:
{ { 7.0,  8.0},
{10.0, 11.0} }

DynamicUpdateSlice

Hãy xem thêm XlaBuilder::DynamicUpdateSlice.

DynamicUpdateSlice tạo một kết quả là giá trị của mảng đầu vào operand, trong đó một lát cắt update bị ghi đè tại start_indices. Hình dạng của update xác định hình dạng của mảng phụ của kết quả được cập nhật. Hình dạng của start_indices phải có thứ hạng == 1, với kích thước kích thước bằng thứ hạng của operand.

DynamicUpdateSlice(operand, update, start_indices)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng thứ nguyên N thuộc loại T
update XlaOp Mảng thứ nguyên N thuộc loại T chứa bản cập nhật lát cắt. Mỗi chiều của hình dạng cập nhật phải lớn hơn 0 và start + update phải nhỏ hơn hoặc bằng kích thước toán hạng cho từng chiều để tránh tạo chỉ mục cập nhật ngoài giới hạn.
start_indices chuỗi N XlaOp Danh sách N số nguyên vô hướng có chứa các chỉ mục bắt đầu của lát cắt cho mỗi chiều. Giá trị phải lớn hơn hoặc bằng 0.

Các chỉ mục lát cắt hiệu quả được tính toán bằng cách áp dụng phép biến đổi sau cho từng chỉ mục i trong [1, N) trước khi thực hiện lát cắt đó:

start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - update.dimension_size[i])

Điều này đảm bảo rằng lát cắt được cập nhật luôn liên kết với mảng toán hạng. Nếu lát cắt nằm trong giới hạn trước khi áp dụng phép biến đổi, thì phép biến đổi đó sẽ không có hiệu lực.

Ví dụ 1 chiều:

let a = {0.0, 1.0, 2.0, 3.0, 4.0}
let u = {5.0, 6.0}
let s = {2}

DynamicUpdateSlice(a, u, s) produces:
{0.0, 1.0, 5.0, 6.0, 4.0}

Ví dụ 2 chiều:

let b =
{ {0.0,  1.0,  2.0},
{3.0,  4.0,  5.0},
{6.0,  7.0,  8.0},
{9.0, 10.0, 11.0} }
let u =
{ {12.0,  13.0},
{14.0,  15.0},
{16.0,  17.0} }

let s = {1, 1}

DynamicUpdateSlice(b, u, s) produces:
{ {0.0,  1.0,  2.0},
{3.0, 12.0, 13.0},
{6.0, 14.0, 15.0},
{9.0, 16.0, 17.0} }

Phép tính số học nhị phân trên phần tử

Hãy xem thêm XlaBuilder::Add.

Một tập hợp các phép tính số học nhị phân theo phần tử được hỗ trợ.

Op(lhs, rhs)

Trong đó Op là một trong các giá trị Add (phép cộng), Sub (phép trừ), Mul (nhân), Div (chia), Rem (số dư), Max (tối đa), Min (tối thiểu), LogicalAnd (hàm logic AND) hoặc LogicalOr (hàm logic OR).

Đối số Loại Ngữ nghĩa
lhs XlaOp toán hạng bên trái: mảng thuộc loại T
rhs XlaOp toán hạng bên phải: mảng thuộc loại T

Hình dạng của đối số phải tương tự nhau hoặc tương thích. Xem tài liệu về truyền phát về ý nghĩa của việc tương thích với các hình dạng. Kết quả của một toán tử có một hình dạng là kết quả của việc truyền đi 2 mảng đầu vào. Trong biến thể này, phép toán giữa các mảng có thứ hạng khác nhau không được hỗ trợ, trừ phi một trong các toán hạng là đại lượng vô hướng.

Khi OpRem, dấu của kết quả được lấy từ số bị chia và giá trị tuyệt đối của kết quả luôn nhỏ hơn giá trị tuyệt đối của số chia.

Chặn tràn phép chia số nguyên (số chia có dấu/chưa ký/số còn lại cho 0 hoặc số chia/số còn lại có dấu của INT_SMIN với -1) sẽ tạo ra một giá trị do phương thức triển khai xác định.

Hiện có một biến thể thay thế có hỗ trợ tính năng phát sóng theo thứ hạng khác cho các thao tác này:

Op(lhs, rhs, broadcast_dimensions)

Trong trường hợp Op giống như trên. Bạn nên sử dụng biến thể này cho các phép tính số học giữa các mảng có thứ hạng khác nhau (chẳng hạn như thêm ma trận vào một vectơ).

Toán hạng broadcast_dimensions bổ sung là một lát số nguyên dùng để mở rộng thứ hạng của toán hạng bậc thấp hơn lên đến thứ hạng của toán hạng bậc cao hơn. broadcast_dimensions ánh xạ kích thước của hình dạng có thứ hạng thấp hơn với kích thước của hình dạng có thứ hạng cao hơn. Các kích thước chưa được ánh xạ của hình dạng mở rộng sẽ được điền vào các kích thước có kích thước 1. Tính năng truyền phát phương diện suy giảm sau đó sẽ truyền các hình dạng dọc theo các chiều suy giảm này để cân bằng hình dạng của cả hai toán hạng. Ngữ nghĩa được mô tả chi tiết trên trang truyền phát.

Toán tử so sánh theo phần tử

Hãy xem thêm XlaBuilder::Eq.

Một tập hợp các phép toán so sánh nhị phân theo phần tử chuẩn được hỗ trợ. Xin lưu ý rằng ngữ nghĩa so sánh dấu phẩy động chuẩn IEEE 754 sẽ áp dụng khi so sánh các loại dấu phẩy động.

Op(lhs, rhs)

Trong đó Op là một trong các giá trị Eq (bằng), Ne (không bằng), Ge (lớn hơn hoặc bằng), Gt (lớn hơn), Le (nhỏ hơn hoặc bằng), Lt (nhỏ hơn). Một nhóm các toán tử khác, EqTotalOrder, NeTotalOrder, GeTotalOrder, GtTotalOrder, LeTotalOrder, LtTotalOrder, mà cung cấp các chức năng tương tự, ngoại trừ việc chúng hỗ trợ thêm một đơn đặt hàng tổng số trên các số dấu phẩy động, bằng cách thực thi -NaN < -Inf < -Finite < -0 < +0 < +Infite <N +Infite <N +

Đối số Loại Ngữ nghĩa
lhs XlaOp toán hạng bên trái: mảng thuộc loại T
rhs XlaOp toán hạng bên phải: mảng thuộc loại T

Hình dạng của đối số phải tương tự nhau hoặc tương thích. Xem tài liệu về truyền phát về ý nghĩa của việc tương thích với các hình dạng. Kết quả của một toán tử có một hình dạng là kết quả của việc truyền hai mảng đầu vào với loại phần tử PRED. Trong biến thể này, thao tác giữa các mảng có thứ hạng khác nhau không được hỗ trợ, trừ phi một trong các toán hạng là đại lượng vô hướng.

Hiện có một biến thể thay thế có hỗ trợ tính năng phát sóng theo thứ hạng khác cho các thao tác này:

Op(lhs, rhs, broadcast_dimensions)

Trong trường hợp Op giống như trên. Bạn nên sử dụng biến thể này của toán tử cho các phép toán so sánh giữa các mảng có thứ hạng khác nhau (chẳng hạn như thêm ma trận vào một vectơ).

Toán hạng broadcast_dimensions bổ sung là một lát số nguyên chỉ định kích thước cần sử dụng để truyền toán hạng. Ngữ nghĩa được mô tả chi tiết trên trang truyền phát.

Hàm đơn nguyên trên phần tử

XlaBuilder hỗ trợ các hàm đơn nguyên phân tách theo phần tử sau đây:

Abs(operand) Cơ chế tuyệt đối theo phần tử x -> |x|.

Ceil(operand) Vị trí cột thông minh phần tử x -> ⌈x⌉.

Cos(operand) Cosin trên phần tử x -> cos(x).

Exp(operand) Số mũ tự nhiên theo phần tử x -> e^x.

Floor(operand) Tầng thông minh theo phần tử x -> ⌊x⌋.

Imag(operand) Phần ảo theo phần tử của một hình dạng phức (hoặc thực). x -> imag(x). Nếu toán hạng là loại dấu phẩy động, trả về 0.

IsFinite(operand) Kiểm tra xem mỗi phần tử của operand có hữu hạn hay không, tức là không phải là vô cực dương hoặc âm và không phải là NaN. Trả về một mảng các giá trị PRED có cùng hình dạng với dữ liệu đầu vào, trong đó mỗi phần tử là true nếu và chỉ khi phần tử đầu vào tương ứng là hữu hạn.

Log(operand) Lôgarit tự nhiên theo phần tử x -> ln(x).

LogicalNot(operand) Logic của phần tử không phải là x -> !(x).

Logistic(operand) Tính toán hàm logistic theo phần tử x -> logistic(x).

PopulationCount(operand) Tính toán số lượng bit được đặt trong mỗi phần tử của operand.

Neg(operand) Giá trị phủ định của phần tử x -> -x.

Real(operand) Phần thực trong phần tử của một hình dạng phức (hoặc hình thực). x -> real(x). Nếu toán hạng là loại dấu phẩy động, sẽ trả về cùng một giá trị.

Rsqrt(operand) nghịch đảo theo phần tử của toán tử căn bậc hai x -> 1.0 / sqrt(x).

Sign(operand) Thao tác ký dựa trên phần tử x -> sgn(x), trong đó

\[\text{sgn}(x) = \begin{cases} -1 & x < 0\\ -0 & x = -0\\ NaN & x = NaN\\ +0 & x = +0\\ 1 & x > 0 \end{cases}\]

bằng cách sử dụng toán tử so sánh của loại phần tử operand.

Sqrt(operand) Toán tử căn bậc hai của phần tử x -> sqrt(x).

Cbrt(operand) Toán tử căn bậc ba của phần tử x -> cbrt(x).

Tanh(operand) Tang hyperbol theo phần tử x -> tanh(x).

Round(operand) Làm tròn theo phần tử, các mối liên kết với nhau từ 0.

RoundNearestEven(operand) Làm tròn theo phần tử, liên kết với số chẵn gần nhất.

Đối số Loại Ngữ nghĩa
operand XlaOp Toán hạng của hàm

Hàm được áp dụng cho từng phần tử trong mảng operand, tạo ra một mảng có cùng hình dạng. operand được phép là đại lượng vô hướng (thứ hạng 0).

Fft

Toán tử XLA FFT triển khai Biến đổi Fourier tiến và nghịch đảo cho đầu vào/đầu ra thực và phức tạp. Hỗ trợ FFT đa chiều trên tối đa 3 trục.

Hãy xem thêm XlaBuilder::Fft.

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng chúng ta đang biến đổi Fourier.
fft_type FftType Xem bảng bên dưới.
fft_length ArraySlice<int64> Độ dài trong miền thời gian của các trục được thay đổi. Điều này đặc biệt cần thiết để IRFFT xác định đúng kích thước trục trong cùng, vì RFFT(fft_length=[16]) có cùng hình dạng đầu ra với RFFT(fft_length=[17]).
FftType Ngữ nghĩa
FFT Chuyển tiếp FFT từ phức tạp đến phức tạp. Hình dạng không thay đổi.
IFFT FFT từ phức tạp đến phức tạp. Hình dạng không thay đổi.
RFFT Chuyển tiếp FFT từ thực đến phức tạp. Hình dạng của trục trong cùng được giảm xuống fft_length[-1] // 2 + 1 nếu fft_length[-1] là một giá trị khác 0, bỏ qua phần liên hợp đảo ngược của tín hiệu đã biến đổi vượt ra ngoài tần số Nyquist.
IRFFT FFT từ thực đến phức tạp (tức là lấy phức, trả về thực). Hình dạng của trục trong cùng được mở rộng thành fft_length[-1] nếu fft_length[-1] là một giá trị khác 0, suy ra phần tín hiệu đã biến đổi vượt quá tần số Nyquist từ liên hợp ngược của 1 thành các mục fft_length[-1] // 2 + 1.

FFT đa chiều

Khi có nhiều hơn 1 fft_length, việc này tương đương với việc áp dụng một tầng hoạt động FFT cho từng trục trong cùng. Xin lưu ý rằng đối với các trường hợp thực->phức tạp và phức tạp->thực, phép biến đổi trục trong cùng được thực hiện (hiệu quả) trước (RFFT; cuối cùng đối với IRFFT), đó là lý do tại sao trục trong cùng là trục trong cùng thay đổi kích thước. Sau đó, các phép biến đổi trục khác sẽ phức tạp->phức tạp.

Thông tin triển khai

CPU FFT được TensorFFT của Eigen hỗ trợ. GPU FFT sử dụng cuFFT.

Tập hợp

Thao tác thu thập XLA sẽ ghép nhiều lát cắt lại với nhau (mỗi lát cắt có độ lệch thời gian chạy có thể khác nhau) của một mảng đầu vào.

Ngữ nghĩa chung

Hãy xem thêm XlaBuilder::Gather. Để có mô tả trực quan hơn, hãy xem phần "Mô tả trang trọng" bên dưới.

gather(operand, start_indices, offset_dims, collapsed_slice_dims, slice_sizes, start_index_map)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng mà chúng tôi đang thu thập từ đó.
start_indices XlaOp Mảng chứa các chỉ mục bắt đầu của các phần cắt chúng tôi thu thập.
index_vector_dim int64 Phương diện trong start_indices "chứa" các chỉ mục bắt đầu. Hãy xem nội dung mô tả chi tiết bên dưới.
offset_dims ArraySlice<int64> Tập hợp kích thước trong hình dạng đầu ra bù trừ thành một mảng được cắt từ toán hạng.
slice_sizes ArraySlice<int64> slice_sizes[i] là các giới hạn cho lát cắt trên kích thước i.
collapsed_slice_dims ArraySlice<int64> Tập hợp kích thước trong mỗi lát được thu gọn. Các phương diện này phải có kích thước 1.
start_index_map ArraySlice<int64> Bản đồ mô tả cách ánh xạ các chỉ mục trong start_indices với các chỉ mục hợp pháp thành toán hạng.
indices_are_sorted bool Liệu các chỉ mục có được đảm bảo sắp xếp theo phương thức gọi hay không.

Để thuận tiện, chúng tôi gắn nhãn các kích thước trong mảng đầu ra không phải trong offset_dimsbatch_dims.

Kết quả là một mảng có thứ hạng batch_dims.size + offset_dims.size.

operand.rank phải bằng tổng của offset_dims.sizecollapsed_slice_dims.size. Ngoài ra, slice_sizes.size phải bằng operand.rank.

Nếu index_vector_dim bằng start_indices.rank, chúng tôi ngầm coi start_indices có chiều 1 theo sau (tức là nếu start_indices có hình dạng [6,7]index_vector_dim2 thì chúng ta ngầm coi start_indices hình dạng của start_indices[6,7,1]).

Các giới hạn cho mảng đầu ra dọc theo kích thước i được tính như sau:

  1. Nếu i có trong batch_dims (tức là bằng batch_dims[k] đối với một số k), thì chúng ta sẽ chọn giới hạn kích thước tương ứng trong số start_indices.shape, bỏ qua index_vector_dim (tức là chọn start_indices.shape.dims[k] nếu k < index_vector_dimstart_indices.shape.dims[k+1] nếu không).

  2. Nếu i có trong offset_dims (tức là bằng offset_dims[k] đối với một số k), thì chúng ta sẽ chọn giới hạn tương ứng trong slice_sizes sau khi tính đến collapsed_slice_dims (tức là chúng ta chọn adjusted_slice_sizes[k], trong đó adjusted_slice_sizesslice_sizes với các giới hạn tại chỉ mục collapsed_slice_dims đã bị xoá).

Chính thức, chỉ mục toán hạng In tương ứng với một chỉ mục đầu ra nhất định Out được tính như sau:

  1. Đặt G = { Out[k] cho k trong batch_dims }. Sử dụng G để cắt một vectơ S sao cho S[i] = start_indices[Kết hợp(G, i)] trong đó Kết hợp(A, b) chèn b tại vị trí index_vector_dim vào A. Lưu ý rằng thuộc tính này được xác định rõ ngay cả khi G trống: Nếu G trống thì S = start_indices.

  2. Tạo chỉ mục bắt đầu, Sin, trong operand sử dụng S bằng cách phân tán S bằng start_index_map. Chính xác hơn:

    1. Sin[start_index_map[k]] = S[k] nếu k < start_index_map.size.

    2. Sin[_] = 0 nếu không.

  3. Tạo chỉ mục Oin vào operand bằng cách phân tán các chỉ mục ở kích thước chênh lệch trong Out theo tập hợp collapsed_slice_dims. Chính xác hơn:

    1. Oin[remapped_offset_dims(k)] = Out[offset_dims[k]] nếu k < offset_dims.size (remapped_offset_dims được định nghĩa ở bên dưới).

    2. Oin[_] = 0 nếu không.

  4. InOin + Sin, trong đó + là phép thêm phần tử.

remapped_offset_dims là một hàm đơn điệu có miền [0, offset_dims.size) và dải ô [0, operand.rank) \ collapsed_slice_dims. Vì vậy, ví dụ: offset_dims.size4, operand.rank6collapsed_slice_dims là {0, 2}, sau đó remapped_offset_dims là {01, 13, 24, 35}.

Nếu bạn đặt indices_are_sorted thành true (đúng), thì XLA có thể giả định rằng start_indices được người dùng sắp xếp (theo thứ tự start_index_map tăng dần). Nếu không, thì nghĩa là việc triển khai ngữ nghĩa sẽ được xác định.

Nội dung mô tả và ví dụ không chính thức

Một cách không chính thức, mọi chỉ mục Out trong mảng đầu ra tương ứng với một phần tử E trong mảng toán hạng, được tính như sau:

  • Chúng tôi sử dụng các kích thước lô trong Out để tra cứu chỉ mục bắt đầu từ start_indices.

  • Chúng tôi sử dụng start_index_map để liên kết chỉ mục bắt đầu (có kích thước có thể nhỏ hơn toán hạng.rank) với chỉ mục bắt đầu "đầy đủ" vào operand.

  • Chúng tôi sẽ phân chia động một lát cắt có kích thước slice_sizes bằng cách sử dụng chỉ mục khởi động đầy đủ.

  • Chúng ta định hình lại lát cắt bằng cách thu gọn kích thước collapsed_slice_dims. Vì tất cả kích thước lát cắt được thu gọn phải có giới hạn là 1, nên hình dạng lại này luôn hợp lệ.

  • Chúng tôi sử dụng kích thước chênh lệch trong Out để lập chỉ mục vào lát cắt này nhằm lấy phần tử đầu vào, E, tương ứng với chỉ mục đầu ra Out.

index_vector_dim được thiết lập thành start_indices.rank1 trong tất cả các ví dụ tiếp theo. Các giá trị thú vị khác của index_vector_dim về cơ bản không thay đổi thao tác, mà làm cho việc trình bày hình ảnh trở nên rườm rà.

Để hiểu cách tất cả các thành phần ở trên khớp với nhau, hãy xem ví dụ tập hợp 5 lát hình dạng [8,6] từ một mảng [16,11]. Vị trí của một lát cắt trong mảng [16,11] có thể được biểu thị dưới dạng vectơ chỉ mục của hình dạng S64[2], do đó, tập hợp 5 vị trí có thể được biểu thị dưới dạng mảng S64[5,2].

Sau đó, hành vi của hoạt động thu thập có thể được mô tả dưới dạng biến đổi chỉ mục, trong đó [G,O0,O1], một chỉ mục trong hình dạng đầu ra và ánh xạ chỉ mục đó với một phần tử trong mảng đầu vào theo cách sau:

Trước tiên, chúng ta chọn một vectơ (X,Y) từ mảng chỉ mục thu thập bằng G. Phần tử trong mảng đầu ra tại chỉ mục [G,O0,O1] khi đó là phần tử trong mảng đầu vào tại chỉ mục [X+O0,Y+O1].

slice_sizes[8,6], quyết định phạm vi của O0 và O1, từ đó quyết định các giới hạn của lát cắt.

Thao tác thu thập này hoạt động như một lát cắt động hàng loạt với G là thứ nguyên lô.

Các chỉ mục thu thập có thể đa chiều. Ví dụ: phiên bản tổng quát hơn của ví dụ ở trên sử dụng mảng "chỉ mục thu thập" có hình dạng [4,5,2] sẽ dịch các chỉ mục như sau:

Xin nhắc lại, đây là lát cắt động của lô G0G1 làm kích thước của lô. Kích thước lát cắt vẫn là [8,6].

Thao tác thu thập trong XLA tổng quát ngữ nghĩa không chính thức nêu trên theo các cách sau:

  1. Chúng ta có thể định cấu hình kích thước trong hình dạng đầu ra là kích thước bù trừ (kích thước chứa O0, O1 trong ví dụ cuối cùng). Các phương diện của lô đầu ra (các phương diện chứa G0, G1 trong ví dụ trước) được xác định là các phương diện đầu ra không phải là các phương diện bù trừ.

  2. Số kích thước chênh lệch đầu ra được trình bày rõ ràng trong hình dạng đầu ra có thể nhỏ hơn thứ hạng đầu vào. Các kích thước "bị thiếu" này được liệt kê rõ ràng là collapsed_slice_dims và phải có kích thước lát cắt là 1. Vì chúng có kích thước lát cắt là 1, nên chỉ mục hợp lệ duy nhất cho chúng là 0 và việc loại bỏ chúng không gây ra sự không rõ ràng.

  3. Lát cắt được trích xuất từ mảng "collect Indices" ((X, Y) trong ví dụ cuối cùng) có thể có ít phần tử hơn thứ hạng mảng đầu vào và một mục ánh xạ rõ ràng cho biết cách chỉ mục cần được mở rộng để có cùng thứ hạng với đầu vào.

Ví dụ cuối cùng là (2) và (3) để triển khai tf.gather_nd:

G0G1 được dùng để cắt một chỉ mục ban đầu khỏi mảng chỉ mục thu thập như bình thường, ngoại trừ chỉ mục ban đầu chỉ có một phần tử X. Tương tự, chỉ có một chỉ mục mức chênh lệch đầu ra có giá trị O0. Tuy nhiên, trước khi được dùng làm chỉ mục trong mảng đầu vào, các chỉ mục này được mở rộng theo "Thu thập ánh xạ chỉ mục" (start_index_map trong phần mô tả chính thức) và "Ánh xạ chênh lệch" (remapped_offset_dims trong phần mô tả chính thức) vào [X,0] và [0,O0], cộng thêm đến [X,O0]. Nói cách khác là chỉ mục đầu ra {1,O0, chuyển với chỉ mục đầu ra [G0, G000OGG11GatherIndicestf.gather_nd

slice_sizes cho trường hợp này là [1,11]. Theo trực quan, điều này có nghĩa là mọi chỉ mục X trong mảng chỉ mục thu thập sẽ chọn toàn bộ một hàng và kết quả sẽ là cách nối tất cả các hàng này.

GetDimensionSize

Hãy xem thêm XlaBuilder::GetDimensionSize.

Trả về kích thước của chiều cho trước của toán hạng. Toán hạng phải có dạng mảng.

GetDimensionSize(operand, dimension)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng đầu vào thứ nguyên n
dimension int64 Một giá trị trong khoảng [0, n) chỉ định chiều

SetDimensionSize

Hãy xem thêm XlaBuilder::SetDimensionSize.

Đặt kích thước động cho phương diện cho trước của XlaOp. Toán hạng phải có dạng mảng.

SetDimensionSize(operand, size, dimension)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng đầu vào n chiều.
size XlaOp int32 biểu thị kích thước động trong thời gian chạy.
dimension int64 Một giá trị trong khoảng [0, n) chỉ định kích thước.

Kết quả là truyền qua toán hạng, với kích thước động do trình biên dịch theo dõi.

Các giá trị đệm sẽ bị các hoạt động giảm thiểu về sau bỏ qua.

let v: f32[10] = f32[10]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
let five: s32 = 5;
let six: s32 = 6;

// Setting dynamic dimension size doesn't change the upper bound of the static
// shape.
let padded_v_five: f32[10] = set_dimension_size(v, five, /*dimension=*/0);
let padded_v_six: f32[10] = set_dimension_size(v, six, /*dimension=*/0);

// sum == 1 + 2 + 3 + 4 + 5
let sum:f32[] = reduce_sum(padded_v_five);
// product == 1 * 2 * 3 * 4 * 5
let product:f32[] = reduce_product(padded_v_five);

// Changing padding size will yield different result.
// sum == 1 + 2 + 3 + 4 + 5 + 6
let sum:f32[] = reduce_sum(padded_v_six);

GetTupleElement

Hãy xem thêm XlaBuilder::GetTupleElement.

Chỉ mục vào một bộ dữ liệu có giá trị không đổi theo thời gian biên dịch.

Giá trị phải là hằng số thời gian biên dịch để dự đoán hình dạng có thể xác định loại giá trị thu được.

Hàm này tương tự như std::get<int N>(t) trong C++. Về mặt lý thuyết:

let v: f32[10] = f32[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
let s: s32 = 5;
let t: (f32[10], s32) = tuple(v, s);
let element_1: s32 = gettupleelement(t, 1);  // Inferred shape matches s32.

Xem thêm tf.tuple.

Trong nguồn cấp dữ liệu

Hãy xem thêm XlaBuilder::Infeed.

Infeed(shape)

Đối số Loại Ngữ nghĩa
shape Shape Hình dạng của dữ liệu được đọc trên giao diện Nguồn cấp dữ liệu. Trường bố cục của hình dạng phải được thiết lập sao cho khớp với bố cục của dữ liệu được gửi đến thiết bị; nếu không, hành vi của hình dạng sẽ không xác định.

Đọc một mục dữ liệu duy nhất từ giao diện truyền trực tuyến nguồn cấp dữ liệu ngầm ẩn của thiết bị, diễn giải dữ liệu dưới dạng hình dạng đã cho và bố cục của dữ liệu đó, đồng thời trả về XlaOp của dữ liệu. Được phép có nhiều toán tử Nguồn cấp dữ liệu trong một tính toán, nhưng các toán tử Nguồn cấp dữ liệu phải có tổng thứ tự. Ví dụ: 2 Nguồn cấp dữ liệu trong đoạn mã bên dưới có tổng thứ tự vì có sự phụ thuộc giữa vòng lặp while.

result1 = while (condition, init = init_value) {
  Infeed(shape)
}

result2 = while (condition, init = result1) {
  Infeed(shape)
}

Không hỗ trợ các hình dạng bộ dữ liệu lồng nhau. Đối với hình dạng bộ dữ liệu trống, thao tác Trong nguồn cấp dữ liệu thực sự không hoạt động và tiếp tục mà không cần đọc bất kỳ dữ liệu nào từ Nguồn cấp dữ liệu của thiết bị.

Iota

Hãy xem thêm XlaBuilder::Iota.

Iota(shape, iota_dimension)

Xây dựng một giá trị cố định cố định trên thiết bị thay vì một hoạt động chuyển máy chủ lưu trữ lớn. Tạo một mảng đã chỉ định hình dạng và giữ các giá trị bắt đầu từ 0 và tăng thêm 1 dọc theo kích thước được chỉ định. Đối với các loại dấu phẩy động, mảng được tạo tương đương với ConvertElementType(Iota(...)), trong đó Iota là loại tích phân và lượt chuyển đổi thành loại dấu phẩy động.

Đối số Loại Ngữ nghĩa
shape Shape Hình dạng của mảng do Iota() tạo
iota_dimension int64 Phương diện tăng dần.

Ví dụ: Iota(s32[4, 8], 0) trả về

  [[0, 0, 0, 0, 0, 0, 0, 0 ],
   [1, 1, 1, 1, 1, 1, 1, 1 ],
   [2, 2, 2, 2, 2, 2, 2, 2 ],
   [3, 3, 3, 3, 3, 3, 3, 3 ]]

Trả lại hàng với mức phí Iota(s32[4, 8], 1)

  [[0, 1, 2, 3, 4, 5, 6, 7 ],
   [0, 1, 2, 3, 4, 5, 6, 7 ],
   [0, 1, 2, 3, 4, 5, 6, 7 ],
   [0, 1, 2, 3, 4, 5, 6, 7 ]]

Bản đồ

Hãy xem thêm XlaBuilder::Map.

Map(operands..., computation)

Đối số Loại Ngữ nghĩa
operands chuỗi N XlaOp giây N mảng thuộc loại T0..T{N-1}
computation XlaComputation tính toán kiểu T_0, T_1, .., T_{N + M -1} -> S với N tham số kiểu T và M thuộc kiểu tuỳ ý
dimensions Mảng int64 mảng phương diện bản đồ

Áp dụng một hàm vô hướng trên các mảng operands đã cho, tạo ra một mảng có cùng chiều, trong đó mỗi phần tử là kết quả của hàm được liên kết, áp dụng cho các phần tử tương ứng trong các mảng đầu vào.

Hàm được ánh xạ là một phép tính tuỳ ý có hạn chế là hàm này có các đầu vào N thuộc kiểu vô hướng T và một đầu ra duy nhất thuộc kiểu S. Kết quả đầu ra có cùng kích thước với toán hạng ngoại trừ việc loại phần tử T được thay thế bằng S.

Ví dụ: Map(op1, op2, op3, computation, par1) liên kết elem_out <- computation(elem1, elem2, elem3, par1) tại mỗi chỉ mục (đa chiều) trong các mảng đầu vào để tạo ra mảng đầu ra.

OptimizationBarrier

Ngăn chặn mọi lượt tối ưu hoá di chuyển các phép tính qua rào cản.

Đảm bảo rằng tất cả dữ liệu đầu vào đều được đánh giá trước mọi toán tử phụ thuộc vào kết quả của rào cản.

Đệm

Hãy xem thêm XlaBuilder::Pad.

Pad(operand, padding_value, padding_config)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng thuộc loại T
padding_value XlaOp đại lượng vô hướng thuộc loại T để điền vào khoảng đệm đã thêm
padding_config PaddingConfig số lượng khoảng đệm ở cả hai cạnh (thấp, cao) và giữa các thành phần của từng kích thước

Mở rộng mảng operand đã cho bằng khoảng đệm xung quanh mảng cũng như giữa các phần tử của mảng với padding_value đã cho. padding_config chỉ định số lượng khoảng đệm cạnh và khoảng đệm bên trong cho mỗi kích thước.

PaddingConfig là một trường lặp lại của PaddingConfigDimension, chứa 3 trường cho mỗi chiều: edge_padding_low, edge_padding_highinterior_padding.

edge_padding_lowedge_padding_high chỉ định lượng khoảng đệm đã thêm ở cấp thấp (bên cạnh chỉ mục 0) và cao cấp (bên cạnh chỉ mục cao nhất) của từng chiều tương ứng. Số lượng khoảng đệm cạnh có thể là số âm -- giá trị tuyệt đối của khoảng đệm âm cho biết số lượng phần tử cần xoá khỏi kích thước được chỉ định.

interior_padding chỉ định lượng khoảng đệm được thêm vào giữa 2 phần tử bất kỳ trong mỗi chiều; giá trị này không được là số âm. Khoảng đệm bên trong xảy ra theo logic trước khoảng đệm cạnh. Vì vậy, trong trường hợp khoảng đệm cạnh âm, các phần tử sẽ bị xoá khỏi toán hạng đã chèn bên trong.

Toán tử này không hoạt động nếu các cặp khoảng đệm cạnh đều là (0, 0) và các giá trị khoảng đệm bên trong đều là 0. Hình dưới đây cho thấy ví dụ về các giá trị edge_paddinginterior_padding khác nhau cho một mảng hai chiều.

Bắt trúng bóng

Hãy xem thêm XlaBuilder::Recv.

Recv(shape, channel_handle)

Đối số Loại Ngữ nghĩa
shape Shape hình dạng dữ liệu cần nhận
channel_handle ChannelHandle giá trị nhận dạng duy nhất cho từng cặp gửi/nhận

Nhận dữ liệu có hình dạng đã cho từ lệnh Send trong một phép tính khác có cùng tên người dùng kênh. Trả về một XlaOp cho dữ liệu đã nhận.

API ứng dụng của hoạt động Recv thể hiện hoạt động giao tiếp đồng bộ. Tuy nhiên, hướng dẫn này được phân tách nội bộ thành 2 lệnh HLO (RecvRecvDone) để cho phép chuyển dữ liệu không đồng bộ. Xem thêm HloInstruction::CreateRecvHloInstruction::CreateRecvDone.

Recv(const Shape& shape, int64 channel_id)

Phân bổ tài nguyên cần thiết để nhận dữ liệu từ lệnh Send có cùng channel_id. Trả về ngữ cảnh cho các tài nguyên được phân bổ. Lệnh RecvDone sau đây sẽ sử dụng ngữ cảnh này để chờ hoàn tất quá trình chuyển dữ liệu. Ngữ cảnh là một bộ dữ liệu của {receive đệm (hình dạng), giá trị nhận dạng yêu cầu (U32)} và chỉ cho phép lệnh RecvDone sử dụng.

RecvDone(HloInstruction context)

Với ngữ cảnh được tạo bằng lệnh Recv, hãy đợi quá trình chuyển dữ liệu hoàn tất và trả về dữ liệu đã nhận.

Giảm bớt

Hãy xem thêm XlaBuilder::Reduce.

Áp dụng hàm rút gọn cho một hoặc nhiều mảng song song.

Reduce(operands..., init_values..., computation, dimensions)

Đối số Loại Ngữ nghĩa
operands Thứ tự của N XlaOp N mảng thuộc loại T_0, ..., T_{N-1}.
init_values Thứ tự của N XlaOp N đại lượng vô hướng thuộc loại T_0, ..., T_{N-1}.
computation XlaComputation phép tính kiểu T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}).
dimensions Mảng int64 mảng thứ nguyên không theo thứ tự để giảm.

Trong trường hợp:

  • N bắt buộc phải lớn hơn hoặc bằng 1.
  • Phép tính phải có tính liên kết "gần đúng" (xem bên dưới).
  • Tất cả các mảng đầu vào phải có cùng phương diện.
  • Tất cả các giá trị ban đầu phải tạo thành một danh tính trong computation.
  • Nếu N = 1, Collate(T) sẽ là T.
  • Nếu N > 1, thì Collate(T_0, ..., T_{N-1}) là một bộ dữ liệu gồm các phần tử N thuộc loại T.

Thao tác này làm giảm một hoặc nhiều chiều của từng mảng đầu vào thành các đại lượng vô hướng. Thứ hạng của mỗi mảng được trả về là rank(operand) - len(dimensions). Kết quả đầu ra của ứng dụng này là Collate(Q_0, ..., Q_N), trong đó Q_i là một mảng thuộc loại T_i, kích thước được mô tả ở bên dưới.

Nhiều phần phụ trợ khác được phép liên kết lại phép tính rút gọn. Điều này có thể dẫn đến sự chênh lệch về số, vì một số hàm rút gọn, chẳng hạn như cộng, không liên kết với số thực có độ chính xác đơn. Tuy nhiên, nếu phạm vi dữ liệu bị hạn chế, thì việc thêm dấu phẩy động gần đủ để liên kết cho hầu hết các mục đích sử dụng thực tế.

Ví dụ

Khi thu gọn trên một phương diện trong một mảng 1D có giá trị [10, 11, 12, 13], bằng hàm thu gọn f (đây là computation), thì giá trị này có thể được tính là

f(10, f(11, f(12, f(init_value, 13)))

nhưng cũng có nhiều khả năng khác, ví dụ:

f(init_value, f(f(10, f(init_value, 11)), f(f(init_value, 12), f(init_value, 13))))

Sau đây là ví dụ về mã giả thô về cách triển khai thao tác rút gọn, sử dụng phép tính lấy tổng làm phép tính rút gọn với giá trị ban đầu là 0.

result_shape <- remove all dims in dimensions from operand_shape

# Iterate over all elements in result_shape. The number of r's here is equal
# to the rank of the result
for r0 in range(result_shape[0]), r1 in range(result_shape[1]), ...:
  # Initialize this result element
  result[r0, r1...] <- 0

  # Iterate over all the reduction dimensions
  for d0 in range(dimensions[0]), d1 in range(dimensions[1]), ...:
    # Increment the result element with the value of the operand's element.
    # The index of the operand's element is constructed from all ri's and di's
    # in the right order (by construction ri's and di's together index over the
    # whole operand shape).
    result[r0, r1...] += operand[ri... di]

Dưới đây là ví dụ về cách giảm một mảng 2D (ma trận). Hình dạng có kích thước 2, kích thước 0 của kích thước 2 và kích thước 1 của kích thước 3:

Kết quả của việc giảm kích thước 0 hoặc 1 bằng hàm "thêm":

Lưu ý rằng cả hai kết quả rút gọn đều là các mảng 1D. Sơ đồ cho thấy một mục dưới dạng cột và một mục dưới dạng hàng để thuận tiện cho hình ảnh.

Để có ví dụ phức tạp hơn, dưới đây là một mảng 3D. Thứ hạng của nó là 3, kích thước 0 của kích thước 4, kích thước 1 của kích thước 2 và kích thước 2 của kích thước 3. Để đơn giản, các giá trị từ 1 đến 6 được nhân bản trên chiều 0.

Tương tự như ví dụ 2D, chúng ta có thể chỉ giảm một kích thước. Ví dụ: nếu giảm phương diện 0, chúng ta sẽ nhận được một mảng hạng 2, trong đó tất cả giá trị trên phương diện 0 được gộp thành một đại lượng vô hướng:

|  4   8  12 |
| 16  20  24 |

Nếu giảm chiều 2, chúng ta cũng nhận được một mảng hạng 2, trong đó tất cả các giá trị trên chiều 2 được gộp lại thành một đại lượng vô hướng:

| 6  15 |
| 6  15 |
| 6  15 |
| 6  15 |

Lưu ý rằng thứ tự tương đối giữa các chiều còn lại trong dữ liệu đầu vào được giữ nguyên trong dữ liệu đầu ra, nhưng một số phương diện có thể được chỉ định các số mới (do thứ hạng thay đổi).

Chúng ta cũng có thể giảm nhiều phương diện. Việc cộng giảm kích thước 0 và 1 sẽ tạo ra mảng 1D [20, 28, 36].

Việc giảm mảng 3D trên tất cả kích thước của mảng sẽ tạo ra 84 vô hướng.

Giảm thiểu sự đa dạng

Khi N > 1, ứng dụng hàm giảm phức tạp hơn một chút vì được áp dụng đồng thời cho tất cả dữ liệu đầu vào. Các toán hạng được cung cấp cho phép tính theo thứ tự sau:

  • Chạy giá trị rút gọn cho toán hạng đầu tiên
  • ...
  • Chạy giá trị rút gọn cho toán hạng thứ N
  • Giá trị nhập cho toán hạng đầu tiên
  • ...
  • Giá trị nhập cho toán hạng N

Ví dụ: hãy xem xét hàm rút gọn sau đây. Hàm này có thể dùng để tính song song giá trị tối đa và argmax của mảng 1-D:

f: (Float, Int, Float, Int) -> Float, Int
f(max, argmax, value, index):
  if value >= max:
    return (value, index)
  else:
    return (max, argmax)

Đối với các mảng Đầu vào 1-D V = Float[N], K = Int[N] và các giá trị khởi tạo I_V = Float, I_K = Int, kết quả f_(N-1) của việc giảm kích thước đầu vào duy nhất tương đương với ứng dụng đệ quy sau:

f_0 = f(I_V, I_K, V_0, K_0)
f_1 = f(f_0.first, f_0.second, V_1, K_1)
...
f_(N-1) = f(f_(N-2).first, f_(N-2).second, V_(N-1), K_(N-1))

Việc áp dụng rút gọn này cho một mảng giá trị và một mảng chỉ số tuần tự (tức là iota), sẽ lặp lại trên các mảng và trả về một bộ dữ liệu chứa giá trị tối đa và chỉ mục phù hợp.

ReducePrecision

Hãy xem thêm XlaBuilder::ReducePrecision.

Mô hình hoá tác động của việc chuyển đổi giá trị dấu phẩy động sang định dạng có độ chính xác thấp hơn (chẳng hạn như IEEE-FP16) và quay lại định dạng ban đầu. Số lượng bit số mũ và bit mantissa ở định dạng có độ chính xác thấp hơn có thể được chỉ định tuỳ ý, mặc dù tất cả các kích thước bit có thể không được hỗ trợ trên mọi phương thức triển khai phần cứng.

ReducePrecision(operand, mantissa_bits, exponent_bits)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng thuộc loại dấu phẩy động T.
exponent_bits int32 số bit số mũ ở định dạng độ chính xác thấp hơn
mantissa_bits int32 số bit mantissa ở định dạng độ chính xác thấp hơn

Kết quả là một mảng thuộc loại T. Các giá trị đầu vào được làm tròn đến giá trị gần nhất biểu diễn được bằng số lượng bit mantissa đã cho (sử dụng ngữ nghĩa "liên kết với số chẵn") và mọi giá trị vượt quá phạm vi được chỉ định theo số bit số mũ sẽ được gắn thành vô hạn dương hoặc âm. Các giá trị NaN vẫn được giữ lại, mặc dù các giá trị này có thể được chuyển đổi thành các giá trị NaN chính tắc.

Định dạng có độ chính xác thấp hơn phải có ít nhất một bit số mũ (để phân biệt một giá trị 0 với vô hạn, vì cả hai đều có mantissa bằng 0) và phải có số lượng bit mantissa không âm. Số lượng bit số mũ hoặc bit mantissa có thể vượt quá giá trị tương ứng cho loại T; phần tương ứng của lượt chuyển đổi khi đó sẽ chỉ là số không hoạt động.

ReduceScatter

Hãy xem thêm XlaBuilder::ReduceScatter.

Giảm Scatter là một thao tác tập thể giúp thực hiện All Tây một cách hiệu quả, sau đó phân tán kết quả bằng cách chia thành các khối shard_count dọc theo scatter_dimension và bản sao i trong nhóm bản sao sẽ nhận được phân đoạn ith.

ReduceScatter(operand, computation, scatter_dim, shard_count, replica_group_ids, channel_id)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng hoặc một bộ dữ liệu mảng không trống để giảm bớt trên các bản sao.
computation XlaComputation Phép tính rút gọn
scatter_dimension int64 Phương diện sẽ phân tán.
shard_count int64 Số khối cần chia scatter_dimension
replica_groups vectơ của vectơ của int64 Các nhóm thực hiện các bước rút gọn
channel_id int64 không bắt buộc Mã nhận dạng kênh không bắt buộc để giao tiếp giữa nhiều mô-đun
  • Khi operand là một bộ dữ liệu mảng, tính năng tán xạ giảm sẽ được thực hiện trên từng phần tử của bộ dữ liệu.
  • replica_groups là danh sách các nhóm bản sao diễn ra quá trình rút gọn (có thể truy xuất giá trị nhận dạng bản sao của bản sao hiện tại bằng ReplicaId). Thứ tự của các bản sao trong mỗi nhóm sẽ xác định thứ tự mà kết quả rút gọn sẽ được phân tán. replica_groups phải để trống (trong trường hợp đó, mọi bản sao đều thuộc về một nhóm duy nhất) hoặc chứa cùng số phần tử với số lượng bản sao. Khi có nhiều nhóm bản sao, các nhóm đó phải có cùng kích thước. Ví dụ: replica_groups = {0, 2}, {1, 3} thực hiện rút gọn giữa các bản sao 02, 13, sau đó phân tán kết quả.
  • shard_count là kích thước của mỗi nhóm bản sao. Chúng ta cần điều này trong trường hợp replica_groups trống. Nếu replica_groups không trống, shard_count phải bằng kích thước của từng nhóm bản sao.
  • channel_id được dùng để giao tiếp trên nhiều mô-đun: chỉ các thao tác reduce-scatter có cùng channel_id mới có thể giao tiếp với nhau.

Hình dạng đầu ra là hình dạng đầu vào với scatter_dimension được thu nhỏ shard_count lần. Ví dụ: nếu có hai bản sao và toán hạng có giá trị [1.0, 2.25][3.0, 5.25] tương ứng trên hai bản sao, thì giá trị đầu ra từ bản sao này trong đó scatter_dim0 sẽ là [4.0] cho bản sao đầu tiên và [7.5] cho bản sao thứ hai.

ReduceWindow

Hãy xem thêm XlaBuilder::ReduceWindow.

Áp dụng hàm rút gọn cho tất cả các phần tử trong mỗi cửa sổ của một chuỗi N mảng đa chiều, tạo ra một hoặc một bộ dữ liệu gồm N mảng đa chiều làm đầu ra. Mỗi mảng đầu ra có cùng số phần tử với số vị trí hợp lệ của cửa sổ. Lớp gộp có thể được biểu thị dưới dạng ReduceWindow. Tương tự như Reduce, computation được áp dụng luôn được chuyển init_values ở bên trái.

ReduceWindow(operands..., init_values..., computation, window_dimensions, window_strides, padding)

Đối số Loại Ngữ nghĩa
operands N XlaOps Một chuỗi gồm N mảng đa chiều thuộc loại T_0,..., T_{N-1}, mỗi mảng đại diện cho vùng cơ sở nơi cửa sổ được đặt.
init_values N XlaOps Giá trị bắt đầu của phép rút gọn, một giá trị cho mỗi toán hạng N. Hãy xem phần Giảm thiểu để biết thông tin chi tiết.
computation XlaComputation Hàm rút gọn thuộc loại T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}) để áp dụng cho các phần tử trong từng cửa sổ của mọi toán hạng đầu vào.
window_dimensions ArraySlice<int64> mảng số nguyên cho các giá trị kích thước cửa sổ
window_strides ArraySlice<int64> mảng số nguyên cho giá trị sải chân cửa sổ
base_dilations ArraySlice<int64> mảng số nguyên cho các giá trị giãn cơ
window_dilations ArraySlice<int64> mảng số nguyên cho các giá trị giãn nở cửa sổ
padding Padding loại khoảng đệm cho cửa sổ (Padding::kSame, có miếng đệm để có hình dạng đầu ra giống với đầu vào nếu sải chân là 1) hoặc Padding::kValid, không sử dụng khoảng đệm và "dừng" cửa sổ khi không còn phù hợp)

Trong trường hợp:

  • N bắt buộc phải lớn hơn hoặc bằng 1.
  • Tất cả các mảng đầu vào phải có cùng phương diện.
  • Nếu N = 1, Collate(T) sẽ là T.
  • Nếu N > 1, thì Collate(T_0, ..., T_{N-1}) là một bộ dữ liệu gồm các phần tử N thuộc loại (T0,...T{N-1}).

Mã và hình bên dưới là ví dụ về cách sử dụng ReduceWindow. Dữ liệu đầu vào là một ma trận có kích thước [4x6], và cả window_dimension và window_stride_dimension đều là [2x3].

// Create a computation for the reduction (maximum).
XlaComputation max;
{
  XlaBuilder builder(client_, "max");
  auto y = builder.Parameter(0, ShapeUtil::MakeShape(F32, {}), "y");
  auto x = builder.Parameter(1, ShapeUtil::MakeShape(F32, {}), "x");
  builder.Max(y, x);
  max = builder.Build().value();
}

// Create a ReduceWindow computation with the max reduction computation.
XlaBuilder builder(client_, "reduce_window_2x3");
auto shape = ShapeUtil::MakeShape(F32, {4, 6});
auto input = builder.Parameter(0, shape, "input");
builder.ReduceWindow(
    input,
    /*init_val=*/builder.ConstantLiteral(LiteralUtil::MinValue(F32)),
    *max,
    /*window_dimensions=*/{2, 3},
    /*window_stride_dimensions=*/{2, 3},
    Padding::kValid);

sải chân 1 trong một kích thước chỉ định rằng vị trí của một cửa sổ trong phương diện đó cách cửa sổ liền kề 1 phần tử. Để chỉ định rằng không có cửa sổ nào chồng chéo nhau, window_stride_dimension phải bằng window_dimension. Hình dưới đây minh hoạ cách sử dụng hai giá trị sải chân khác nhau. Khoảng đệm được áp dụng cho từng kích thước của giá trị đầu vào và các phép tính giống như đầu vào đó với kích thước của khoảng đệm sau khoảng đệm.

Đối với ví dụ về khoảng đệm không nhỏ, hãy cân nhắc việc tính toán mức tối thiểu của cửa sổ thu nhỏ (giá trị ban đầu là MAX_FLOAT) với kích thước 3 và sải chân 2 trên mảng đầu vào [10000, 1000, 100, 10, 1]. Khoảng đệm kValid tính toán mức tối thiểu qua 2 cửa sổ hợp lệ: [10000, 1000, 100][100, 10, 1], dẫn đến đầu ra [100, 1]. Khoảng đệm đầu tiên kSame sẽ đệm mảng đó để hình dạng sau cửa sổ thu gọn giống với dữ liệu đầu vào cho sải chân bằng cách thêm các phần tử ban đầu ở cả hai bên, nhận được [MAX_VALUE, 10000, 1000, 100, 10, 1, MAX_VALUE]. Thao tác chạy cửa sổ rút gọn trên mảng đệm sẽ hoạt động trên 3 cửa sổ [MAX_VALUE, 10000, 1000], [1000, 100, 10], [10, 1, MAX_VALUE] và lợi nhuận [1000, 10, 1].

Thứ tự đánh giá của hàm rút gọn là tuỳ ý và có thể không xác định. Do đó, hàm giảm không được quá nhạy cảm đối với việc liên kết lại. Xem nội dung thảo luận về tính kết hợp trong ngữ cảnh của Reduce để biết thêm thông tin chi tiết.

ReplicaId

Hãy xem thêm XlaBuilder::ReplicaId.

Trả về mã nhận dạng duy nhất (đại lượng vô hướng U32) của bản sao.

ReplicaId()

Mã nhận dạng duy nhất của mỗi bản sao là một số nguyên chưa ký trong khoảng [0, N), trong đó N là số lượng bản sao. Vì tất cả các bản sao đều đang chạy cùng một chương trình, nên lệnh gọi ReplicaId() trong chương trình sẽ trả về một giá trị riêng trên từng bản sao.

Đổi hình dạng

Hãy xem thêm XlaBuilder::Reshape và thao tác Collapse.

Đổi hình dạng kích thước của một mảng thành một cấu hình mới.

Reshape(operand, new_sizes) Reshape(operand, dimensions, new_sizes)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng thuộc loại T
dimensions Vectơ int64 thứ tự thu gọn thứ nguyên
new_sizes Vectơ int64 vectơ có kích thước của các chiều mới

Về mặt lý thuyết, việc định dạng lại sẽ làm phẳng một mảng thành vectơ một chiều chứa các giá trị dữ liệu, sau đó tinh chỉnh vectơ này thành một hình dạng mới. Các đối số đầu vào là một mảng tuỳ ý thuộc loại T, một vectơ không đổi tại thời gian biên dịch của các chỉ số kích thước và một vectơ không đổi kích thước tại thời gian biên dịch cho kết quả. Các giá trị trong vectơ dimension, nếu được cung cấp, phải là hoán vị của tất cả các chiều của T; giá trị mặc định nếu không được cho là {0, ..., rank - 1}. Thứ tự của các phương diện trong dimensions là từ chiều thay đổi chậm nhất (chủ yếu nhất) đến chiều thay đổi nhanh nhất (hầu hết nhỏ) trong lồng vòng lặp. Hàm này sẽ thu gọn mảng dữ liệu đầu vào thành một chiều duy nhất. Vectơ new_sizes xác định kích thước của mảng đầu ra. Giá trị tại chỉ mục 0 trong new_sizes là kích thước của phương diện 0, giá trị tại chỉ mục 1 là kích thước của phương diện 1, v.v. Tích của kích thước new_size phải bằng tích của kích thước kích thước của toán hạng. Khi tinh chỉnh mảng đã thu gọn thành mảng đa chiều do new_sizes xác định, các kích thước trong new_sizes được sắp xếp theo thứ tự từ thay đổi chậm nhất (lớn nhất) đến biến đổi nhanh nhất (hầu hết nhỏ).

Ví dụ: giả sử v là một mảng gồm 24 phần tử:

let v = f32[4x2x3] { { {10, 11, 12}, {15, 16, 17} },
                    { {20, 21, 22}, {25, 26, 27} },
                    { {30, 31, 32}, {35, 36, 37} },
                    { {40, 41, 42}, {45, 46, 47} } };

In-order collapse:
let v012_24 = Reshape(v, {0,1,2}, {24});
then v012_24 == f32[24] {10, 11, 12, 15, 16, 17, 20, 21, 22, 25, 26, 27,
                         30, 31, 32, 35, 36, 37, 40, 41, 42, 45, 46, 47};

let v012_83 = Reshape(v, {0,1,2}, {8,3});
then v012_83 == f32[8x3] { {10, 11, 12}, {15, 16, 17},
                          {20, 21, 22}, {25, 26, 27},
                          {30, 31, 32}, {35, 36, 37},
                          {40, 41, 42}, {45, 46, 47} };

Out-of-order collapse:
let v021_24 = Reshape(v, {1,2,0}, {24});
then v012_24 == f32[24]  {10, 20, 30, 40, 11, 21, 31, 41, 12, 22, 32, 42,
                          15, 25, 35, 45, 16, 26, 36, 46, 17, 27, 37, 47};

let v021_83 = Reshape(v, {1,2,0}, {8,3});
then v021_83 == f32[8x3] { {10, 20, 30}, {40, 11, 21},
                          {31, 41, 12}, {22, 32, 42},
                          {15, 25, 35}, {45, 16, 26},
                          {36, 46, 17}, {27, 37, 47} };


let v021_262 = Reshape(v, {1,2,0}, {2,6,2});
then v021_262 == f32[2x6x2] { { {10, 20}, {30, 40},
                              {11, 21}, {31, 41},
                              {12, 22}, {32, 42} },
                             { {15, 25}, {35, 45},
                              {16, 26}, {36, 46},
                              {17, 27}, {37, 47} } };

Trong trường hợp đặc biệt, việc đổi hình dạng có thể biến đổi một mảng phần tử đơn lẻ thành đại lượng vô hướng và ngược lại. Ví dụ:

Reshape(f32[1x1] { {5} }, {0,1}, {}) == 5;
Reshape(5, {}, {1,1}) == f32[1x1] { {5} };

Lần hồi (đảo ngược)

Hãy xem thêm XlaBuilder::Rev.

Rev(operand, dimensions)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng thuộc loại T
dimensions ArraySlice<int64> phương diện để đảo ngược

Đảo ngược thứ tự của các phần tử trong mảng operand dọc theo dimensions được chỉ định, tạo ra một mảng đầu ra có cùng hình dạng. Mỗi phần tử của mảng toán hạng tại một chỉ mục đa chiều được lưu trữ trong mảng đầu ra tại một chỉ mục đã biến đổi. Chỉ mục đa chiều được chuyển đổi bằng cách đảo ngược chỉ mục trong mỗi chiều cần đảo ngược (nghĩa là nếu chiều có kích thước N là một trong các chiều đảo ngược, thì chỉ mục i của nó sẽ được chuyển đổi thành N - 1 - i).

Một cách sử dụng cho toán tử Rev là đảo ngược mảng trọng số tích chập dọc theo hai kích thước cửa sổ trong quá trình tính toán chuyển màu trong mạng nơron.

RngNormal

Hãy xem thêm XlaBuilder::RngNormal.

Tạo kết quả của một hình dạng cho trước với các số ngẫu nhiên được tạo theo \(N(\mu, \sigma)\) phân phối chuẩn. Các tham số \(\mu\) và \(\sigma\)và hình dạng đầu ra phải có kiểu phần tử dấu phẩy động. Các tham số hơn nữa phải có giá trị vô hướng.

RngNormal(mu, sigma, shape)

Đối số Loại Ngữ nghĩa
mu XlaOp Giá trị vô hướng thuộc loại T xác định trung bình của số được tạo
sigma XlaOp Giá trị vô hướng thuộc loại T chỉ định độ lệch chuẩn của được tạo
shape Shape Hình dạng đầu ra thuộc loại T

RngUniform

Hãy xem thêm XlaBuilder::RngUniform.

Dựng kết quả của một hình dạng cho trước với các số ngẫu nhiên được tạo sau sự phân phối đồng nhất trong khoảng \([a,b)\). Các tham số và loại phần tử đầu ra phải là loại boolean, loại tích phân hoặc loại dấu phẩy động, đồng thời các loại phải nhất quán. Các phần phụ trợ CPU và GPU hiện chỉ hỗ trợ F64, F32, F16, BF16, S64, U64, S32 và U32. Hơn nữa, các tham số cần phải có giá trị vô hướng. Nếu \(b <= a\) kết quả là phương thức triển khai được xác định.

RngUniform(a, b, shape)

Đối số Loại Ngữ nghĩa
a XlaOp Giá trị vô hướng thuộc loại T chỉ định giới hạn dưới của khoảng
b XlaOp Giá trị vô hướng thuộc loại T xác định giới hạn trên của khoảng
shape Shape Hình dạng đầu ra thuộc loại T

RngBitGenerator

Tạo dữ liệu đầu ra có hình dạng nhất định chứa các bit ngẫu nhiên đồng nhất bằng cách sử dụng thuật toán được chỉ định (hoặc giá trị mặc định của phần phụ trợ) và trả về trạng thái cập nhật (có hình dạng giống như trạng thái ban đầu) và dữ liệu ngẫu nhiên được tạo.

Trạng thái ban đầu là trạng thái ban đầu của quá trình tạo số ngẫu nhiên hiện tại. Biểu đồ này và hình dạng bắt buộc cũng như các giá trị hợp lệ phụ thuộc vào thuật toán được sử dụng.

Dữ liệu đầu ra được đảm bảo là một hàm tất định của trạng thái ban đầu, nhưng không đảm bảo mang tính tất định giữa các phần phụ trợ và các phiên bản trình biên dịch khác nhau.

RngBitGenerator(algorithm, key, shape)

Đối số Loại Ngữ nghĩa
algorithm RandomAlgorithm Thuật toán PRNG sẽ được sử dụng.
initial_state XlaOp Trạng thái ban đầu của thuật toán PRNG.
shape Shape Hình dạng đầu ra cho dữ liệu được tạo.

Những giá trị hiện có cho algorithm:

Tán xạ

Thao tác tán xạ XLA tạo ra một chuỗi kết quả. Đó là các giá trị của mảng đầu vào operands, trong đó một số lát cắt (tại các chỉ mục do scatter_indices chỉ định) được cập nhật với chuỗi các giá trị trong updates bằng update_computation.

Hãy xem thêm XlaBuilder::Scatter.

scatter(operands..., scatter_indices, updates..., update_computation, index_vector_dim, update_window_dims, inserted_window_dims, scatter_dims_to_operand_dims)

Đối số Loại Ngữ nghĩa
operands Thứ tự của N XlaOp N mảng thuộc loại T_0, ..., T_N sẽ được phân tán.
scatter_indices XlaOp Mảng chứa các chỉ mục bắt đầu của các lát cắt phải được phân tán.
updates Thứ tự của N XlaOp N mảng thuộc loại T_0, ..., T_N. updates[i] chứa các giá trị phải được dùng để tán xạ operands[i].
update_computation XlaComputation Phép tính được dùng để kết hợp các giá trị hiện có trong mảng đầu vào và nội dung cập nhật trong quá trình tán xạ. Phép tính này phải thuộc kiểu T_0, ..., T_N, T_0, ..., T_N -> Collate(T_0, ..., T_N).
index_vector_dim int64 Phương diện trong scatter_indices chứa các chỉ mục bắt đầu.
update_window_dims ArraySlice<int64> Tập hợp kích thước trong hình dạng updateskích thước cửa sổ.
inserted_window_dims ArraySlice<int64> Tập hợp kích thước cửa sổ phải được chèn vào hình dạng updates.
scatter_dims_to_operand_dims ArraySlice<int64> Kích thước ánh xạ từ các chỉ mục tán xạ đến không gian chỉ mục toán hạng. Mảng này được hiểu là ánh xạ i đến scatter_dims_to_operand_dims[i] . Chỉ số này phải có một với một và toàn bộ.
indices_are_sorted bool Liệu các chỉ mục có được đảm bảo sắp xếp theo phương thức gọi hay không.
unique_indices bool Liệu các chỉ mục có được phương thức gọi đảm bảo là duy nhất hay không.

Trong trường hợp:

  • N bắt buộc phải lớn hơn hoặc bằng 1.
  • operands[0], ..., operands[N-1] phải có cùng phương diện.
  • updates[0], ..., updates[N-1] phải có cùng phương diện.
  • Nếu N = 1, Collate(T) sẽ là T.
  • Nếu N > 1, thì Collate(T_0, ..., T_N) là một bộ dữ liệu gồm các phần tử N thuộc loại T.

Nếu index_vector_dim bằng scatter_indices.rank, chúng tôi sẽ ngầm xem scatter_indices có chiều 1 theo sau.

Chúng ta xác định update_scatter_dims thuộc loại ArraySlice<int64> là tập hợp kích thước trong hình dạng updates không nằm trong update_window_dims và theo thứ tự tăng dần.

Các đối số của tán xạ phải tuân theo các quy tắc ràng buộc sau:

  • Mỗi mảng updates phải có thứ hạng update_window_dims.size + scatter_indices.rank - 1.

  • Các giới hạn của kích thước i trong mỗi mảng updates phải tuân theo các giới hạn sau:

    • Nếu i có trong update_window_dims (tức là bằng update_window_dims[k] đối với một số k), thì giới hạn kích thước i trong updates không được vượt quá giới hạn tương ứng của operand sau khi tính đến inserted_window_dims (cụ thể là adjusted_window_bounds[k], trong đó adjusted_window_bounds chứa các giới hạn của operand khi đã xoá các giới hạn tại chỉ mục inserted_window_dims).
    • Nếu i có trong update_scatter_dims (tức là bằng update_scatter_dims[k] đối với một số k), thì giới hạn của chiều i trong updates phải bằng giới hạn tương ứng của scatter_indices, bỏ qua index_vector_dim (tức là scatter_indices.shape.dims[k], nếu k < index_vector_dim và nếu không là scatter_indices.shape.dims[k+1]).
  • update_window_dims phải theo thứ tự tăng dần, không có bất kỳ số thứ nguyên lặp lại nào và nằm trong phạm vi [0, updates.rank).

  • inserted_window_dims phải theo thứ tự tăng dần, không có bất kỳ số thứ nguyên lặp lại nào và nằm trong phạm vi [0, operand.rank).

  • operand.rank phải bằng tổng của update_window_dims.sizeinserted_window_dims.size.

  • scatter_dims_to_operand_dims.size phải bằng scatter_indices.shape.dims[index_vector_dim] và các giá trị của thuộc tính này phải trong khoảng [0, operand.rank).

Đối với một chỉ mục U nhất định trong mỗi mảng updates, chỉ mục tương ứng I trong mảng operands tương ứng mà bản cập nhật này phải được áp dụng được tính như sau:

  1. Giả sử G = { U[k] cho k trong update_scatter_dims }. Hãy dùng G để tra cứu vectơ chỉ mục S trong mảng scatter_indices sao cho S[i] = scatter_indices[Kết hợp(G, i)] trong đó Kết hợp(A, b) chèn b tại vị trí index_vector_dim vào A.
  2. Tạo chỉ mục Sin vào operand sử dụng S bằng cách phân tán S bằng bản đồ scatter_dims_to_operand_dims. Chính thức hơn:
    1. Sin[scatter_dims_to_operand_dims[k]] = S[k] nếu k < scatter_dims_to_operand_dims.size.
    2. Sin[_] = 0 nếu không.
  3. Tạo một chỉ mục Win vào mỗi mảng operands bằng cách phân tán các chỉ mục đó tại update_window_dims trong U theo inserted_window_dims. Chính thức hơn:
    1. Win[window_dims_to_operand_dims(k)] = U[k] nếu k nằm trong update_window_dims, trong đó window_dims_to_operand_dims là hàm đơn điệu có miền [0, update_window_dims.size) và dải ô [0, operand.rank) \ inserted_window_dims. (Ví dụ: nếu update_window_dims.size4, operand.rank6inserted_window_dims là {0, 2}, thì window_dims_to_operand_dims sẽ là {01, 13, 24, 35}).
    2. Win[_] = 0 nếu không.
  4. IWin + Sin, trong đó + là phép thêm phần tử.

Tóm lại, bạn có thể xác định hoạt động tán xạ như sau.

  • Khởi động output với operands, tức là cho tất cả các chỉ mục J, cho tất cả chỉ báo O trong mảng operands[J]:
    output[J][O] = operands[J][O]
  • Với mọi chỉ mục U trong mảng updates[J] và chỉ mục tương ứng O trong mảng operand[J], nếu O là chỉ mục hợp lệ cho output:
    (output[0][O], ..., output[N-1][O]) =update_computation(output[0][O], ..., ,output[N-1][O],updates[0][U], ...,updates[N-1][U])

Thứ tự áp dụng nội dung cập nhật là không xác định. Vì vậy, khi nhiều chỉ mục trong updates tham chiếu đến cùng một chỉ mục trong operands, giá trị tương ứng trong output sẽ không xác định.

Xin lưu ý rằng tham số đầu tiên được truyền vào update_computation sẽ luôn là giá trị hiện tại từ mảng output và tham số thứ hai sẽ luôn là giá trị của mảng updates. Điều này đặc biệt quan trọng đối với các trường hợp update_computation không có tính giao hoán.

Nếu bạn đặt indices_are_sorted thành true (đúng), thì XLA có thể giả định rằng start_indices được người dùng sắp xếp (theo thứ tự start_index_map tăng dần). Nếu không, thì nghĩa là việc triển khai ngữ nghĩa sẽ được xác định.

Nếu bạn đặt unique_indices thành true thì XLA có thể giả định rằng tất cả các phần tử được phân tán là duy nhất. Vì vậy, XLA có thể sử dụng các hoạt động phi nguyên tử. Nếu unique_indices được đặt thành đúng và các chỉ mục được phân tán không phải là duy nhất, thì ngữ nghĩa sẽ được xác định.

Một cách không chính thức, bạn có thể xem hoạt động phân tán là một phương diện ngược của hoạt động thu thập, tức là hoạt động phân tán sẽ cập nhật các phần tử trong đầu vào mà được trích xuất bằng hoạt động thu thập tương ứng.

Để xem ví dụ và nội dung mô tả không chính thức chi tiết, hãy tham khảo phần "Mô tả trang trọng" trong Gather.

Chọn

Hãy xem thêm XlaBuilder::Select.

Tạo một mảng đầu ra từ các phần tử của 2 mảng đầu vào, dựa trên các giá trị của một mảng thuộc tính.

Select(pred, on_true, on_false)

Đối số Loại Ngữ nghĩa
pred XlaOp mảng thuộc loại PRED
on_true XlaOp mảng thuộc loại T
on_false XlaOp mảng thuộc loại T

Các mảng on_trueon_false phải có cùng hình dạng. Đây cũng là hình dạng của mảng đầu ra. Mảng pred phải có cùng chiều với on_trueon_false với loại phần tử PRED.

Đối với mỗi phần tử P của pred, phần tử tương ứng của mảng đầu ra sẽ được lấy từ on_true nếu giá trị của Ptrue và từ on_false nếu giá trị của Pfalse. Là một dạng truyền phát bị hạn chế, pred có thể là đại lượng vô hướng thuộc kiểu PRED. Trong trường hợp này, mảng đầu ra được lấy hoàn toàn từ on_true nếu predtrue và từ on_false nếu predfalse.

Ví dụ với pred không vô hướng:

let pred: PRED[4] = {true, false, false, true};
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 200, 300, 4};

Ví dụ với đại lượng vô hướng pred:

let pred: PRED = true;
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 2, 3, 4};

Hỗ trợ lựa chọn giữa các bộ dữ liệu. Lừa được coi là kiểu vô hướng vì mục đích này. Nếu on_trueon_false là các bộ dữ liệu (phải có cùng hình dạng!) thì pred phải là một đại lượng vô hướng thuộc kiểu PRED.

SelectAndScatter

Hãy xem thêm XlaBuilder::SelectAndScatter.

Toán tử này có thể được coi là phép toán tổng hợp, trước tiên sẽ tính toán ReduceWindow trên mảng operand để chọn một phần tử từ mỗi cửa sổ, sau đó phân tán mảng source tới các chỉ mục của các phần tử đã chọn để tạo một mảng đầu ra có hình dạng giống như mảng toán hạng. Hàm nhị phân select được dùng để chọn một phần tử từ mỗi cửa sổ bằng cách áp dụng phần tử đó trên từng cửa sổ. Hàm này được gọi với thuộc tính mà vectơ chỉ mục của tham số đầu tiên nhỏ hơn về mặt từ vựng so với vectơ chỉ mục của tham số thứ hai. Hàm select trả về true nếu tham số đầu tiên được chọn và trả về false nếu tham số thứ hai được chọn, đồng thời hàm phải duy trì tính bắc cầu (tức là nếu select(a, b)select(b, c)true, thì select(a, c) cũng là true) để phần tử được chọn không phụ thuộc vào thứ tự của các phần tử được truyền tải trong một cửa sổ nhất định.

Hàm scatter được áp dụng cho mỗi chỉ mục đã chọn trong mảng đầu ra. Hàm này cần 2 tham số vô hướng:

  1. Giá trị hiện tại ở chỉ mục đã chọn trong mảng đầu ra
  2. Giá trị tán xạ từ source áp dụng cho chỉ mục đã chọn

Phương thức này kết hợp 2 tham số và trả về một giá trị vô hướng được dùng để cập nhật giá trị tại chỉ mục đã chọn trong mảng đầu ra. Ban đầu, tất cả các chỉ mục của mảng đầu ra được đặt thành init_value.

Mảng đầu ra có cùng hình dạng với mảng operand và mảng source phải có cùng hình dạng do áp dụng toán tử ReduceWindow cho mảng operand. Bạn có thể dùng SelectAndScatter để truyền ngược các giá trị độ dốc của lớp gộp trong mạng nơron.

SelectAndScatter(operand, select, window_dimensions, window_strides, padding, source, init_value, scatter)

Đối số Loại Ngữ nghĩa
operand XlaOp mảng loại T mà cửa sổ trượt qua
select XlaComputation tính toán nhị phân thuộc kiểu T, T -> PRED, để áp dụng cho tất cả phần tử trong từng cửa sổ; trả về true nếu tham số đầu tiên được chọn và trả về false nếu tham số thứ hai được chọn
window_dimensions ArraySlice<int64> mảng số nguyên cho các giá trị kích thước cửa sổ
window_strides ArraySlice<int64> mảng số nguyên cho giá trị sải chân cửa sổ
padding Padding loại khoảng đệm cho cửa sổ (Padding::kSame hoặc Padding::kValid)
source XlaOp mảng loại T có các giá trị tán xạ
init_value XlaOp giá trị vô hướng thuộc loại T cho giá trị ban đầu của mảng đầu ra
scatter XlaComputation tính toán nhị phân thuộc loại T, T -> T, để áp dụng từng phần tử nguồn tán xạ cùng với phần tử đích của phần tử đó

Hình dưới đây cho thấy ví dụ về cách sử dụng SelectAndScatter, trong đó hàm select tính toán giá trị tối đa trong số các tham số của hàm đó. Xin lưu ý rằng khi các cửa sổ chồng chéo nhau, như trong hình (2) bên dưới, một chỉ mục của mảng operand có thể được chọn nhiều lần theo các cửa sổ khác nhau. Trong hình này, phần tử có giá trị 9 được cả hai cửa sổ trên cùng (màu xanh dương và màu đỏ) chọn, đồng thời hàm bổ sung nhị phân scatter tạo ra phần tử đầu ra của giá trị 8 (2 + 6).

Thứ tự đánh giá của hàm scatter là tuỳ ý và có thể không xác định. Do đó, hàm scatter không được nhạy cảm quá mức đối với việc liên kết lại. Xem nội dung thảo luận về tính kết hợp trong ngữ cảnh của Reduce để biết thêm thông tin chi tiết.

Gửi

Hãy xem thêm XlaBuilder::Send.

Send(operand, channel_handle)

Đối số Loại Ngữ nghĩa
operand XlaOp dữ liệu cần gửi (mảng loại T)
channel_handle ChannelHandle giá trị nhận dạng duy nhất cho từng cặp gửi/nhận

Gửi dữ liệu toán hạng đã cho đến lệnh Recv trong một phép tính khác có cùng tên người dùng kênh. Không trả về bất kỳ dữ liệu nào.

Tương tự như thao tác Recv, API ứng dụng của thao tác Send thể hiện hoạt động giao tiếp đồng bộ và được phân tách nội bộ thành 2 lệnh HLO (SendSendDone) để cho phép chuyển dữ liệu không đồng bộ. Xem thêm HloInstruction::CreateSendHloInstruction::CreateSendDone.

Send(HloInstruction operand, int64 channel_id)

Bắt đầu một quá trình chuyển toán hạng không đồng bộ sang các tài nguyên do lệnh Recv phân bổ có cùng mã nhận dạng kênh. Trả về một ngữ cảnh được lệnh SendDone sau đây sử dụng để chờ hoàn tất quá trình chuyển dữ liệu. Ngữ cảnh là một bộ dữ liệu của {toán hạng (hình dạng), giá trị nhận dạng yêu cầu (U32)} và chỉ có thể dùng lệnh SendDone.

SendDone(HloInstruction context)

Với ngữ cảnh được tạo bằng lệnh Send, hãy đợi quá trình chuyển dữ liệu hoàn tất. Lệnh này không trả về bất kỳ dữ liệu nào.

Lên lịch đăng hướng dẫn lên kênh

Thứ tự thực thi của 4 hướng dẫn cho mỗi kênh (Recv, RecvDone, Send, SendDone) như sau.

  • Recv diễn ra trước Send
  • Send diễn ra trước RecvDone
  • Recv diễn ra trước RecvDone
  • Send diễn ra trước SendDone

Khi trình biên dịch phụ trợ tạo lịch biểu tuyến tính cho mỗi phép tính giao tiếp thông qua lệnh kênh, không được có chu kỳ giữa các phép tính. Ví dụ: bên dưới lịch biểu dẫn đến tắc nghẽn.

Slice (lát cắt)

Hãy xem thêm XlaBuilder::Slice.

Cắt trích xuất một mảng con từ mảng đầu vào. Mảng con có cùng thứ hạng với đầu vào và chứa các giá trị bên trong một hộp giới hạn trong mảng đầu vào, nơi các kích thước và chỉ mục của hộp giới hạn được cung cấp làm đối số cho thao tác cắt lát.

Slice(operand, start_indices, limit_indices, strides)

Đối số Loại Ngữ nghĩa
operand XlaOp Mảng thứ nguyên N thuộc loại T
start_indices ArraySlice<int64> Danh sách N số nguyên có chứa các chỉ mục bắt đầu của lát cắt cho mỗi chiều. Giá trị phải lớn hơn hoặc bằng 0.
limit_indices ArraySlice<int64> Danh sách N số nguyên có chứa các chỉ mục kết thúc (không bao gồm) cho lát cắt của mỗi phương diện. Mỗi giá trị phải lớn hơn hoặc bằng giá trị start_indices tương ứng của phương diện và nhỏ hơn hoặc bằng kích thước của phương diện.
strides ArraySlice<int64> Danh sách số nguyên N quyết định bước tiến đầu vào của lát cắt. Lát cắt chọn mọi phần tử strides[d] trong phương diện d.

Ví dụ 1 chiều:

let a = {0.0, 1.0, 2.0, 3.0, 4.0}
Slice(a, {2}, {4}) produces:
  {2.0, 3.0}

Ví dụ 2 chiều:

let b =
 { {0.0,  1.0,  2.0},
   {3.0,  4.0,  5.0},
   {6.0,  7.0,  8.0},
   {9.0, 10.0, 11.0} }

Slice(b, {2, 1}, {4, 3}) produces:
  { { 7.0,  8.0},
    {10.0, 11.0} }

Sắp xếp

Hãy xem thêm XlaBuilder::Sort.

Sort(operands, comparator, dimension, is_stable)

Đối số Loại Ngữ nghĩa
operands ArraySlice<XlaOp> Các toán hạng cần sắp xếp.
comparator XlaComputation Phép tính so sánh sẽ được sử dụng.
dimension int64 Phương diện để sắp xếp.
is_stable bool Liệu có nên sử dụng cách sắp xếp ổn định hay không.

Nếu chỉ cung cấp một toán hạng:

  • Nếu toán hạng là một tensor xếp hạng 1 (một mảng), kết quả là một mảng được sắp xếp. Nếu bạn muốn sắp xếp mảng theo thứ tự tăng dần, trình so sánh sẽ thực hiện phép so sánh nhỏ hơn. Chính thức, sau khi được sắp xếp, mảng sẽ giữ cho tất cả các vị trí chỉ mục i, ji < jcomparator(value[i], value[j]) = comparator(value[j], value[i]) = false hoặc comparator(value[i], value[j]) = true.

  • Nếu toán hạng có thứ hạng cao hơn, thì toán hạng sẽ được sắp xếp theo phương diện đã cho. Ví dụ: đối với tensor hạng 2 (ma trận), giá trị kích thước của 0 sẽ sắp xếp độc lập từng cột và giá trị kích thước 1 sẽ sắp xếp độc lập từng hàng. Nếu bạn không cung cấp số phương diện, thì phương diện gần đây nhất sẽ được chọn theo mặc định. Đối với thứ nguyên được sắp xếp, thứ tự sắp xếp tương tự sẽ áp dụng như trong trường hợp xếp hạng 1.

Nếu bạn cung cấp toán hạng n > 1:

  • Tất cả toán hạng n phải là tensor có cùng kích thước. Các loại phần tử của tensor có thể khác nhau.

  • Tất cả các toán hạng được sắp xếp cùng nhau, không phải riêng lẻ. Về mặt lý thuyết, các toán hạng được coi là một bộ dữ liệu. Khi kiểm tra xem các phần tử của mỗi toán hạng ở vị trí chỉ mục ij có cần được hoán đổi hay không, trình so sánh sẽ được gọi bằng tham số vô hướng 2 * n, trong đó tham số 2 * k tương ứng với giá trị ở vị trí i từ toán hạng k-th và tham số 2 * k + 1 tương ứng với giá trị tại vị trí j từ toán hạng k-th. Do đó, trình so sánh sẽ so sánh các tham số 2 * k2 * k + 1 với nhau, cũng như có thể sử dụng các cặp tham số khác làm yếu tố ngắt liên kết.

  • Kết quả là một bộ dữ liệu bao gồm các toán hạng theo thứ tự được sắp xếp (theo chiều được cung cấp, như ở trên). Toán hạng i-th của bộ dữ liệu tương ứng với toán hạng i-th của Sắp xếp.

Ví dụ: nếu có ba toán hạng operand0 = [3, 1], operand1 = [42, 50], operand2 = [-3.0, 1.1] và trình so sánh chỉ so sánh các giá trị của operand0 với toán hạng nhỏ hơn, thì kết quả của loại toán hạng này sẽ là bộ dữ liệu ([1, 3], [50, 42], [1.1, -3.0]).

Nếu bạn đặt is_stable thành true, cách sắp xếp này được đảm bảo là ổn định, nghĩa là nếu có các phần tử được trình so sánh coi là bằng nhau, thì thứ tự tương đối của các giá trị bằng nhau sẽ được giữ nguyên. Hai phần tử e1e2 bằng nhau khi và chỉ khi comparator(e1, e2) = comparator(e2, e1) = false. Theo mặc định, is_stable được đặt thành false.

Hoán vị

Ngoài ra, hãy xem phép toán tf.reshape.

Transpose(operand)

Đối số Loại Ngữ nghĩa
operand XlaOp Toán hạng cần hoán vị.
permutation ArraySlice<int64> Cách hiển thị phương diện.

Hoán vị cho các chiều của toán hạng bằng hoán vị đã cho, vì vậy, ∀ i . 0 ≤ i < rank ⇒ input_dimensions[permutation[i]] = output_dimensions[i].

Điều này giống với Reshape(toán hạng, hoán vị, Permute(hoán vị, toán hạng.shape.dimension)).

TriangularSolve

Hãy xem thêm XlaBuilder::TriangularSolve.

Giải hệ phương trình tuyến tính có ma trận hệ số tam giác dưới hoặc trên bằng phép thế tiến hoặc thế lùi. Việc truyền phát dọc theo các thứ nguyên chính, quy trình này sẽ giải quyết một trong các hệ thống ma trận op(a) * x = b hoặc x * op(a) = b cho biến x, nếu có ab, trong đó op(a)op(a) = a, op(a) = Transpose(a) hoặc op(a) = Conj(Transpose(a)).

TriangularSolve(a, b, left_side, lower, unit_diagonal, transpose_a)

Đối số Loại Ngữ nghĩa
a XlaOp một mảng > 2 của một kiểu dấu phẩy động hoặc phức tạp có hình dạng [..., M, M].
b XlaOp một mảng xếp hạng > 2 cùng loại có hình dạng [..., M, K] nếu left_side là đúng, nếu không thì là [..., K, M].
left_side bool cho biết sẽ giải một hệ thống dạng op(a) * x = b (true) hay x * op(a) = b (false).
lower bool xem nên sử dụng tam giác trên hay dưới của a.
unit_diagonal bool nếu là true, các phần tử đường chéo của a được giả định là 1 và không được truy cập.
transpose_a Transpose liệu cần sử dụng a nguyên trạng, hoán vị hay dùng hoán vị liên hợp.

Dữ liệu đầu vào chỉ được đọc từ tam giác dưới/trên của a, tuỳ thuộc vào giá trị của lower. Giá trị của tam giác còn lại sẽ bị bỏ qua. Dữ liệu đầu ra được trả về trong cùng một tam giác; các giá trị trong tam giác khác được xác định theo phương thức triển khai và có thể là bất kỳ giá trị nào.

Nếu thứ hạng của ab lớn hơn 2, thì chúng được coi là các lô ma trận, trong đó tất cả ngoại trừ 2 chiều nhỏ đều là các chiều lô. ab phải có các kích thước lô bằng nhau.

Khay lót

Hãy xem thêm XlaBuilder::Tuple.

Một bộ dữ liệu chứa nhiều trình xử lý dữ liệu, mỗi trình xử lý có hình dạng riêng.

Hàm này tương tự như std::tuple trong C++. Về mặt lý thuyết:

let v: f32[10] = f32[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
let s: s32 = 5;
let t: (f32[10], s32) = tuple(v, s);

Bạn có thể huỷ cấu trúc (truy cập) Tuples thông qua thao tác GetTupleElement.

Mặc dù

Hãy xem thêm XlaBuilder::While.

While(condition, body, init)

Đối số Loại Ngữ nghĩa
condition XlaComputation XlaComputation thuộc loại T -> PRED xác định điều kiện kết thúc của vòng lặp.
body XlaComputation XlaComputation thuộc kiểu T -> T xác định phần nội dung của vòng lặp.
init T Giá trị ban đầu cho tham số conditionbody.

Thực thi body theo tuần tự cho đến khi condition không thành công. Điều này tương tự như vòng lặp while thông thường ở nhiều ngôn ngữ khác, ngoại trừ những điểm khác biệt và hạn chế nêu dưới đây.

  • Nút While trả về một giá trị thuộc loại T. Đây là kết quả từ lần thực thi gần đây nhất của body.
  • Hình dạng của kiểu T được xác định theo phương thức tĩnh và phải giống nhau trong tất cả các vòng lặp.

Tham số T của các phép tính được khởi tạo bằng giá trị init trong lần lặp đầu tiên và được tự động cập nhật thành kết quả mới từ body trong mỗi lần lặp tiếp theo.

Một trường hợp sử dụng chính của nút While là để triển khai việc thực thi lặp lại quá trình huấn luyện trong mạng nơron. Mã giả được đơn giản hoá sẽ được thể hiện ở bên dưới cùng một biểu đồ thể hiện phép tính. Bạn có thể tìm thấy mã này trong while_test.cc. Kiểu T trong ví dụ này là Tuple bao gồm int32 cho số lần lặp lại và vector[10] cho tích luỹ. Đối với 1000 vòng lặp, vòng lặp tiếp tục thêm một vectơ không đổi vào tích luỹ.

// Pseudocode for the computation.
init = {0, zero_vector[10]} // Tuple of int32 and float[10].
result = init;
while (result(0) < 1000) {
  iteration = result(0) + 1;
  new_vector = result(1) + constant_vector[10];
  result = {iteration, new_vector};
}