| 18 | static constexpr int SAM2_VERSION = 1; |
| 19 | |
| 20 | static bool sam3_quantize_model(const std::string & fname_inp, |
| 21 | const std::string & fname_out, |
| 22 | ggml_type qtype) { |
| 23 | auto finp = std::ifstream(fname_inp, std::ios::binary); |
| 24 | if (!finp) { |
| 25 | fprintf(stderr, "%s: failed to open '%s' for reading\n", __func__, fname_inp.c_str()); |
| 26 | return false; |
| 27 | } |
| 28 | |
| 29 | auto fout = std::ofstream(fname_out, std::ios::binary); |
| 30 | if (!fout) { |
| 31 | fprintf(stderr, "%s: failed to open '%s' for writing\n", __func__, fname_out.c_str()); |
| 32 | return false; |
| 33 | } |
| 34 | |
| 35 | // ── Read + write header (16 bytes) ────────────────────────────────────── |
| 36 | uint32_t magic; |
| 37 | int32_t version, ftype, n_tensors; |
| 38 | |
| 39 | finp.read(reinterpret_cast<char *>(&magic), 4); |
| 40 | finp.read(reinterpret_cast<char *>(&version), 4); |
| 41 | finp.read(reinterpret_cast<char *>(&ftype), 4); |
| 42 | finp.read(reinterpret_cast<char *>(&n_tensors), 4); |
| 43 | |
| 44 | bool is_sam2 = false; |
| 45 | if (magic == SAM3_MAGIC) { |
| 46 | if (version != SAM3_VERSION) { |
| 47 | fprintf(stderr, "%s: unsupported SAM3 version %d (expected %d)\n", |
| 48 | __func__, version, SAM3_VERSION); |
| 49 | return false; |
| 50 | } |
| 51 | } else if (magic == SAM2_MAGIC) { |
| 52 | if (version != SAM2_VERSION) { |
| 53 | fprintf(stderr, "%s: unsupported SAM2 version %d (expected %d)\n", |
| 54 | __func__, version, SAM2_VERSION); |
| 55 | return false; |
| 56 | } |
| 57 | is_sam2 = true; |
| 58 | } else { |
| 59 | fprintf(stderr, "%s: unknown magic 0x%08x\n", __func__, magic); |
| 60 | return false; |
| 61 | } |
| 62 | |
| 63 | const int32_t ftype_out = static_cast<int32_t>(qtype); |
| 64 | |
| 65 | fout.write(reinterpret_cast<const char *>(&magic), 4); |
| 66 | fout.write(reinterpret_cast<const char *>(&version), 4); |
| 67 | fout.write(reinterpret_cast<const char *>(&ftype_out), 4); |
| 68 | fout.write(reinterpret_cast<const char *>(&n_tensors), 4); |
| 69 | |
| 70 | fprintf(stderr, "%s: %s v%d, ftype %d -> %d (%s), %d tensors\n", |
| 71 | __func__, is_sam2 ? "SAM2" : "SAM3", version, ftype, |
| 72 | ftype_out, ggml_type_name(qtype), n_tensors); |
| 73 | |
| 74 | // ── Read + write hparams (copy through) ───────────────────────────────── |
| 75 | // The number of hparam fields differs between SAM2 and SAM3. |
| 76 | // SAM2: 50 int32 fields; SAM3: variable (depends on n_global_attn). |
| 77 | // We copy them all byte-for-byte. |