//+------------------------------------------------------------------+ //| KronosVerifyEncoder.mq5 | //| MMQ — Muhammad Minhas Qamar | //| www.mql5.com/en/articles/23304 | //+------------------------------------------------------------------+ #property copyright "MMQ — Muhammad Minhas Qamar" #property link "https://www.mql5.com/en/articles/23304" #property version "1.00" #property script_show_inputs #property strict #include // pulls in TokenizerMath + TransformerCore input string InpRefDir = "kronos_refs\\"; // refs folder under MQL5/Files/ input int InpLookback = 256; // L (rows in x_norm) //+------------------------------------------------------------------+ //| Read a [rows,cols] float32 .bin into a matrix(double). | //+------------------------------------------------------------------+ bool LoadF32Matrix(const string fname, ulong rows, ulong cols, matrix &out) { int h = FileOpen(fname, FILE_READ | FILE_BIN); if(h == INVALID_HANDLE) { PrintFormat("LoadF32Matrix: cannot open %s (err %d)", fname, GetLastError()); return false; } ulong n = rows * cols; float buf[]; ArrayResize(buf, (int)n); uint got = FileReadArray(h, buf, 0, (int)n); FileClose(h); if(got != n) { PrintFormat("LoadF32Matrix: short read %s (%u of %I64u)", fname, got, n); return false; } out = matrix::Zeros(rows, cols); for(ulong r = 0; r < rows; r++) for(ulong c = 0; c < cols; c++) out[r][c] = (double)buf[r * cols + c]; return true; } //+------------------------------------------------------------------+ //| Read N int32 values from a .bin into an int[]. | //+------------------------------------------------------------------+ bool LoadI32Array(const string fname, int n, int &out[]) { int h = FileOpen(fname, FILE_READ | FILE_BIN); if(h == INVALID_HANDLE) { PrintFormat("LoadI32Array: cannot open %s (err %d)", fname, GetLastError()); return false; } ArrayResize(out, n); uint got = FileReadArray(h, out, 0, n); // int matches int32 width FileClose(h); if(got != (uint)n) { PrintFormat("LoadI32Array: short read %s (%u of %d)", fname, got, n); return false; } return true; } //+------------------------------------------------------------------+ //| Count mismatched elements and record the first mismatch index. | //+------------------------------------------------------------------+ int CountMismatch(const int &a[], const int &b[], int n, int &first_idx) { int bad = 0; first_idx = -1; for(int i = 0; i < n; i++) if(a[i] != b[i]) { bad++; if(first_idx < 0) first_idx = i; } return bad; } //+------------------------------------------------------------------+ //| Script entry point. | //+------------------------------------------------------------------+ void OnStart() { Print("================ Kronos encoder verification ================"); const int L = InpLookback; //--- 1) load the frozen normalized input window matrix x_norm; if(!LoadF32Matrix(InpRefDir + "x_norm.bin", (ulong)L, KR_NFEAT, x_norm)) { Print("ABORT: could not load x_norm.bin"); return; } PrintFormat("Loaded x_norm: %I64u x %I64u", x_norm.Rows(), x_norm.Cols()); //--- 2) load the golden token ids int ref_s1[], ref_s2[]; if(!LoadI32Array(InpRefDir + "s1_ids.bin", L, ref_s1)) { Print("ABORT: s1_ids.bin"); return; } if(!LoadI32Array(InpRefDir + "s2_ids.bin", L, ref_s2)) { Print("ABORT: s2_ids.bin"); return; } //--- 3) build + load the encoder, run it CKronosEncoder enc; if(!enc.Init(KR_TOK_WEIGHT_DIR, KR_TOK_N_ENC_LAYERS, KR_TOK_D_MODEL, KR_TOK_N_HEADS, KR_TOK_FF_DIM)) { Print("ABORT: encoder Init failed (weights/paths)"); return; } Print("Encoder weights loaded."); int s1[], s2[]; if(!enc.Encode(x_norm, s1, s2)) { Print("ABORT: Encode() failed"); return; } PrintFormat("Encode produced %d s1 ids, %d s2 ids", ArraySize(s1), ArraySize(s2)); if(ArraySize(s1) != L || ArraySize(s2) != L) { PrintFormat("ABORT: length mismatch (got %d/%d, expected %d)", ArraySize(s1), ArraySize(s2), L); return; } //--- 4) exact integer comparison int first1, first2; int bad1 = CountMismatch(s1, ref_s1, L, first1); int bad2 = CountMismatch(s2, ref_s2, L, first2); PrintFormat("s1: %d / %d match (mismatches: %d)", L - bad1, L, bad1); PrintFormat("s2: %d / %d match (mismatches: %d)", L - bad2, L, bad2); //--- 5) localize the first few mismatches if any if(bad1 > 0) { PrintFormat("first s1 mismatch at t=%d : mql=%d ref=%d", first1, s1[first1], ref_s1[first1]); int shown = 0; for(int i = 0; i < L && shown < 8; i++) if(s1[i] != ref_s1[i]) { PrintFormat(" s1[%d] mql=%d ref=%d", i, s1[i], ref_s1[i]); shown++; } } if(bad2 > 0) { PrintFormat("first s2 mismatch at t=%d : mql=%d ref=%d", first2, s2[first2], ref_s2[first2]); int shown = 0; for(int i = 0; i < L && shown < 8; i++) if(s2[i] != ref_s2[i]) { PrintFormat(" s2[%d] mql=%d ref=%d", i, s2[i], ref_s2[i]); shown++; } } if(bad1 == 0 && bad2 == 0) Print(">>> ENCODER VERIFIED: exact integer match on s1 and s2. <<<"); else Print(">>> ENCODER MISMATCH: see dumps above. Likely culprits: " "transpose convention, RoPE layout, or block count. <<<"); Print("============================================================="); } //+------------------------------------------------------------------+