From 93b1d694cfa64d2948e981dc5a0311a2b4cf3a42 Mon Sep 17 00:00:00 2001
From: Martin Bauer <martin.bauer@fau.de>
Date: Tue, 11 Apr 2017 16:47:33 +0200
Subject: [PATCH] Bugfix in JIT cacheing

- cache relied on uniqueness of  python id()
- id may be reused if object is freed
-> object must be held alive
-> kernel keeps all it arguments it was ever called with, alive (problematic in terms of memory consumption)
---
 cpu/cpujit.py      | 2 ++
 gpucuda/cudajit.py | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/cpu/cpujit.py b/cpu/cpujit.py
index cdb73b82c..02d9291aa 100644
--- a/cpu/cpujit.py
+++ b/cpu/cpujit.py
@@ -430,6 +430,7 @@ def makePythonFunctionIncompleteParams(kernelFunctionNode, argumentDict):
     parameters = kernelFunctionNode.parameters
 
     cache = {}
+    cacheValues = []
 
     def wrapper(**kwargs):
         key = hash(tuple((k, id(v)) for k, v in kwargs.items()))
@@ -441,6 +442,7 @@ def makePythonFunctionIncompleteParams(kernelFunctionNode, argumentDict):
             fullArguments.update(kwargs)
             args = buildCTypeArgumentList(parameters, fullArguments)
             cache[key] = args
+            cacheValues.append(kwargs)  # keep objects alive such that ids remain unique
             func(*args)
     return wrapper
 
diff --git a/gpucuda/cudajit.py b/gpucuda/cudajit.py
index 0b18c1359..299492d63 100644
--- a/gpucuda/cudajit.py
+++ b/gpucuda/cudajit.py
@@ -29,6 +29,7 @@ def makePythonFunction(kernelFunctionNode, argumentDict={}):
     parameters = kernelFunctionNode.parameters
 
     cache = {}
+    cacheValues = []
 
     def wrapper(**kwargs):
         key = hash(tuple((k, id(v)) for k, v in kwargs.items()))
@@ -45,6 +46,7 @@ def makePythonFunction(kernelFunctionNode, argumentDict={}):
 
             args = _buildNumpyArgumentList(parameters, fullArguments)
             cache[key] = (args, dictWithBlockAndThreadNumbers)
+            cacheValues.append(kwargs)  # keep objects alive such that ids remain unique
             func(*args, **dictWithBlockAndThreadNumbers)
         #cuda.Context.synchronize() # useful for debugging, to get errors right after kernel was called
     return wrapper
-- 
GitLab