Skip to content

Review #1191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Review #1191

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ CMakeSettings.json
.vs/
.vscode/
.clangd

.llama_env/
.venv/
ggml_env/
.exrc
Expand Down
26 changes: 17 additions & 9 deletions src/ggml-opt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
#include <vector>

struct ggml_opt_dataset {
struct ggml_context * ctx = nullptr;
ggml_backend_buffer_t buf = nullptr;
struct ggml_tensor * data = nullptr;
struct ggml_tensor * labels = nullptr;
struct ggml_context * ctx = nullptr; //A memory context used to manage the tensors (data and labels) associated with the dataset.
ggml_backend_buffer_t buf = nullptr; // A backend buffer used to store the dataset's tensors in a specific memory backend (e.g., CPU or GPU)
struct ggml_tensor * data = nullptr; // A tensor that holds the input data for the dataset
struct ggml_tensor * labels = nullptr; // A tensor that holds the labels for the dataset

int64_t ndata = -1;
int64_t ndata_shard = -1;
Expand Down Expand Up @@ -72,7 +72,15 @@ struct ggml_opt_result {
};

// ====== Dataset ======

/**
* @brief a function to initialize a dataset
*
* @param ne_datapoint // The number of features (or dimensions) in each data point.
* @param ne_label //The number of labels associated with each data point.
* @param ndata // The total number of data points in the dataset
* @param ndata_shard The number of data points in each shard. Shards are used to divide the dataset into smaller chunks for distributed or batched processing.
* @return ggml_opt_dataset_t
*/
ggml_opt_dataset_t ggml_opt_dataset_init(int64_t ne_datapoint, int64_t ne_label, int64_t ndata, int64_t ndata_shard) {
GGML_ASSERT(ne_datapoint > 0);
GGML_ASSERT(ne_label >= 0);
Expand All @@ -85,14 +93,14 @@ ggml_opt_dataset_t ggml_opt_dataset_init(int64_t ne_datapoint, int64_t ne_label,

{
struct ggml_init_params params = {
/*.mem_size =*/ 2*ggml_tensor_overhead(),
/*.mem_size =*/ 2*ggml_tensor_overhead(), //data tensor and labels tensor itself, not include the tensors' data
/*.mem_buffer =*/ nullptr,
/*.no_alloc =*/ true,
};
result->ctx = ggml_init(params);
result->ctx = ggml_init(params);//the brace hope params will be destructed immediately
}

result->data = ggml_new_tensor_2d(result->ctx, GGML_TYPE_F32, ne_datapoint, ndata);
// after init, the memory of ctx is allocated, the tensors memory is also allocated, but the tensors' data is not allocated yet
result->data = ggml_new_tensor_2d(result->ctx, GGML_TYPE_F32, ne_datapoint, ndata);//get data tensor memory from context, set tensor attributes
result->nbs_data = ggml_nbytes(result->data) * ndata_shard/ndata;

if (ne_label > 0) {
Expand Down
37 changes: 19 additions & 18 deletions src/ggml.c
Original file line number Diff line number Diff line change
Expand Up @@ -880,15 +880,15 @@ static const size_t GGML_OBJECT_SIZE = sizeof(struct ggml_object);
//

struct ggml_context {
size_t mem_size;
void * mem_buffer;
bool mem_buffer_owned;
bool no_alloc;
size_t mem_size;// Total size of the memory buffer allocated for this context.
void * mem_buffer;// Total size of the memory buffer allocated for this context.
bool mem_buffer_owned;// Indicates if the memory buffer is owned by this context or not.
bool no_alloc;// Indicates if the context should allocate memory or not.

int n_objects;
int n_objects;//Number of objects (e.g., tensors) currently allocated in this context.

struct ggml_object * objects_begin;
struct ggml_object * objects_end;
struct ggml_object * objects_begin;//pointer to the beginning of the list of objects
struct ggml_object * objects_end;//pointer to the end of the list of objects
};

struct ggml_context_container {
Expand Down Expand Up @@ -1297,7 +1297,8 @@ enum ggml_type ggml_ftype_to_ggml_type(enum ggml_ftype ftype) {
}

size_t ggml_tensor_overhead(void) {
return GGML_OBJECT_SIZE + GGML_TENSOR_SIZE;
//tensor overhead is the size of tensor struct + size of object struct, ggml_obj is used to describe the tensor/graph/buffer
return GGML_OBJECT_SIZE + GGML_TENSOR_SIZE;
}

bool ggml_is_transposed(const struct ggml_tensor * tensor) {
Expand Down Expand Up @@ -1418,7 +1419,7 @@ struct ggml_context * ggml_init(struct ggml_init_params params) {
if (is_first_call) {
// initialize time system (required on Windows)
ggml_time_init();

//if is first called, calculate the mapping from fp16 to f32 and store it in the table
for (int i = 0; i < (1 << 16); ++i) {
union {
uint16_t u16;
Expand All @@ -1432,15 +1433,15 @@ struct ggml_context * ggml_init(struct ggml_init_params params) {

ggml_critical_section_end();

struct ggml_context * ctx = GGML_MALLOC(sizeof(struct ggml_context));
struct ggml_context * ctx = GGML_MALLOC(sizeof(struct ggml_context));//malloc for the context struct itself

// allow to call ggml_init with 0 size
if (params.mem_size == 0) {
params.mem_size = GGML_MEM_ALIGN;
}

const size_t mem_size = params.mem_buffer ? params.mem_size : GGML_PAD(params.mem_size, GGML_MEM_ALIGN);

//allow initialize a context with a extern buffer, if no buffer is provided, malloc a buffer
*ctx = (struct ggml_context) {
/*.mem_size =*/ mem_size,
/*.mem_buffer =*/ params.mem_buffer ? params.mem_buffer : ggml_aligned_malloc(mem_size),
Expand Down Expand Up @@ -1519,7 +1520,7 @@ static struct ggml_object * ggml_new_object(struct ggml_context * ctx, enum ggml
// always insert objects at the end of the context's memory pool
struct ggml_object * obj_cur = ctx->objects_end;

const size_t cur_offs = obj_cur == NULL ? 0 : obj_cur->offs;
const size_t cur_offs = obj_cur == NULL ? 0 : obj_cur->offs; // offs is the start, [cur_offs, cur_offs + cur_size) is the lastest object
const size_t cur_size = obj_cur == NULL ? 0 : obj_cur->size;
const size_t cur_end = cur_offs + cur_size;

Expand All @@ -1528,7 +1529,7 @@ static struct ggml_object * ggml_new_object(struct ggml_context * ctx, enum ggml

char * const mem_buffer = ctx->mem_buffer;
struct ggml_object * const obj_new = (struct ggml_object *)(mem_buffer + cur_end);

//[cur_end, cur_end + GGML_OBJECT_SIZE) is the ggml_object( just a descriptor of the object )
if (cur_end + size_needed + GGML_OBJECT_SIZE > ctx->mem_size) {
GGML_LOG_WARN("%s: not enough space in the context's memory pool (needed %zu, available %zu)\n",
__func__, cur_end + size_needed + GGML_OBJECT_SIZE, ctx->mem_size);
Expand All @@ -1537,14 +1538,14 @@ static struct ggml_object * ggml_new_object(struct ggml_context * ctx, enum ggml
#endif
return NULL;
}

// just assign value for the new object, the memory is prepared yet
*obj_new = (struct ggml_object) {
.offs = cur_end + GGML_OBJECT_SIZE,
.size = size_needed,
.next = NULL,
.type = type,
};

//[cur_end + GGML_OBJECT_SIZE, cur_end + GGML_OBJECT_SIZE + size_needed) is the actual memory of the object
GGML_ASSERT_ALIGNED(mem_buffer + obj_new->offs);

if (obj_cur != NULL) {
Expand Down Expand Up @@ -1578,14 +1579,14 @@ static struct ggml_tensor * ggml_new_tensor_impl(
view_src = view_src->view_src;
}

size_t data_size = ggml_row_size(type, ne[0]);
for (int i = 1; i < n_dims; i++) {
size_t data_size = ggml_row_size(type, ne[0]);//ne[0] is the number of elements in the first dimension
for (int i = 1; i < n_dims; i++) { // first dimension multiple by each other dimension
data_size *= ne[i];
}

GGML_ASSERT(view_src == NULL || data_size == 0 || data_size + view_offs <= ggml_nbytes(view_src));

void * data = view_src != NULL ? view_src->data : NULL;
void * data = view_src != NULL ? view_src->data : NULL; // handle virw_src, which is used to view another tensor
if (data != NULL) {
data = (char *) data + view_offs;
}
Expand Down