Source code for ingest_amrex
#!/usr/bin/env python3
import os
import sys
import subprocess
import glob
import tempfile
from pathlib import Path
# Try to import necessary libraries
try:
import chromadb
from sentence_transformers import SentenceTransformer
except ImportError:
print("Please run this script from an environment with chromadb and sentence_transformers installed.")
sys.exit(1)
OFA_ROOT = os.environ.get("OFA_ROOT", str(Path(__file__).resolve().parent.parent))
VECTORDB_PATH = os.environ.get("OFA_VECTORDB", os.path.join(OFA_ROOT, "vectordb"))
TMP_CLONE_DIR = os.environ.get(
"OFA_AMREX_CLONE_DIR",
os.path.join(tempfile.gettempdir(), f"amrex_ingest_{os.environ.get('USER', 'default')}"),
)
# Ensure user directory setup
os.makedirs(TMP_CLONE_DIR, exist_ok=True)
os.chdir(TMP_CLONE_DIR)
print("Cloning repositories...")
if not os.path.exists("amrex"):
subprocess.run(["git", "clone", "https://github.com/amrex-codes/amrex.git"])
if not os.path.exists("marblesThermal"):
subprocess.run(["git", "clone", "https://github.com/nileshsawant/marblesThermal.git"])
# Load model
print("Loading embedding model...")
model_path = os.environ.get("OFA_EMBEDDING_MODEL", os.path.join(OFA_ROOT, "embedding_model"))
embed_model = SentenceTransformer(model_path, device="cpu")
# Initialize Master ChromaDB
print(f"Connecting to ChromaDB at {VECTORDB_PATH}...")
client = chromadb.PersistentClient(path=VECTORDB_PATH)
[docs]
def process_repo(repo_name, coll_name, extensions):
print(f"\nProcessing {repo_name} -> Collection: {coll_name}")
try:
collection = client.create_collection(coll_name)
except ValueError:
collection = client.get_collection(coll_name)
print(f"Collection {coll_name} already exists. Appending...")
files_to_process = []
for ext in extensions:
files_to_process.extend(glob.glob(f"{repo_name}/**/*{ext}", recursive=True))
docs = []
metadatas = []
ids = []
CHUNK_SIZE = 1500 # rough characters
for i, fp in enumerate(files_to_process):
try:
with open(fp, "r", encoding="utf-8", errors="ignore") as f:
content = f.read()
# Simple chunking for source code
chunks = [content[i:i+CHUNK_SIZE] for i in range(0, len(content), CHUNK_SIZE - 200)]
for j, chunk in enumerate(chunks):
doc_id = f"{repo_name}_{os.path.basename(fp)}_{i}_{j}"
docs.append(chunk)
metadatas.append({"filepath": fp, "repo": repo_name})
ids.append(doc_id)
except Exception as e:
pass
if docs:
print(f"Embedding {len(docs)} chunks for {repo_name}...")
# Embed in batches of 32
BATCH = 32
for b in range(0, len(docs), BATCH):
batch_docs = docs[b:b+BATCH]
batch_metas = metadatas[b:b+BATCH]
batch_ids = ids[b:b+BATCH]
embeddings = embed_model.encode(batch_docs).tolist()
collection.add(
documents=batch_docs,
embeddings=embeddings,
metadatas=batch_metas,
ids=batch_ids
)
print(f" Inserted {b+len(batch_docs)}/{len(docs)}", end='\r')
print("\nDone.")
else:
print(f"No documents found for {repo_name}.")
process_repo("amrex", "amrex_src", [".cpp", ".H", ".h", ".f90"])
process_repo("marblesThermal", "marbles_src", [".cpp", ".H", ".h"])
print("\nIngestion complete. You can now use `ofa --amrex` safely!")