Skip to content

Commit 719ea6a

Browse files
added ai scripts
1 parent 9fad15e commit 719ea6a

File tree

5 files changed

+260
-77
lines changed

5 files changed

+260
-77
lines changed

genaisrc/codeupdate.genai.mts

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
2+
script({
3+
title: "Invoke LLM code update",
4+
})
5+
6+
7+
async function runCodePrompt(role, message, code) {
8+
const answer = await runPrompt(
9+
(_) => {
10+
_.def("ROLE", role);
11+
_.def("REQUEST", message);
12+
_.def("CODE", code);
13+
_.$`Your role is <ROLE>.
14+
The request is given by <REQUEST>
15+
original code:
16+
<CODE>.`
17+
}
18+
)
19+
console.log(answer.text);
20+
return answer.text;
21+
}
22+
23+
async function invokeLLMUpdate(code, inputFile) {
24+
25+
let role = `You are a highly experienced compiler engineer with over 20 years of expertise,
26+
specializing in C and C++ programming. Your deep knowledge of best coding practices
27+
and software engineering principles enables you to produce robust, efficient, and
28+
maintainable code in any scenario.`;
29+
30+
let userMessage = `Please modify the original code to ensure that it enforces the following:
31+
- do not use pointer arithmetic for the updates.
32+
- do not introduce uses of std::vector.
33+
- only make replacements that are compatible with the ones listed below.
34+
- add white space between operators:
35+
For example:
36+
i=0
37+
by
38+
i = 0
39+
For example
40+
a+b
41+
by
42+
a + b
43+
- remove brackets around single statements:
44+
For example:
45+
{ break; }
46+
by
47+
break;
48+
- replaces uses of for loops using begin(), end() iterator patterns by C++21 style for loops
49+
For example replace
50+
for (auto it = x.begin(), end = x.end(); it != end; ++it)
51+
by
52+
for (auto & e : x)
53+
54+
For example, replace
55+
for (unsigned i = 0; i < a->get_num_args(); ++i) {
56+
expr* arg = a->get_arg(i);
57+
...
58+
}
59+
by
60+
for (auto arg : *a) {
61+
...
62+
}
63+
`;
64+
65+
return runCodePrompt(role, userMessage, code);
66+
}
67+
68+
69+
const inputFile = env.files[0];
70+
const file = await workspace.readText(inputFile);
71+
const answer = await invokeLLMUpdate(file.content, inputFile);
72+
// Extract the code from the answer by removing ```cpp and ```:
73+
let code = answer.replace(/```cpp/g, "").replace(/```/g, "");
74+
const outputFile = inputFile.filename + ".patch";
75+
await workspace.writeText(outputFile, code);
76+

genaisrc/mergeopt.genai.mts

+3-52
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,7 @@ script({
22
title: "Merge optimizations function changes for a C++ file"
33
})
44

5-
// given a source file <src>
6-
// list files in code_slice directory based on that name with extension opt
7-
// replace functions in src by the corresponding ones in the opt files.
8-
// Save into <dst>
9-
10-
11-
import * as fs from 'fs';
12-
13-
14-
function get_functions(captures : QueryCapture[], code : string) {
15-
return captures.map(({ name, node }) => ({
16-
code : node.text,
17-
start : node.startIndex,
18-
end : node.endIndex,
19-
name : node.text.split('(')[0].trim()
20-
}))
21-
}
22-
23-
5+
import { mergeFunctions } from "./myai.genai.mts";
246
const inputFile = env.files[0];
25-
26-
const { captures: functions } = await parsers.code(
27-
inputFile,
28-
`(function_definition) @function`
29-
);
30-
31-
32-
let funs = get_functions(functions, inputFile.content);
33-
34-
const modifiedFunctions = "slice_" + path.basename(inputFile.filename) + "*.opt";
35-
36-
let inputCode = inputFile.content;
37-
console.log(modifiedFunctions);
38-
const directory_path = path.join("code_slices", modifiedFunctions);
39-
const files = await workspace.findFiles(directory_path);
40-
for (const file of files) {
41-
console.log(file.filename);
42-
const code = file.content.match(/```cpp([\s\S]*?)```/);
43-
if (!code) {
44-
continue;
45-
}
46-
const modifiedFunction = code[1];
47-
const name = modifiedFunction.split('(')[0].trim();
48-
console.log(name);
49-
const fun = funs.find(f => f.name === name);
50-
if (fun) {
51-
console.log("Updated function: " + name);
52-
inputCode = inputCode.replace(fun.code, modifiedFunction);
53-
}
54-
}
55-
56-
console.log(inputCode);
57-
await workspace.writeText(inputFile.filename + ".opt.cpp", inputCode);
7+
let new_code = await mergeFunctions(inputFile);
8+
await workspace.writeText(inputFile.filename + ".opt.cpp", new_code);

genaisrc/myai.genai.mts

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
function function_name_from_code(code: string) {
2+
let name = code.split('(')[0].trim();
3+
name = name
4+
.replace(/::/g, '_')
5+
.replace(/ /g, '_')
6+
.replace(/\*/g, '');
7+
return name;
8+
}
9+
10+
function tree_sitter_get_functions(captures: QueryCapture[], code: string) {
11+
return captures.map(({ name, node }) => ({
12+
code: node.text,
13+
start: node.startIndex,
14+
end: node.endIndex,
15+
name: function_name_from_code(node.text)
16+
}));
17+
}
18+
19+
function output_name_from_file(inputFile: WorkspaceFile, name: string) {
20+
let outputFile = "slice_" + path.basename(inputFile.filename) + name + ".cpp";
21+
return path.join("code_slices", outputFile);
22+
}
23+
24+
export async function splitFunctions(inputFile: WorkspaceFile) {
25+
const { captures: functions } = await parsers.code(
26+
inputFile,
27+
`(function_definition) @function`
28+
);
29+
return tree_sitter_get_functions(functions, inputFile.content);
30+
}
31+
32+
33+
export async function saveFunctions(inputFile: WorkspaceFile, funs: { code: string, name: string }[]) {
34+
for (const fun of funs) {
35+
let name = function_name_from_code(fun.code);
36+
console.log(name);
37+
let outputFile = output_name_from_file(inputFile, name);
38+
await workspace.writeText(outputFile, `//Extracted ${name} in ${inputFile.filename}\n${fun.code}\n\n`);
39+
}
40+
}
41+
42+
// given a source file <src>
43+
// list files in code_slice directory based on that name with extension opt
44+
// replace functions in src by the corresponding ones in the opt files.
45+
// Save into <dst>
46+
47+
async function parseOptFunctions(inputFile: WorkspaceFile) {
48+
const modifiedFunctions = "slice_" + path.basename(inputFile.filename) + "*.opt";
49+
console.log(modifiedFunctions);
50+
const directory_path = path.join("code_slices", modifiedFunctions);
51+
const files = await workspace.findFiles(directory_path);
52+
let modifiedFunctionsList = [];
53+
for (const file of files) {
54+
console.log(file.filename);
55+
const code = file.content.match(/```cpp([\s\S]*?)```/);
56+
if (!code) {
57+
continue;
58+
}
59+
const modifiedFunction = code[1];
60+
modifiedFunctionsList.push(modifiedFunction);
61+
}
62+
return modifiedFunctionsList;
63+
}
64+
65+
import * as fs from 'fs';
66+
67+
export async function mergeModifiedFunction(code :string, funs : { code: string, name: string }[], new_code : string) {
68+
let name = function_name_from_code(new_code);
69+
let fun = funs.find(f => f.name === name);
70+
if (fun) {
71+
console.log("Updated function: " + name);
72+
code = code.replace(fun.code, new_code);
73+
}
74+
return code;
75+
}
76+
77+
async function canCompileCode(inputFile : WorkspaceFile, code : string) {
78+
79+
// move input file to a temp file
80+
// move code to the inputFile.filename
81+
// invoke ninja in the build directory: ninja -b build
82+
// move the temp file back to the original file
83+
// return true iff it succeeded
84+
85+
let tempFile = inputFile.filename + ".tmp";
86+
let original_content = inputFile.content;
87+
await workspace.writeText(tempFile, inputFile.content);
88+
await workspace.writeText(inputFile.filename, code);
89+
let result = await host.exec(`cmd /k "C:\Program\ Files/Microsoft\ Visual\ Studio/2022/Enterprise/Common7/Tools/VsDevCmd.bat" -arch=x64 & ninja`, { cwd: "build" });
90+
91+
// await fs.delete(tempFile);
92+
if (result.exitCode !== 0) {
93+
await workspace.writeText(inputFile.filename, original_content);
94+
console.log(result.stderr);
95+
return false;
96+
}
97+
return true;
98+
}
99+
100+
export async function mergeCompileFunction(inputFile : WorkspaceFile, code : string, funs : { code: string, name: string }[], new_code_input : string) {
101+
let match_new_code = new_code_input.match(/```cpp([\s\S]*?)```/);
102+
if (!match_new_code) {
103+
console.log("Invalid new code");
104+
return code;
105+
}
106+
let new_code = match_new_code[1];
107+
108+
let name = function_name_from_code(new_code);
109+
let fun = funs.find(f => f.name == name);
110+
111+
if (!fun) {
112+
console.log(`Function name '${name}' not found`);
113+
for (const fun of funs)
114+
console.log("'" + fun.name + "'");
115+
return code;
116+
}
117+
console.log("Updated function: " + name);
118+
let modified_code = code.replace(fun.code, new_code);
119+
if (code == modified_code) {
120+
console.log("No change in function: " + name);
121+
return code;
122+
}
123+
let canCompile = await canCompileCode(inputFile, modified_code);
124+
console.log("Can compile: " + canCompile);
125+
if (canCompile)
126+
return modified_code;
127+
return code;
128+
}
129+
130+
export async function mergeFunctionsFromList(inputCode: string, funs: { code: string, name: string }[], modifiedFunctionList: string[]) {
131+
let code = inputCode;
132+
for (const new_code of modifiedFunctionList)
133+
code = await mergeModifiedFunction(code, funs, new_code);
134+
return code;
135+
}
136+
137+
export async function mergeFunctions(inputFile: WorkspaceFile) {
138+
let funs = await splitFunctions(inputFile);
139+
let modifiedFunctionList = await parseOptFunctions(inputFile);
140+
return mergeFunctionsFromList(inputFile.content, funs, modifiedFunctionList);
141+
}
142+
143+
export async function invokeLLMOpt(code : string) {
144+
const answer = await runPrompt(
145+
(_) => {
146+
_.def("CODE", code);
147+
_.$`You are a highly experienced compiler engineer with over 20 years of expertise,
148+
specializing in C and C++ programming. Your deep knowledge of best coding practices
149+
and software engineering principles enables you to produce robust, efficient, and
150+
maintainable code in any scenario.
151+
152+
Please modify the original code in <CODE> to ensure that it uses best practices for optimal code execution.' `
153+
}, {
154+
system: [],
155+
systemSafety: false
156+
}
157+
);
158+
return answer.text;
159+
}

genaisrc/myopt.genai.mts

+4-25
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,9 @@ script({
33
files: "code_slices/muz/spacer/orig_spacer_antiunify.cpp_anti_unifier.cpp"
44
})
55

6+
import { invokeLLMOpt } from "./myai.genai.mts";
67

7-
async function invokeLLMUpdate(code) {
8-
const answer = await runPrompt(
9-
(_) => {
10-
_.def("CODE", code);
11-
_.$`
12-
You are a highly experienced compiler engineer with over 20 years of expertise,
13-
specializing in C and C++ programming. Your deep knowledge of best coding practices
14-
and software engineering principles enables you to produce robust, efficient, and
15-
maintainable code in any scenario.
16-
17-
Please modify the original code in <CODE> to ensure that it uses best practices for optimal code execution.' `
18-
}, {
19-
system: [],
20-
systemSafety: false
21-
}
22-
)
23-
console.log(answer.text);
24-
return answer.text;
25-
}
26-
27-
28-
const inputFile = env.files[0];
29-
const file = await workspace.readText(inputFile);
30-
const answer = await invokeLLMUpdate(file.content);
31-
const outputFile = inputFile.filename + ".opt";
8+
let file = env.files[0];
9+
let answer = await invokeLLMOpt(file);
10+
const outputFile = file.filename + ".opt";
3211
await workspace.writeText(outputFile, answer);

genaisrc/myopttool.genai.mts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
script({
3+
title: "optimize functions in a file",
4+
files: "src/muz/spacer/spacer_qe_project.cpp"
5+
})
6+
7+
import { splitFunctions, invokeLLMOpt, mergeFunctionsFromList, mergeCompileFunction} from "./myai.genai.mts";
8+
9+
const inputFile = env.files[0];
10+
let funs = await splitFunctions(inputFile);
11+
let new_code = inputFile.content;
12+
for (const fun of funs) {
13+
let answer = await invokeLLMOpt(fun.code);
14+
if (answer)
15+
new_code = await mergeCompileFunction(inputFile, new_code, funs, answer);
16+
}
17+
18+
await workspace.writeText(inputFile.filename + "opt.cpp", new_code);

0 commit comments

Comments
 (0)