Skip to content
Merged
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
267 changes: 71 additions & 196 deletions IDEAS.mk

Large diffs are not rendered by default.

63 changes: 63 additions & 0 deletions LEARNING.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#
# Copyright (C) 2026 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#

MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
MAKEFILE_DIR := $(realpath $(dir $(MAKEFILE_PATH)))
EXAMPLES_DIR := examples/Test-Corpus/Public-Tests

PROVIDER ?= hosted_vllm## Provider to use with DSPy/LiteLLM
MODEL ?= Qwen/Qwen3-Coder-30B-A3B-Instruct## Model to use to translate
REVISION ?= None## Revision of model to load in vLLM
HOST ?= localhost
PORT ?= 8000## Port to use for vLLM
BASE_URL ?= http://${HOST}:${PORT}/v1## Base URL of vLLM server

DATA_DIR ?= translation.$(shell git rev-parse HEAD)## Directory to collect data from
TEACHER_PROVIDER ?= openrouter## GEPA teacher model provider
TEACHER_MODEL ?= openai/gpt-5-mini## GEPA teacher model name
TEACHER_BASE_URL ?= https://openrouter.ai/api/v1## GEPA teacher model base URL
REFLECT_PROVIDER ?= openrouter## GEPA reflection model provider
REFLECT_MODEL ?= openai/gpt-5.1## GEPA reflection model name
REFLECT_BASE_URL ?= https://openrouter.ai/api/v1## GEPA reflection model base URL


EXAMPLES ?= $(sort $(patsubst %/test_case,%,$(shell find ${EXAMPLES_DIR} -maxdepth 3 -name test_case -type d)))## List of examples to run on
ifeq ($(EXAMPLES),)
$(warning No projects found in ${EXAMPLES_DIR}. You may need to re-run commands!)
endif

.PRECIOUS: student_examples.lst
student_examples.lst:
-@$(MAKE) -j128 -f ${MAKEFILE_DIR}/Makefile examples/wrapper \
TRANSLATION_DIR=${DATA_DIR}.student \
PROVIDER=${PROVIDER} \
MODEL=${MODEL} \
BASE_URL=${BASE_URL}
@echo "$(EXAMPLES)" | tr ' ' '\n' | sort | xargs realpath | sed "s|$$|/${DATA_DIR}.student|" > $@

.PRECIOUS: teacher_examples.lst
teacher_examples.lst:
-@$(MAKE) -j128 -f ${MAKEFILE_DIR}/Makefile examples/wrapper \
TRANSLATION_DIR=${DATA_DIR}.teacher \
PROVIDER=${TEACHER_PROVIDER} \
MODEL=${TEACHER_MODEL} \
BASE_URL=${TEACHER_BASE_URL}
@echo "$(EXAMPLES)" | tr ' ' '\n' | sort | xargs realpath | sed "s|$$|/${DATA_DIR}.teacher|" > $@

.PHONY: learn/translate
learn/translate:## Learn a prompt for translating C to Rust
learn/translate: student_examples.lst teacher_examples.lst
uv run python -m ideas.learn.translate \
student_examples=$(realpath student_examples.lst) \
teacher_examples=$(realpath teacher_examples.lst) \
model.name=${PROVIDER}/${MODEL} \
model.base_url=${BASE_URL} \
reflect_model.name=${REFLECT_PROVIDER}/${REFLECT_MODEL} \
reflect_model.base_url=${REFLECT_BASE_URL}


clean:
rm -f student_examples.lst teacher_examples.lst
87 changes: 37 additions & 50 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ REVISION ?= None## Revision of model to load in vLLM
HOST ?= localhost
PORT ?= 8000## Port to use for vLLM
BASE_URL ?= http://${HOST}:${PORT}/v1## Base URL of vLLM server
VLLM_VERSION ?= 0.13.0
VLLM_ARGS ?= --tensor-parallel-size 8 --enable-expert-parallel --max-num-seqs 32 --max-model-len 128k## Args to pass to vllm serve
TRANSLATION_DIR ?= translation.$(shell git rev-parse HEAD)## Directory to put IDEAS translation
TRANSLATE_ARGS ?= ## Args to pass to IDEAS translation
Expand All @@ -28,7 +29,7 @@ AFL_TAG = aflplusplus/aflplusplus:stable
# Pass these variables to IDEAS.mk
export MODEL BASE_URL TRANSLATION_DIR TESTGEN_DIR RUSTFLAGS

EXAMPLES ?= $(sort $(shell find ${EXAMPLES_DIR} -maxdepth 3 -name test_case -type d))## List of examples to run on
EXAMPLES ?= $(sort $(patsubst %/test_case,%,$(shell find ${EXAMPLES_DIR} -maxdepth 3 -name test_case -type d)))## List of examples to run on
ifeq ($(EXAMPLES),)
$(warning No projects found in ${EXAMPLES_DIR}. You may need to re-run commands!)
endif
Expand All @@ -40,8 +41,8 @@ all: help ;
install: install-uv install-rust install-deno ## Install uv, Rust, and Deno

.PHONY: install-uv
install-uv:## Install uv@0.7.12
curl -LsSf https://astral.sh/uv/0.7.12/install.sh | sh
install-uv:## Install uv@0.9.22
curl -LsSf https://astral.sh/uv/0.9.22/install.sh | sh

.PHONY: install-rust
install-rust:## Install Rust@1.88.0
Expand All @@ -51,23 +52,30 @@ install-rust:## Install Rust@1.88.0
install-deno:## Install Deno, which is required by dspy.PythonInterpreter()
curl -fsSL https://deno.land/install.sh | sh

.PHONY: install-clang
install-clang:## Install Clang-21, must be sudo
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
-./llvm.sh 21 all
rm ./llvm.sh

.PHONY: test
test:## Run pytest
uv run pytest

.PHONY: serve
serve:## Start vLLM server
uv run vllm serve ${MODEL} --revision ${REVISION} --host ${HOST} --port ${PORT} --dtype auto ${VLLM_ARGS}
uv run --no-project --python 3.11 --with vllm==${VLLM_VERSION} vllm serve ${MODEL} --revision ${REVISION} --host ${HOST} --port ${PORT} --dtype auto ${VLLM_ARGS}

kill:## Kill all vLLM serves
pkill -f "^uv run vllm serve" -u ${USER}
pkill -f "^uv run --no-project --python 3.11 --with vllm==${VLLM_VERSION} vllm serve" -u ${USER}

.PHONY: FORCE
FORCE:

.PHONY: examples/init
examples/init:## Initialize all examples
examples/init: $(subst /test_case,/init,${EXAMPLES}) ;
examples/init: $(addsuffix /init,${EXAMPLES}) ;
@echo "# ${TRANSLATION_DIR}"
examples/%/init:## Initialize specific example
examples/%/init: FORCE
Expand All @@ -77,11 +85,11 @@ examples/%/init: FORCE

.PHONY: examples/cmake
examples/cmake:## CMake generate and build all examples
examples/cmake: $(subst /test_case,/cmake,${EXAMPLES}) ;
examples/cmake: $(addsuffix /cmake,${EXAMPLES}) ;
@echo "# cmake"
@echo "\`\`\`"
@find ${EXAMPLES_DIR} -path "*/build-ninja/build.log" -size 0 -exec echo SUCCEEDED \; | uniq -c
@find ${EXAMPLES_DIR} -path "*/build-ninja/build.log" -size +0 -exec echo FAILED \; | uniq -c
@find ${EXAMPLES} -path "*/build-ninja/build.log" -size 0 -exec echo SUCCEEDED \; | uniq -c
@find ${EXAMPLES} -path "*/build-ninja/build.log" -size +0 -exec echo FAILED \; | uniq -c
@echo "\`\`\`"
examples/%/cmake:## CMake generate and build specific example
examples/%/cmake: FORCE
Expand All @@ -90,11 +98,11 @@ examples/%/cmake: FORCE

.PHONY: examples/translate
examples/translate:## Translate all examples
examples/translate: $(subst /test_case,/translate,${EXAMPLES})
examples/translate: $(addsuffix /translate,${EXAMPLES})
@echo "# ${TRANSLATION_DIR}"
@echo "\`\`\`"
@echo "--- Translation Count ---"
@find ${EXAMPLES_DIR} -path "*/${TRANSLATION_DIR}/translate.log" | wc -l
@find ${EXAMPLES} -path "*/${TRANSLATION_DIR}/translate.log" | wc -l
@echo "\`\`\`"
examples/%/translate:## Translate specific example
examples/%/translate: FORCE
Expand All @@ -104,7 +112,7 @@ examples/%/translate: FORCE

.PHONY: examples/wrapper
examples/wrapper:## Generate C FFI wrappers for all examples
examples/wrapper: $(subst /test_case,/wrapper,${EXAMPLES})
examples/wrapper: $(addsuffix /wrapper,${EXAMPLES})
examples/%/wrapper:## Generate C FFI wrappers for specific example
examples/%/wrapper: FORCE
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) cmake
Expand All @@ -113,23 +121,23 @@ examples/%/wrapper: FORCE

.PHONY: examples/add_test_vectors
examples/add_test_vectors:## Build all translated examples
examples/add_test_vectors: $(subst /test_case,/add_test_vectors,${EXAMPLES})
examples/add_test_vectors: $(addsuffix /add_test_vectors,${EXAMPLES})
examples/%/add_test_vectors:## Build specific translated example
examples/%/add_test_vectors: FORCE
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) cmake
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) add_test_vectors

.PHONY: examples/build
examples/build:## Build all translated examples
examples/build: $(subst /test_case,/build,${EXAMPLES})
examples/build: $(addsuffix /build,${EXAMPLES})
@echo "# ${TRANSLATION_DIR}"
@echo "\`\`\`"
@echo "--- Project Builds ---"
@find ${EXAMPLES_DIR} -path "*/${TRANSLATION_DIR}/build.log" -size 0 -exec echo SUCCEEDED \; | uniq -c
@find ${EXAMPLES_DIR} -path "*/${TRANSLATION_DIR}/build.log" -size +0 -exec echo FAILED \; | uniq -c
@find ${EXAMPLES} -path "*/${TRANSLATION_DIR}/build.log" -size 0 -exec echo SUCCEEDED \; | uniq -c
@find ${EXAMPLES} -path "*/${TRANSLATION_DIR}/build.log" -size +0 -exec echo FAILED \; | uniq -c
ifneq (${VERBOSE},0)
@echo ""
@find ${EXAMPLES_DIR} -path "*/${TRANSLATION_DIR}/build.log" -size +0 | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e "s/^/ FAILED /gi"
@find ${EXAMPLES} -path "*/${TRANSLATION_DIR}/build.log" -size +0 | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e "s/^/ FAILED /gi"
@echo ""
endif
@echo "\`\`\`"
Expand All @@ -140,69 +148,48 @@ examples/%/build: FORCE

.PHONY: examples/test
examples/test:## Test all translated examples
examples/test: $(subst /test_case,/test,${EXAMPLES})
examples/test: $(addsuffix /test,${EXAMPLES})
@echo "# ${TRANSLATION_DIR}"
@echo "\`\`\`"
@echo "--- Project Builds ---"
@find ${EXAMPLES_DIR} -path "*/${TRANSLATION_DIR}/build.log" -size 0 -exec echo SUCCEEDED \; | uniq -c
@find ${EXAMPLES_DIR} -path "*/${TRANSLATION_DIR}/build.log" -size +0 -exec echo FAILED \; | uniq -c
@find ${EXAMPLES} -path "*/${TRANSLATION_DIR}/build.log" -size 0 -exec echo SUCCEEDED \; | uniq -c
@find ${EXAMPLES} -path "*/${TRANSLATION_DIR}/build.log" -size +0 -exec echo FAILED \; | uniq -c
@echo ""
ifneq (${VERBOSE},0)
@find ${EXAMPLES_DIR} -path "*/${TRANSLATION_DIR}/build.log" -size +0 | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e "s/^/ FAILED /gi"
@find ${EXAMPLES} -path "*/${TRANSLATION_DIR}/build.log" -size +0 | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e "s/^/ FAILED /gi"
@echo ""
endif
@echo "--- Project Completion Count ---"
@find ${EXAMPLES_DIR} -path '*/${TRANSLATION_DIR}/cargo_test.log' -exec ./scripts/test_log_stats.sh {} \; | cut -d" " -f1 | sort | uniq -c
@find ${EXAMPLES} -path '*/${TRANSLATION_DIR}/cargo_test.log' -exec ./scripts/test_log_stats.sh {} \; | cut -d" " -f1 | sort | uniq -c
@echo ""
ifneq (${VERBOSE},0)
@find ${EXAMPLES_DIR} -path '*/${TRANSLATION_DIR}/cargo_test.log' -exec ./scripts/test_log_stats.sh {} \; | egrep "PARTIAL" | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e 's/^/ /'
@find ${EXAMPLES} -path '*/${TRANSLATION_DIR}/cargo_test.log' -exec ./scripts/test_log_stats.sh {} \; | egrep "PARTIAL" | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e 's/^/ /'
@echo ""
@find ${EXAMPLES} -path '*/${TRANSLATION_DIR}/cargo_test.log' -exec ./scripts/test_log_stats.sh {} \; | egrep "MISSING" | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e 's/^/ /'
@echo ""
@find ${EXAMPLES_DIR} -path '*/${TRANSLATION_DIR}/cargo_test.log' -exec ./scripts/test_log_stats.sh {} \; | egrep "FAILED" | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e 's/^/ /'
@find ${EXAMPLES} -path '*/${TRANSLATION_DIR}/cargo_test.log' -exec ./scripts/test_log_stats.sh {} \; | egrep "FAILED" | sort | sed -e "s/${TRANSLATION_DIR}.*//gi" | sed -e 's/^/ /'
@echo ""
endif
@echo "--- Aggregated Test Count ---"
@find ${EXAMPLES_DIR} -path '*/${TRANSLATION_DIR}/cargo_test.log' | xargs cat | grep -aE "^test \S+ ... \S+$$" | cut -d" " -f4 | sort | uniq -c
@find ${EXAMPLES} -path '*/${TRANSLATION_DIR}/cargo_test.log' | xargs cat | grep -aE "^test \S+ ... \S+$$" | cut -d" " -f4 | sort | uniq -c
@echo "\`\`\`"
examples/%/test:## Test specific translated example
examples/%/test: FORCE
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) cmake
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) test


.PHONY: examples/repair
examples/repair:## Repair all examples
examples/repair: $(subst /test_case,/repair,${EXAMPLES})
examples/%/repair:## Repair specific example
examples/%/repair: FORCE
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) cmake
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) repair

.PHONY: examples/clean
examples/clean:## Clean all examples
examples/clean: $(subst /test_case,/clean,${EXAMPLES})
examples/clean: $(addsuffix /clean,${EXAMPLES})
examples/%/clean:## Clean specific example
examples/%/clean: FORCE
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) clean

# experiment across preprocessing strategies
PREPROC_STRATEGIES ?= clang clang-directive-filter clang-sys-filter tu tu-sys-filter c## List of preprocessing stragegies to use in experiment

.PRECIOUS: ${TRANSLATION_DIR}.preproc_strategy_%.log
${TRANSLATION_DIR}.preproc_strategy_%.log:
$(MAKE) --no-print-directory examples/test TRANSLATION_DIR="${TRANSLATION_DIR}.preproc_strategy_$*" TRANSLATE_ARGS="${TRANSLATE_ARGS} preproc_strategy=$*" | tee -a $@

.PHONY: examples/experiment
examples/experiment: $(addsuffix .log,$(addprefix ${TRANSLATION_DIR}.preproc_strategy_,${PREPROC_STRATEGIES}))## Run all preprocessing strategies and print metrics
@for PREPROC_STRATEGY in ${PREPROC_STRATEGIES} ; \
do \
grep -A100 "# ${TRANSLATION_DIR}.preproc_strategy_$$PREPROC_STRATEGY" ${TRANSLATION_DIR}.preproc_strategy_$$PREPROC_STRATEGY.log ; \
echo "" ; \
done

# update tests
.PHONY: examples/update_tests
examples/update_tests:## Update test cases to use TRANSLATION_DIR test cases for all examples
examples/update_tests: $(subst /test_case,/update_tests,${EXAMPLES})
examples/update_tests: $(addsuffix /update_tests,${EXAMPLES})
examples/%/update_tests:## Update specific test cases to use TRANSLATION_DIR test cases
examples/%/update_tests: FORCE
-@$(MAKE) -j1 -f $(IDEAS_MAKEFILE) -C $(@D) cmake
Expand Down
19 changes: 8 additions & 11 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,18 @@ dynamic = ["version"]
description = "Improved Decoding and Equivalence Automated testing at Scale"
readme = "README.md"
license = {file = "LICENSE"}
requires-python = "~=3.11.0"
requires-python = "~=3.14.0"

dependencies = [
"clang==14.0",
"dspy==3.0.4",
"hydra-core==1.3.2",
"clang==21.1.7",
"dspy==3.1.0",
"hydra-core",
"tree-sitter==0.24.0",
"tree-sitter-c==0.23.4",
"tree-sitter-rust==0.23.2",
]

[project.optional-dependencies]
gpu = [
"accelerate==1.6.0",
"transformers==4.55.2",
"vllm==0.11.0",
]

[dependency-groups]
dev = [
"basedpyright==1.29.4",
"pre-commit==4.2.0",
Expand Down Expand Up @@ -49,3 +43,6 @@ pythonpath = ["src"]

[tool.ruff]
line-length = 96

[tool.uv.sources]
hydra-core = { git = "https://github.com/facebookresearch/hydra.git", rev = "1ac07c7c001f73b2a6cdbc4c2ad700287cdf592c" }
16 changes: 8 additions & 8 deletions src/ideas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@

from .logging import JSONFormatter, CodePairFilter
from .ast import create_translation_unit, extract_info_c, TreeResult
from .ast_rust import ensure_no_mangle_in_module
from .ltu import build_unit
from .model import ModelConfig, GenerateConfig
from .agents import TranslateAgent
from .tools import get_info_from_cargo_toml
from .translate_recurrent import RecurrentTranslator
from .translate_symbol import SymbolTranslator
from clang.cindex import Config

__version__ = "2025.10"

__all__ = [
"create_translation_unit",
"extract_info_c",
"TreeResult",
"ensure_no_mangle_in_module",
"ModelConfig",
"GenerateConfig",
"JSONFormatter",
"CodePairFilter",
"build_unit",
"TranslateAgent",
"get_info_from_cargo_toml",
"RecurrentTranslator",
"SymbolTranslator",
]

# NOTE: .so is *nix specific
Config.set_library_file("libclang-21.so")
Loading