ArrayToFP16
Sao chép một mảng kiểu float hoặc double vào một mảng kiểu ushort với định dạng được chỉ định.
bool ArrayToFP16(
const ushort& dst_array[], // sao chép đến
const float& 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 ArrayToFP16(
const ushort& dst_array[], // sao chép đến
const double& 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 ushort.
src_array[]
[in] Mảng nguồn kiểu float hoặc double.
fmt
[in] Định dạng sao chép từ liệt kê ENUM_FLOAT16_FORMAT.
Giá trị trả về
Trả về true nếu thành công, nếu không trả về false.
Ghi chú
Các định dạng FLOAT16 và BFLOAT16 được định nghĩa trong liệt kê ENUM_FLOAT16_FORMAT và chỉ được sử dụng trong MQL5 cho các thao tác với mô hình ONNX.
Hàm chuyển đổi các tham số đầu vào kiểu float hoặc double sang kiểu FLOAT16 và BFLOAT16. Các tham số đầu vào này sau đó được sử dụng trong hàm OnnxRun.
FLOAT16, còn được gọi là float nửa độ chính xác, sử dụng 16 bit để biểu diễn 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 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 (hoặc 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 phầ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 tính toán một cách hiệu quả.
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("lỗi trong ArrayToFP16. mã lỗi=",GetLastError());
return(false);
}
Print("mảng kiểm tra:");
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("lỗi trong ArrayFromFP16. mã lỗi=",GetLastError());
return(false);
}
for(int i=0; i<12; i++)
{
input_float16_values[i].value=data_uint16[i];
PrintFormat("%d giá trị đầu vào =%f Hex float16 = %s giá trị ushort=%d",i,test_data_float[i],ArrayToString(input_float16_values[i].uc),input_float16_values[i].value);
}
Print("Mảng đầu vào ONNX:");
ArrayPrint(input_float16_values);
bool res=OnnxRun(model_handle,ONNX_NO_CONVERSION,input_float16_values,output_double_values);
if(!res)
{
PrintFormat("lỗi trong OnnxRun. mã lỗi=%d",GetLastError());
return(false);
}
Print("Mảng đầu ra ONNX:");
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 đầu ra double %f = %s chênh lệch=%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