Related
Hi I'm trying to create an AI inspired NEAT but I ran into a problem after performing the calculation, the data from the device can't be moved to the host.
I'm trying to use cuda.synchronize () before moving the data, but in this case the error has already occurred on this line.
I tried the cuda features before and they worked without problems until now.
I'm attaching the code with an error.
Please can you help me?
code:
import os
# needs to appear before cuda import
os.environ["NUMBA_ENABLE_CUDASIM"] = "0"
# set to "1" for more debugging, but slower performance
os.environ["NUMBA_CUDA_DEBUGINFO"] = "0"
from numba import cuda
import numpy as np
from random import uniform
from pprint import pprint
#cuda.jit(device=True)
def LeakyRelu(x):
return max(x * 0.1, x)
#cuda.jit
def Calculate(set_io, many_neurons, many_inputs, reindex_io, memory_io, weights_io, biases_io, nets_info_io, auxmemort_io):
x = cuda.grid(1)
shape = set_io.shape
if x < shape[0]:
netidx = reindex_io[x, 0]
neuidx = reindex_io[x, 1]
weiidx = reindex_io[x, 2]
result = 0
for i in range(nets_info_io[netidx, 1]):
result += memory_io[nets_info_io[netidx, 0] + i] * weights_io[weiidx + i]
result += biases_io[x]
result = LeakyRelu(result)
auxmemort_io[neuidx] = result
def CalculateSlow():
pass
class ANET:
def __init__(self, many_inputs, many_outputs, many_networks, info = True, activation_function = LeakyRelu):
self.many_inputs = many_inputs
self.many_outputs = many_outputs
self.many_networks = many_networks
self.activation_function = activation_function
self.info = info
self.netid = -1
self.cuda_many_input = cuda.to_device(self.many_inputs)
if self.info:
print("starting Setup:\n|")
device = str(cuda.get_current_device()).split("'b'")[1].split("''")[0]
print(f"| cuda run on: {device}")
print(f"| generate genomes")
self.networks_genomes = [self._GenerateGenome() for _ in range(self.many_networks)]
self._BuildPopulation()
def _CudaPre(self, block, array):
griddim = tuple(np.array(array.shape) // block + 1)
blockdim = tuple(np.full_like(griddim, block))
return griddim, blockdim
def _GenerateGenome(self):
neurons_genome = [[self.activation_function, uniform(-1,1), i + self.many_inputs] for i in range(self.many_outputs)]
synapses_genome = [[[i, ii], uniform(-1,1), True] for i in range(self.many_inputs) for ii in range(self.many_inputs, self.many_outputs + self.many_inputs)]
self.netid += 1
return [neurons_genome, synapses_genome, self.netid]
def _BuildPopulation(self):
memory_len = sum([(len(i[0]) + self.many_inputs) for i in self.networks_genomes])
memory = np.zeros(memory_len, dtype=np.float64)
auxmemory = np.copy(memory)
weights_len = sum([(len(i[1]) + self.many_inputs + 1) for i in self.networks_genomes])
weights = np.zeros(weights_len, dtype=np.float64)
biases_len = sum([len(i[0]) for i in self.networks_genomes])
biases = np.zeros(biases_len, dtype=np.float64)
nets_info = np.zeros([self.many_networks, 5], dtype=np.int64)
movmem = 0
movwei = 0
movbia = 0
for idx,i in enumerate(self.networks_genomes):
nets_info[idx] = (movmem, len(i[0]) + self.many_inputs, movwei, movbia, i[2])
movmem += len(i[0]) + self.many_inputs
movwei += len(i[1]) + self.many_inputs + 1
movbia += len(i[0])
biaidx = 0
for genome, net_info in zip(self.networks_genomes, nets_info):
for gen, biagen in zip(genome[1], genome[0]):
if gen[2]:
if gen[0][0] < self.many_inputs:
target = gen[0][0]
else:
target = genome[0][gen[0][0] - self.many_inputs - self.many_outputs][2] + self.many_inputs
weights[(gen[0][1] - self.many_inputs) * net_info[1] + net_info[2] + target] = gen[1]
biases[biaidx] = biagen[1]
biaidx += 1
reindex = np.empty([sum([(i[1] - self.many_inputs) for i in nets_info]), 3], dtype=np.int64)
write = 0
weiidx = 0
for idx,inf in enumerate(nets_info):
for i in range(inf[1] - self.many_inputs):
reindex[write][0] = idx
reindex[write][1] = inf[0] + i + self.many_inputs
reindex[write][2] = weiidx
weiidx += inf[1]
write += 1
if self.info:
print("| move arrays to device")
self.memory = memory
self.cuda_auxmemory = cuda.to_device(auxmemory)
print(self.cuda_auxmemory.copy_to_host())
self.cuda_weights = cuda.to_device(weights)
self.cuda_biases = cuda.to_device(biases)
self.nets_info = nets_info
self.cuda_nets_info = cuda.to_device(nets_info)
self.many_neurons = np.sum(nets_info, axis=0)[1]
self.cuda_many_neurons = cuda.to_device(self.many_neurons)
self.cuda_reindex = cuda.to_device(reindex)
# print(nets_info)
# print(f"{memory_len} | {weights_len} | {biases_len}")
def MathPopulation(self, inputs):
for idx, inp in enumerate(inputs):
self.memory[self.nets_info[idx][0]: self.nets_info[idx][0] + self.many_inputs] = inp
self.cuda_memory = cuda.to_device(self.memory)
setlen = cuda.to_device(np.zeros(self.many_neurons))
Calculate[self._CudaPre(32, np.empty([self.many_neurons]))](setlen, self.cuda_many_neurons, self.cuda_many_input, self.cuda_reindex, self.cuda_memory, self.cuda_weights, self.cuda_biases, self.cuda_nets_info, self.cuda_auxmemory)
# cuda.synchronize()
arr = self.cuda_auxmemory.copy_to_host()
print(arr)
if __name__ == '__main__':
anet = ANET(many_inputs = 3, many_outputs = 2, many_networks = 5)
# pprint(anet._GenerateGenome())
anet.MathPopulation([[1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15]])
error:
Traceback (most recent call last):
File "c:\Users\Ondra\Documents\Pythonporno\ANET\ANET.py", line 144, in <module>
anet.MathPopulation([[1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15]])
File "c:\Users\Ondra\Documents\Pythonporno\ANET\ANET.py", line 138, in MathPopulation
arr = self.cuda_auxmemory.copy_to_host()
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\devices.py", line 232, in _require_cuda_context
return fn(*args, **kws)
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\devicearray.py", line 277, in copy_to_host
_driver.device_to_host(hostary, self, self.alloc_size,
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\driver.py", line 2998, in device_to_host
fn(host_pointer(dst), device_pointer(src), size, *varargs)
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\driver.py", line 319, in safe_cuda_api_call
self._check_ctypes_error(fname, retcode)
File "C:\Users\Ondra\AppData\Local\Programs\Python\Python310\lib\site-packages\numba\cuda\cudadrv\driver.py", line 384, in _check_ctypes_error
raise CudaAPIError(retcode, msg)
numba.cuda.cudadrv.driver.CudaAPIError: [700] Call to cuMemcpyDtoH results in UNKNOWN_CUDA_ERROR
So I'm trying to make a large list containing all the elements I need, as seen in the output of the following code:
set = [1, 5, 15, 30, 60, 240, 360, 720, 1440, 10080]
ShortEMASet = []
LongEMASet = []
MACDSet = []
SignalSet = []
SetofSets = [ShortEMASet, LongEMASet, MACDSet, SignalSet]
for x in set:
ShortEMASet.append("ShortEMA" + str(x))
LongEMASet.append("LongEMASet" + str(x))
MACDSet.append("MACDSet" + str(x))
SignalSet.append("SignalSet" + str(x))
SetofSets
This returns the output
[['ShortEMA1',
'ShortEMA5',
'ShortEMA15',
'ShortEMA30',
'ShortEMA60',
'ShortEMA240',
'ShortEMA360',
'ShortEMA720',
'ShortEMA1440',
'ShortEMA10080'],
['LongEMASet1',
'LongEMASet5',
'LongEMASet15',
'LongEMASet30',
'LongEMASet60',
'LongEMASet240',
'LongEMASet360',
'LongEMASet720',
'LongEMASet1440',
'LongEMASet10080'],
['MACDSet1',
'MACDSet5',
'MACDSet15',
'MACDSet30',
'MACDSet60',
'MACDSet240',
'MACDSet360',
'MACDSet720',
'MACDSet1440',
'MACDSet10080'],
['SignalSet1',
'SignalSet5',
'SignalSet15',
'SignalSet30',
'SignalSet60',
'SignalSet240',
'SignalSet360',
'SignalSet720',
'SignalSet1440',
'SignalSet10080']]
However the problem is, if my variable SetofSets contained 100+ lists inside it, then it would be SUPER tedious to write this out 100+ times, how can I make it more scalable?
I tried the following:
set = [1, 5, 15, 30, 60, 240, 360, 720, 1440, 10080]
ShortEMASet = []
LongEMASet = []
MACDSet = []
SignalSet = []
SetofSets = [ShortEMASet, LongEMASet, MACDSet, SignalSet]
for x in set:
for i in SetofSets:
SetofSets[i].append(str(SetofSets[i]) + str(x))
SetofSets
Which fails due to this error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-641-81831a6939e2> in <module>
8 for x in set:
9 for i in SetofSets:
---> 10 SetofSets[i].append(str(SetofSets[i]) + str(x))
11 SetofSets
TypeError: list indices must be integers or slices, not list
You can do nested for-loop:
lst = [1, 5, 15, 30, 60, 240, 360, 720, 1440, 10080]
names = ["ShortEMASet", "LongEMASet", "MACDSet", "SignalSet"]
out = []
for n in names:
out.append([])
for l in lst:
out[-1].append(n + str(l))
print(out)
Prints:
[
[
"ShortEMASet1",
"ShortEMASet5",
"ShortEMASet15",
"ShortEMASet30",
"ShortEMASet60",
"ShortEMASet240",
"ShortEMASet360",
"ShortEMASet720",
"ShortEMASet1440",
"ShortEMASet10080",
],
[
"LongEMASet1",
"LongEMASet5",
"LongEMASet15",
"LongEMASet30",
"LongEMASet60",
"LongEMASet240",
"LongEMASet360",
"LongEMASet720",
"LongEMASet1440",
"LongEMASet10080",
],
[
"MACDSet1",
"MACDSet5",
"MACDSet15",
"MACDSet30",
"MACDSet60",
"MACDSet240",
"MACDSet360",
"MACDSet720",
"MACDSet1440",
"MACDSet10080",
],
[
"SignalSet1",
"SignalSet5",
"SignalSet15",
"SignalSet30",
"SignalSet60",
"SignalSet240",
"SignalSet360",
"SignalSet720",
"SignalSet1440",
"SignalSet10080",
],
]
Or list-comprehension:
out = [[n + str(l) for l in lst] for n in names]
print(out)
EDIT: You can create a dictionary instead of a list:
lst = [1, 5, 15, 30, 60, 240, 360, 720, 1440, 10080]
names = ["ShortEMASet", "LongEMASet", "MACDSet", "SignalSet"]
out = {}
for n in names:
for l in lst:
out.setdefault(n, []).append(n + str(l))
print(out)
Prints:
{
"ShortEMASet": [
"ShortEMASet1",
"ShortEMASet5",
"ShortEMASet15",
"ShortEMASet30",
"ShortEMASet60",
"ShortEMASet240",
"ShortEMASet360",
"ShortEMASet720",
"ShortEMASet1440",
"ShortEMASet10080",
],
"LongEMASet": [
"LongEMASet1",
"LongEMASet5",
"LongEMASet15",
"LongEMASet30",
"LongEMASet60",
"LongEMASet240",
"LongEMASet360",
"LongEMASet720",
"LongEMASet1440",
"LongEMASet10080",
],
"MACDSet": [
"MACDSet1",
"MACDSet5",
"MACDSet15",
"MACDSet30",
"MACDSet60",
"MACDSet240",
"MACDSet360",
"MACDSet720",
"MACDSet1440",
"MACDSet10080",
],
"SignalSet": [
"SignalSet1",
"SignalSet5",
"SignalSet15",
"SignalSet30",
"SignalSet60",
"SignalSet240",
"SignalSet360",
"SignalSet720",
"SignalSet1440",
"SignalSet10080",
],
}
Then you can call:
print(out["ShortEMASet"])
to print:
[
"ShortEMASet1",
"ShortEMASet5",
"ShortEMASet15",
"ShortEMASet30",
"ShortEMASet60",
"ShortEMASet240",
"ShortEMASet360",
"ShortEMASet720",
"ShortEMASet1440",
"ShortEMASet10080",
]
Just a small mistake:
for x in set:
for i in SetofSets:
SetofSets[i].append(str(SetofSets[i]) + str(x))
should be
for x in set:
for i in SetofSets:
i.append(str(SetofSets[i]) + str(x))
P.S. Off-top, but generally I'd advice you to avoid calling a variable with a built-in type (set is a built-in type, I probably noticed the `set is highlighted differently) and follow the PEP-8 formatting.
This is a K-Knights problem solved with CSP, and the issue seems to be the constraints.
Error coming from here
File "F:/Lectures/AI Lab/Codes/nonattacking/aicodes/csp.py", line 23, in init
self.setUpVariableDomains()
File "F:/Lectures/AI Lab/Codes/nonattacking/aicodes/csp.py", line 28, in setUpVariableDomains
self.addVariableDomain(var, self._domain)
File "F:/Lectures/AI Lab/Codes/nonattacking/aicodes/csp.py", line 35, in addVariableDomain
self._domainOfVariable[var] = copy.deepcopy(domain)
TypeError: unhashable type: 'list'
import variable
import copy
import notEqualConstraint
import simpleInference
import time
import backtrackingSearch
import consoleListener
import nonAttackingConstraint
class CSP():
def __init__(self, variables = [], domains = [], constraints = []):
self._variables = variables
self._domain = domains
self._constraints = constraints
self._domainOfVariable = {}
self._contraintsOfVariable = {}
self.setUpVariableDomains()
self.setUpConstraints()
def setUpVariableDomains(self):
for var in self._variables:
self.addVariableDomain(var, self._domain)
def setUpConstraints(self):
for constraint in self._constraints:
self.addConstraint(constraint)
def addVariableDomain(self,var,domain):
self._domainOfVariable[var] = copy.deepcopy(domain)
def addConstraint(self,constraint):
for var in constraint.getScope():
if var not in self._contraintsOfVariable:
self._contraintsOfVariable[var] = []
self._contraintsOfVariable[var].append(constraint)
def addSingleConstraint(self,constraint):
self._constraints.append(constraint)
for var in constraint.getScope():
if var not in self._contraintsOfVariable:
self._contraintsOfVariable[var] = []
self._contraintsOfVariable[var].append(constraint)
def addVariable(self,variable):
self._variables.append(variable)
self.addVariableDomain(variable,self._domain)
def getVariables(self):
return self._variables
def getDomainValues(self,var):
return self._domainOfVariable[var]
def getConstraints(self,var):
if var not in self._contraintsOfVariable:
return []
return self._contraintsOfVariable[var]
def getVariableDomains(self):
return self._domainOfVariable
def setVariableDomains(self,domainOfVariable):
self._domainOfVariable = domainOfVariable
def copy(self):
variables = copy.deepcopy(self._variables)
domains = copy.deepcopy(self._variables)
constraints = copy.deepcopy(self._variables)
csp = CSP(variables, domains, constraints)
return csp
def getNeighbour(self,variable,constraint):
neigh = []
for va in constraint.getScope():
if va != variable and (va not in neigh):
neigh.append(va)
return neigh
def removeValueFromDomain(self,variable,value):
values = []
for val in self.getDomainValues(variable):
if val != value:
values.append(val)
self._domainOfVariable[variable] = values
if __name__ == '__main__':
domains = ["K","A"]
variables = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
X=[[2,1],[2,-1],[-2,1],[-2,-1],[1,2],[1,-2],[-1,2],[-1,-2]]
constraints = [
nonAttackingConstraint.NotAttackingConstraint(X)
]
Csp = CSP(variables,domains,constraints)
inPro = simpleInference.SimpleInference()
bts = backtrackingSearch.BactrackingSearch(inPro,[consoleListener.ConsoleListener()],variableOrdering = True)
start = time.time()
result = bts.solve(Csp)
end = time.time()
print("%.2f ‐ %.2f" % (start,end))
Specifically stops at addVariableDomain in the CSP Class above, and gives me the unhashable type: 'list' error due to my constraint being a list. Is the issue identifiable? Is there a solution?
Lists can not be used as dictionary keys as they are mutable and hence not suitable for hashing. Try converting the list to tuple.
def addVariableDomain(self,var,domain):
self._domainOfVariable[tuple(var)] = copy.deepcopy(domain)
You may have to do the same wherever var is used as a dictionary key.
I've been testing text recognition from images using pyocr (tesseract-ocr and libetesseract). I've been applying various PIL.ImageFilters and getting the result of one specific string in the image. It has not been accurate, but I have 14 different results. Between all of them, all of the correct letters of the string in the image are there. So I have enumerated each string and created a dict containing the characters' position as keys that contain a dict of each character that has appeared in that position at keys and the number of occurrences as the value. Here's a shortened example
String In Image:
2HG2
Results:
#Note: this is not the actual order in which the strings are produced
2HC2
2HC2
2HCZ
2HOZ
2HOZ
2HOZ
2HOZ
2HGZ
2HGZ
2HGZ
ZHGZ
ZHGZ
ZH6Z
ZN6z
Dictionary:
{
0: {
u'2': 10,
u'Z': 4
}, 1: {
u'H': 13,
u'N': 1
}, 2: {
u'C': 3,
u'O': 4,
u'G': 5,
u'6': 2
}, 3: {
u'2': 2,
u'Z': 11,
u'z': 1
}
}
I'd like to try each combination of letters in each position until I get 2HG2. Any help would be appreciated.
EDIT:
The goal I'm trying to achieve is to scan a car registration, get text from it, and then populate a form with the data. As a proof of concept, I'm trying to get the VIN number from my person registration. At the moment, I'm (most likely naively) applying a series of PIL.ImageFilters and getting text from each. Below is my script.
import re
from itertools import permutations
from PIL import Image, ImageFilter
import pyocr
from pyocr import builders
vins = []
characters = {}
def validate(vincode):
"""
Validation code from https://en.wikipedia.org/wiki/Vehicle_identification_number
"""
maps = "0123456789X"
weights = [
8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2
]
table = {
"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9,
"A": 1, "B": 2, "C": 3, "D": 4, "E": 5, "F": 6, "G": 7, "H": 8,
"J": 1, "K": 2, "L": 3, "M": 4, "N": 5, "P": 7, "R": 9,
"S": 2, "T": 3, "U": 4, "V": 5, "W": 6, "X": 7, "Y": 8, "Z": 9,
}
if not isinstance(vincode, str) and not isinstance(vincode, unicode):
return False
if len(vincode) != 17:
return False
vincode = vincode.upper()
if "I" in vincode or "O" in vincode or "Q" in vincode:
return False
total = 0
for index, value in enumerate(vincode):
try:
products = table[value] * weights[index]
except KeyError:
break
total += products
index = total % 11
return maps[index] == vincode[8]
def get_text(tools_, img_):
for tool in tools_:
if tool.get_name() == 'Cuneiform (sh)':
continue
# print '=======================\nUsing {}\n======================='.format(tool.get_name())
boxes = tool.image_to_string(img_, lang='eng', builder=builders.WordBoxBuilder())
global vins
pattern = re.compile('[\W_]+')
vins += [pattern.sub('', x.content) for x in boxes if len(pattern.sub('', x.content)) == 17]
# boxes = [x for x in boxes if len(x.content.strip()) != 0]
# print boxes[3].content
# for box in boxes:
# print box.content
def apply_filters_and_get_text(img_, filter_):
for x in range(1, 5):
print 'Applying {} size: {}'.format(str(filter_), x)
try:
img_ = img_.filter(filter_(x))
except ValueError:
print 'error on {} size: {}'.format(str(filter_), x)
continue
img_.save('tmp{}-{}.jpg'.format(str(filter_), x))
get_text(tools, img_)
def count_occurrences(value):
global characters
for index, c in enumerate(value):
if index in characters and c in characters[index]:
characters[index][c] += 1
continue
if index in characters and isinstance(characters[index], dict):
characters[index][c] = 1
continue
characters[index] = {c: 1}
tools = pyocr.get_available_tools()
img = Image.open('images/test18.jpg')
# get_text(tools)
# img = img.filter(ImageFilter.MaxFilter(5))
# img = img.filter(ImageFilter.SHARPEN)
# img = img.filter(ImageFilter.SMOOTH_MORE)
# get_text(tools)
# get_text(tools)
img = img.convert('L')
# get_text(tools)
# img = img.filter(ImageFilter.MaxFilter(5))
# img = img.filter(ImageFilter.SHARPEN)
# img = img.filter(ImageFilter.SMOOTH_MORE)
# get_text(tools)
# get_text(tools)
img = img.point(lambda x: 0 if x < 128 else 255, '1')
apply_filters_and_get_text(img, ImageFilter.MedianFilter)
apply_filters_and_get_text(img, ImageFilter.MinFilter)
apply_filters_and_get_text(img, ImageFilter.MaxFilter)
apply_filters_and_get_text(img, ImageFilter.ModeFilter)
for vin in vins:
count_occurrences(vin)
# print vin
# print validate(vin)
print characters
I was able to figure out a recursive function that tries every combination of the letters with priority to characters with higher weight.
def determine_character(characters_, tried=[]):
next_character = ""
current_rank = 0
for ch in characters_:
if characters_[ch] > current_rank and ch not in tried:
next_character = ch
return next_character
def determine_weight(word):
global characters
weight = 0
for index, ch in enumerate(word):
weight += characters[index][ch]
return weight
def descramble(word="", index=0):
global characters
count = len(characters)
if index == count and validate(word):
global vin_count, valid_vins
vin_count += 1
valid_vins.append({'vin': word, 'weight': determine_weight(word)})
return {'word': word, 'done': True}
if index == count:
return False
tried = []
while len(tried) < len(characters[index]):
ch = determine_character(characters[index], tried)
tried.append(ch)
next_index = index + 1
descramble("{word}{ch}".format(word=word, ch=ch), next_index)
from multiprocessing import Process , Queue
from datetime import datetime
c = [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]
out = Queue()
def support(m):
for k in m :
print "%s <-- hi" % k
out.put("done")
all = Queue()
temp = []
total = len(c)
count = 0
for m in c :
count += 1
total = total - 1
temp.append(m)
if count == 5 or total == 0 :
all.put(temp)
count = 0
temp = []
process_count = 3
while all.qsize() != 0 :
process_list = []
try :
for x in range(process_count) :
p = Process(target=support, args=(all.get(),))
process_list.append(p)
for p in process_list :
p.start()
for p in process_list :
p.join()
except Exception as e :
print e
while out.qsize != 0 :
print out.get()
print "all done"
I dont know why it does not end and does not print "all done" , just remain continuously in loop or keep executing .
Will be of great help if you can make this code more efficient but first i want to know why it does not end .
The problem is:
while out.qsize != 0 :
print out.get()
out.qsize is a function, so now you're comparing the function itself (not the return value!) with 0, with is of course always False.
You should use:
while out.qsize() != 0 :
print out.get()