| 1575 | fprintf(stderr, "generate_expert_tensor: %s %d %s %d/%d experts\n", |
| 1576 | j->expert.scope == EXP_SCOPE_MTP ? "stage" : "layer", |
| 1577 | j->expert.layer, j->wid, done, j->n_experts); |
| 1578 | } |
| 1579 | pthread_mutex_unlock(&j->lock); |
| 1580 | } |
| 1581 | return NULL; |
| 1582 | } |
| 1583 | |
| 1584 | static byte_buf generate_expert(st_db *db, const char *gguf_name, const tensor_meta *tmpl, |
| 1585 | ds4q_type target, int n_experts, int n_threads, |
| 1586 | const imatrix_store *imatrix) { |
| 1587 | expert_tensor e = parse_expert_tensor(gguf_name); |
| 1588 | if (!e.is_expert) die("not an expert tensor"); |
| 1589 | if (target != DS4Q_TYPE_MXFP4 && !is_quantizable_target(target)) { |
| 1590 | die("unsupported expert target type"); |
| 1591 | } |
| 1592 | const char *wid = expert_part_name(e.part); |
| 1593 | const int64_t ncols = tmpl->ne[0]; |
| 1594 | const int64_t nrows = tmpl->ne[1]; |
| 1595 | const size_t per_expert = (size_t)nrows * ds4q_row_size(target, ncols); |
| 1596 | byte_buf out = { .size = per_expert * (size_t)n_experts, .data = xmalloc(per_expert * (size_t)n_experts) }; |
| 1597 | ds4q_quantize_init(target); |
| 1598 | int worker_count = n_threads > 0 ? n_threads : 8; |
| 1599 | if (worker_count < 1) worker_count = 1; |
| 1600 | if (worker_count > n_experts) worker_count = n_experts; |
| 1601 | fprintf(stderr, "generate_expert_tensor: %s %d %s using %d worker%s\n", |
| 1602 | e.scope == EXP_SCOPE_MTP ? "stage" : "layer", |
| 1603 | e.layer, wid, worker_count, worker_count == 1 ? "" : "s"); |
| 1604 | expert_job job = { |
| 1605 | .db = db, .gguf_name = gguf_name, .tmpl = tmpl, .target = target, |
| 1606 | .n_experts = n_experts, .imatrix = imatrix, .expert = e, .wid = wid, |
| 1607 | .ncols = ncols, .nrows = nrows, .per_expert = per_expert, .out = &out, |
no test coverage detected