This is the code used to find the global dimensions of endomorphism rings of modules over E8.
Using the notation of Yoshino for the indecomposable modules, the correspondence between vertices of the quiver used here and indecomposable modules is as follows:

0: N2
1: D2
2: X1
3: B2
4: X2
5: C1
6: B1
7: N1
8: R
9: M2
10: C2
11: Y1
12: A2
13: Y2
14: D1
15: A1
16: M1
17: 0
------------------------

import sys

#These routines switch between representing a module as a vector with a summand's multiplicity in the corresponding position (i.e. (1,0,2,0)) or as a list of indecomposable summands (i.e. [0,2,2])
def veckter(a,n):
        zippy = zero_vector(ZZ,n)
        if type(a) == Integer or type(a) == int:
                zippy[a] = 1
        elif type(a) == list:
                for i in a:
                        zippy = zippy + veckter(i,n)
        return zippy

def vertecks(v):
        listy = []
        for i in [0..len(v)-1]:
                if v[i] >= 1:
                        for n in [1..v[i]]:
                                listy.append(i)
        if len(listy) == 1:
                return listy[0]
        else:
                return listy

#Changes all positive entries of a vector to one, to represent a module up to multiplicities of its summands.
def haircut(v):
        h = zero_vector(len(v))
        for i in [0..len(h)-1]:
                if v[i] > 0:
                        h[i] = 1
        return h
       
#This is the AR quiver of E8
E8 = DiGraph(matrix([[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],[0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0],[0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0],[0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0],[0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0],[0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0],[0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0],[0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0],[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1],[0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0]]))

#Here we construct a matrix to represent the AR translate
G = Graph(18)
for i in [0..8]:
                G.add_edge(i,i + 9)
tau = G.adjacency_matrix()

#A routine to approximate one indecomposable module.
#Parameters:
#v: The number of the vertex in the AR quiver corresponding to the module to be approximated
#G: The AR quiver
#tau: The AR translate matrix
#S: The set of modulesto be used in the approximation
def approxOne(v,G,tau,S):
       
        #Defining variables:

        q = len(G)
        n = q - 1
       
        #The current number of vertices of the graph ("the graph" being the finite portion of the universal cover of the AR quiver which we are working with)
        vertNum = 1
     
        #The level of the graph which is currently being numbered
        curlev = 1

        #A list used to match a vertex with its level - if vertex a is at level b, then levels[a] == b
        levels = [1]

        #A list showing which modules of the AR quiver each vertex is identified with
        ids = [v]

        #A finite portion of the graph
        UC = DiGraph(1)

        #Adjacency matrix of the AR quiver
        arqMat = G.adjacency_matrix()

        #A list recording the numbers of the vertices - mults[i] is the number of vertex i
        mults = [1]

        #The kernel and middle term of the approximation, represented as vectors
        ker = zero_vector(ZZ,n)
        midterm = zero_vector(ZZ,n)
       
        #A list of all vertices at level l of the graph
        def levlist(l):
                laval = []
                for i in [0..len(levels)-1]:
                        if levels[i] == l:
                                laval.append(i)
                return laval
       
        #Finds the inverse AR translate of a vertex
        def tauf(w):
                lev = levels[w]
                #If the vertex's inverse AR translate is outside the portion of the graph we've constructed, the value None is returned (vertices outside the constructed portion are all numbered zero)
                if lev - 2 <= 0:
                        return None
                for i in levlist(lev-2):
                        if ids[i] == vertecks(veckter(ids[w],q)*tau):
                                return i
                return None
       
        #Determines whether a vertex is numbered zero or otherwise treated as zero
        def isZip(w):
                return (mults[w] <= 0 or ids[w] == n or (ids[w] in S and w != 0))
       
        #Determines whether the current and previous levels are both full of zeros (in which case we can stop the algorithm)
        def stop():
                redlight = true
                for w in levlist(curlev):
                        if isZip(w) == false:
                                redlight = false
                for w in levlist(curlev-1):
                        if isZip(w) == false:
                                redlight = false
                return redlight
               
        #This loop adds a new level to the graph
        while stop() == false:
                for u in levlist(curlev):
                        #Identifying predecessors of vertex u
                        old = ids[u]
                        nextsteps = arqMat*veckter(old,q)
                        #Checking whether a vertex corresponding to a particular predecessor i has already been added
                        for i in [0..q-1]:
                                if nextsteps[i] == 1:
                                        make = true
                                        for t in levlist(curlev + 1):
                                                if ids[t] == i:
                                                        #If a vertex corresponding to i has already been added to the next level, we don't create another, but simply connect that vertex to u
                                                        UC.add_edge(t,u)
                                                        make = false
                                        if make:
                                                #Adding another vertex to the next level, corresponding to the predecessor i, and connecting it to u
                                                UC.add_vertex(vertNum)
                                                UC.add_edge(vertNum,u)
                                                #Updating relevant lists to record the new vertex
                                                ids.append(i)
                                                levels.append(curlev + 1)
                                                mults.append(0)
                                                vertNum = vertNum + 1
                #Updating the current level
                curlev = curlev + 1

                #Now we number each vertex on the current level
                ucMat = UC.adjacency_matrix()
                for w in levlist(curlev):
                     
                        #The terms to be added and subtracted to obtain the number of v
                        middle = 0
                        back = 0
                        #A list of successors of vertex w, represented as a vector (e.g. [0,1,0,1] if the successors are 1 and 3)
                        right = veckter(w,len(UC))*ucMat
                        for x in [0..len(right)-1]:
                                #If vertex x is a successor of w and its number is not treated as zero, its number is added
                                if right[x] == 1 and isZip(x) == false:
                                        middle = middle + mults[x]
                        #The number of the inverse AR translate of w is subtracted
                        t = tauf(w)
                        if t != None and isZip(t) == false:
                                back = mults[t]
                        #The number of w is calculated
                        mults[w] = middle - back
                        #If w has a negative number and is not associated with the zero module, the multiplicity of its corresponding module in the kernel is increased by the negative of its number
                        if ids[w] != n and mults[w] < 0:
                                ker[ids[w]] = ker[ids[w]] - mults[w]
                        #If w has a positive number and is associated with a module in S, the multiplicity of its corresponding module in the kernel is increased by its number
                        elif ids[w] in S:
                                midterm[ids[w]] = midterm[ids[w]] + mults[w]
       
        #The first two terms of the approximation, represented as vectors, are returned
        return [ker,midterm]

#Approximates a sum of indecomposable modules, represented as a list of summands
def approx(v,G,tau,S):
        if type(v) != list:
                return approx([v],G,tau,S)
        seq = zero_matrix(2,len(G)-1)
        for i in v:
                seq = seq + Matrix(approxOne(i,G,tau,S))
        return list(seq)

#Checks whether a sum of indecomposable modules, represented as a vector, contains only summands in the set S
def okay(v,S):
        o = true
        for i in [0..len(v)-1]:
                if (i in S or v[i] == 0)==false:
                        o = false
        return o

#Computes approximations recursively and splices them together until we obtain an approximation of v in terms of modules in S only, or detect an infinite repeating patern.
def recur(v,G,tau,S):
        #A list of modules not in S that have appeared in kernels of approximations
        archive = []
        #The first approximation of v, represented as a list of its terms in the form of vectors
        T = list(approx(v,G,tau,S))
        n = len(T[0])
        #If the kernel contains terms not in S, we must approximate those terms
        while okay(T[0],S)==false:
                #A list of summands of the kernel, not in S
                bads = list(zero_vector(ZZ,n))
                for i in [0..n-1]:
                        #If a module i has a nonzero multiplicity in the kernel and is not in S, it must be approximated.
                        if (T[0][i] > 0) and ((i in S) == false):
                                bads[i] = bads[i] + T[0][i]
                #If the set of modules to be approximated is identical to one which has occurred at a previous step of the approximation (up to multiplicities), then the approximation is infinite, and the value None is returned.
                bads = haircut(bads)
                if bads in archive:
                        return
                else:
                        #If the set of modules to be approximated has not appeared previously, it is added to the archive so that the pattern can be detected if it appears again in a subsequent step.
                        archive.append(bads)
                #The summands of the kernel not in S are approximated, and this sequence is spliced together with the previous approximation
                goods = T[0] - vector(bads)
                newprox = list(approx(vertecks(bads),G,tau,S))
                newprox[1] = newprox[1] + goods
                for w in [1..len(T)-1]:
                        newprox.append(T[w])
                T = newprox
        return T

#Approximates all modules of a set S, using the modules of S
def allMods(G,tau,S):
        proxList = []
        for m in list(S):
                proxList.append(recur(m,G,tau,S))
        return proxList

#Computes the global dimensions of the endomorphism rings of all modules over the ring with AR quiver G and AR translate tau
def allSubsets(G,tau):
        #A list of finite global dimensions that have ocurred
        ll = []
        #The modules over the ring correspond to subsets of the nonzero modules in the AR quiver
        for l in powerset(set([0..len(G)-2])):
                S = set(l)
                #The maximum length of approximations of indecomposable summands of the module l computed so far
                ML = 0
                if S == set([]):
                        allClear = false
                else:
                        allClear = true
                for m in l:
                        #The approximation of indecomposable module m is computed
                        r = recur(m,G,tau,S)
                        if r == None:
                                #If the approximation was infinte, the global dimension of the endomorphism ring will be infinite as well
                                allClear = false
                                break
                        else:
                                #Finding the length of the approximation and updating the maximum length, if necessary
                                ml = 0
                                for a in r:
                                        if a != 0:
                                                ml = ml + 1
                                if ml > ML:
                                        ML = ml
                #If all approximations are found to be finite and the global dimension has not occurred previously, it is added to the list (actually I made a mistake in writing this part, and the length of the longest finite chain is added even if the global dimension is infinite; however, we later did a more detailed breakdown of the finite global dimensions which made this part of the code superfluous anyway. One could correct this error by putting this section of the code inside the next one, after "if allClear:"
                if (ML in ll) == false:
                        ll.append(ML)
                #If all approximations are found to be finite, the module, represented as a set of its indecomposable summands, is printed, along with its global dimension (the maximum length of approximations)
                if allClear:
                        print S
                        print 'max length: ', ML
                        sys.stdout.flush()
        #The list of all global dimensions that occurred is printed
        print 'Global Dimensions: ', ll

#A method to compute the minimal length of projective resolutions for a particular indecomposable summand of a particular module.
def projdim(v,G,tau,S):
        seq = recur(v,G,tau,S)
        if seq == None:
                return infinity
        elif seq[0] == zero_vector(len(seq[0])):
                return len(seq) -1
        else:
                return len(recur(v,G,tau,S))

#A method to compute the global dimension of the endomorphism ring of one module.
def gldim(G,tau,S):
        dims = []
        for v in S:
                dims.append(projdim(v,G,tau,S))
        return max(dims)