File size: 6,680 Bytes
8468957
fb4977b
3b2c794
 
 
 
 
 
 
 
 
 
6b46d06
3b2c794
49569a4
3b2c794
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import gradio as gr 
import os
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langchain_openai import ChatOpenAI

class MigrationState(TypedDict):
    codigo_original: str
    codigo_traducido: str
    analisis_seguridad: str

# Nota: El código trabaja actualmente con el modelo DeepSeek V3.1. 
# Sin embargo, se recomienda trabajar con Qwen2.5-Coder 32B para un mejor análisis de código. 
llm = ChatOpenAI(
    api_key = os.environ.get("API_KEY"),
    base_url="https://api.fireworks.ai/inference/v1",
    model="accounts/fireworks/models/deepseek-v3p1" 
)

def nodo_traductor(state: MigrationState):
    prompt = f"Actúa como un experto en AMD ROCm. Traduce este código NVIDIA CUDA a AMD HIP. Solo devuelve el código final, sin explicaciones:\n\n{state['codigo_original']}"
    respuesta = llm.invoke(prompt)
    
    codigo_limpio = respuesta.content
    if codigo_limpio.startswith("```"):
         lineas = codigo_limpio.split("\n")
         codigo_limpio = "\n".join(lineas[1:-1])
         
    return {"codigo_traducido": codigo_limpio}

def nodo_auditor(state: MigrationState):
    prompt = f"Revisa este código AMD HIP. Confirma si la migración fue correcta y advierte sobre posibles fugas de memoria. Sé breve (máximo 3 líneas):\n\n{state['codigo_traducido']}"
    respuesta = llm.invoke(prompt)
    return {"analisis_seguridad": respuesta.content}

workflow = StateGraph(MigrationState)
workflow.add_node("traductor", nodo_traductor)
workflow.add_node("auditor", nodo_auditor)
workflow.add_edge(START, "traductor")
workflow.add_edge("traductor", "auditor")
workflow.add_edge("auditor", END)

agente_rocm = workflow.compile()

DUMMY_CUDA_CODE = """#include <iostream>

__global__ void vectorAdd(const float *A, const float *B, float *C, int numElements) {
    int i = blockDim.x * blockIdx.x + threadIdx.x;
    if (i < numElements) {
        C[i] = A[i] + B[i];
    }
}

int main() {
    return 0;
}
"""

def leer_archivo(archivo):
    if archivo is not None:
        try:
            with open(archivo.name, "r", encoding="utf-8") as f:
                return f.read()
        except Exception as e:
            return f"Error al leer el archivo: {str(e)}"
    return ""

def chat_con_agente(mensaje_usuario, historial):
    if not historial:
        historial = []
    
    prompt_chat = f"""Eres el Ingeniero Líder de ROCm-Sentinel. 
    El usuario te da esta instrucción para la migración: '{mensaje_usuario}'. 
    Responde en una frase corta y técnica cómo integrarás esta instrucción en el proceso de traducción a AMD HIP."""
    
    try:
        respuesta = llm.invoke(prompt_chat)
        historial.append({"role": "user", "content": mensaje_usuario})
        historial.append({"role": "assistant", "content": respuesta.content})
    except Exception:
        historial.append({"role": "user", "content": mensaje_usuario})
        historial.append({"role": "assistant", "content": "Entendido. Aplicaré esas optimizaciones técnicas al código."})
    
    return "", historial

def simular_migracion(cuda_code, historial):
    if not historial: historial = []
    if not cuda_code:
         yield "Error: Ingresa código.", historial, "Desconocido", ""
         return
        
    historial.append({"role": "assistant", "content": "🚀 **Proceso iniciado.** El Agente Traductor está analizando los kernels de CUDA..."})
    yield "Estado: Analizando Kernels...", historial, "Analizando...", ""
    
    try:
        resultado = agente_rocm.invoke({"codigo_original": cuda_code})
        rocm_code = resultado["codigo_traducido"]
        reporte_auditor = resultado["analisis_seguridad"]
        
        historial.append({"role": "assistant", "content": f"✅ **Migración Exitosa.**\n\n🛡️ **Auditoría de Seguridad:**\n{reporte_auditor}"})
        yield "Estado: Completado con éxito", historial, "NVIDIA CUDA (nvcc) -> AMD HIP (hipcc)", rocm_code
        
    except Exception as e:
        historial.append({"role": "assistant", "content": f"❌ Error en el flujo: {str(e)}"})
        yield "Estado: Error crítico", historial, "Error", ""

with gr.Blocks() as demo:
    gr.Markdown(
        """
        <div style='text-align: center;'>
            <h1 style='color: #FF3232;'>ROCm-Sentinel</h1>
            <p><strong>Advanced CUDA to AMD ROCm Migration Agent</strong></p>
        </div>
        """
    )
    
    with gr.Row():
        with gr.Column(scale=1):
            archivo_subida = gr.File(
                label="📁 Subir archivo fuente", 
                file_types=[".cu", ".cpp", ".txt", ".h"]
            )
            gr.Markdown("### 📜 Código Origen (CUDA)")
            input_code = gr.Code(
                label="Editor de entrada", 
                language="cpp", 
                lines=15, 
                value=DUMMY_CUDA_CODE
            )
            
        with gr.Column(scale=1):
            lenguaje_detectado = gr.Textbox(
                label="🔍 Firma / Lenguaje Detectado", 
                interactive=False
            )
            estado_migracion = gr.Textbox(
                label="⚡ Monitor de Proceso (Estado)",
                interactive=False,
                placeholder="Listo para procesar..."
            )
            gr.Markdown("### 🛠️ Código Migrado (AMD HIP)")
            output_code = gr.Code(
                label="Resultado de la migración", 
                language="cpp", 
                lines=15, 
                interactive=False
            )
            
    with gr.Row():
        migrate_btn = gr.Button(
            "🚀 INICIAR MIGRACIÓN SEGURA A ROCm", 
            variant="primary", 
            size="lg"
        )
            
    with gr.Row():
        with gr.Column(scale=1):
            gr.Markdown("### 🤖 Centro de Control del Agente")
            chatbot = gr.Chatbot(
                label="Interacción con el Agente de IA", 
                height=300
            )
            chat_input = gr.Textbox(
                label="Instrucciones adicionales para el Agente", 
                placeholder="Ej: 'Usa memoria unificada' o 'Optimiza para hilos específicos'..."
            )
            
    archivo_subida.change(fn=leer_archivo, inputs=archivo_subida, outputs=input_code)
    
    chat_input.submit(
        fn=chat_con_agente, 
        inputs=[chat_input, chatbot], 
        outputs=[chat_input, chatbot]
    )
    
    migrate_btn.click(
        fn=simular_migracion, 
        inputs=[input_code, chatbot], 
        outputs=[estado_migracion, chatbot, lenguaje_detectado, output_code]
    )

if __name__ == "__main__":
    demo.launch(theme=gr.themes.Monochrome())