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ằngReplicaId
). 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
đếnN - 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 sao0
và2
, cũng như1
với3
.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ợpreplica_groups
trống.channel_id
được dùng để giao tiếp trên nhiều mô-đun: chỉ các thao tácall-gather
có cùngchannel_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]
và [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_dim
là 0
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ằngReplicaId
).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 sao0
và2
, cũng như1
và3
.channel_id
được dùng để giao tiếp trên nhiều mô-đun: chỉ các thao tácall-reduce
có cùngchannel_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]
và [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:
- 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 theosplit_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. - 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ụngReplicaId
). 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ếureplica_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 chosplit_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::BatchNormGrad
và bà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
, offset
và scale
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 w
và h
):
\[ \begin{split} c_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sigma^2_l+\epsilon} \right) \\\\ d_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \\\\ \nabla x_{ijkl} &= \frac{\gamma_{l} }{\sqrt{\sigma^2_{l}+\epsilon} } \left( \nabla y_{ijkl} - d_l - c_l (x_{ijkl} - \mu_{l}) \right) \\\\ \nabla \gamma_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sqrt{\sigma^2_{l}+\epsilon} } \right) \\\\\ \nabla \beta_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \end{split} \]
Giá trị đầu vào mean
và variance
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::BatchNormInference
và bà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 mean
và variance
cho mỗi lô. Phương thức này sử dụng dữ liệu đầu vào mean
và variance
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::BatchNormTraining
và the 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ử m
có w
và h
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_mean
và batch_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.0f
và broadcast_sizes
là {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 lower
là true
, tính các ma trận tam giác dưới l
sao cho $a = l .
l^T$. Nếu lower
là false
, 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 min
và max
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 pred
là true
, false_computation
nếu pred
là false
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_computation
và false_computation
phải giống nhau.
Xin lưu ý rằng chỉ một trong số true_computation
và false_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 giann
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ệnz
của đầu ra.input-z
: Kích thước của kích thước này nhân vớifeature_group_count
phải bằng kích thước của kích thướcz
tính theo lhs.spatial_dims
: Mô tả các kích thước không giann
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 y
và padding[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]
là (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_dilation
và rhs_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ớibatch_group_count
phải bằng với kích thước của kích thướcbatch
tính theo lhs.z
: Cùng kích thước vớioutput-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 lhs
và rhs
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ả lhs
và rhs
.
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ừ lhs
và rhs
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ừ lhs
và rhs
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 Op
là Rem
, 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_dims
là batch_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.size
và collapsed_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]
và index_vector_dim
là 2
thì chúng ta ngầm coi start_indices
hình dạng của start_indices
là [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:
Nếu
i
có trongbatch_dims
(tức là bằngbatch_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ỏ quaindex_vector_dim
(tức là chọnstart_indices.shape.dims
[k
] nếuk
<index_vector_dim
vàstart_indices.shape.dims
[k
+1
] nếu không).Nếu
i
có trongoffset_dims
(tức là bằngoffset_dims
[k
] đối với một sốk
), thì chúng ta sẽ chọn giới hạn tương ứng trongslice_sizes
sau khi tính đếncollapsed_slice_dims
(tức là chúng ta chọnadjusted_slice_sizes
[k
], trong đóadjusted_slice_sizes
làslice_sizes
với các giới hạn tại chỉ mụccollapsed_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:
Đặt
G
= {Out
[k
] chok
trongbatch_dims
}. Sử dụngG
để cắt một vectơS
sao choS
[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ả khiG
trống: NếuG
trống thìS
=start_indices
.Tạo chỉ mục bắt đầu,
S
in
, trongoperand
sử dụngS
bằng cách phân tánS
bằngstart_index_map
. Chính xác hơn:S
in
[start_index_map
[k
]] =S
[k
] nếuk
<start_index_map.size
.S
in
[_
] =0
nếu không.
Tạo chỉ mục
O
in
vàooperand
bằng cách phân tán các chỉ mục ở kích thước chênh lệch trongOut
theo tập hợpcollapsed_slice_dims
. Chính xác hơn:O
in
[remapped_offset_dims
(k
)] =Out
[offset_dims
[k
]] nếuk
<offset_dims.size
(remapped_offset_dims
được định nghĩa ở bên dưới).O
in
[_
] =0
nếu không.
In
làO
in
+S
in
, 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.size
là 4
, operand.rank
là 6
và collapsed_slice_dims
là {0
, 2
}, sau đó remapped_offset_dims
là {0
→1
,
1
→3
, 2
→4
, 3
→5
}.
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àooperand
.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 raOut
.
index_vector_dim
được thiết lập thành start_indices.rank
– 1
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
,O
0
,O
1
], 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
,O
0
,O
1
] khi đó là phần tử trong mảng đầu vào tại chỉ mục [X
+O
0
,Y
+O
1
].
slice_sizes
là [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ô G
0
và G
1
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:
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
O
0
,O
1
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ứaG
0
,G
1
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ừ.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.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
:
G
0
và G
1
đượ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ị O
0
. 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
,O
0
], cộng thêm đến [X
,O
0
]. Nói cách khác là chỉ mục đầu ra {1,O
0
, chuyển với chỉ mục đầu ra [G
0
, G
0
0
0
O
G
G
1
1
GatherIndices
tf.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_high
và interior_padding
.
edge_padding_low
và edge_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_padding
và interior_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 (Recv
và RecvDone
) để cho phép chuyển dữ liệu không đồng bộ. Xem thêm HloInstruction::CreateRecv
và HloInstruction::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ạiT
.
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ằngReplicaId
). 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 sao0
và2
,1
và3
, 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ợpreplica_groups
trống. Nếureplica_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ácreduce-scatter
có cùngchannel_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]
và [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_dim
là 0
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]
và [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
:
rng_default
: Thuật toán dành riêng cho phần phụ trợ có yêu cầu về hình dạng cụ thể cho phần phụ trợ.rng_three_fry
: Thuật toán PRNG dựa trên bộ đếm ThreeFry. Hình dạnginitial_state
làu64[2]
với các giá trị tuỳ ý. Salmon và cộng sự SC 2011. Số ngẫu nhiên song song: dễ như 1, 2, 3.rng_philox
: Thuật toán Philox để tạo song song các số ngẫu nhiên. Hình dạnginitial_state
làu64[3]
với các giá trị tuỳ ý. Salmon và cộng sự SC 2011. Số ngẫu nhiên song song: dễ như 1, 2, 3.
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 updates là kí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ạiT
.
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ạngupdate_window_dims.size + scatter_indices.rank - 1
.Các giới hạn của kích thước
i
trong mỗi mảngupdates
phải tuân theo các giới hạn sau:- Nếu
i
có trongupdate_window_dims
(tức là bằngupdate_window_dims
[k
] đối với một sốk
), thì giới hạn kích thướci
trongupdates
không được vượt quá giới hạn tương ứng củaoperand
sau khi tính đếninserted_window_dims
(cụ thể làadjusted_window_bounds
[k
], trong đóadjusted_window_bounds
chứa các giới hạn củaoperand
khi đã xoá các giới hạn tại chỉ mụcinserted_window_dims
). - Nếu
i
có trongupdate_scatter_dims
(tức là bằngupdate_scatter_dims
[k
] đối với một sốk
), thì giới hạn của chiềui
trongupdates
phải bằng giới hạn tương ứng củascatter_indices
, bỏ quaindex_vector_dim
(tức làscatter_indices.shape.dims
[k
], nếuk
<index_vector_dim
và nếu không làscatter_indices.shape.dims
[k+1
]).
- Nếu
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ủaupdate_window_dims.size
vàinserted_window_dims.size
.scatter_dims_to_operand_dims.size
phải bằngscatter_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:
- Giả sử
G
= {U
[k
] chok
trongupdate_scatter_dims
}. Hãy dùngG
để tra cứu vectơ chỉ mụcS
trong mảngscatter_indices
sao choS
[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. - Tạo chỉ mục
S
in
vàooperand
sử dụngS
bằng cách phân tánS
bằng bản đồscatter_dims_to_operand_dims
. Chính thức hơn:S
in
[scatter_dims_to_operand_dims
[k
]] =S
[k
] nếuk
<scatter_dims_to_operand_dims.size
.S
in
[_
] =0
nếu không.
- Tạo một chỉ mục
W
in
vào mỗi mảngoperands
bằng cách phân tán các chỉ mục đó tạiupdate_window_dims
trongU
theoinserted_window_dims
. Chính thức hơn:W
in
[window_dims_to_operand_dims
(k
)] =U
[k
] nếuk
nằm trongupdate_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ếuupdate_window_dims.size
là4
,operand.rank
là6
vàinserted_window_dims
là {0
,2
}, thìwindow_dims_to_operand_dims
sẽ là {0
→1
,1
→3
,2
→4
,3
→5
}).W
in
[_
] =0
nếu không.
I
làW
in
+S
in
, 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ớioperands
, tức là cho tất cả các chỉ mụcJ
, cho tất cả chỉ báoO
trong mảngoperands
[J
]:
output
[J
][O
] =operands
[J
][O
] - Với mọi chỉ mục
U
trong mảngupdates
[J
] và chỉ mục tương ứngO
trong mảngoperand
[J
], nếuO
là chỉ mục hợp lệ chooutput
:
(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_true
và on_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_true
và on_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 P
là true
và từ on_false
nếu giá trị của P
là false
. 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 pred
là true
và từ on_false
nếu pred
là false
.
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_true
và on_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)
và select(b, c)
là 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:
- Giá trị hiện tại ở chỉ mục đã chọn trong mảng đầu ra
- 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 (Send
và SendDone
) để cho phép chuyển dữ liệu không đồng bộ. Xem thêm HloInstruction::CreateSend
và HloInstruction::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ướcSend
Send
diễn ra trướcRecvDone
Recv
diễn ra trướcRecvDone
Send
diễn ra trướcSendDone
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, j
cói < j
làcomparator(value[i], value[j]) = comparator(value[j], value[i]) = false
hoặccomparator(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ước1
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
i
vàj
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ướng2 * n
, trong đó tham số2 * k
tương ứng với giá trị ở vị tríi
từ toán hạngk-th
và tham số2 * k + 1
tương ứng với giá trị tại vị tríj
từ toán hạngk-th
. Do đó, trình so sánh sẽ so sánh các tham số2 * k
và2 * 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ạngi-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ử e1
và e2
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ó a
và b
, trong đó op(a)
là 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 a
và b
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ô. a
và
b
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ố condition và body . |
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ạiT
. Đây là kết quả từ lần thực thi gần đây nhất củabody
. - 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};
}