Skip to content

Commit e6bf007

Browse files
danbevHanClinto
andauthored
llama : return nullptr from llama_grammar_init (#8093)
* llama : return nullptr from llama_grammar_init This commit updates llama_grammar_init to return nullptr instead of throwing an exception. The motivation for this is that this function is declared inside an extern "C" block and is intended/may be used from C code which will not be able to handle exceptions thrown, and results in undefined behavior. On Windows and using MSVC the following warning is currently generated: ```console C:\llama.cpp\llama.cpp(13998,1): warning C4297: 'llama_grammar_init': function assumed not to throw an exception but does C:\llama.cpp\llama.cpp(13998,1): message : __declspec(nothrow), throw(), noexcept(true), or noexcept was specified on the function ``` Signed-off-by: Daniel Bevenius <[email protected]> * squash! llama : return nullptr from llama_grammar_init Add checks for nullptr when calling llama_grammar_init. Signed-off-by: Daniel Bevenius <[email protected]> --------- Signed-off-by: Daniel Bevenius <[email protected]> Co-authored-by: Clint Herron <[email protected]>
1 parent 84631fe commit e6bf007

File tree

6 files changed

+28
-7
lines changed

6 files changed

+28
-7
lines changed

common/sampling.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ struct llama_sampling_context * llama_sampling_init(const struct llama_sampling_
2828

2929
std::vector<const llama_grammar_element *> grammar_rules(result->parsed_grammar.c_rules());
3030

31-
result->grammar = llama_grammar_init(
31+
struct llama_grammar * grammar = llama_grammar_init(
3232
grammar_rules.data(),
3333
grammar_rules.size(), result->parsed_grammar.symbol_ids.at("root"));
34+
if (grammar == nullptr) {
35+
throw std::runtime_error("Failed to initialize llama_grammar");
36+
}
37+
result->grammar = grammar;
3438
}
3539

3640
result->prev.resize(params.n_prev);
@@ -59,9 +63,13 @@ void llama_sampling_reset(llama_sampling_context * ctx) {
5963
if (!ctx->parsed_grammar.rules.empty()) {
6064
std::vector<const llama_grammar_element *> grammar_rules(ctx->parsed_grammar.c_rules());
6165

62-
ctx->grammar = llama_grammar_init(
66+
struct llama_grammar * grammar = llama_grammar_init(
6367
grammar_rules.data(),
6468
grammar_rules.size(), ctx->parsed_grammar.symbol_ids.at("root"));
69+
if (grammar == nullptr) {
70+
throw std::runtime_error("Failed to initialize llama_grammar");
71+
}
72+
ctx->grammar = grammar;
6573
}
6674

6775
std::fill(ctx->prev.begin(), ctx->prev.end(), 0);

examples/gbnf-validator/gbnf-validator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ int main(int argc, char** argv) {
101101
auto grammar = llama_grammar_init(
102102
grammar_rules.data(),
103103
grammar_rules.size(), parsed_grammar.symbol_ids.at("root"));
104-
104+
if (grammar == nullptr) {
105+
throw std::runtime_error("Failed to initialize llama_grammar");
106+
}
105107
// Read the input file
106108
std::string input_str;
107109
{

llama.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14500,7 +14500,8 @@ struct llama_grammar * llama_grammar_init(
1450014500
continue;
1450114501
}
1450214502
if (llama_grammar_detect_left_recursion(vec_rules, i, &rules_visited, &rules_in_progress, &rules_may_be_empty)) {
14503-
throw std::runtime_error(format("unsupported grammar, left recursion detected for nonterminal at index %zu", i));
14503+
LLAMA_LOG_ERROR("unsupported grammar, left recursion detected for nonterminal at index %zu", i);
14504+
return nullptr;
1450414505
}
1450514506
}
1450614507

llama.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,12 @@ extern "C" {
924924
// Grammar
925925
//
926926

927+
/// Initialize a llama_grammar.
928+
///
929+
/// @param rules The rule elements of the grammar to initialize.
930+
/// @param n_rules The number of rules.
931+
/// @param start_rule_index The index of the root rule (the starting point of the grammar).
932+
/// @return The initialized llama_grammar or nullptr if initialization failed.
927933
LLAMA_API struct llama_grammar * llama_grammar_init(
928934
const llama_grammar_element ** rules,
929935
size_t n_rules,

tests/test-grammar-integration.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ static llama_grammar* build_grammar(const std::string & grammar_str) {
3636
static bool test_build_grammar_fails(const std::string & grammar_str) {
3737
fprintf(stderr, "⚫ Testing failure for grammar: %s\n", grammar_str.c_str());
3838
bool grammar_fails = false;
39-
try {
40-
build_grammar(grammar_str);
39+
llama_grammar * grammar = build_grammar(grammar_str);
40+
if (grammar != nullptr) {
4141
fprintf(stderr, " ❌ Expected build failure, but succeeded\n");
42-
} catch (const std::exception & err) {
42+
} else {
4343
grammar_fails = true;
4444
fprintf(stdout, " ✅︎\n");
4545
}

tests/test-llama-grammar.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ int main()
116116
std::vector<const llama_grammar_element *> grammar_rules(parsed_grammar.c_rules());
117117
grammar = llama_grammar_init(
118118
grammar_rules.data(), grammar_rules.size(), parsed_grammar.symbol_ids.at("root"));
119+
if (grammar == nullptr)
120+
{
121+
throw std::runtime_error("Failed to initialize llama_grammar");
122+
}
119123

120124
std::vector<std::vector<llama_grammar_element>> expected_stacks = {
121125
{

0 commit comments

Comments
 (0)