Replies: 4 comments 2 replies
-
I think it is unlikely to change the existing functions, unless it turns out to be a common limitation for other FFI systems. Adding "overloads" might be more realistic. What about functions that return structs - do you need/have a workaround? LLAMA_API struct llama_model_params llama_model_default_params(void);
LLAMA_API struct llama_context_params llama_context_default_params(void);
LLAMA_API struct llama_model_quantize_params llama_model_quantize_default_params(void); |
Beta Was this translation helpful? Give feedback.
-
That is okay, I would not expect to make breaking changes in the library interface just because of a single user being inconvenienced. For functions returning structs, I currently have the following wrappers: size_t model_params_size()
{
return sizeof(struct llama_model_params);
}
void model_params_default(struct llama_model_params * params)
{
*params = llama_model_default_params();
} Something like this would work too: struct llama_model_params * model_params_init()
{
struct llama_model_params * params = malloc(sizeof(struct llama_model_params));
*params = llama_model_default_params();
return params;
}
void model_params_free(struct llama_model_params * params)
{
free(params);
} The second approach is a bit more convenient from the perspective of the FFI user, since all the memory allocation and associated size measurements happen on the C side. I have similar wrappers for If this is something that would in principle be acceptable to have in the library, I could draft up a PR, that would make it easier to talk about the interface design, unless you already have some opinions or ideas on how to do this. I am mostly worried about making the library interface redundant/ambiguous/confusing just for my singular use case and I am not sure how to get to a long-term clean interface that is non-redundant and works for everyone. |
Beta Was this translation helpful? Give feedback.
-
I have had some time to think about this and I realized that there is another problem. It is not enough to be able to create/free the structs, they also need to be filled. One option would be to add Java-style setter functions like this: void context_params_set_n_ctx(struct llama_context_params * params, uint32_t value) { params->n_ctx = value; } This feels a little out of place in a C library, and I am not sure if it is a good idea unless a significant number of other people would also find something like this useful. In principle, I could also calculate the offset of |
Beta Was this translation helpful? Give feedback.
-
C alignment is fairly well-defined. To be FFI friendly, the struct/signature definition file could be automatically generated. |
Beta Was this translation helpful? Give feedback.
-
I am using llama.cpp as a dynamic library from Haskell via FFI. Haskell's FFI system only supports basic types like char, int, float, bool, and pointers to be passed to and from foreign functions. In order to work around this, I currently have a C wrapper that wraps those functions from the
llama.h
interface that use plain structs (likellama_load_model_from_file
orllama_batch_init
) to use pointers to structs instead.There seem to be only a handful of those cases so it feels feasible to adjust the
llama.h
interface to restrict itself to functions passing only basic types, which would make my life a little easier. However, it would either be a breaking change or introduce redundant functions. This might not be worth it unless other people would also benefit from this change.So my questions are:
llama.h
interface? How big of a benefit does a change need to have to justify a breaking change or a potentially redundant addition?Beta Was this translation helpful? Give feedback.
All reactions