ArrayFromFP16
Sao chép một mảng kiểu ushort
vào một mảng kiểu float hoặc double với định dạng được chỉ định.
bool ArrayFromFP16(
const float& dst_array[], // sao chép đến
const ushort& src_array[], // sao chép từ
ENUM_FLOAT16_FORMAT fmt // định dạng
);
2
3
4
5
Nạp chồng cho kiểu double
bool ArrayFromFP16(
const double& dst_array[], // sao chép đến
const ushort& src_array[], // sao chép từ
ENUM_FLOAT16_FORMAT fmt // định dạng
);
2
3
4
5
Tham số
dst_array[]
[out] Mảng đích kiểu float hoặc double.
src_array[]
[in] Mảng nguồn kiểu ushort
.
fmt
[in] Định dạng sao chép từ bảng liệt kê ENUM_FLOAT16_FORMAT.
Giá trị trả về
Trả về true
nếu thành công, ngược lại trả về false
.
Ghi chú
Định dạng FLOAT16
và BFLOAT16
được định nghĩa trong bảng liệt kê ENUM_FLOAT16_FORMAT và được sử dụng trong MQL5 chỉ cho các thao tác với mô hình ONNX.
Nếu các tham số đầu ra thu được từ việc thực thi hàm OnnxRun có kiểu FLOAT16
và BFLOAT16
, bạn có thể sử dụng hàm này để chuyển đổi kết quả thành mảng float hoặc double.
FLOAT16
, còn được gọi là số thực dấu phẩy động nửa chính xác, sử dụng 16 bit để biểu diễn các số thực dấu phẩy động. Định dạng này cung cấp sự cân bằng giữa độ chính xác và hiệu quả tính toán. FLOAT16
được sử dụng rộng rãi trong các thuật toán học sâu và mạng nơ-ron, đòi hỏi xử lý hiệu suất cao với các tập dữ liệu lớn. Định dạng này tăng tốc các phép tính bằng cách giảm kích thước của số, điều này đặc biệt quan trọng khi huấn luyện mạng nơ-ron sâu trên GPU.
BFLOAT16
(hay Brain Floating Point 16) cũng sử dụng 16 bit nhưng khác với FLOAT16
ở cách biểu diễn định dạng. Trong định dạng này, 8 bit được phân bổ để biểu diễn số mũ, trong khi 7 bit còn lại được sử dụng để biểu diễn mantissa. Định dạng này được phát triển để sử dụng trong học sâu và trí tuệ nhân tạo, đặc biệt trong Đơn vị Xử lý Tensor (TPU) của Google. BFLOAT16
thể hiện hiệu suất tuyệt vời trong việc huấn luyện mạng nơ-ron và có thể tăng tốc hiệu quả các phép tính.
Ví dụ:
Hàm từ bài viết Làm việc với mô hình ONNX ở định dạng float16 và float8
//+------------------------------------------------------------------+
//| RunCastFloat16ToDouble |
//+------------------------------------------------------------------+
bool RunCastFloat16ToDouble(long model_handle)
{
PrintFormat("test=%s", __FUNCTION__);
double test_data[12]= {1,2,3,4,5,6,7,8,9,10,11,12};
ushort data_uint16[12];
if(!ArrayToFP16(data_uint16, test_data, FLOAT_FP16))
{
Print("error in ArrayToFP16. error code=", GetLastError());
return(false);
}
Print("test array:");
ArrayPrint(test_data);
Print("ArrayToFP16:");
ArrayPrint(data_uint16);
U<ushort> input_float16_values[3*4];
U<double> output_double_values[3*4];
float test_data_float[];
if(!ArrayFromFP16(test_data_float, data_uint16, FLOAT_FP16))
{
Print("error in ArrayFromFP16. error code=", GetLastError());
return(false);
}
for(int i=0; i<12; i++)
{
input_float16_values[i].value = data_uint16[i];
PrintFormat("%d input value =%f Hex float16 = %s ushort value=%d", i, test_data_float[i], ArrayToString(input_float16_values[i].uc), input_float16_values[i].value);
}
Print("ONNX input array:");
ArrayPrint(input_float16_values);
bool res = OnnxRun(model_handle, ONNX_NO_CONVERSION, input_float16_values, output_double_values);
if(!res)
{
PrintFormat("error in OnnxRun. error code=%d", GetLastError());
return(false);
}
Print("ONNX output array:");
ArrayPrint(output_double_values);
//---
double sum_error = 0.0;
for(int i=0; i<12; i++)
{
double delta = test_data[i] - output_double_values[i].value;
sum_error += MathAbs(delta);
PrintFormat("%d output double %f = %s difference=%f", i, output_double_values[i].value, ArrayToString(output_double_values[i].uc), delta);
}
//---
PrintFormat("test=%s sum_error=%f", __FUNCTION__, sum_error);
//---
return(true);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53