| 145 | const std::vector<float> & values, |
| 146 | const core::TensorShape & shape, |
| 147 | ggml_type type) { |
| 148 | if (!ggml_is_quantized(type)) { |
| 149 | throw std::runtime_error("tensor quantization target is not a quantized ggml type"); |
| 150 | } |
| 151 | if (ggml_quantize_requires_imatrix(type)) { |
| 152 | throw std::runtime_error("tensor quantization target requires an importance matrix: " + std::string(name)); |
| 153 | } |
| 154 | if (shape.rank < 2) { |
| 155 | throw std::runtime_error("quantized tensor must have rank >= 2: " + std::string(name)); |
| 156 | } |
| 157 | const int64_t elements_per_row = shape.last_dim(); |
| 158 | if (elements_per_row % ggml_blck_size(type) != 0) { |
| 159 | throw std::runtime_error("quantized tensor row size is not divisible by block size: " + std::string(name)); |
| 160 | } |
| 161 | const int64_t rows = shape.prefix_elements(); |
| 162 | if (rows <= 0 || elements_per_row <= 0 || |
| 163 | static_cast<size_t>(rows * elements_per_row) != values.size()) { |
| 164 | throw std::runtime_error("quantized tensor shape does not match F32 value count: " + std::string(name)); |
| 165 | } |
| 166 | std::vector<std::byte> bytes(static_cast<size_t>(rows) * ggml_row_size(type, elements_per_row)); |
| 167 | const size_t written = ggml_quantize_chunk( |
| 168 | type, |
| 169 | values.data(), |
| 170 | bytes.data(), |
| 171 | 0, |
| 172 | rows, |
| 173 | elements_per_row, |
| 174 | nullptr); |
| 175 | if (written != bytes.size()) { |
| 176 | throw std::runtime_error("quantized tensor byte size mismatch: " + std::string(name)); |
| 177 | } |
| 178 | return bytes; |
| 179 | } |
| 180 | |
| 181 | void set_tensor_bytes(ggml_tensor * tensor, const void * data, size_t bytes, std::string_view name) { |
| 182 | if (tensor == nullptr) { |
| 183 | throw std::runtime_error("cannot upload to a null backend tensor: " + std::string(name)); |
| 184 | } |
| 185 | if (bytes != ggml_nbytes(tensor)) { |
| 186 | throw std::runtime_error("backend tensor byte size mismatch for " + std::string(name)); |
| 187 | } |
| 188 | ggml_backend_tensor_set(tensor, data, 0, bytes); |
| 189 | } |
| 190 | |
| 191 | std::vector<float> decode_tensor_data_f32(std::string_view name, const TensorData & tensor) { |
| 192 | if (tensor.type == GGML_TYPE_F32) { |
| 193 | if (tensor.bytes.size() != static_cast<size_t>(tensor.shape.num_elements()) * sizeof(float)) { |
| 194 | throw std::runtime_error("invalid F32 tensor byte size: " + std::string(name)); |
| 195 | } |
| 196 | std::vector<float> values(static_cast<size_t>(tensor.shape.num_elements())); |
| 197 | std::memcpy(values.data(), tensor.bytes.data(), tensor.bytes.size()); |
| 198 | return values; |
| 199 | } |
| 200 | if (tensor.type == GGML_TYPE_F16) { |
| 201 | if (tensor.bytes.size() != static_cast<size_t>(tensor.shape.num_elements()) * sizeof(ggml_fp16_t)) { |
| 202 | throw std::runtime_error("invalid F16 tensor byte size: " + std::string(name)); |
| 203 | } |
no test coverage detected