Skip to content
Snippets Groups Projects
Commit fe872898 authored by Matthieu Oberon's avatar Matthieu Oberon
Browse files

Merge branch 'AddNtoCalculation' into 'master'

Add nto calculation

See merge request 2019marechals/st7-intel!4
parents 0707be69 75341f79
No related branches found
No related tags found
No related merge requests found
......@@ -6,7 +6,7 @@ import compute_path
import tools
import launcher_SUBP
def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3=256,
def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1_max=256, n2_max=256, n3_max=256,
fancy_strategy='AS', sub_threshold=0.1, sup_threshold=10**9,
nb_threads=8, reps=100):
""" Ant colony optimization of the cache blocking parameters for the execution of
......@@ -22,9 +22,9 @@ def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3
nb_ants (int): number of ants
tau_0 (float): initial quantity of pheromones on each edge
n_iter (int): number of cycles done for ACO
n1 (int, optional): First dimension of matrix. Defaults to 256.
n2 (int, optional): Second dimension of matrix. Defaults to 256.
n3 (int, optional): Third dimension of matrix. Defaults to 256.
n1_max (int, optional): Maximal first dimension of matrix. Defaults to 256.
n2_max (int, optional): Maximal second dimension of matrix. Defaults to 256.
n3_max (int, optional): Maximal third dimension of matrix. Defaults to 256.
fancy_strategy (string, optional): Strategy used to update tau. Defaults to 'AS'.
sub_threshold (float, optional): Inferior threshold for Min-Max strategy. Defaults to 0.1.
sup_threshold (float, optional): Superior threshold for Min-Max strategy. Defaults to 10**9.
......@@ -36,13 +36,19 @@ def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3
"""
# Initialisation of the graph and pheromon matrix
n_cbx = n1//16
n_cby = n2
n_cbz = n3
tau = np.zeros((n_cbx + n_cby + 1, n_cbx + n_cby + n_cbz + 1), dtype="float64")
tau[0, 1:n_cbx+1] = tau_0
tau[1:n_cbx+1, n_cbx+1:n_cbx+n_cby+1] = tau_0
tau[n_cbx+1:n_cbx+n_cby+1, n_cbx+n_cby+1:n_cbx+n_cby+n_cbz+1] = tau_0
n_cbx = n1_max//16
n_cby = n2_max
n_cbz = n3_max
n1_size = int(1 + np.log2(n1_max/256))
n2_size = int(1 + np.log2(n2_max/256))
n3_size = int(1 + np.log2(n3_max/256))
tau = np.zeros((n1_size + n2_size + n3_size + n_cbx + n_cby + 1, n1_size + n2_size + n3_size + n_cbx + n_cby + n_cbz + 1), dtype="float64")
tau[0, 1:(n1_size+1)] = tau_0
tau[1:(n1_size+1), (n1_size+1):(n1_size + n2_size + 1)] = tau_0
tau[(n1_size+1):(n1_size + n2_size + 1), (n1_size + n2_size + 1):(n1_size + n2_size + n3_size + 1)] = tau_0
tau[(n1_size + n2_size + 1):(n1_size + n2_size + n3_size + 1), (n1_size + n2_size + n3_size + 1):(n1_size + n2_size + n3_size + n_cbx + 1)] = tau_0
tau[(n1_size + n2_size + n3_size + 1):(n1_size + n2_size + n3_size + n_cbx + 1), (n1_size + n2_size + n3_size + n_cbx + 1):(n1_size + n2_size + n3_size + n_cbx + n_cby + 1)] = tau_0
tau[(n1_size + n2_size + n3_size + n_cbx + 1):(n1_size + n2_size + n3_size + n_cbx + n_cby + 1), (n1_size + n2_size + n3_size + n_cbx + n_cby + 1):(n1_size + n2_size + n3_size + n_cbx + n_cby + n_cbz + 1)] = tau_0
cost_opti = math.inf
# n_iter cycles of ants traveling through the graph
......@@ -50,10 +56,16 @@ def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3
paths = []
costs = []
for k in range(nb_ants//NbP):
path = compute_path.compute_path(tau, alpha, n1, n2, n3)
cost = launcher_SUBP.deploySUBP(n1, n2, n3, nb_threads, reps, path[0]*16, path[1], path[2])
path = compute_path.compute_path(tau, alpha, n1_size, n2_size, n3_size)
n1 = 256 * (2**(path[0]-1))
n2 = 256 * (2**(path[1]-1))
n3 = 256 * (2**(path[2]-1))
cbx = path[3]*16
cby = path[4]
cbz = path[5]
cost = launcher_SUBP.deploySUBP(n1, n2, n3, nb_threads, reps, cbx, cby, cbz)
cost = [cost]
print(f"Path followed at iteration {iter} on process {Me} by ant {k} : {[path[0]*16, path[1], path[2]]} with cost equal to {cost[0]}.")
print(f"Path followed at iteration {iter} on process {Me} by ant {k} : {[n1, n2, n3, cbx, cby, cbz]} with cost equal to {cost[0]}.")
paths.append(path)
costs.append(cost)
paths = np.array(paths, dtype="int32")
......@@ -68,13 +80,13 @@ def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3
tau = tau * (1-rho)
#we compute the new pheromon with the ants already present
tau = tools.add_pheromones(tau, paths, costs, Q, n1, n2)
tau = tools.add_pheromones(tau, paths, costs, Q, n1_size, n2_size, n3_size, n_cbx, n_cby)
for i in range(1,NbP):
#we exchange the ants with a ring structure to compute locally tau
comm.Sendrecv_replace(paths, dest=(Me+1)%NbP, source=(Me-1)%NbP)
comm.Sendrecv_replace(costs, dest=(Me+1)%NbP, source=(Me-1)%NbP)
tau = tools.add_pheromones(tau, paths, costs, Q, n1, n2)
tau = tools.add_pheromones(tau, paths, costs, Q, n1_size, n2_size, n3_size, n_cbx, n_cby)
#we search for the best path
new_cost = np.amin(costs)
if new_cost < best_cost:
......@@ -82,7 +94,7 @@ def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3
best_p = paths[np.argmin(costs), :]
if fancy_strategy == 'ElitistAS':
tau = tools.add_pheromones(tau, np.array(best_p), np.array(best_cost), Q, n1, n2)
tau = tools.add_pheromones(tau, np.array(best_p), np.array(best_cost), Q, n1_size, n2_size, n3_size, n_cbx, n_cby)
if fancy_strategy == 'MMAS':
#we compute the best path locally
......@@ -97,7 +109,7 @@ def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3
#we compute the pheromon using only the best path
tau = tau * (1-rho)
tau = add_pheromones.add_pheromones(tau, np.array(best_p), np.array(best_cost), Q, n1, n2, n3)
tau = tools.add_pheromones(tau, np.array(best_p), np.array(best_cost), Q, n1_size, n2_size, n3_size, n_cbx, n_cby)
#verification of the threshold constraint
size = np.size(tau)
......@@ -113,8 +125,13 @@ def ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter, n1=256, n2=256, n3
cost_opti = best_cost
path_opti = best_p
path_opti[0] *= 16
return path_opti, cost_opti
n1 = 256 * (2**(path_opti[0]-1))
n2 = 256 * (2**(path_opti[1]-1))
n3 = 256 * (2**(path_opti[2]-1))
cbx= path_opti[3]*16
cby= path_opti[4]
cbz= path_opti[5]
return [n1, n2, n3, cbx, cby, cbz], cost_opti
if __name__ == "__main__":
......@@ -135,7 +152,7 @@ if __name__ == "__main__":
# Parameters for compilation and execution of iso3dfd
nb_threads = 8
reps = 100
n1, n2, n3 = 256, 256, 256
n1_max, n2_max, n3_max = 256, 256, 256
optimization = "-O3"
simd = "avx512"
......@@ -146,7 +163,7 @@ if __name__ == "__main__":
comm.Barrier()
path_opti, cost_opti = ACO(Me, NbP, comm, alpha, rho, Q, nb_ants, tau_0, n_iter,
n1=n1, n2=n2, n3=n3, fancy_strategy=fancy_strategy,
n1_max=n1_max, n2_max=n2_max, n3_max=n3_max, fancy_strategy=fancy_strategy,
nb_threads=nb_threads, reps=reps)
if Me == 0:
print(f"Le chemin optimal est {path_opti}.")
......
import random as rd
import numpy as np
#tau : pheromone matrix, size : 1 + n1//16 + n2 x 1 + n1//16 + n2 + n3
#tau : pheromone matrix, size : 1 + n1_size + n2_size + n3_size + n1_max//16 + n2_max x 1 + n1_size + n2_size + n3_size + n1//16 + n2 + n3
def proba(i, alpha, tau, n1_size, n2_size, n3_size, n_cbx, n_cby, n_cbz):
n1_max = (2**(n1_size-1)) * 16
n2_max = (2**(n2_size-1)) * 256
n3_max = (2**(n3_size-1)) * 256
def proba(i, alpha, tau, n_cbx, n_cby, n_cbz):
if i == 0 :
#we are on the initial state
#the ant is going to choose cbx
sequence = np.arange(1, n_cbx +1)
#the ant is going to choose n1
sequence = np.arange(1, n1_size +1)
if i>0 and i<n_cbx +1 :
elif i > 0 and i < n1_size + 1 :
#we are on the first state
#the ant is going to choose cby
sequence = np.arange(n_cbx + 1, n_cbx + n_cby + 1)
#the ant is going to choose n2
sequence = np.arange(n1_size + 1, n1_size + n2_size + 1)
if i>n_cbx and i<n_cbx + n_cby + 1 :
elif i > n1_size and i < n1_size + n2_size + 1 :
#we are on the second state
#the ant is going to choose n3
sequence = np.arange(n1_size + n2_size + 1, n1_size + n2_size + n3_size + 1)
elif i > n1_size + n2_size and i < n1_size + n2_size + n3_size + 1 :
#we are on the third state
#the ant is going to choose cbx
sequence = np.arange(n1_size + n2_size + n3_size + 1, n1_size + n2_size + n3_size + n_cbx + 1)
elif i > n1_size + n2_size + n3_size and i < n1_size + n2_size + n3_size + n1_max + 1 :
#we are on the fourth state
#the ant is going to choose cby
sequence = np.arange(n1_size + n2_size + n3_size + n1_max + 1, n1_size + n2_size + n3_size + n1_max + n_cby + 1)
elif i > n1_size + n2_size + n3_size + n1_max and i < n1_size + n2_size + n3_size + n1_max + n2_max + 1 :
#we are on the fifth state
#the ant is going to choose cbz
sequence = np.arange(n_cbx + n_cby + 1,n_cbx + n_cby + n_cbz + 1)
sequence = np.arange(n1_size + n2_size + n3_size + n1_max + n2_max + 1, n1_size + n2_size + n3_size + n1_max + n2_max + n_cbz + 1)
#we compute the weights and then we normalize it
weights = np.power(tau[i][sequence[0]:sequence[-1]+1],alpha)
norm = np.sum(weights)
weights = weights/norm
#Uncomment the two next lines to normalize the weights
#norm = np.sum(weights)
#weights = weights/norm
return (sequence, weights)
def compute_path(tau, alpha, n1, n2, n3):
n_cbx = n1//16
n_cby = n2
n_cbz = n3
path = []
def compute_path(tau, alpha, n1_size, n2_size, n3_size):
sequence, weights = proba(0, alpha, tau, n_cbx, n_cby, n_cbz)
new_node = rd.choices(sequence,weights)[0]
path.append(new_node)
#n_cbx, n_cby, n_cbz will be initialized after the choice of n1, n2, n3
n_cbx = 0
n_cby = 0
n_cbz = 0
path = []
sequence, weights = proba(path[0], alpha, tau, n_cbx, n_cby, n_cbz)
sequence, weights = proba(0, alpha, tau, n1_size, n2_size, n3_size, n_cbx, n_cby, n_cbz)
new_node = rd.choices(sequence,weights)[0]
path.append(new_node)
sequence, weights = proba(path[1], alpha, tau, n_cbx, n_cby, n_cbz)
for i in range(5):
sequence, weights = proba(path[i], alpha, tau, n1_size, n2_size, n3_size, n_cbx, n_cby, n_cbz)
new_node = rd.choices(sequence,weights)[0]
path.append(new_node)
if i == 1:
n1 = 256 * (2**(path[0]-1))
n2 = 256 * (2**(path[1] - n1_size - 1))
n3 = 256 * (2**(path[2] - n1_size - n2_size - 1))
n_cbx, n_cby, n_cbz = n1//16, n2, n3
#we transform the path so that it is now in the following form : [n_cbx, n_cby, n_cbz]
path[1] = path[1] - n_cbx
path[2] = path[2] - n_cbx - n_cby
#we transform the path so that it is now in the following form : [n1, n2, n3, n_cbx, n_cby, n_cbz]
path[1] = path[1] - n1_size
path[2] = path[2] - n1_size - n2_size
path[3] = path[3] - n1_size - n2_size - n3_size
path[4] = path[4] - n1_size - n2_size - n3_size - (2**(n1_size-1)) * 16
path[5] = path[5] - n1_size - n2_size - n3_size - (2**(n1_size-1)) * 16 - (2**(n2_size-1)) * 256
return path
if __name__ == "__main__":
n1_max, n2_max, n3_max = 1024, 1024, 1024
n_cbx = n1_max//16
n_cby = n2_max
n_cbz = n3_max
n1_size = int(1 + np.log2(n1_max/256))
n2_size = int(1 + np.log2(n2_max/256))
n3_size = int(1 + np.log2(n3_max/256))
tau_0 = 10
tau = np.zeros((n1_size + n2_size + n3_size + n_cbx + n_cby + 1, n1_size + n2_size + n3_size + n_cbx + n_cby + n_cbz + 1), dtype="float64")
tau[0, 1:(n1_size+1)] = tau_0
tau[1:(n1_size+1), (n1_size+1):(n1_size + n2_size + 1)] = tau_0
tau[(n1_size+1):(n1_size + n2_size + 1), (n1_size + n2_size + 1):(n1_size + n2_size + n3_size + 1)] = tau_0
tau[(n1_size + n2_size + 1):(n1_size + n2_size + n3_size + 1), (n1_size + n2_size + n3_size + 1):(n1_size + n2_size + n3_size + n_cbx + 1)] = tau_0
tau[(n1_size + n2_size + n3_size + 1):(n1_size + n2_size + n3_size + n_cbx + 1), (n1_size + n2_size + n3_size + n_cbx + 1):(n1_size + n2_size + n3_size + n_cbx + n_cby + 1)] = tau_0
tau[(n1_size + n2_size + n3_size + n_cbx + 1):(n1_size + n2_size + n3_size + n_cbx + n_cby + 1), (n1_size + n2_size + n3_size + n_cbx + n_cby + 1):(n1_size + n2_size + n3_size + n_cbx + n_cby + n_cbz + 1)] = tau_0
path = compute_path(tau, 1, n1_size, n2_size, n3_size)
print(path)
......@@ -92,7 +92,7 @@ def commandLineExtract(commandLineOutput):
# Add pheromones function
#-----------------------------------------------------------------
def add_pheromones(tau, paths, costs, Q, n1, n2):
def add_pheromones(tau, paths, costs, Q, n1_size, n2_size, n3_size, n_cbx, n_cby):
"""Computing of the pheromon matrix and the cost of each path.
Args:
......@@ -100,8 +100,11 @@ def add_pheromones(tau, paths, costs, Q, n1, n2):
paths (np.array): Array of the paths taken by the ants: paths[i]=(cb_x//16,cb_y,cb_z)
costs (np.array): Column array containing the costs.
Q (float): quantity of pheromones added by an ant on an edge
n1 (int): First dimension of matrix
n2 (int): Second dimension of matrix
n1_size (int): First dimension of matrix
n2_size (int): Second dimension of matrix
n3_size (int): Second dimension of matrix
n_cbx (int): Second dimension of matrix
n_cby (int): Second dimension of matrix
Returns:
(np.array, list, float): the updated pheromon matrix, the best path and the associated cost
......@@ -111,7 +114,10 @@ def add_pheromones(tau, paths, costs, Q, n1, n2):
p = paths[i, :]
cost = costs[i, 0]
tau[0,p[0]] += Q*(-1)*cost
tau[p[0],n1//16+p[1]] += Q*(-1)*cost
tau[n1//16+p[1],n1//16+n2+p[2]] += Q*(-1)*cost
tau[p[0], p[1] + n1_size] += Q*(-1)*cost
tau[p[1] + n1_size, p[2] + n1_size + n2_size] += Q*(-1)*cost
tau[p[2] + n1_size + n2_size, p[3] + n1_size + n2_size + n3_size] += Q*(-1)*cost
tau[p[3] + n1_size + n2_size + n3_size, p[4] + n1_size + n2_size + n3_size + n_cbx] += Q*(-1)*cost
tau[p[4] + n1_size + n2_size + n3_size + n_cbx, p[5] + n1_size + n2_size + n3_size + n_cbx + n_cby] += Q*(-1)*cost
return tau
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment