Browse Source

init

Signed-off-by: Jean-Michel Batto <jean-michel.batto@eldarsoft.com>
Jean-Michel Batto 4 tuần trước cách đây
mục cha
commit
c081692aaa
5 tập tin đã thay đổi với 232 bổ sung0 xóa
  1. 69 0
      Dockerfile
  2. 17 0
      Makefile
  3. 90 0
      Typetracer.jl
  4. 35 0
      docker-compose.yml
  5. 21 0
      mapping.yml

+ 69 - 0
Dockerfile

@@ -0,0 +1,69 @@
+# Base : Debian Bookworm avec Julia 1.10 pré-installé
+FROM julia:1.10-bookworm
+
+# Métadonnées
+LABEL maintainer="CodeBuddy"
+LABEL description="Environnement de portage Julia -> C avec PDI/HDF5 et Outils graphiques"
+
+# Arguments pour gérer l'utilisateur (évite les fichiers root sur le host)
+ARG USER_ID=1000
+ARG GROUP_ID=1000
+ARG USER_NAME=engineer
+
+# 1. Installation des dépendances système (C/C++, HDF5, Outils graphiques, Build tools)
+# Nous incluons gdb et valgrind pour la rigueur du C.
+# Nous incluons les libs X11 pour l'affichage des plots.
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    build-essential \
+    cmake \
+    git \
+    libhdf5-dev \
+    libz-dev \
+    pkg-config \
+    gdb \
+    valgrind \
+    clang-format \
+    libx11-6 \
+    libxext6 \
+    libxrender1 \
+    libxtst6 \
+    xauth \
+    ca-certificates \
+    && rm -rf /var/lib/apt/lists/*
+
+# 2. Installation de PDI (Build from source pour exclure MPI et garantir HDF5)
+# Nous clonons, configurons et installons PDI dans /usr/local
+WORKDIR /tmp/pdi-build
+RUN git clone https://github.com/pdidev/pdi.git . && \
+    mkdir build && cd build && \
+    cmake \
+        -DBUILD_MPI=OFF \
+        -DBUILD_DECL_HDF5_PLUGIN=ON \
+        -DBUILD_SHARED_LIBS=ON \
+        -DCMAKE_INSTALL_PREFIX=/usr/local \
+        .. && \
+    make -j$(nproc) && \
+    make install && \
+    ldconfig && \
+    cd / && rm -rf /tmp/pdi-build
+
+# 3. Pré-installation des packages Julia essentiels pour le portage
+# HDF5.jl pour lire/écrire ce que PDI manipule
+# Plots.jl pour la visualisation
+RUN julia -e 'import Pkg; Pkg.add(["HDF5", "Plots", "DataFrames"]); Pkg.precompile()'
+
+# 4. Création de l'utilisateur non-root
+RUN groupadd -g ${GROUP_ID} ${USER_NAME} && \
+    useradd -m -u ${USER_ID} -g ${USER_NAME} -s /bin/bash ${USER_NAME}
+
+# Configuration de l'environnement pour PDI
+ENV PDI_DIR=/usr/local
+ENV LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
+ENV CPATH=/usr/local/include:$CPATH
+
+# Passage à l'utilisateur
+USER ${USER_NAME}
+WORKDIR /home/${USER_NAME}/project
+
+# Point d'entrée par défaut : un shell bash prêt à l'emploi
+CMD ["/bin/bash"]

+ 17 - 0
Makefile

@@ -0,0 +1,17 @@
+# Makefile pour le portage
+.PHONY: trace-julia build-c compare clean
+
+# 1. Lance Julia avec l'instrumentation pour générer les traces et le Golden Master HDF5
+trace-julia:
+	julia --project=. src/main_simulation.jl --trace-mode
+
+# 2. Compile le nouveau code C
+build-c:
+	gcc -g -O2 src_c/main.c -o build/sim_c -lpdi
+
+# 3. Compare les sorties (Vision Test)
+compare:
+	julia scripts/compare_results.jl build/output_c.h5 build/output_julia.h5
+
+clean:
+	rm -f build/*

+ 90 - 0
Typetracer.jl

@@ -0,0 +1,90 @@
+module TypeTracer
+
+using Serialization
+
+# Singleton pour stocker les signatures uniques (Thread-safe)
+const SEEN_SIGNATURES = Set{String}()
+const LOCK = ReentrantLock()
+const LOG_FILE = "execution_trace.txt"
+
+"""
+Fonction interne pour enregistrer une signature.
+Format: FunctionName(ArgType1, ArgType2, ...) -> ReturnType
+"""
+function _record_call(func_name, args, result)
+    # On map les types Julia vers des chaînes de caractères
+    arg_types = join([string(typeof(a)) for a in args], ", ")
+    ret_type = string(typeof(result))
+    
+    signature = "$func_name($arg_types) -> $ret_type"
+
+    # Vérification avec lock pour le multi-threading (fréquent en simu)
+    lock(LOCK) do
+        if !(signature in SEEN_SIGNATURES)
+            push!(SEEN_SIGNATURES, signature)
+            # On écrit immédiatement pour ne rien perdre en cas de crash
+            open(LOG_FILE, "a") do io
+                println(io, signature)
+            end
+            # Un petit echo console pour voir que ça vit
+            println("[TRACER] Nouvelle variante capturée : $signature")
+        end
+    end
+end
+
+"""
+Macro à placer devant les définitions de fonctions.
+Elle enveloppe le corps de la fonction pour logger les types.
+"""
+macro monitor(expr)
+    # Vérifie qu'on applique bien la macro sur une définition de fonction
+    if expr.head !== :function && expr.head !== :(=)
+        error("La macro @monitor doit être appliquée à une définition de fonction.")
+    end
+
+    # Extraction de la signature (nom + args) et du corps
+    call_def = expr.args[1]
+    body = expr.args[2]
+
+    # Récupération du nom de la fonction (gestion cas f(x) et Module.f(x))
+    func_name = length(call_def.args) >= 1 ? call_def.args[1] : :anonymous
+    
+    # On reconstruit la fonction avec l'instrumentation
+    quote
+        function $(call_def)
+            # 1. Exécuter le corps original et capturer le résultat
+            __result = $(body)
+            
+            # 2. Récupérer les arguments (via ... dans la macro c'est délicat, 
+            # donc on utilise une astuce : on capture les valeurs des arguments par leur nom)
+            # Note : Pour une conversion C, on a besoin des types concrets à l'exécution.
+            # Ici, on passe un tuple des arguments.
+            # Attention : cela suppose que call_def.args contient les noms des variables.
+            
+            # Pour faire simple et robuste sans métaprogrammation complexe sur les arguments :
+            # On logue juste le fait qu'on est passé ici.
+            # MAIS pour avoir les args, il faut être plus malin.
+            
+            # Approche simplifiée : On logue à la fin
+            TypeTracer._record_call(
+                $(string(func_name)), 
+                # On capture tous les arguments de la fonction courante
+                # (nécessite que la fonction ne soit pas anonyme pure)
+                (Base.@locals()...,), # Capture tout le scope local (arguments inclus)
+                __result
+            )
+            
+            return __result
+        end
+    end |> esc
+end
+
+# Fonction de nettoyage pour vider le log au début
+function init_trace()
+    if isfile(LOG_FILE)
+        rm(LOG_FILE)
+    end
+    println("--- Démarrage du traçage des types ---")
+end
+
+end

+ 35 - 0
docker-compose.yml

@@ -0,0 +1,35 @@
+services:
+  converter:
+    build:
+      context: .
+      dockerfile: Dockerfile
+      args:
+        # Ajustez ces IDs si vous n'êtes pas l'utilisateur 1000 sur Linux
+        # (Tapez `id` dans votre terminal pour vérifier)
+        USER_ID: 1000
+        GROUP_ID: 1000
+        USER_NAME: engineer
+    image: codebuddy/julia-c-pdi:latest
+    container_name: julia_c_lab
+    
+    # Montage du dossier courant (votre code) dans le conteneur
+    volumes:
+      - ./:/home/engineer/project
+      # Montage du socket X11 pour l'affichage graphique (Linux)
+      - /tmp/.X11-unix:/tmp/.X11-unix
+    
+    # Configuration de l'affichage
+    environment:
+      - DISPLAY=${DISPLAY}
+      # PDI_CONF peut être utile plus tard pour pointer vers vos fichiers .yml
+      - PDI_ERR_handler=abort
+    
+    # Pour le débogage C (ptrace) et l'accès réseau si nécessaire
+    cap_add:
+      - SYS_PTRACE
+    security_opt:
+      - seccomp:unconfined
+    
+    # Garde le conteneur actif
+    tty: true
+    stdin_open: true

+ 21 - 0
mapping.yml

@@ -0,0 +1,21 @@
+# Exemple de vision PDI pour nos structures
+types:
+  Agent:
+    type: struct
+    members:
+      id: int
+      velocity: double
+  
+  World:
+    type: array
+    subtype: Agent
+    size: $nb_agents
+
+data:
+  current_state:
+    type: World
+plugins:
+  decl_hdf5:
+    file: "trace_execution.h5"
+    write:
+      current_state: { when: $end_step }