diff --git a/runtime/boundary_weights.hpp b/runtime/boundary_weights.hpp
index bf8ffbf3772eb0a46542996c3bcf22329ee2edf4..6f625474a24d626889bd43ceb37aeff03552b359 100644
--- a/runtime/boundary_weights.hpp
+++ b/runtime/boundary_weights.hpp
@@ -5,7 +5,13 @@
 //---
 #include "pairs.hpp"
 #include "pairs_common.hpp"
-#include "gen/interfaces.hpp"
+
+#define INTERFACE_DIR "interfaces/"
+#define INTERFACE_EXT ".hpp"
+#define INTERFACE_FILE(a, b, c) a ## b ## c
+#define INCLUDE_FILE(filename) #filename
+
+#include INCLUDE_FILE(INTERFACE_FILE(INTERFACE_DIR, APPLICATION_REFERENCE, INTERFACE_EXT))
 
 #pragma once
 
@@ -51,4 +57,4 @@ void compute_boundary_weights(
     }
 }
 
-}
\ No newline at end of file
+}
diff --git a/src/pairs/code_gen/cgen.py b/src/pairs/code_gen/cgen.py
index a053d942e72fabf44dba726c8bd6c4e93a919f5e..7973f444809c59d5af752ccc536731f810ed3f38 100644
--- a/src/pairs/code_gen/cgen.py
+++ b/src/pairs/code_gen/cgen.py
@@ -54,10 +54,50 @@ class CGen:
     def real_type(self):
         return Types.c_keyword(self.sim, Types.Real)
 
+    def generate_interfaces(self):
+        self.print = Printer(f"runtime/interfaces/{self.ref}.hpp")
+        self.print.start()
+        self.print("#include \"../pairs.hpp\"")
+        self.generate_interface_namespace('pairs_host_interface')
+        self.generate_interface_namespace('pairs_cuda_interface', "__inline__ __device__")
+        self.print.end()
+
+    def generate_interface_namespace(self, namespace, prefix=None):
+        self.print("")
+        self.print(f"namespace {namespace} {{")
+        self.print("")
+
+        for prop in self.sim.properties.all():
+            prop_name = prop.name()
+            t = prop.type()
+            tkw = Types.c_keyword(self.sim, t)
+            func_decl = "" if prefix is None else f"{prefix} "
+            if Types.is_scalar(t):
+                func_decl += f"{tkw} get_{prop_name}({tkw} *{prop_name}, int i) {{ return {prop_name}[i]; }}"
+
+            else:
+                nelems = Types.number_of_elements(self.sim, t)
+                func_decl += f"{tkw} get_{prop_name}({tkw} *{prop_name}, int i, int j, int capacity) {{ return {prop_name}["
+
+                if prop.layout() == Layouts.AoS:
+                    func_decl += f"i * {nelems} + j"
+
+                else:
+                    func_decl += f"j * capacity + i"
+
+                func_decl += "]; }"
+
+            self.print(func_decl)
+
+        self.print("")
+        self.print("}")
+
+
     def generate_program(self, ast_node):
         ext = ".cu" if self.target.is_gpu() else ".cpp"
         self.print = Printer(self.ref + ext)
         self.print.start()
+        self.print("#define APPLICATION_REFERENCE \"{self.ref}\"")
 
         if self.target.is_gpu():
             self.print("#define PAIRS_TARGET_CUDA")
diff --git a/src/pairs/sim/domain_partitioning.py b/src/pairs/sim/domain_partitioning.py
index e3668bed2e00caa2275fe556ec03a79151adedd5..a6173004d422d8f2d06bb84c125df5597821b440 100644
--- a/src/pairs/sim/domain_partitioning.py
+++ b/src/pairs/sim/domain_partitioning.py
@@ -1,5 +1,6 @@
 from pairs.ir.assign import Assign
 from pairs.ir.branches import Filter
+from pairs.ir.loops import For
 from pairs.ir.functions import Call_Int, Call_Void
 from pairs.ir.scalars import ScalarOp
 from pairs.ir.select import Select
diff --git a/src/pairs/sim/simulation.py b/src/pairs/sim/simulation.py
index defaf998a2a04c12d244c3e6f6e1b47fce0e9ac4..048f309f6157d44f4ee63379daf6692df2d96181 100644
--- a/src/pairs/sim/simulation.py
+++ b/src/pairs/sim/simulation.py
@@ -453,3 +453,4 @@ class Simulation:
         # Generate program
         #ASTGraph(self.functions, "functions.dot").render()
         self.code_gen.generate_program(program)
+        self.code_gen.generate_interfaces()