break;
}
+ // check that the size of the tensor in bytes is representable
+ if (ok && uint64_t(ggml_nelements(&info.t)/ggml_blck_size(info.t.type)) > SIZE_MAX/ggml_type_size(info.t.type)) {
+ GGML_LOG_ERROR("%s: tensor '%s' with shape (%" PRIi64 ", %" PRIi64 ", %" PRIi64 ", %" PRIi64 ") has a size in bytes > %zu\n",
+ __func__, info.t.name, info.t.ne[0], info.t.ne[1], info.t.ne[2], info.t.ne[3], SIZE_MAX);
+ ok = false;
+ break;
+ }
+
// calculate byte offsets given the tensor shape and type
info.t.nb[0] = type_size;
info.t.nb[1] = info.t.nb[0]*(info.t.ne[0]/blck_size);
#include "ggml.h"
#include "ggml-backend.h"
#include "../ggml/src/ggml-impl.h"
+#include "gguf.h"
#include <algorithm>
#include <array>
+#include <cmath>
#include <cstdint>
#include <cstdio>
#include <random>
HANDCRAFTED_TENSORS_BAD_N_DIMS = 20 + offset_has_tensors,
HANDCRAFTED_TENSORS_BAD_SHAPE = 30 + offset_has_tensors,
HANDCRAFTED_TENSORS_NE_TOO_BIG = 40 + offset_has_tensors,
+ HANDCRAFTED_TENSORS_NBYTES_TOO_BIG = 45 + offset_has_tensors,
HANDCRAFTED_TENSORS_BAD_TYPE = 50 + offset_has_tensors,
HANDCRAFTED_TENSORS_BAD_OFFSET = 60 + offset_has_tensors,
HANDCRAFTED_TENSORS_DUPLICATE_NAME = 70 + offset_has_tensors,
case HANDCRAFTED_TENSORS_BAD_N_DIMS: return "TENSORS_BAD_N_DIMS";
case HANDCRAFTED_TENSORS_BAD_SHAPE: return "TENSORS_BAD_SHAPE";
case HANDCRAFTED_TENSORS_NE_TOO_BIG: return "TENSORS_NE_TOO_BIG";
+ case HANDCRAFTED_TENSORS_NBYTES_TOO_BIG: return "TENSORS_NBYTES_TOO_BIG";
case HANDCRAFTED_TENSORS_BAD_TYPE: return "TENSORS_BAD_TYPE";
case HANDCRAFTED_TENSORS_BAD_OFFSET: return "TENSORS_BAD_OFFSET";
case HANDCRAFTED_TENSORS_DUPLICATE_NAME: return "TENSORS_DUPLICATE_NAME";
uint64_t offset = 0;
for (int i = 0; i < int(tensor_configs.size()); ++i) {
- const ggml_type type = tensor_configs[i].first;
+ const ggml_type type = hft == HANDCRAFTED_TENSORS_NBYTES_TOO_BIG ? GGML_TYPE_I64 : tensor_configs[i].first;
const std::array<int64_t, GGML_MAX_DIMS> shape = tensor_configs[i].second;
std::string name = "my_tensor";
}
helper_write(file, name.data(), name.length());
- uint32_t n_dims = hft == HANDCRAFTED_TENSORS_NE_TOO_BIG ? 2 : 1;
+ uint32_t n_dims = (hft == HANDCRAFTED_TENSORS_NE_TOO_BIG || hft == HANDCRAFTED_TENSORS_NBYTES_TOO_BIG) ? 2 : 1;
for (int i = GGML_MAX_DIMS-1; i >= 1; --i) {
if (shape[i] != 1) {
n_dims = i + 1;
}
if (hft == HANDCRAFTED_TENSORS_BAD_SHAPE) {
+ const int64_t bad_dim = -1;
for (uint32_t j = 0; j < n_dims; ++j) {
- const int64_t bad_dim = -1;
helper_write(file, bad_dim);
}
} else if (hft == HANDCRAFTED_TENSORS_NE_TOO_BIG){
+ const int64_t big_dim = 4*int64_t(INT32_MAX);
+ for (uint32_t j = 0; j < n_dims; ++j) {
+ helper_write(file, big_dim);
+ }
+ } else if (hft == HANDCRAFTED_TENSORS_NBYTES_TOO_BIG){
+ const size_t big_ne = SIZE_MAX/ggml_type_size(type);
+ const int64_t big_dim = GGML_PAD(int64_t(1.01f*std::pow(big_ne, 1.0f/n_dims)) + 1, ggml_blck_size(type));
for (uint32_t j = 0; j < n_dims; ++j) {
- const int64_t big_dim = 4*int64_t(INT32_MAX);
helper_write(file, big_dim);
}
} else {
HANDCRAFTED_TENSORS_BAD_N_DIMS,
HANDCRAFTED_TENSORS_BAD_SHAPE,
HANDCRAFTED_TENSORS_NE_TOO_BIG,
+ HANDCRAFTED_TENSORS_NBYTES_TOO_BIG,
HANDCRAFTED_TENSORS_BAD_TYPE,
HANDCRAFTED_TENSORS_BAD_OFFSET,
HANDCRAFTED_TENSORS_DUPLICATE_NAME,